1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "sandbox/win/src/eat_resolver.h" 6 7 #include "base/win/pe_image.h" 8 #include "sandbox/win/src/sandbox_nt_util.h" 9 10 namespace sandbox { 11 12 NTSTATUS EatResolverThunk::Setup(const void* target_module, 13 const void* interceptor_module, 14 const char* target_name, 15 const char* interceptor_name, 16 const void* interceptor_entry_point, 17 void* thunk_storage, 18 size_t storage_bytes, 19 size_t* storage_used) { 20 NTSTATUS ret = Init(target_module, interceptor_module, target_name, 21 interceptor_name, interceptor_entry_point, 22 thunk_storage, storage_bytes); 23 if (!NT_SUCCESS(ret)) 24 return ret; 25 26 if (!eat_entry_) 27 return STATUS_INVALID_PARAMETER; 28 29 size_t thunk_bytes = GetInternalThunkSize(); 30 31 #if defined(_WIN64) 32 // We have two thunks, in order: the return path and the forward path. 33 if (!SetInternalThunk(thunk_storage, storage_bytes, NULL, target_)) 34 return STATUS_BUFFER_TOO_SMALL; 35 36 storage_bytes -= thunk_bytes; 37 thunk_storage = reinterpret_cast<char*>(thunk_storage) + thunk_bytes; 38 #endif 39 40 if (!SetInternalThunk(thunk_storage, storage_bytes, target_, interceptor_)) 41 return STATUS_BUFFER_TOO_SMALL; 42 43 AutoProtectMemory memory; 44 ret = memory.ChangeProtection(eat_entry_, sizeof(DWORD), PAGE_READWRITE); 45 if (!NT_SUCCESS(ret)) 46 return ret; 47 48 // Perform the patch. 49 #pragma warning(push) 50 #pragma warning(disable: 4311) 51 // These casts generate warnings because they are 32 bit specific. 52 *eat_entry_ = reinterpret_cast<DWORD>(thunk_storage) - 53 reinterpret_cast<DWORD>(target_module); 54 #pragma warning(pop) 55 56 if (NULL != storage_used) 57 *storage_used = GetThunkSize(); 58 59 return ret; 60 } 61 62 NTSTATUS EatResolverThunk::ResolveTarget(const void* module, 63 const char* function_name, 64 void** address) { 65 DCHECK_NT(address); 66 if (!module) 67 return STATUS_INVALID_PARAMETER; 68 69 base::win::PEImage pe(module); 70 if (!pe.VerifyMagic()) 71 return STATUS_INVALID_IMAGE_FORMAT; 72 73 eat_entry_ = pe.GetExportEntry(function_name); 74 75 if (!eat_entry_) 76 return STATUS_PROCEDURE_NOT_FOUND; 77 78 *address = pe.RVAToAddr(*eat_entry_); 79 80 return STATUS_SUCCESS; 81 } 82 83 size_t EatResolverThunk::GetThunkSize() const { 84 #if defined(_WIN64) 85 return GetInternalThunkSize() * 2; 86 #else 87 return GetInternalThunkSize(); 88 #endif 89 } 90 91 } // namespace sandbox 92