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 |