1*6777b538SAndroid Build Coastguard Worker // Copyright 2011 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_WIN_IAT_PATCH_FUNCTION_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_WIN_IAT_PATCH_FUNCTION_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <windows.h> 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 11*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h" 12*6777b538SAndroid Build Coastguard Worker 13*6777b538SAndroid Build Coastguard Worker namespace base { 14*6777b538SAndroid Build Coastguard Worker namespace win { 15*6777b538SAndroid Build Coastguard Worker 16*6777b538SAndroid Build Coastguard Worker // A class that encapsulates Import Address Table patching helpers and restores 17*6777b538SAndroid Build Coastguard Worker // the original function in the destructor. 18*6777b538SAndroid Build Coastguard Worker // 19*6777b538SAndroid Build Coastguard Worker // It will intercept functions for a specific DLL imported from another DLL. 20*6777b538SAndroid Build Coastguard Worker // This is the case when, for example, we want to intercept 21*6777b538SAndroid Build Coastguard Worker // CertDuplicateCertificateContext function (exported from crypt32.dll) called 22*6777b538SAndroid Build Coastguard Worker // by wininet.dll. 23*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT IATPatchFunction { 24*6777b538SAndroid Build Coastguard Worker public: 25*6777b538SAndroid Build Coastguard Worker IATPatchFunction(); 26*6777b538SAndroid Build Coastguard Worker 27*6777b538SAndroid Build Coastguard Worker IATPatchFunction(const IATPatchFunction&) = delete; 28*6777b538SAndroid Build Coastguard Worker IATPatchFunction& operator=(const IATPatchFunction&) = delete; 29*6777b538SAndroid Build Coastguard Worker 30*6777b538SAndroid Build Coastguard Worker ~IATPatchFunction(); 31*6777b538SAndroid Build Coastguard Worker 32*6777b538SAndroid Build Coastguard Worker // Intercept a function in an import table of a specific 33*6777b538SAndroid Build Coastguard Worker // module. Save the original function and the import 34*6777b538SAndroid Build Coastguard Worker // table address. These values will be used later 35*6777b538SAndroid Build Coastguard Worker // during Unpatch 36*6777b538SAndroid Build Coastguard Worker // 37*6777b538SAndroid Build Coastguard Worker // Arguments: 38*6777b538SAndroid Build Coastguard Worker // module Module to be intercepted 39*6777b538SAndroid Build Coastguard Worker // imported_from_module Module that exports the 'function_name' 40*6777b538SAndroid Build Coastguard Worker // function_name Name of the API to be intercepted 41*6777b538SAndroid Build Coastguard Worker // 42*6777b538SAndroid Build Coastguard Worker // Returns: Windows error code (winerror.h). NO_ERROR if successful 43*6777b538SAndroid Build Coastguard Worker // 44*6777b538SAndroid Build Coastguard Worker // Note: Patching a function will make the IAT patch take some "ownership" on 45*6777b538SAndroid Build Coastguard Worker // |module|. It will LoadLibrary(module) to keep the DLL alive until a call 46*6777b538SAndroid Build Coastguard Worker // to Unpatch(), which will call FreeLibrary() and allow the module to be 47*6777b538SAndroid Build Coastguard Worker // unloaded. The idea is to help prevent the DLL from going away while a 48*6777b538SAndroid Build Coastguard Worker // patch is still active. 49*6777b538SAndroid Build Coastguard Worker DWORD Patch(const wchar_t* module, 50*6777b538SAndroid Build Coastguard Worker const char* imported_from_module, 51*6777b538SAndroid Build Coastguard Worker const char* function_name, 52*6777b538SAndroid Build Coastguard Worker void* new_function); 53*6777b538SAndroid Build Coastguard Worker 54*6777b538SAndroid Build Coastguard Worker // Same as Patch(), but uses a handle to a |module| instead of the DLL name. 55*6777b538SAndroid Build Coastguard Worker DWORD PatchFromModule(HMODULE module, 56*6777b538SAndroid Build Coastguard Worker const char* imported_from_module, 57*6777b538SAndroid Build Coastguard Worker const char* function_name, 58*6777b538SAndroid Build Coastguard Worker void* new_function); 59*6777b538SAndroid Build Coastguard Worker 60*6777b538SAndroid Build Coastguard Worker // Unpatch the IAT entry using internally saved original 61*6777b538SAndroid Build Coastguard Worker // function. 62*6777b538SAndroid Build Coastguard Worker // 63*6777b538SAndroid Build Coastguard Worker // Returns: Windows error code (winerror.h). NO_ERROR if successful 64*6777b538SAndroid Build Coastguard Worker DWORD Unpatch(); 65*6777b538SAndroid Build Coastguard Worker is_patched()66*6777b538SAndroid Build Coastguard Worker bool is_patched() const { return (nullptr != intercept_function_); } 67*6777b538SAndroid Build Coastguard Worker 68*6777b538SAndroid Build Coastguard Worker void* original_function() const; 69*6777b538SAndroid Build Coastguard Worker 70*6777b538SAndroid Build Coastguard Worker private: 71*6777b538SAndroid Build Coastguard Worker HMODULE module_handle_ = nullptr; 72*6777b538SAndroid Build Coastguard Worker raw_ptr<void> intercept_function_ = nullptr; 73*6777b538SAndroid Build Coastguard Worker raw_ptr<void> original_function_ = nullptr; 74*6777b538SAndroid Build Coastguard Worker raw_ptr<IMAGE_THUNK_DATA> iat_thunk_ = nullptr; 75*6777b538SAndroid Build Coastguard Worker }; 76*6777b538SAndroid Build Coastguard Worker 77*6777b538SAndroid Build Coastguard Worker } // namespace win 78*6777b538SAndroid Build Coastguard Worker } // namespace base 79*6777b538SAndroid Build Coastguard Worker 80*6777b538SAndroid Build Coastguard Worker #endif // BASE_WIN_IAT_PATCH_FUNCTION_H_ 81