Home | History | Annotate | Download | only in windows
      1 /* Copyright (c) 2007, Google Inc.
      2  * All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  *
     30  * ---
     31  * Author: Joi Sigurdsson
     32  * Author: Scott Francis
     33  *
     34  * Definition of PreamblePatcher
     35  */
     36 
     37 #ifndef GOOGLE_PERFTOOLS_PREAMBLE_PATCHER_H_
     38 #define GOOGLE_PERFTOOLS_PREAMBLE_PATCHER_H_
     39 
     40 #include "config.h"
     41 #include <windows.h>
     42 
     43 // compatibility shim
     44 #include "base/logging.h"
     45 #define SIDESTEP_ASSERT(cond)  RAW_DCHECK(cond, #cond)
     46 #define SIDESTEP_LOG(msg)      RAW_VLOG(1, msg)
     47 
     48 // Maximum size of the preamble stub. We overwrite at least the first 5
     49 // bytes of the function. Considering the worst case scenario, we need 4
     50 // bytes + the max instruction size + 5 more bytes for our jump back to
     51 // the original code. With that in mind, 32 is a good number :)
     52 #ifdef _M_X64
     53 // In 64-bit mode we may need more room.  In 64-bit mode all jumps must be
     54 // within +/-2GB of RIP.  Because of this limitation we may need to use a
     55 // trampoline to jump to the replacement function if it is further than 2GB
     56 // away from the target. The trampoline is 14 bytes.
     57 //
     58 // So 4 bytes + max instruction size (17 bytes) + 5 bytes to jump back to the
     59 // original code + trampoline size.  64 bytes is a nice number :-)
     60 #define MAX_PREAMBLE_STUB_SIZE    (64)
     61 #else
     62 #define MAX_PREAMBLE_STUB_SIZE    (32)
     63 #endif
     64 
     65 // Determines if this is a 64-bit binary.
     66 #ifdef _M_X64
     67 static const bool kIs64BitBinary = true;
     68 #else
     69 static const bool kIs64BitBinary = false;
     70 #endif
     71 
     72 namespace sidestep {
     73 
     74 // Possible results of patching/unpatching
     75 enum SideStepError {
     76   SIDESTEP_SUCCESS = 0,
     77   SIDESTEP_INVALID_PARAMETER,
     78   SIDESTEP_INSUFFICIENT_BUFFER,
     79   SIDESTEP_JUMP_INSTRUCTION,
     80   SIDESTEP_FUNCTION_TOO_SMALL,
     81   SIDESTEP_UNSUPPORTED_INSTRUCTION,
     82   SIDESTEP_NO_SUCH_MODULE,
     83   SIDESTEP_NO_SUCH_FUNCTION,
     84   SIDESTEP_ACCESS_DENIED,
     85   SIDESTEP_UNEXPECTED,
     86 };
     87 
     88 #define SIDESTEP_TO_HRESULT(error)                      \
     89   MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, error)
     90 
     91 class DeleteUnsignedCharArray;
     92 
     93 // Implements a patching mechanism that overwrites the first few bytes of
     94 // a function preamble with a jump to our hook function, which is then
     95 // able to call the original function via a specially-made preamble-stub
     96 // that imitates the action of the original preamble.
     97 //
     98 // NOTE:  This patching mechanism should currently only be used for
     99 // non-production code, e.g. unit tests, because it is not threadsafe.
    100 // See the TODO in preamble_patcher_with_stub.cc for instructions on what
    101 // we need to do before using it in production code; it's fairly simple
    102 // but unnecessary for now since we only intend to use it in unit tests.
    103 //
    104 // To patch a function, use either of the typesafe Patch() methods.  You
    105 // can unpatch a function using Unpatch().
    106 //
    107 // Typical usage goes something like this:
    108 // @code
    109 // typedef int (*MyTypesafeFuncPtr)(int x);
    110 // MyTypesafeFuncPtr original_func_stub;
    111 // int MyTypesafeFunc(int x) { return x + 1; }
    112 // int HookMyTypesafeFunc(int x) { return 1 + original_func_stub(x); }
    113 //
    114 // void MyPatchInitializingFunction() {
    115 //   original_func_stub = PreamblePatcher::Patch(
    116 //              MyTypesafeFunc, HookMyTypesafeFunc);
    117 //   if (!original_func_stub) {
    118 //     // ... error handling ...
    119 //   }
    120 //
    121 //   // ... continue - you have patched the function successfully ...
    122 // }
    123 // @endcode
    124 //
    125 // Note that there are a number of ways that this method of patching can
    126 // fail.  The most common are:
    127 //    - If there is a jump (jxx) instruction in the first 5 bytes of
    128 //    the function being patched, we cannot patch it because in the
    129 //    current implementation we do not know how to rewrite relative
    130 //    jumps after relocating them to the preamble-stub.  Note that
    131 //    if you really really need to patch a function like this, it
    132 //    would be possible to add this functionality (but at some cost).
    133 //    - If there is a return (ret) instruction in the first 5 bytes
    134 //    we cannot patch the function because it may not be long enough
    135 //    for the jmp instruction we use to inject our patch.
    136 //    - If there is another thread currently executing within the bytes
    137 //    that are copied to the preamble stub, it will crash in an undefined
    138 //    way.
    139 //
    140 // If you get any other error than the above, you're either pointing the
    141 // patcher at an invalid instruction (e.g. into the middle of a multi-
    142 // byte instruction, or not at memory containing executable instructions)
    143 // or, there may be a bug in the disassembler we use to find
    144 // instruction boundaries.
    145 //
    146 // NOTE:  In optimized builds, when you have very trivial functions that
    147 // the compiler can reason do not have side effects, the compiler may
    148 // reuse the result of calling the function with a given parameter, which
    149 // may mean if you patch the function in between your patch will never get
    150 // invoked.  See preamble_patcher_test.cc for an example.
    151 class PERFTOOLS_DLL_DECL PreamblePatcher {
    152  public:
    153 
    154   // This is a typesafe version of RawPatch(), identical in all other
    155   // ways than it takes a template parameter indicating the type of the
    156   // function being patched.
    157   //
    158   // @param T The type of the function you are patching. Usually
    159   // you will establish this type using a typedef, as in the following
    160   // example:
    161   // @code
    162   // typedef BOOL (WINAPI *MessageBoxPtr)(HWND, LPCTSTR, LPCTSTR, UINT);
    163   // MessageBoxPtr original = NULL;
    164   // PreamblePatcher::Patch(MessageBox, Hook_MessageBox, &original);
    165   // @endcode
    166   template <class T>
    167   static SideStepError Patch(T target_function,
    168                              T replacement_function,
    169                              T* original_function_stub) {
    170     // NOTE: casting from a function to a pointer is contra the C++
    171     //       spec.  It's not safe on IA64, but is on i386.  We use
    172     //       a C-style cast here to emphasize this is not legal C++.
    173     return RawPatch((void*)(target_function),
    174                     (void*)(replacement_function),
    175                     (void**)(original_function_stub));
    176   }
    177 
    178   // Patches a named function imported from the named module using
    179   // preamble patching.  Uses RawPatch() to do the actual patching
    180   // work.
    181   //
    182   // @param T The type of the function you are patching.  Must
    183   // exactly match the function you specify using module_name and
    184   // function_name.
    185   //
    186   // @param module_name The name of the module from which the function
    187   // is being imported.  Note that the patch will fail if this module
    188   // has not already been loaded into the current process.
    189   //
    190   // @param function_name The name of the function you wish to patch.
    191   //
    192   // @param replacement_function Your replacement function which
    193   // will be called whenever code tries to call the original function.
    194   //
    195   // @param original_function_stub Pointer to memory that should receive a
    196   // pointer that can be used (e.g. in the replacement function) to call the
    197   // original function, or NULL to indicate failure.
    198   //
    199   // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS
    200   // indicates success.
    201   template <class T>
    202   static SideStepError Patch(LPCTSTR module_name,
    203                              LPCSTR function_name,
    204                              T replacement_function,
    205                              T* original_function_stub) {
    206     SIDESTEP_ASSERT(module_name && function_name);
    207     if (!module_name || !function_name) {
    208       SIDESTEP_ASSERT(false &&
    209                       "You must specify a module name and function name.");
    210       return SIDESTEP_INVALID_PARAMETER;
    211     }
    212     HMODULE module = ::GetModuleHandle(module_name);
    213     SIDESTEP_ASSERT(module != NULL);
    214     if (!module) {
    215       SIDESTEP_ASSERT(false && "Invalid module name.");
    216       return SIDESTEP_NO_SUCH_MODULE;
    217     }
    218     FARPROC existing_function = ::GetProcAddress(module, function_name);
    219     if (!existing_function) {
    220       SIDESTEP_ASSERT(
    221           false && "Did not find any function with that name in the module.");
    222       return SIDESTEP_NO_SUCH_FUNCTION;
    223     }
    224     // NOTE: casting from a function to a pointer is contra the C++
    225     //       spec.  It's not safe on IA64, but is on i386.  We use
    226     //       a C-style cast here to emphasize this is not legal C++.
    227     return RawPatch((void*)existing_function, (void*)replacement_function,
    228                     (void**)(original_function_stub));
    229   }
    230 
    231   // Patches a function by overwriting its first few bytes with
    232   // a jump to a different function.  This is the "worker" function
    233   // for each of the typesafe Patch() functions.  In most cases,
    234   // it is preferable to use the Patch() functions rather than
    235   // this one as they do more checking at compile time.
    236   //
    237   // @param target_function A pointer to the function that should be
    238   // patched.
    239   //
    240   // @param replacement_function A pointer to the function that should
    241   // replace the target function.  The replacement function must have
    242   // exactly the same calling convention and parameters as the original
    243   // function.
    244   //
    245   // @param original_function_stub Pointer to memory that should receive a
    246   // pointer that can be used (e.g. in the replacement function) to call the
    247   // original function, or NULL to indicate failure.
    248   //
    249   // @param original_function_stub Pointer to memory that should receive a
    250   // pointer that can be used (e.g. in the replacement function) to call the
    251   // original function, or NULL to indicate failure.
    252   //
    253   // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS
    254   // indicates success.
    255   //
    256   // @note The preamble-stub (the memory pointed to by
    257   // *original_function_stub) is allocated on the heap, and (in
    258   // production binaries) never destroyed, resulting in a memory leak.  This
    259   // will be the case until we implement safe unpatching of a method.
    260   // However, it is quite difficult to unpatch a method (because other
    261   // threads in the process may be using it) so we are leaving it for now.
    262   // See however UnsafeUnpatch, which can be used for binaries where you
    263   // know only one thread is running, e.g. unit tests.
    264   static SideStepError RawPatch(void* target_function,
    265                                 void* replacement_function,
    266                                 void** original_function_stub);
    267 
    268   // Unpatches target_function and deletes the stub that previously could be
    269   // used to call the original version of the function.
    270   //
    271   // DELETES the stub that is passed to the function.
    272   //
    273   // @param target_function Pointer to the target function which was
    274   // previously patched, i.e. a pointer which value should match the value
    275   // of the symbol prior to patching it.
    276   //
    277   // @param replacement_function Pointer to the function target_function
    278   // was patched to.
    279   //
    280   // @param original_function_stub Pointer to the stub returned when
    281   // patching, that could be used to call the original version of the
    282   // patched function.  This function will also delete the stub, which after
    283   // unpatching is useless.
    284   //
    285   // If your original call was
    286   //    Patch(VirtualAlloc, MyVirtualAlloc, &origptr)
    287   // then to undo it you would call
    288   //    Unpatch(VirtualAlloc, MyVirtualAlloc, origptr);
    289   //
    290   // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS
    291   // indicates success.
    292   static SideStepError Unpatch(void* target_function,
    293                                void* replacement_function,
    294                                void* original_function_stub);
    295 
    296   // A helper routine when patching, which follows jmp instructions at
    297   // function addresses, to get to the "actual" function contents.
    298   // This allows us to identify two functions that are at different
    299   // addresses but actually resolve to the same code.
    300   //
    301   // @param target_function Pointer to a function.
    302   //
    303   // @return Either target_function (the input parameter), or if
    304   // target_function's body consists entirely of a JMP instruction,
    305   // the address it JMPs to (or more precisely, the address at the end
    306   // of a chain of JMPs).
    307   template <class T>
    308   static T ResolveTarget(T target_function) {
    309     return (T)ResolveTargetImpl((unsigned char*)target_function, NULL);
    310   }
    311 
    312   // Allocates a block of memory of size MAX_PREAMBLE_STUB_SIZE that is as
    313   // close (within 2GB) as possible to target.  This is done to ensure that
    314   // we can perform a relative jump from target to a trampoline if the
    315   // replacement function is > +-2GB from target.  This means that we only need
    316   // to patch 5 bytes in the target function.
    317   //
    318   // @param target    Pointer to target function.
    319   //
    320   // @return  Returns a block of memory of size MAX_PREAMBLE_STUB_SIZE that can
    321   //          be used to store a function preamble block.
    322   static unsigned char* AllocPreambleBlockNear(void* target);
    323 
    324   // Frees a block allocated by AllocPreambleBlockNear.
    325   //
    326   // @param block     Block that was returned by AllocPreambleBlockNear.
    327   static void FreePreambleBlock(unsigned char* block);
    328 
    329  private:
    330   friend class DeleteUnsignedCharArray;
    331 
    332    // Used to store data allocated for preamble stubs
    333   struct PreamblePage {
    334     unsigned int magic_;
    335     PreamblePage* next_;
    336     // This member points to a linked list of free blocks within the page
    337     // or NULL if at the end
    338     void* free_;
    339   };
    340 
    341   // In 64-bit mode, the replacement function must be within 2GB of the original
    342   // target in order to only require 5 bytes for the function patch.  To meet
    343   // this requirement we're creating an allocator within this class to
    344   // allocate blocks that are within 2GB of a given target. This member is the
    345   // head of a linked list of pages used to allocate blocks that are within
    346   // 2GB of the target.
    347   static PreamblePage* preamble_pages_;
    348 
    349   // Page granularity
    350   static long granularity_;
    351 
    352   // Page size
    353   static long pagesize_;
    354 
    355   // Determines if the patcher has been initialized.
    356   static bool initialized_;
    357 
    358   // Used to initialize static members.
    359   static void Initialize();
    360 
    361   // Patches a function by overwriting its first few bytes with
    362   // a jump to a different function.  This is similar to the RawPatch
    363   // function except that it uses the stub allocated by the caller
    364   // instead of allocating it.
    365   //
    366   // We call VirtualProtect to make the
    367   // target function writable at least for the duration of the call.
    368   //
    369   // @param target_function A pointer to the function that should be
    370   // patched.
    371   //
    372   // @param replacement_function A pointer to the function that should
    373   // replace the target function.  The replacement function must have
    374   // exactly the same calling convention and parameters as the original
    375   // function.
    376   //
    377   // @param preamble_stub A pointer to a buffer where the preamble stub
    378   // should be copied. The size of the buffer should be sufficient to
    379   // hold the preamble bytes.
    380   //
    381   // @param stub_size Size in bytes of the buffer allocated for the
    382   // preamble_stub
    383   //
    384   // @param bytes_needed Pointer to a variable that receives the minimum
    385   // number of bytes required for the stub.  Can be set to NULL if you're
    386   // not interested.
    387   //
    388   // @return An error code indicating the result of patching.
    389   static SideStepError RawPatchWithStubAndProtections(
    390       void* target_function,
    391       void* replacement_function,
    392       unsigned char* preamble_stub,
    393       unsigned long stub_size,
    394       unsigned long* bytes_needed);
    395 
    396   // A helper function used by RawPatchWithStubAndProtections -- it
    397   // does everything but the VirtualProtect work.  Defined in
    398   // preamble_patcher_with_stub.cc.
    399   //
    400   // @param target_function A pointer to the function that should be
    401   // patched.
    402   //
    403   // @param replacement_function A pointer to the function that should
    404   // replace the target function.  The replacement function must have
    405   // exactly the same calling convention and parameters as the original
    406   // function.
    407   //
    408   // @param preamble_stub A pointer to a buffer where the preamble stub
    409   // should be copied. The size of the buffer should be sufficient to
    410   // hold the preamble bytes.
    411   //
    412   // @param stub_size Size in bytes of the buffer allocated for the
    413   // preamble_stub
    414   //
    415   // @param bytes_needed Pointer to a variable that receives the minimum
    416   // number of bytes required for the stub.  Can be set to NULL if you're
    417   // not interested.
    418   //
    419   // @return An error code indicating the result of patching.
    420   static SideStepError RawPatchWithStub(void* target_function,
    421                                         void* replacement_function,
    422                                         unsigned char* preamble_stub,
    423                                         unsigned long stub_size,
    424                                         unsigned long* bytes_needed);
    425 
    426 
    427   // A helper routine when patching, which follows jmp instructions at
    428   // function addresses, to get to the "actual" function contents.
    429   // This allows us to identify two functions that are at different
    430   // addresses but actually resolve to the same code.
    431   //
    432   // @param target_function Pointer to a function.
    433   //
    434   // @param stop_before If, when following JMP instructions from
    435   // target_function, we get to the address stop, we return
    436   // immediately, the address that jumps to stop_before.
    437   //
    438   // @param stop_before_trampoline  When following JMP instructions from
    439   // target_function, stop before a trampoline is detected.  See comment in
    440   // PreamblePatcher::RawPatchWithStub for more information.  This parameter
    441   // has no effect in 32-bit mode.
    442   //
    443   // @return Either target_function (the input parameter), or if
    444   // target_function's body consists entirely of a JMP instruction,
    445   // the address it JMPs to (or more precisely, the address at the end
    446   // of a chain of JMPs).
    447   static void* ResolveTargetImpl(unsigned char* target_function,
    448                                  unsigned char* stop_before,
    449                                  bool stop_before_trampoline = false);
    450 
    451   // Helper routine that attempts to allocate a page as close (within 2GB)
    452   // as possible to target.
    453   //
    454   // @param target    Pointer to target function.
    455   //
    456   // @return   Returns an address that is within 2GB of target.
    457   static void* AllocPageNear(void* target);
    458 
    459   // Helper routine that determines if a target instruction is a short
    460   // conditional jump.
    461   //
    462   // @param target            Pointer to instruction.
    463   //
    464   // @param instruction_size  Size of the instruction in bytes.
    465   //
    466   // @return  Returns true if the instruction is a short conditional jump.
    467   static bool IsShortConditionalJump(unsigned char* target,
    468                                      unsigned int instruction_size);
    469 
    470   // Helper routine that determines if a target instruction is a near
    471   // conditional jump.
    472   //
    473   // @param target            Pointer to instruction.
    474   //
    475   // @param instruction_size  Size of the instruction in bytes.
    476   //
    477   // @return  Returns true if the instruction is a near conditional jump.
    478   static bool IsNearConditionalJump(unsigned char* target,
    479                                     unsigned int instruction_size);
    480 
    481   // Helper routine that determines if a target instruction is a near
    482   // relative jump.
    483   //
    484   // @param target            Pointer to instruction.
    485   //
    486   // @param instruction_size  Size of the instruction in bytes.
    487   //
    488   // @return  Returns true if the instruction is a near absolute jump.
    489   static bool IsNearRelativeJump(unsigned char* target,
    490                                  unsigned int instruction_size);
    491 
    492   // Helper routine that determines if a target instruction is a near
    493   // absolute call.
    494   //
    495   // @param target            Pointer to instruction.
    496   //
    497   // @param instruction_size  Size of the instruction in bytes.
    498   //
    499   // @return  Returns true if the instruction is a near absolute call.
    500   static bool IsNearAbsoluteCall(unsigned char* target,
    501                                  unsigned int instruction_size);
    502 
    503   // Helper routine that determines if a target instruction is a near
    504   // absolute call.
    505   //
    506   // @param target            Pointer to instruction.
    507   //
    508   // @param instruction_size  Size of the instruction in bytes.
    509   //
    510   // @return  Returns true if the instruction is a near absolute call.
    511   static bool IsNearRelativeCall(unsigned char* target,
    512                                  unsigned int instruction_size);
    513 
    514   // Helper routine that determines if a target instruction is a 64-bit MOV
    515   // that uses a RIP-relative displacement.
    516   //
    517   // @param target            Pointer to instruction.
    518   //
    519   // @param instruction_size  Size of the instruction in bytes.
    520   //
    521   // @return  Returns true if the instruction is a MOV with displacement.
    522   static bool IsMovWithDisplacement(unsigned char* target,
    523                                     unsigned int instruction_size);
    524 
    525   // Helper routine that converts a short conditional jump instruction
    526   // to a near conditional jump in a target buffer.  Note that the target
    527   // buffer must be within 2GB of the source for the near jump to work.
    528   //
    529   // A short conditional jump instruction is in the format:
    530   // 7x xx = Jcc rel8off
    531   //
    532   // @param source              Pointer to instruction.
    533   //
    534   // @param instruction_size    Size of the instruction.
    535   //
    536   // @param target              Target buffer to write the new instruction.
    537   //
    538   // @param target_bytes        Pointer to a buffer that contains the size
    539   //                            of the target instruction, in bytes.
    540   //
    541   // @param target_size         Size of the target buffer.
    542   //
    543   // @return  Returns SIDESTEP_SUCCESS if successful, otherwise an error.
    544   static SideStepError PatchShortConditionalJump(unsigned char* source,
    545                                                  unsigned int instruction_size,
    546                                                  unsigned char* target,
    547                                                  unsigned int* target_bytes,
    548                                                  unsigned int target_size);
    549 
    550   // Helper routine that converts an instruction that will convert various
    551   // jump-like instructions to corresponding instructions in the target buffer.
    552   // What this routine does is fix up the relative offsets contained in jump
    553   // instructions to point back to the original target routine.  Like with
    554   // PatchShortConditionalJump, the target buffer must be within 2GB of the
    555   // source.
    556   //
    557   // We currently handle the following instructions:
    558   //
    559   // E9 xx xx xx xx     = JMP rel32off
    560   // 0F 8x xx xx xx xx  = Jcc rel32off
    561   // FF /2 xx xx xx xx  = CALL reg/mem32/mem64
    562   // E8 xx xx xx xx     = CALL rel32off
    563   //
    564   // It should not be hard to update this function to support other
    565   // instructions that jump to relative targets.
    566   //
    567   // @param source              Pointer to instruction.
    568   //
    569   // @param instruction_size    Size of the instruction.
    570   //
    571   // @param target              Target buffer to write the new instruction.
    572   //
    573   // @param target_bytes        Pointer to a buffer that contains the size
    574   //                            of the target instruction, in bytes.
    575   //
    576   // @param target_size         Size of the target buffer.
    577   //
    578   // @return  Returns SIDESTEP_SUCCESS if successful, otherwise an error.
    579   static SideStepError PatchNearJumpOrCall(unsigned char* source,
    580                                            unsigned int instruction_size,
    581                                            unsigned char* target,
    582                                            unsigned int* target_bytes,
    583                                            unsigned int target_size);
    584 
    585   // Helper routine that patches a 64-bit MOV instruction with a RIP-relative
    586   // displacement.  The target buffer must be within 2GB of the source.
    587   //
    588   // 48 8B 0D XX XX XX XX = MOV rel32off
    589   //
    590   // @param source              Pointer to instruction.
    591   //
    592   // @param instruction_size    Size of the instruction.
    593   //
    594   // @param target              Target buffer to write the new instruction.
    595   //
    596   // @param target_bytes        Pointer to a buffer that contains the size
    597   //                            of the target instruction, in bytes.
    598   //
    599   // @param target_size         Size of the target buffer.
    600   //
    601   // @return  Returns SIDESTEP_SUCCESS if successful, otherwise an error.
    602   static SideStepError PatchMovWithDisplacement(unsigned char* source,
    603                                                 unsigned int instruction_size,
    604                                                 unsigned char* target,
    605                                                 unsigned int* target_bytes,
    606                                                 unsigned int target_size);
    607 };
    608 
    609 };  // namespace sidestep
    610 
    611 #endif  // GOOGLE_PERFTOOLS_PREAMBLE_PATCHER_H_
    612