| Index: tools/memory_watcher/preamble_patcher.h
|
| diff --git a/tools/memory_watcher/preamble_patcher.h b/tools/memory_watcher/preamble_patcher.h
|
| deleted file mode 100644
|
| index fae2551bd7b247c5e7d35f5021f95ba7a8c531ff..0000000000000000000000000000000000000000
|
| --- a/tools/memory_watcher/preamble_patcher.h
|
| +++ /dev/null
|
| @@ -1,293 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -/*
|
| - * Definition of PreamblePatcher
|
| - */
|
| -
|
| -#ifndef MEMORY_WATCHER_PREAMBLE_PATCHER_H__
|
| -#define MEMORY_WATCHER_PREAMBLE_PATCHER_H__
|
| -
|
| -#include <windows.h>
|
| -
|
| -// compatibility shim
|
| -#include "base/logging.h"
|
| -#define ASSERT(cond, msg) DCHECK(cond)
|
| -#define ASSERT1(cond) DCHECK(cond)
|
| -
|
| -// Maximum size of the preamble stub. We overwrite at least the first 5
|
| -// bytes of the function. Considering the worst case scenario, we need 4
|
| -// bytes + the max instruction size + 5 more bytes for our jump back to
|
| -// the original code. With that in mind, 32 is a good number :)
|
| -#define MAX_PREAMBLE_STUB_SIZE (32)
|
| -
|
| -namespace sidestep {
|
| -
|
| -// Possible results of patching/unpatching
|
| -enum SideStepError {
|
| - SIDESTEP_SUCCESS = 0,
|
| - SIDESTEP_INVALID_PARAMETER,
|
| - SIDESTEP_INSUFFICIENT_BUFFER,
|
| - SIDESTEP_JUMP_INSTRUCTION,
|
| - SIDESTEP_FUNCTION_TOO_SMALL,
|
| - SIDESTEP_UNSUPPORTED_INSTRUCTION,
|
| - SIDESTEP_NO_SUCH_MODULE,
|
| - SIDESTEP_NO_SUCH_FUNCTION,
|
| - SIDESTEP_ACCESS_DENIED,
|
| - SIDESTEP_UNEXPECTED,
|
| -};
|
| -
|
| -#define SIDESTEP_TO_HRESULT(error) \
|
| - MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, error)
|
| -
|
| -// Implements a patching mechanism that overwrites the first few bytes of
|
| -// a function preamble with a jump to our hook function, which is then
|
| -// able to call the original function via a specially-made preamble-stub
|
| -// that imitates the action of the original preamble.
|
| -//
|
| -// NOTE: This patching mechanism should currently only be used for
|
| -// non-production code, e.g. unit tests, because it is not threadsafe.
|
| -// See the TODO in preamble_patcher_with_stub.cc for instructions on what
|
| -// we need to do before using it in production code; it's fairly simple
|
| -// but unnecessary for now since we only intend to use it in unit tests.
|
| -//
|
| -// To patch a function, use either of the typesafe Patch() methods. You
|
| -// can unpatch a function using Unpatch().
|
| -//
|
| -// Typical usage goes something like this:
|
| -// @code
|
| -// typedef int (*MyTypesafeFuncPtr)(int x);
|
| -// MyTypesafeFuncPtr original_func_stub;
|
| -// int MyTypesafeFunc(int x) { return x + 1; }
|
| -// int HookMyTypesafeFunc(int x) { return 1 + original_func_stub(x); }
|
| -//
|
| -// void MyPatchInitializingFunction() {
|
| -// original_func_stub = PreamblePatcher::Patch(
|
| -// MyTypesafeFunc, HookMyTypesafeFunc);
|
| -// if (!original_func_stub) {
|
| -// // ... error handling ...
|
| -// }
|
| -//
|
| -// // ... continue - you have patched the function successfully ...
|
| -// }
|
| -// @endcode
|
| -//
|
| -// Note that there are a number of ways that this method of patching can
|
| -// fail. The most common are:
|
| -// - If there is a jump (jxx) instruction in the first 5 bytes of
|
| -// the function being patched, we cannot patch it because in the
|
| -// current implementation we do not know how to rewrite relative
|
| -// jumps after relocating them to the preamble-stub. Note that
|
| -// if you really really need to patch a function like this, it
|
| -// would be possible to add this functionality (but at some cost).
|
| -// - If there is a return (ret) instruction in the first 5 bytes
|
| -// we cannot patch the function because it may not be long enough
|
| -// for the jmp instruction we use to inject our patch.
|
| -// - If there is another thread currently executing within the bytes
|
| -// that are copied to the preamble stub, it will crash in an undefined
|
| -// way.
|
| -//
|
| -// If you get any other error than the above, you're either pointing the
|
| -// patcher at an invalid instruction (e.g. into the middle of a multi-
|
| -// byte instruction, or not at memory containing executable instructions)
|
| -// or, there may be a bug in the disassembler we use to find
|
| -// instruction boundaries.
|
| -//
|
| -// NOTE: In optimized builds, when you have very trivial functions that
|
| -// the compiler can reason do not have side effects, the compiler may
|
| -// reuse the result of calling the function with a given parameter, which
|
| -// may mean if you patch the function in between your patch will never get
|
| -// invoked. See preamble_patcher_test.cc for an example.
|
| -class PreamblePatcher {
|
| - public:
|
| -
|
| - // This is a typesafe version of RawPatch(), identical in all other
|
| - // ways than it takes a template parameter indicating the type of the
|
| - // function being patched.
|
| - //
|
| - // @param T The type of the function you are patching. Usually
|
| - // you will establish this type using a typedef, as in the following
|
| - // example:
|
| - // @code
|
| - // typedef BOOL (WINAPI *MessageBoxPtr)(HWND, LPCTSTR, LPCTSTR, UINT);
|
| - // MessageBoxPtr original = NULL;
|
| - // PreamblePatcher::Patch(MessageBox, Hook_MessageBox, &original);
|
| - // @endcode
|
| - template <class T>
|
| - static SideStepError Patch(T target_function,
|
| - T replacement_function,
|
| - T* original_function_stub) {
|
| - // NOTE: casting from a function to a pointer is contra the C++
|
| - // spec. It's not safe on IA64, but is on i386. We use
|
| - // a C-style cast here to emphasize this is not legal C++.
|
| - return RawPatch((void*)(target_function),
|
| - (void*)(replacement_function),
|
| - (void**)(original_function_stub));
|
| - }
|
| -
|
| - // Patches a named function imported from the named module using
|
| - // preamble patching. Uses RawPatch() to do the actual patching
|
| - // work.
|
| - //
|
| - // @param T The type of the function you are patching. Must
|
| - // exactly match the function you specify using module_name and
|
| - // function_name.
|
| - //
|
| - // @param module_name The name of the module from which the function
|
| - // is being imported. Note that the patch will fail if this module
|
| - // has not already been loaded into the current process.
|
| - //
|
| - // @param function_name The name of the function you wish to patch.
|
| - //
|
| - // @param replacement_function Your replacement function which
|
| - // will be called whenever code tries to call the original function.
|
| - //
|
| - // @param original_function_stub Pointer to memory that should receive a
|
| - // pointer that can be used (e.g. in the replacement function) to call the
|
| - // original function, or NULL to indicate failure.
|
| - //
|
| - // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS
|
| - // indicates success.
|
| - template <class T>
|
| - static SideStepError Patch(LPCTSTR module_name,
|
| - LPCSTR function_name,
|
| - T replacement_function,
|
| - T* original_function_stub) {
|
| - ASSERT1(module_name && function_name);
|
| - if (!module_name || !function_name) {
|
| - ASSERT(false,
|
| - "You must specify a module name and function name.");
|
| - return SIDESTEP_INVALID_PARAMETER;
|
| - }
|
| - HMODULE module = ::GetModuleHandle(module_name);
|
| - ASSERT1(module != NULL);
|
| - if (!module) {
|
| - ASSERT(false, "Invalid module name.");
|
| - return SIDESTEP_NO_SUCH_MODULE;
|
| - }
|
| - FARPROC existing_function = ::GetProcAddress(module, function_name);
|
| - if (!existing_function) {
|
| - return SIDESTEP_NO_SUCH_FUNCTION;
|
| - }
|
| - // NOTE: casting from a function to a pointer is contra the C++
|
| - // spec. It's not safe on IA64, but is on i386. We use
|
| - // a C-style cast here to emphasize this is not legal C++.
|
| - return RawPatch((void*)existing_function, (void*)replacement_function,
|
| - (void**)(original_function_stub));
|
| - }
|
| -
|
| - // Patches a function by overwriting its first few bytes with
|
| - // a jump to a different function. This is the "worker" function
|
| - // for each of the typesafe Patch() functions. In most cases,
|
| - // it is preferable to use the Patch() functions rather than
|
| - // this one as they do more checking at compile time.
|
| - //
|
| - // @param target_function A pointer to the function that should be
|
| - // patched.
|
| - //
|
| - // @param replacement_function A pointer to the function that should
|
| - // replace the target function. The replacement function must have
|
| - // exactly the same calling convention and parameters as the original
|
| - // function.
|
| - //
|
| - // @param original_function_stub Pointer to memory that should receive a
|
| - // pointer that can be used (e.g. in the replacement function) to call the
|
| - // original function, or NULL to indicate failure.
|
| - //
|
| - // @param original_function_stub Pointer to memory that should receive a
|
| - // pointer that can be used (e.g. in the replacement function) to call the
|
| - // original function, or NULL to indicate failure.
|
| - //
|
| - // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS
|
| - // indicates success.
|
| - //
|
| - // @note The preamble-stub (the memory pointed to by
|
| - // *original_function_stub) is allocated on the heap, and (in
|
| - // production binaries) never destroyed, resulting in a memory leak. This
|
| - // will be the case until we implement safe unpatching of a method.
|
| - // However, it is quite difficult to unpatch a method (because other
|
| - // threads in the process may be using it) so we are leaving it for now.
|
| - // See however UnsafeUnpatch, which can be used for binaries where you
|
| - // know only one thread is running, e.g. unit tests.
|
| - static SideStepError RawPatch(void* target_function,
|
| - void* replacement_function,
|
| - void** original_function_stub);
|
| -
|
| - // Unpatches target_function and deletes the stub that previously could be
|
| - // used to call the original version of the function.
|
| - //
|
| - // DELETES the stub that is passed to the function.
|
| - //
|
| - // @param target_function Pointer to the target function which was
|
| - // previously patched, i.e. a pointer which value should match the value
|
| - // of the symbol prior to patching it.
|
| - //
|
| - // @param replacement_function Pointer to the function target_function
|
| - // was patched to.
|
| - //
|
| - // @param original_function_stub Pointer to the stub returned when
|
| - // patching, that could be used to call the original version of the
|
| - // patched function. This function will also delete the stub, which after
|
| - // unpatching is useless.
|
| - //
|
| - // If your original call was
|
| - // origptr = Patch(VirtualAlloc, MyVirtualAlloc)
|
| - // then to undo it you would call
|
| - // Unpatch(VirtualAlloc, MyVirtualAlloc, origptr);
|
| - //
|
| - // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS
|
| - // indicates success.
|
| - static SideStepError Unpatch(void* target_function,
|
| - void* replacement_function,
|
| - void* original_function_stub);
|
| -
|
| - private:
|
| -
|
| - // Patches a function by overwriting its first few bytes with
|
| - // a jump to a different function. This is similar to the RawPatch
|
| - // function except that it uses the stub allocated by the caller
|
| - // instead of allocating it.
|
| - //
|
| - // We call VirtualProtect to make the
|
| - // target function writable at least for the duration of the call.
|
| - //
|
| - // @param target_function A pointer to the function that should be
|
| - // patched.
|
| - //
|
| - // @param replacement_function A pointer to the function that should
|
| - // replace the target function. The replacement function must have
|
| - // exactly the same calling convention and parameters as the original
|
| - // function.
|
| - //
|
| - // @param preamble_stub A pointer to a buffer where the preamble stub
|
| - // should be copied. The size of the buffer should be sufficient to
|
| - // hold the preamble bytes.
|
| - //
|
| - // @param stub_size Size in bytes of the buffer allocated for the
|
| - // preamble_stub
|
| - //
|
| - // @param bytes_needed Pointer to a variable that receives the minimum
|
| - // number of bytes required for the stub. Can be set to NULL if you're
|
| - // not interested.
|
| - //
|
| - // @return An error code indicating the result of patching.
|
| - static SideStepError RawPatchWithStubAndProtections(void* target_function,
|
| - void *replacement_function,
|
| - unsigned char* preamble_stub,
|
| - unsigned long stub_size,
|
| - unsigned long* bytes_needed);
|
| -
|
| - // A helper function used by RawPatchWithStubAndProtections -- it does
|
| - // everything but the VirtualProtect wsork. Defined in
|
| - // preamble_patcher_with_stub.cc.
|
| - static SideStepError RawPatchWithStub(void* target_function,
|
| - void *replacement_function,
|
| - unsigned char* preamble_stub,
|
| - unsigned long stub_size,
|
| - unsigned long* bytes_needed);
|
| -};
|
| -
|
| -}; // namespace sidestep
|
| -
|
| -#endif // MEMORY_WATCHER_PREAMBLE_PATCHER_H__
|
|
|