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