| Index: sandbox/win/src/sidestep/preamble_patcher_with_stub.cpp
|
| diff --git a/sandbox/win/src/sidestep/preamble_patcher_with_stub.cpp b/sandbox/win/src/sidestep/preamble_patcher_with_stub.cpp
|
| deleted file mode 100644
|
| index b5016009d60ac38b256968801497fc168f669def..0000000000000000000000000000000000000000
|
| --- a/sandbox/win/src/sidestep/preamble_patcher_with_stub.cpp
|
| +++ /dev/null
|
| @@ -1,181 +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.
|
| -
|
| -// Implementation of PreamblePatcher
|
| -
|
| -#include "sandbox/win/src/sidestep/preamble_patcher.h"
|
| -
|
| -#include <stddef.h>
|
| -
|
| -#include "sandbox/win/src/sandbox_nt_util.h"
|
| -#include "sandbox/win/src/sidestep/mini_disassembler.h"
|
| -
|
| -// Definitions of assembly statements we need
|
| -#define ASM_JMP32REL 0xE9
|
| -#define ASM_INT3 0xCC
|
| -
|
| -namespace {
|
| -
|
| -// Very basic memcpy. We are copying 4 to 12 bytes most of the time, so there
|
| -// is no attempt to optimize this code or have a general purpose function.
|
| -// We don't want to call the crt from this code.
|
| -inline void* RawMemcpy(void* destination, const void* source, size_t bytes) {
|
| - const char* from = reinterpret_cast<const char*>(source);
|
| - char* to = reinterpret_cast<char*>(destination);
|
| -
|
| - for (size_t i = 0; i < bytes ; i++)
|
| - to[i] = from[i];
|
| -
|
| - return destination;
|
| -}
|
| -
|
| -// Very basic memset. We are filling 1 to 7 bytes most of the time, so there
|
| -// is no attempt to optimize this code or have a general purpose function.
|
| -// We don't want to call the crt from this code.
|
| -inline void* RawMemset(void* destination, int value, size_t bytes) {
|
| - char* to = reinterpret_cast<char*>(destination);
|
| -
|
| - for (size_t i = 0; i < bytes ; i++)
|
| - to[i] = static_cast<char>(value);
|
| -
|
| - return destination;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -#define ASSERT(a, b) DCHECK_NT(a)
|
| -
|
| -namespace sidestep {
|
| -
|
| -SideStepError PreamblePatcher::RawPatchWithStub(
|
| - void* target_function,
|
| - void* replacement_function,
|
| - unsigned char* preamble_stub,
|
| - size_t stub_size,
|
| - size_t* bytes_needed) {
|
| - if ((NULL == target_function) ||
|
| - (NULL == replacement_function) ||
|
| - (NULL == preamble_stub)) {
|
| - ASSERT(false, (L"Invalid parameters - either pTargetFunction or "
|
| - L"pReplacementFunction or pPreambleStub were NULL."));
|
| - return SIDESTEP_INVALID_PARAMETER;
|
| - }
|
| -
|
| - // TODO(V7:joi) Siggi and I just had a discussion and decided that both
|
| - // patching and unpatching are actually unsafe. We also discussed a
|
| - // method of making it safe, which is to freeze all other threads in the
|
| - // process, check their thread context to see if their eip is currently
|
| - // inside the block of instructions we need to copy to the stub, and if so
|
| - // wait a bit and try again, then unfreeze all threads once we've patched.
|
| - // Not implementing this for now since we're only using SideStep for unit
|
| - // testing, but if we ever use it for production code this is what we
|
| - // should do.
|
| - //
|
| - // NOTE: Stoyan suggests we can write 8 or even 10 bytes atomically using
|
| - // FPU instructions, and on newer processors we could use cmpxchg8b or
|
| - // cmpxchg16b. So it might be possible to do the patching/unpatching
|
| - // atomically and avoid having to freeze other threads. Note though, that
|
| - // doing it atomically does not help if one of the other threads happens
|
| - // to have its eip in the middle of the bytes you change while you change
|
| - // them.
|
| - unsigned char* target = reinterpret_cast<unsigned char*>(target_function);
|
| -
|
| - // Let's disassemble the preamble of the target function to see if we can
|
| - // patch, and to see how much of the preamble we need to take. We need 5
|
| - // bytes for our jmp instruction, so let's find the minimum number of
|
| - // instructions to get 5 bytes.
|
| - MiniDisassembler disassembler;
|
| - unsigned int preamble_bytes = 0;
|
| - while (preamble_bytes < 5) {
|
| - InstructionType instruction_type =
|
| - disassembler.Disassemble(target + preamble_bytes, &preamble_bytes);
|
| - if (IT_JUMP == instruction_type) {
|
| - ASSERT(false, (L"Unable to patch because there is a jump instruction "
|
| - L"in the first 5 bytes."));
|
| - return SIDESTEP_JUMP_INSTRUCTION;
|
| - } else if (IT_RETURN == instruction_type) {
|
| - ASSERT(false, (L"Unable to patch because function is too short"));
|
| - return SIDESTEP_FUNCTION_TOO_SMALL;
|
| - } else if (IT_GENERIC != instruction_type) {
|
| - ASSERT(false, (L"Disassembler encountered unsupported instruction "
|
| - L"(either unused or unknown"));
|
| - return SIDESTEP_UNSUPPORTED_INSTRUCTION;
|
| - }
|
| - }
|
| -
|
| - if (NULL != bytes_needed)
|
| - *bytes_needed = preamble_bytes + 5;
|
| -
|
| - // Inv: preamble_bytes is the number of bytes (at least 5) that we need to
|
| - // take from the preamble to have whole instructions that are 5 bytes or more
|
| - // in size total. The size of the stub required is cbPreamble + size of
|
| - // jmp (5)
|
| - if (preamble_bytes + 5 > stub_size) {
|
| - NOTREACHED_NT();
|
| - return SIDESTEP_INSUFFICIENT_BUFFER;
|
| - }
|
| -
|
| - // First, copy the preamble that we will overwrite.
|
| - RawMemcpy(reinterpret_cast<void*>(preamble_stub),
|
| - reinterpret_cast<void*>(target), preamble_bytes);
|
| -
|
| - // Now, make a jmp instruction to the rest of the target function (minus the
|
| - // preamble bytes we moved into the stub) and copy it into our preamble-stub.
|
| - // find address to jump to, relative to next address after jmp instruction
|
| -#pragma warning(push)
|
| -#pragma warning(disable:4244)
|
| - // This assignment generates a warning because it is 32 bit specific.
|
| - int relative_offset_to_target_rest
|
| - = ((reinterpret_cast<unsigned char*>(target) + preamble_bytes) -
|
| - (preamble_stub + preamble_bytes + 5));
|
| -#pragma warning(pop)
|
| - // jmp (Jump near, relative, displacement relative to next instruction)
|
| - preamble_stub[preamble_bytes] = ASM_JMP32REL;
|
| - // copy the address
|
| - RawMemcpy(reinterpret_cast<void*>(preamble_stub + preamble_bytes + 1),
|
| - reinterpret_cast<void*>(&relative_offset_to_target_rest), 4);
|
| -
|
| - // Inv: preamble_stub points to assembly code that will execute the
|
| - // original function by first executing the first cbPreamble bytes of the
|
| - // preamble, then jumping to the rest of the function.
|
| -
|
| - // Overwrite the first 5 bytes of the target function with a jump to our
|
| - // replacement function.
|
| - // (Jump near, relative, displacement relative to next instruction)
|
| - target[0] = ASM_JMP32REL;
|
| -
|
| - // Find offset from instruction after jmp, to the replacement function.
|
| -#pragma warning(push)
|
| -#pragma warning(disable:4244)
|
| - int offset_to_replacement_function =
|
| - reinterpret_cast<unsigned char*>(replacement_function) -
|
| - reinterpret_cast<unsigned char*>(target) - 5;
|
| -#pragma warning(pop)
|
| - // complete the jmp instruction
|
| - RawMemcpy(reinterpret_cast<void*>(target + 1),
|
| - reinterpret_cast<void*>(&offset_to_replacement_function), 4);
|
| - // Set any remaining bytes that were moved to the preamble-stub to INT3 so
|
| - // as not to cause confusion (otherwise you might see some strange
|
| - // instructions if you look at the disassembly, or even invalid
|
| - // instructions). Also, by doing this, we will break into the debugger if
|
| - // some code calls into this portion of the code. If this happens, it
|
| - // means that this function cannot be patched using this patcher without
|
| - // further thought.
|
| - if (preamble_bytes > 5) {
|
| - RawMemset(reinterpret_cast<void*>(target + 5), ASM_INT3,
|
| - preamble_bytes - 5);
|
| - }
|
| -
|
| - // Inv: The memory pointed to by target_function now points to a relative
|
| - // jump instruction that jumps over to the preamble_stub. The preamble
|
| - // stub contains the first stub_size bytes of the original target
|
| - // function's preamble code, followed by a relative jump back to the next
|
| - // instruction after the first cbPreamble bytes.
|
| -
|
| - return SIDESTEP_SUCCESS;
|
| -}
|
| -
|
| -}; // namespace sidestep
|
| -
|
| -#undef ASSERT
|
|
|