Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(207)

Side by Side Diff: sandbox/src/sidestep/preamble_patcher.h

Issue 10689170: Move the Windows sandbox to sandbox/win (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase on top of tree (properly this time) Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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__
OLDNEW
« no previous file with comments | « sandbox/src/sidestep/mini_disassembler_types.h ('k') | sandbox/src/sidestep/preamble_patcher_with_stub.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698