iat_patch_function.h 2.7 KB

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