security/sandbox/win/src/sidestep/preamble_patcher.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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.
     5 // Definition of PreamblePatcher
     7 #ifndef SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__
     8 #define SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__
    10 #include <stddef.h>
    12 namespace sidestep {
    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;
    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 };
    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   }
    72  private:
    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 };
   109 };  // namespace sidestep
   111 #endif  // SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__

mercurial