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__ 294