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