| 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 // Definition of PreamblePatcher | |
| 6 | |
| 7 #ifndef SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__ | |
| 8 #define SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__ | |
| 9 | |
| 10 namespace sidestep { | |
| 11 | |
| 12 // Maximum size of the preamble stub. We overwrite at least the first 5 | |
| 13 // bytes of the function. Considering the worst case scenario, we need 4 | |
| 14 // bytes + the max instruction size + 5 more bytes for our jump back to | |
| 15 // the original code. With that in mind, 32 is a good number :) | |
| 16 const size_t kMaxPreambleStubSize = 32; | |
| 17 | |
| 18 // Possible results of patching/unpatching | |
| 19 enum SideStepError { | |
| 20 SIDESTEP_SUCCESS = 0, | |
| 21 SIDESTEP_INVALID_PARAMETER, | |
| 22 SIDESTEP_INSUFFICIENT_BUFFER, | |
| 23 SIDESTEP_JUMP_INSTRUCTION, | |
| 24 SIDESTEP_FUNCTION_TOO_SMALL, | |
| 25 SIDESTEP_UNSUPPORTED_INSTRUCTION, | |
| 26 SIDESTEP_NO_SUCH_MODULE, | |
| 27 SIDESTEP_NO_SUCH_FUNCTION, | |
| 28 SIDESTEP_ACCESS_DENIED, | |
| 29 SIDESTEP_UNEXPECTED, | |
| 30 }; | |
| 31 | |
| 32 // Implements a patching mechanism that overwrites the first few bytes of | |
| 33 // a function preamble with a jump to our hook function, which is then | |
| 34 // able to call the original function via a specially-made preamble-stub | |
| 35 // that imitates the action of the original preamble. | |
| 36 // | |
| 37 // Note that there are a number of ways that this method of patching can | |
| 38 // fail. The most common are: | |
| 39 // - If there is a jump (jxx) instruction in the first 5 bytes of | |
| 40 // the function being patched, we cannot patch it because in the | |
| 41 // current implementation we do not know how to rewrite relative | |
| 42 // jumps after relocating them to the preamble-stub. Note that | |
| 43 // if you really really need to patch a function like this, it | |
| 44 // would be possible to add this functionality (but at some cost). | |
| 45 // - If there is a return (ret) instruction in the first 5 bytes | |
| 46 // we cannot patch the function because it may not be long enough | |
| 47 // for the jmp instruction we use to inject our patch. | |
| 48 // - If there is another thread currently executing within the bytes | |
| 49 // that are copied to the preamble stub, it will crash in an undefined | |
| 50 // way. | |
| 51 // | |
| 52 // If you get any other error than the above, you're either pointing the | |
| 53 // patcher at an invalid instruction (e.g. into the middle of a multi- | |
| 54 // byte instruction, or not at memory containing executable instructions) | |
| 55 // or, there may be a bug in the disassembler we use to find | |
| 56 // instruction boundaries. | |
| 57 class PreamblePatcher { | |
| 58 public: | |
| 59 // Patches target_function to point to replacement_function using a provided | |
| 60 // preamble_stub of stub_size bytes. | |
| 61 // Returns An error code indicating the result of patching. | |
| 62 template <class T> | |
| 63 static SideStepError Patch(T target_function, T replacement_function, | |
| 64 void* preamble_stub, size_t stub_size) { | |
| 65 return RawPatchWithStub(target_function, replacement_function, | |
| 66 reinterpret_cast<unsigned char*>(preamble_stub), | |
| 67 stub_size, NULL); | |
| 68 } | |
| 69 | |
| 70 private: | |
| 71 | |
| 72 // Patches a function by overwriting its first few bytes with | |
| 73 // a jump to a different function. This is similar to the RawPatch | |
| 74 // function except that it uses the stub allocated by the caller | |
| 75 // instead of allocating it. | |
| 76 // | |
| 77 // To use this function, you first have to call VirtualProtect to make the | |
| 78 // target function writable at least for the duration of the call. | |
| 79 // | |
| 80 // target_function: A pointer to the function that should be | |
| 81 // patched. | |
| 82 // | |
| 83 // replacement_function: A pointer to the function that should | |
| 84 // replace the target function. The replacement function must have | |
| 85 // exactly the same calling convention and parameters as the original | |
| 86 // function. | |
| 87 // | |
| 88 // preamble_stub: A pointer to a buffer where the preamble stub | |
| 89 // should be copied. The size of the buffer should be sufficient to | |
| 90 // hold the preamble bytes. | |
| 91 // | |
| 92 // stub_size: Size in bytes of the buffer allocated for the | |
| 93 // preamble_stub | |
| 94 // | |
| 95 // bytes_needed: Pointer to a variable that receives the minimum | |
| 96 // number of bytes required for the stub. Can be set to NULL if you're | |
| 97 // not interested. | |
| 98 // | |
| 99 // Returns An error code indicating the result of patching. | |
| 100 static SideStepError RawPatchWithStub(void* target_function, | |
| 101 void *replacement_function, | |
| 102 unsigned char* preamble_stub, | |
| 103 size_t stub_size, | |
| 104 size_t* bytes_needed); | |
| 105 }; | |
| 106 | |
| 107 }; // namespace sidestep | |
| 108 | |
| 109 #endif // SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__ | |
| OLD | NEW |