OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 | |
5 /* | |
6 * Definition of PreamblePatcher | |
7 */ | |
8 | |
9 #ifndef MEMORY_WATCHER_PREAMBLE_PATCHER_H__ | |
10 #define MEMORY_WATCHER_PREAMBLE_PATCHER_H__ | |
11 | |
12 #include <windows.h> | |
13 | |
14 // compatibility shim | |
15 #include "base/logging.h" | |
16 #define ASSERT(cond, msg) DCHECK(cond) | |
17 #define ASSERT1(cond) DCHECK(cond) | |
18 | |
19 // Maximum size of the preamble stub. We overwrite at least the first 5 | |
20 // bytes of the function. Considering the worst case scenario, we need 4 | |
21 // bytes + the max instruction size + 5 more bytes for our jump back to | |
22 // the original code. With that in mind, 32 is a good number :) | |
23 #define MAX_PREAMBLE_STUB_SIZE (32) | |
24 | |
25 namespace sidestep { | |
26 | |
27 // Possible results of patching/unpatching | |
28 enum SideStepError { | |
29 SIDESTEP_SUCCESS = 0, | |
30 SIDESTEP_INVALID_PARAMETER, | |
31 SIDESTEP_INSUFFICIENT_BUFFER, | |
32 SIDESTEP_JUMP_INSTRUCTION, | |
33 SIDESTEP_FUNCTION_TOO_SMALL, | |
34 SIDESTEP_UNSUPPORTED_INSTRUCTION, | |
35 SIDESTEP_NO_SUCH_MODULE, | |
36 SIDESTEP_NO_SUCH_FUNCTION, | |
37 SIDESTEP_ACCESS_DENIED, | |
38 SIDESTEP_UNEXPECTED, | |
39 }; | |
40 | |
41 #define SIDESTEP_TO_HRESULT(error) \ | |
42 MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, error) | |
43 | |
44 // Implements a patching mechanism that overwrites the first few bytes of | |
45 // a function preamble with a jump to our hook function, which is then | |
46 // able to call the original function via a specially-made preamble-stub | |
47 // that imitates the action of the original preamble. | |
48 // | |
49 // NOTE: This patching mechanism should currently only be used for | |
50 // non-production code, e.g. unit tests, because it is not threadsafe. | |
51 // See the TODO in preamble_patcher_with_stub.cc for instructions on what | |
52 // we need to do before using it in production code; it's fairly simple | |
53 // but unnecessary for now since we only intend to use it in unit tests. | |
54 // | |
55 // To patch a function, use either of the typesafe Patch() methods. You | |
56 // can unpatch a function using Unpatch(). | |
57 // | |
58 // Typical usage goes something like this: | |
59 // @code | |
60 // typedef int (*MyTypesafeFuncPtr)(int x); | |
61 // MyTypesafeFuncPtr original_func_stub; | |
62 // int MyTypesafeFunc(int x) { return x + 1; } | |
63 // int HookMyTypesafeFunc(int x) { return 1 + original_func_stub(x); } | |
64 // | |
65 // void MyPatchInitializingFunction() { | |
66 // original_func_stub = PreamblePatcher::Patch( | |
67 // MyTypesafeFunc, HookMyTypesafeFunc); | |
68 // if (!original_func_stub) { | |
69 // // ... error handling ... | |
70 // } | |
71 // | |
72 // // ... continue - you have patched the function successfully ... | |
73 // } | |
74 // @endcode | |
75 // | |
76 // Note that there are a number of ways that this method of patching can | |
77 // fail. The most common are: | |
78 // - If there is a jump (jxx) instruction in the first 5 bytes of | |
79 // the function being patched, we cannot patch it because in the | |
80 // current implementation we do not know how to rewrite relative | |
81 // jumps after relocating them to the preamble-stub. Note that | |
82 // if you really really need to patch a function like this, it | |
83 // would be possible to add this functionality (but at some cost). | |
84 // - If there is a return (ret) instruction in the first 5 bytes | |
85 // we cannot patch the function because it may not be long enough | |
86 // for the jmp instruction we use to inject our patch. | |
87 // - If there is another thread currently executing within the bytes | |
88 // that are copied to the preamble stub, it will crash in an undefined | |
89 // way. | |
90 // | |
91 // If you get any other error than the above, you're either pointing the | |
92 // patcher at an invalid instruction (e.g. into the middle of a multi- | |
93 // byte instruction, or not at memory containing executable instructions) | |
94 // or, there may be a bug in the disassembler we use to find | |
95 // instruction boundaries. | |
96 // | |
97 // NOTE: In optimized builds, when you have very trivial functions that | |
98 // the compiler can reason do not have side effects, the compiler may | |
99 // reuse the result of calling the function with a given parameter, which | |
100 // may mean if you patch the function in between your patch will never get | |
101 // invoked. See preamble_patcher_test.cc for an example. | |
102 class PreamblePatcher { | |
103 public: | |
104 | |
105 // This is a typesafe version of RawPatch(), identical in all other | |
106 // ways than it takes a template parameter indicating the type of the | |
107 // function being patched. | |
108 // | |
109 // @param T The type of the function you are patching. Usually | |
110 // you will establish this type using a typedef, as in the following | |
111 // example: | |
112 // @code | |
113 // typedef BOOL (WINAPI *MessageBoxPtr)(HWND, LPCTSTR, LPCTSTR, UINT); | |
114 // MessageBoxPtr original = NULL; | |
115 // PreamblePatcher::Patch(MessageBox, Hook_MessageBox, &original); | |
116 // @endcode | |
117 template <class T> | |
118 static SideStepError Patch(T target_function, | |
119 T replacement_function, | |
120 T* original_function_stub) { | |
121 // NOTE: casting from a function to a pointer is contra the C++ | |
122 // spec. It's not safe on IA64, but is on i386. We use | |
123 // a C-style cast here to emphasize this is not legal C++. | |
124 return RawPatch((void*)(target_function), | |
125 (void*)(replacement_function), | |
126 (void**)(original_function_stub)); | |
127 } | |
128 | |
129 // Patches a named function imported from the named module using | |
130 // preamble patching. Uses RawPatch() to do the actual patching | |
131 // work. | |
132 // | |
133 // @param T The type of the function you are patching. Must | |
134 // exactly match the function you specify using module_name and | |
135 // function_name. | |
136 // | |
137 // @param module_name The name of the module from which the function | |
138 // is being imported. Note that the patch will fail if this module | |
139 // has not already been loaded into the current process. | |
140 // | |
141 // @param function_name The name of the function you wish to patch. | |
142 // | |
143 // @param replacement_function Your replacement function which | |
144 // will be called whenever code tries to call the original function. | |
145 // | |
146 // @param original_function_stub Pointer to memory that should receive a | |
147 // pointer that can be used (e.g. in the replacement function) to call the | |
148 // original function, or NULL to indicate failure. | |
149 // | |
150 // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS | |
151 // indicates success. | |
152 template <class T> | |
153 static SideStepError Patch(LPCTSTR module_name, | |
154 LPCSTR function_name, | |
155 T replacement_function, | |
156 T* original_function_stub) { | |
157 ASSERT1(module_name && function_name); | |
158 if (!module_name || !function_name) { | |
159 ASSERT(false, | |
160 "You must specify a module name and function name."); | |
161 return SIDESTEP_INVALID_PARAMETER; | |
162 } | |
163 HMODULE module = ::GetModuleHandle(module_name); | |
164 ASSERT1(module != NULL); | |
165 if (!module) { | |
166 ASSERT(false, "Invalid module name."); | |
167 return SIDESTEP_NO_SUCH_MODULE; | |
168 } | |
169 FARPROC existing_function = ::GetProcAddress(module, function_name); | |
170 if (!existing_function) { | |
171 return SIDESTEP_NO_SUCH_FUNCTION; | |
172 } | |
173 // NOTE: casting from a function to a pointer is contra the C++ | |
174 // spec. It's not safe on IA64, but is on i386. We use | |
175 // a C-style cast here to emphasize this is not legal C++. | |
176 return RawPatch((void*)existing_function, (void*)replacement_function, | |
177 (void**)(original_function_stub)); | |
178 } | |
179 | |
180 // Patches a function by overwriting its first few bytes with | |
181 // a jump to a different function. This is the "worker" function | |
182 // for each of the typesafe Patch() functions. In most cases, | |
183 // it is preferable to use the Patch() functions rather than | |
184 // this one as they do more checking at compile time. | |
185 // | |
186 // @param target_function A pointer to the function that should be | |
187 // patched. | |
188 // | |
189 // @param replacement_function A pointer to the function that should | |
190 // replace the target function. The replacement function must have | |
191 // exactly the same calling convention and parameters as the original | |
192 // function. | |
193 // | |
194 // @param original_function_stub Pointer to memory that should receive a | |
195 // pointer that can be used (e.g. in the replacement function) to call the | |
196 // original function, or NULL to indicate failure. | |
197 // | |
198 // @param original_function_stub Pointer to memory that should receive a | |
199 // pointer that can be used (e.g. in the replacement function) to call the | |
200 // original function, or NULL to indicate failure. | |
201 // | |
202 // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS | |
203 // indicates success. | |
204 // | |
205 // @note The preamble-stub (the memory pointed to by | |
206 // *original_function_stub) is allocated on the heap, and (in | |
207 // production binaries) never destroyed, resulting in a memory leak. This | |
208 // will be the case until we implement safe unpatching of a method. | |
209 // However, it is quite difficult to unpatch a method (because other | |
210 // threads in the process may be using it) so we are leaving it for now. | |
211 // See however UnsafeUnpatch, which can be used for binaries where you | |
212 // know only one thread is running, e.g. unit tests. | |
213 static SideStepError RawPatch(void* target_function, | |
214 void* replacement_function, | |
215 void** original_function_stub); | |
216 | |
217 // Unpatches target_function and deletes the stub that previously could be | |
218 // used to call the original version of the function. | |
219 // | |
220 // DELETES the stub that is passed to the function. | |
221 // | |
222 // @param target_function Pointer to the target function which was | |
223 // previously patched, i.e. a pointer which value should match the value | |
224 // of the symbol prior to patching it. | |
225 // | |
226 // @param replacement_function Pointer to the function target_function | |
227 // was patched to. | |
228 // | |
229 // @param original_function_stub Pointer to the stub returned when | |
230 // patching, that could be used to call the original version of the | |
231 // patched function. This function will also delete the stub, which after | |
232 // unpatching is useless. | |
233 // | |
234 // If your original call was | |
235 // origptr = Patch(VirtualAlloc, MyVirtualAlloc) | |
236 // then to undo it you would call | |
237 // Unpatch(VirtualAlloc, MyVirtualAlloc, origptr); | |
238 // | |
239 // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS | |
240 // indicates success. | |
241 static SideStepError Unpatch(void* target_function, | |
242 void* replacement_function, | |
243 void* original_function_stub); | |
244 | |
245 private: | |
246 | |
247 // Patches a function by overwriting its first few bytes with | |
248 // a jump to a different function. This is similar to the RawPatch | |
249 // function except that it uses the stub allocated by the caller | |
250 // instead of allocating it. | |
251 // | |
252 // We call VirtualProtect to make the | |
253 // target function writable at least for the duration of the call. | |
254 // | |
255 // @param target_function A pointer to the function that should be | |
256 // patched. | |
257 // | |
258 // @param replacement_function A pointer to the function that should | |
259 // replace the target function. The replacement function must have | |
260 // exactly the same calling convention and parameters as the original | |
261 // function. | |
262 // | |
263 // @param preamble_stub A pointer to a buffer where the preamble stub | |
264 // should be copied. The size of the buffer should be sufficient to | |
265 // hold the preamble bytes. | |
266 // | |
267 // @param stub_size Size in bytes of the buffer allocated for the | |
268 // preamble_stub | |
269 // | |
270 // @param bytes_needed Pointer to a variable that receives the minimum | |
271 // number of bytes required for the stub. Can be set to NULL if you're | |
272 // not interested. | |
273 // | |
274 // @return An error code indicating the result of patching. | |
275 static SideStepError RawPatchWithStubAndProtections(void* target_function, | |
276 void *replacement_function, | |
277 unsigned char* preamble_stub, | |
278 unsigned long stub_size, | |
279 unsigned long* bytes_needed); | |
280 | |
281 // A helper function used by RawPatchWithStubAndProtections -- it does | |
282 // everything but the VirtualProtect wsork. Defined in | |
283 // preamble_patcher_with_stub.cc. | |
284 static SideStepError RawPatchWithStub(void* target_function, | |
285 void *replacement_function, | |
286 unsigned char* preamble_stub, | |
287 unsigned long stub_size, | |
288 unsigned long* bytes_needed); | |
289 }; | |
290 | |
291 }; // namespace sidestep | |
292 | |
293 #endif // MEMORY_WATCHER_PREAMBLE_PATCHER_H__ | |
OLD | NEW |