- add sources.
[platform/framework/web/crosswalk.git] / src / sandbox / win / src / sidestep / preamble_patcher.h
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__