1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/win/src/sidestep/preamble_patcher.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,111 @@ 1.4 +// Copyright (c) 2012 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +// Definition of PreamblePatcher 1.9 + 1.10 +#ifndef SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__ 1.11 +#define SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__ 1.12 + 1.13 +#include <stddef.h> 1.14 + 1.15 +namespace sidestep { 1.16 + 1.17 +// Maximum size of the preamble stub. We overwrite at least the first 5 1.18 +// bytes of the function. Considering the worst case scenario, we need 4 1.19 +// bytes + the max instruction size + 5 more bytes for our jump back to 1.20 +// the original code. With that in mind, 32 is a good number :) 1.21 +const size_t kMaxPreambleStubSize = 32; 1.22 + 1.23 +// Possible results of patching/unpatching 1.24 +enum SideStepError { 1.25 + SIDESTEP_SUCCESS = 0, 1.26 + SIDESTEP_INVALID_PARAMETER, 1.27 + SIDESTEP_INSUFFICIENT_BUFFER, 1.28 + SIDESTEP_JUMP_INSTRUCTION, 1.29 + SIDESTEP_FUNCTION_TOO_SMALL, 1.30 + SIDESTEP_UNSUPPORTED_INSTRUCTION, 1.31 + SIDESTEP_NO_SUCH_MODULE, 1.32 + SIDESTEP_NO_SUCH_FUNCTION, 1.33 + SIDESTEP_ACCESS_DENIED, 1.34 + SIDESTEP_UNEXPECTED, 1.35 +}; 1.36 + 1.37 +// Implements a patching mechanism that overwrites the first few bytes of 1.38 +// a function preamble with a jump to our hook function, which is then 1.39 +// able to call the original function via a specially-made preamble-stub 1.40 +// that imitates the action of the original preamble. 1.41 +// 1.42 +// Note that there are a number of ways that this method of patching can 1.43 +// fail. The most common are: 1.44 +// - If there is a jump (jxx) instruction in the first 5 bytes of 1.45 +// the function being patched, we cannot patch it because in the 1.46 +// current implementation we do not know how to rewrite relative 1.47 +// jumps after relocating them to the preamble-stub. Note that 1.48 +// if you really really need to patch a function like this, it 1.49 +// would be possible to add this functionality (but at some cost). 1.50 +// - If there is a return (ret) instruction in the first 5 bytes 1.51 +// we cannot patch the function because it may not be long enough 1.52 +// for the jmp instruction we use to inject our patch. 1.53 +// - If there is another thread currently executing within the bytes 1.54 +// that are copied to the preamble stub, it will crash in an undefined 1.55 +// way. 1.56 +// 1.57 +// If you get any other error than the above, you're either pointing the 1.58 +// patcher at an invalid instruction (e.g. into the middle of a multi- 1.59 +// byte instruction, or not at memory containing executable instructions) 1.60 +// or, there may be a bug in the disassembler we use to find 1.61 +// instruction boundaries. 1.62 +class PreamblePatcher { 1.63 + public: 1.64 + // Patches target_function to point to replacement_function using a provided 1.65 + // preamble_stub of stub_size bytes. 1.66 + // Returns An error code indicating the result of patching. 1.67 + template <class T> 1.68 + static SideStepError Patch(T target_function, T replacement_function, 1.69 + void* preamble_stub, size_t stub_size) { 1.70 + return RawPatchWithStub(target_function, replacement_function, 1.71 + reinterpret_cast<unsigned char*>(preamble_stub), 1.72 + stub_size, NULL); 1.73 + } 1.74 + 1.75 + private: 1.76 + 1.77 + // Patches a function by overwriting its first few bytes with 1.78 + // a jump to a different function. This is similar to the RawPatch 1.79 + // function except that it uses the stub allocated by the caller 1.80 + // instead of allocating it. 1.81 + // 1.82 + // To use this function, you first have to call VirtualProtect to make the 1.83 + // target function writable at least for the duration of the call. 1.84 + // 1.85 + // target_function: A pointer to the function that should be 1.86 + // patched. 1.87 + // 1.88 + // replacement_function: A pointer to the function that should 1.89 + // replace the target function. The replacement function must have 1.90 + // exactly the same calling convention and parameters as the original 1.91 + // function. 1.92 + // 1.93 + // preamble_stub: A pointer to a buffer where the preamble stub 1.94 + // should be copied. The size of the buffer should be sufficient to 1.95 + // hold the preamble bytes. 1.96 + // 1.97 + // stub_size: Size in bytes of the buffer allocated for the 1.98 + // preamble_stub 1.99 + // 1.100 + // bytes_needed: Pointer to a variable that receives the minimum 1.101 + // number of bytes required for the stub. Can be set to NULL if you're 1.102 + // not interested. 1.103 + // 1.104 + // Returns An error code indicating the result of patching. 1.105 + static SideStepError RawPatchWithStub(void* target_function, 1.106 + void *replacement_function, 1.107 + unsigned char* preamble_stub, 1.108 + size_t stub_size, 1.109 + size_t* bytes_needed); 1.110 +}; 1.111 + 1.112 +}; // namespace sidestep 1.113 + 1.114 +#endif // SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__