12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- // Copyright (c) 2006-2010 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/eat_resolver.h"
- #include <stddef.h>
- #include "base/win/pe_image.h"
- #include "sandbox/win/src/sandbox_nt_util.h"
- namespace sandbox {
- NTSTATUS EatResolverThunk::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;
- if (!eat_entry_)
- return STATUS_INVALID_PARAMETER;
- #if defined(_WIN64)
- // We have two thunks, in order: the return path and the forward path.
- if (!SetInternalThunk(thunk_storage, storage_bytes, nullptr, target_))
- return STATUS_BUFFER_TOO_SMALL;
- size_t thunk_bytes = GetInternalThunkSize();
- storage_bytes -= thunk_bytes;
- thunk_storage = reinterpret_cast<char*>(thunk_storage) + thunk_bytes;
- #endif
- if (!SetInternalThunk(thunk_storage, storage_bytes, target_, interceptor_))
- return STATUS_BUFFER_TOO_SMALL;
- AutoProtectMemory memory;
- ret = memory.ChangeProtection(eat_entry_, sizeof(DWORD), PAGE_READWRITE);
- if (!NT_SUCCESS(ret))
- return ret;
- // Perform the patch.
- *eat_entry_ = static_cast<DWORD>(reinterpret_cast<uintptr_t>(thunk_storage)) -
- static_cast<DWORD>(reinterpret_cast<uintptr_t>(target_module));
- if (storage_used)
- *storage_used = GetThunkSize();
- return ret;
- }
- NTSTATUS EatResolverThunk::ResolveTarget(const void* module,
- const char* function_name,
- void** address) {
- DCHECK_NT(address);
- if (!module)
- return STATUS_INVALID_PARAMETER;
- base::win::PEImage pe(module);
- if (!pe.VerifyMagic())
- return STATUS_INVALID_IMAGE_FORMAT;
- eat_entry_ = pe.GetExportEntry(function_name);
- if (!eat_entry_)
- return STATUS_PROCEDURE_NOT_FOUND;
- *address = pe.RVAToAddr(*eat_entry_);
- return STATUS_SUCCESS;
- }
- size_t EatResolverThunk::GetThunkSize() const {
- #if defined(_WIN64)
- return GetInternalThunkSize() * 2;
- #else
- return GetInternalThunkSize();
- #endif
- }
- } // namespace sandbox
|