Index: sandbox/win/src/sidestep_resolver.cc |
diff --git a/sandbox/win/src/sidestep_resolver.cc b/sandbox/win/src/sidestep_resolver.cc |
deleted file mode 100644 |
index d5da2fbe95a5f3e8b426b0b3738e4a523fc3152f..0000000000000000000000000000000000000000 |
--- a/sandbox/win/src/sidestep_resolver.cc |
+++ /dev/null |
@@ -1,204 +0,0 @@ |
-// Copyright (c) 2006-2008 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. |
- |
-#include "sandbox/win/src/sidestep_resolver.h" |
- |
-#include <stddef.h> |
- |
-#include "base/win/pe_image.h" |
-#include "sandbox/win/src/sandbox_nt_util.h" |
-#include "sandbox/win/src/sidestep/preamble_patcher.h" |
- |
-namespace { |
- |
-const size_t kSizeOfSidestepStub = sidestep::kMaxPreambleStubSize; |
- |
-struct SidestepThunk { |
- char sidestep[kSizeOfSidestepStub]; // Storage for the sidestep stub. |
- int internal_thunk; // Dummy member to the beginning of the internal thunk. |
-}; |
- |
-struct SmartThunk { |
- const void* module_base; // Target module's base. |
- const void* interceptor; // Real interceptor. |
- SidestepThunk sidestep; // Standard sidestep thunk. |
-}; |
- |
-} // namespace |
- |
-namespace sandbox { |
- |
-NTSTATUS SidestepResolverThunk::Setup(const void* target_module, |
- const void* interceptor_module, |
- const char* target_name, |
- const char* interceptor_name, |
- const void* interceptor_entry_point, |
- void* thunk_storage, |
- size_t storage_bytes, |
- size_t* storage_used) { |
- NTSTATUS ret = Init(target_module, interceptor_module, target_name, |
- interceptor_name, interceptor_entry_point, |
- thunk_storage, storage_bytes); |
- if (!NT_SUCCESS(ret)) |
- return ret; |
- |
- SidestepThunk* thunk = reinterpret_cast<SidestepThunk*>(thunk_storage); |
- |
- size_t internal_bytes = storage_bytes - kSizeOfSidestepStub; |
- if (!SetInternalThunk(&thunk->internal_thunk, internal_bytes, thunk_storage, |
- interceptor_)) |
- return STATUS_BUFFER_TOO_SMALL; |
- |
- AutoProtectMemory memory; |
- ret = memory.ChangeProtection(target_, kSizeOfSidestepStub, PAGE_READWRITE); |
- if (!NT_SUCCESS(ret)) |
- return ret; |
- |
- sidestep::SideStepError rv = sidestep::PreamblePatcher::Patch( |
- target_, reinterpret_cast<void*>(&thunk->internal_thunk), thunk_storage, |
- kSizeOfSidestepStub); |
- |
- if (sidestep::SIDESTEP_INSUFFICIENT_BUFFER == rv) |
- return STATUS_BUFFER_TOO_SMALL; |
- |
- if (sidestep::SIDESTEP_SUCCESS != rv) |
- return STATUS_UNSUCCESSFUL; |
- |
- if (storage_used) |
- *storage_used = GetThunkSize(); |
- |
- return ret; |
-} |
- |
-size_t SidestepResolverThunk::GetThunkSize() const { |
- return GetInternalThunkSize() + kSizeOfSidestepStub; |
-} |
- |
-// This is basically a wrapper around the normal sidestep patch that extends |
-// the thunk to use a chained interceptor. It uses the fact that |
-// SetInternalThunk generates the code to pass as the first parameter whatever |
-// it receives as original_function; we let SidestepResolverThunk set this value |
-// to its saved code, and then we change it to our thunk data. |
-NTSTATUS SmartSidestepResolverThunk::Setup(const void* target_module, |
- const void* interceptor_module, |
- const char* target_name, |
- const char* interceptor_name, |
- const void* interceptor_entry_point, |
- void* thunk_storage, |
- size_t storage_bytes, |
- size_t* storage_used) { |
- if (storage_bytes < GetThunkSize()) |
- return STATUS_BUFFER_TOO_SMALL; |
- |
- SmartThunk* thunk = reinterpret_cast<SmartThunk*>(thunk_storage); |
- thunk->module_base = target_module; |
- |
- NTSTATUS ret; |
- if (interceptor_entry_point) { |
- thunk->interceptor = interceptor_entry_point; |
- } else { |
- ret = ResolveInterceptor(interceptor_module, interceptor_name, |
- &thunk->interceptor); |
- if (!NT_SUCCESS(ret)) |
- return ret; |
- } |
- |
- // Perform a standard sidestep patch on the last part of the thunk, but point |
- // to our internal smart interceptor. |
- size_t standard_bytes = storage_bytes - offsetof(SmartThunk, sidestep); |
- ret = SidestepResolverThunk::Setup(target_module, interceptor_module, |
- target_name, NULL, &SmartStub, |
- &thunk->sidestep, standard_bytes, NULL); |
- if (!NT_SUCCESS(ret)) |
- return ret; |
- |
- // Fix the internal thunk to pass the whole buffer to the interceptor. |
- SetInternalThunk(&thunk->sidestep.internal_thunk, GetInternalThunkSize(), |
- thunk_storage, &SmartStub); |
- |
- if (storage_used) |
- *storage_used = GetThunkSize(); |
- |
- return ret; |
-} |
- |
-size_t SmartSidestepResolverThunk::GetThunkSize() const { |
- return GetInternalThunkSize() + kSizeOfSidestepStub + |
- offsetof(SmartThunk, sidestep); |
-} |
- |
-// This code must basically either call the intended interceptor or skip the |
-// call and invoke instead the original function. In any case, we are saving |
-// the registers that may be trashed by our c++ code. |
-// |
-// This function is called with a first parameter inserted by us, that points |
-// to our SmartThunk. When we call the interceptor we have to replace this |
-// parameter with the one expected by that function (stored inside our |
-// structure); on the other hand, when we skip the interceptor we have to remove |
-// that extra argument before calling the original function. |
-// |
-// When we skip the interceptor, the transformation of the stack looks like: |
-// On Entry: On Use: On Exit: |
-// [param 2] = first real argument [param 2] (esp+1c) [param 2] |
-// [param 1] = our SmartThunk [param 1] (esp+18) [ret address] |
-// [ret address] = real caller [ret address] (esp+14) [xxx] |
-// [xxx] [addr to jump to] (esp+10) [xxx] |
-// [xxx] [saved eax] [xxx] |
-// [xxx] [saved ebx] [xxx] |
-// [xxx] [saved ecx] [xxx] |
-// [xxx] [saved edx] [xxx] |
-__declspec(naked) |
-void SmartSidestepResolverThunk::SmartStub() { |
- __asm { |
- push eax // Space for the jump. |
- push eax // Save registers. |
- push ebx |
- push ecx |
- push edx |
- mov ebx, [esp + 0x18] // First parameter = SmartThunk. |
- mov edx, [esp + 0x14] // Get the return address. |
- mov eax, [ebx]SmartThunk.module_base |
- push edx |
- push eax |
- call SmartSidestepResolverThunk::IsInternalCall |
- add esp, 8 |
- |
- test eax, eax |
- lea edx, [ebx]SmartThunk.sidestep // The original function. |
- jz call_interceptor |
- |
- // Skip this call |
- mov ecx, [esp + 0x14] // Return address. |
- mov [esp + 0x18], ecx // Remove first parameter. |
- mov [esp + 0x10], edx |
- pop edx // Restore registers. |
- pop ecx |
- pop ebx |
- pop eax |
- ret 4 // Jump to original function. |
- |
- call_interceptor: |
- mov ecx, [ebx]SmartThunk.interceptor |
- mov [esp + 0x18], edx // Replace first parameter. |
- mov [esp + 0x10], ecx |
- pop edx // Restore registers. |
- pop ecx |
- pop ebx |
- pop eax |
- ret // Jump to original function. |
- } |
-} |
- |
-bool SmartSidestepResolverThunk::IsInternalCall(const void* base, |
- void* return_address) { |
- DCHECK_NT(base); |
- DCHECK_NT(return_address); |
- |
- base::win::PEImage pe(base); |
- if (pe.GetImageSectionFromAddr(return_address)) |
- return true; |
- return false; |
-} |
- |
-} // namespace sandbox |