xref: /aosp_15_r20/external/cronet/base/win/iat_patch_function.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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