diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 22:41:28 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 22:41:28 +0000 |
commit | a814a8d55429605fe6d7045045cd25b6bf624580 (patch) | |
tree | 58fcd994d4ce41ef021f6406a6fac32d9ca2d265 /sandbox/src/resolver.cc | |
parent | e6c9e14e0dfec2bb156a1f7a107cda3ebee8d392 (diff) | |
download | chromium_src-a814a8d55429605fe6d7045045cd25b6bf624580.zip chromium_src-a814a8d55429605fe6d7045045cd25b6bf624580.tar.gz chromium_src-a814a8d55429605fe6d7045045cd25b6bf624580.tar.bz2 |
Add sandbox to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox/src/resolver.cc')
-rw-r--r-- | sandbox/src/resolver.cc | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/sandbox/src/resolver.cc b/sandbox/src/resolver.cc new file mode 100644 index 0000000..13a55d2 --- /dev/null +++ b/sandbox/src/resolver.cc @@ -0,0 +1,164 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "sandbox/src/resolver.h" + +#include "sandbox/src/pe_image.h" +#include "sandbox/src/sandbox_nt_util.h" + +namespace { + +#pragma pack(push, 1) +struct InternalThunk { + // This struct contains roughly the following code: + // sub esp, 8 // Create working space + // push edx // Save register + // mov edx, [esp + 0xc] // Get return adddress + // mov [esp + 8], edx // Store return address + // mov dword ptr [esp + 0xc], 0x7c401200 // Store extra argument + // mov dword ptr [esp + 4], 0x40010203 // Store address to jump to + // pop edx // Restore register + // ret // Jump to interceptor + // + // This code only modifies esp and eip so it must work with to normal calling + // convention. It is assembled as: + // + // 00 83ec08 sub esp,8 + // 03 52 push edx + // 04 8b54240c mov edx,dword ptr [esp + 0Ch] + // 08 89542408 mov dword ptr [esp + 8], edx + // 0c c744240c0012407c mov dword ptr [esp + 0Ch], 7C401200h + // 14 c744240403020140 mov dword ptr [esp + 4], 40010203h + // 1c 5a pop edx + // 1d c3 ret + InternalThunk() { + opcodes_1 = 0x5208ec83; + opcodes_2 = 0x0c24548b; + opcodes_3 = 0x08245489; + opcodes_4 = 0x0c2444c7; + opcodes_5 = 0x042444c7; + opcodes_6 = 0xc35a; + extra_argument = 0; + interceptor_function = 0; + }; + ULONG opcodes_1; // = 0x5208ec83 + ULONG opcodes_2; // = 0x0c24548b + ULONG opcodes_3; // = 0x08245489 + ULONG opcodes_4; // = 0x0c2444c7 + ULONG extra_argument; + ULONG opcodes_5; // = 0x042444c7 + ULONG interceptor_function; + USHORT opcodes_6; // = 0xc35a +}; +#pragma pack(pop) + +}; // namespace + +namespace sandbox { + +NTSTATUS ResolverThunk::Init(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) { + if (NULL == thunk_storage || 0 == storage_bytes || + NULL == target_module || NULL == target_name) + return STATUS_INVALID_PARAMETER; + + if (storage_bytes < GetThunkSize()) + return STATUS_BUFFER_TOO_SMALL; + + NTSTATUS ret = STATUS_SUCCESS; + if (NULL == interceptor_entry_point) { + ret = ResolveInterceptor(interceptor_module, interceptor_name, + &interceptor_entry_point); + if (!NT_SUCCESS(ret)) + return ret; + } + + ret = ResolveTarget(target_module, target_name, &target_); + if (!NT_SUCCESS(ret)) + return ret; + + interceptor_ = interceptor_entry_point; + + return ret; +} + +size_t ResolverThunk::GetInternalThunkSize() const { + return sizeof(InternalThunk); +} + +bool ResolverThunk::SetInternalThunk(void* storage, size_t storage_bytes, + const void* original_function, + const void* interceptor) { + if (storage_bytes < sizeof(InternalThunk)) + return false; + + InternalThunk* thunk = new(storage, NT_PLACE) InternalThunk; + +#pragma warning(push) +#pragma warning(disable: 4311) + // These casts generate warnings because they are 32 bit specific. + thunk->interceptor_function = reinterpret_cast<ULONG>(interceptor); + thunk->extra_argument = reinterpret_cast<ULONG>(original_function); +#pragma warning(pop) + + return true; +} + +NTSTATUS ResolverThunk::ResolveInterceptor(const void* interceptor_module, + const char* interceptor_name, + const void** address) { + DCHECK_NT(address); + if (!interceptor_module) + return STATUS_INVALID_PARAMETER; + + PEImage pe(interceptor_module); + if (!pe.VerifyMagic()) + return STATUS_INVALID_IMAGE_FORMAT; + + *address = pe.GetProcAddress(interceptor_name); + + if (!(*address)) + return STATUS_PROCEDURE_NOT_FOUND; + + return STATUS_SUCCESS; +} + +NTSTATUS ResolverThunk::ResolveTarget(const void* module, + const char* function_name, + void** address) { + const void** casted = const_cast<const void**>(address); + return ResolverThunk::ResolveInterceptor(module, function_name, casted); +} + +} // namespace sandbox |