1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/win/src/eat_resolver.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,91 @@ 1.4 +// Copyright (c) 2006-2010 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 +#include "sandbox/win/src/eat_resolver.h" 1.9 + 1.10 +#include "base/win/pe_image.h" 1.11 +#include "sandbox/win/src/sandbox_nt_util.h" 1.12 + 1.13 +namespace sandbox { 1.14 + 1.15 +NTSTATUS EatResolverThunk::Setup(const void* target_module, 1.16 + const void* interceptor_module, 1.17 + const char* target_name, 1.18 + const char* interceptor_name, 1.19 + const void* interceptor_entry_point, 1.20 + void* thunk_storage, 1.21 + size_t storage_bytes, 1.22 + size_t* storage_used) { 1.23 + NTSTATUS ret = Init(target_module, interceptor_module, target_name, 1.24 + interceptor_name, interceptor_entry_point, 1.25 + thunk_storage, storage_bytes); 1.26 + if (!NT_SUCCESS(ret)) 1.27 + return ret; 1.28 + 1.29 + if (!eat_entry_) 1.30 + return STATUS_INVALID_PARAMETER; 1.31 + 1.32 + size_t thunk_bytes = GetInternalThunkSize(); 1.33 + 1.34 +#if defined(_WIN64) 1.35 + // We have two thunks, in order: the return path and the forward path. 1.36 + if (!SetInternalThunk(thunk_storage, storage_bytes, NULL, target_)) 1.37 + return STATUS_BUFFER_TOO_SMALL; 1.38 + 1.39 + storage_bytes -= thunk_bytes; 1.40 + thunk_storage = reinterpret_cast<char*>(thunk_storage) + thunk_bytes; 1.41 +#endif 1.42 + 1.43 + if (!SetInternalThunk(thunk_storage, storage_bytes, target_, interceptor_)) 1.44 + return STATUS_BUFFER_TOO_SMALL; 1.45 + 1.46 + AutoProtectMemory memory; 1.47 + ret = memory.ChangeProtection(eat_entry_, sizeof(DWORD), PAGE_READWRITE); 1.48 + if (!NT_SUCCESS(ret)) 1.49 + return ret; 1.50 + 1.51 + // Perform the patch. 1.52 +#pragma warning(push) 1.53 +#pragma warning(disable: 4311) 1.54 + // These casts generate warnings because they are 32 bit specific. 1.55 + *eat_entry_ = reinterpret_cast<DWORD>(thunk_storage) - 1.56 + reinterpret_cast<DWORD>(target_module); 1.57 +#pragma warning(pop) 1.58 + 1.59 + if (NULL != storage_used) 1.60 + *storage_used = GetThunkSize(); 1.61 + 1.62 + return ret; 1.63 +} 1.64 + 1.65 +NTSTATUS EatResolverThunk::ResolveTarget(const void* module, 1.66 + const char* function_name, 1.67 + void** address) { 1.68 + DCHECK_NT(address); 1.69 + if (!module) 1.70 + return STATUS_INVALID_PARAMETER; 1.71 + 1.72 + base::win::PEImage pe(module); 1.73 + if (!pe.VerifyMagic()) 1.74 + return STATUS_INVALID_IMAGE_FORMAT; 1.75 + 1.76 + eat_entry_ = pe.GetExportEntry(function_name); 1.77 + 1.78 + if (!eat_entry_) 1.79 + return STATUS_PROCEDURE_NOT_FOUND; 1.80 + 1.81 + *address = pe.RVAToAddr(*eat_entry_); 1.82 + 1.83 + return STATUS_SUCCESS; 1.84 +} 1.85 + 1.86 +size_t EatResolverThunk::GetThunkSize() const { 1.87 +#if defined(_WIN64) 1.88 + return GetInternalThunkSize() * 2; 1.89 +#else 1.90 + return GetInternalThunkSize(); 1.91 +#endif 1.92 +} 1.93 + 1.94 +} // namespace sandbox