• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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