Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4075)

Unified Diff: chrome_elf/hook_util/hook_util.cc

Issue 2242323002: Revert of [chrome_elf] Big cleanup and removing dependencies that recently crept in. Part 1. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome_elf/hook_util/hook_util.h ('k') | chrome_elf/hook_util/test/hook_util_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome_elf/hook_util/hook_util.cc
diff --git a/chrome_elf/hook_util/hook_util.cc b/chrome_elf/hook_util/hook_util.cc
deleted file mode 100644
index e16330d9975e54f34242f9d0cacd8d4127edbb07..0000000000000000000000000000000000000000
--- a/chrome_elf/hook_util/hook_util.cc
+++ /dev/null
@@ -1,334 +0,0 @@
-// Copyright 2014 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 "hook_util.h"
-
-#include <versionhelpers.h> // windows.h must be before
-
-#include "base/win/pe_image.h"
-#include "sandbox/win/src/interception_internal.h"
-#include "sandbox/win/src/internal_types.h"
-#include "sandbox/win/src/sandbox_utils.h"
-#include "sandbox/win/src/service_resolver.h"
-
-namespace {
-
-//------------------------------------------------------------------------------
-// Common hooking utility functions - LOCAL
-//------------------------------------------------------------------------------
-
-#if !defined(_WIN64)
-// Whether a process is running under WOW64 (the wrapper that allows 32-bit
-// processes to run on 64-bit versions of Windows). This will return
-// WOW64_DISABLED for both "32-bit Chrome on 32-bit Windows" and "64-bit
-// Chrome on 64-bit Windows". WOW64_UNKNOWN means "an error occurred", e.g.
-// the process does not have sufficient access rights to determine this.
-enum WOW64Status {
- WOW64_DISABLED,
- WOW64_ENABLED,
- WOW64_UNKNOWN,
-};
-
-WOW64Status GetWOW64StatusForCurrentProcess() {
- typedef BOOL(WINAPI * IsWow64ProcessFunc)(HANDLE, PBOOL);
- IsWow64ProcessFunc is_wow64_process = reinterpret_cast<IsWow64ProcessFunc>(
- GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process"));
- if (!is_wow64_process)
- return WOW64_DISABLED;
- BOOL is_wow64 = FALSE;
- if (!is_wow64_process(GetCurrentProcess(), &is_wow64))
- return WOW64_UNKNOWN;
- return is_wow64 ? WOW64_ENABLED : WOW64_DISABLED;
-}
-#endif // !defined(_WIN64)
-
-// Change the page protections to writable, copy the data,
-// restore protections. Returns a winerror code.
-DWORD PatchMem(void* target, void* new_bytes, size_t length) {
- if (target == nullptr || new_bytes == nullptr || length == 0)
- return ERROR_INVALID_PARAMETER;
-
- // Preserve executable state.
- MEMORY_BASIC_INFORMATION memory_info = {};
- if (!::VirtualQuery(target, &memory_info, sizeof(memory_info))) {
- return GetLastError();
- }
-
- DWORD is_executable = (PAGE_EXECUTE | PAGE_EXECUTE_READ |
- PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) &
- memory_info.Protect;
-
- // Make target writeable.
- DWORD old_page_protection = 0;
- if (!::VirtualProtect(target, length,
- is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE,
- &old_page_protection)) {
- return GetLastError();
- }
-
- // Write the data.
- ::memcpy(target, new_bytes, length);
-
- // Restore old page protection.
- if (!::VirtualProtect(target, length, old_page_protection,
- &old_page_protection)) {
-// Yes, this could fail. However, memory was already patched.
-#ifdef _DEBUG
- assert(false);
-#endif // _DEBUG
- }
-
- return NO_ERROR;
-}
-
-//------------------------------------------------------------------------------
-// Import Address Table hooking support - LOCAL
-//------------------------------------------------------------------------------
-
-void* GetIATFunctionPtr(IMAGE_THUNK_DATA* iat_thunk) {
- if (iat_thunk == nullptr)
- return nullptr;
-
- // Works around the 64 bit portability warning:
- // The Function member inside IMAGE_THUNK_DATA is really a pointer
- // to the IAT function. IMAGE_THUNK_DATA correctly maps to IMAGE_THUNK_DATA32
- // or IMAGE_THUNK_DATA64 for correct pointer size.
- union FunctionThunk {
- IMAGE_THUNK_DATA thunk;
- void* pointer;
- } iat_function;
-
- iat_function.thunk = *iat_thunk;
- return iat_function.pointer;
-}
-
-// Used to pass target function information during pe_image enumeration.
-struct IATHookFunctionInfo {
- bool finished_operation;
- const char* imported_from_module;
- const char* function_name;
- void* new_function;
- void** old_function;
- IMAGE_THUNK_DATA** iat_thunk;
- DWORD return_code;
-};
-
-// Callback function for pe_image enumeration. This function is called from
-// within PEImage::EnumOneImportChunk().
-// NOTE: Returning true means continue enumerating. False means stop.
-bool IATFindHookFuncCallback(const base::win::PEImage& image,
- const char* module,
- DWORD ordinal,
- const char* import_name,
- DWORD hint,
- IMAGE_THUNK_DATA* iat,
- void* cookie) {
- IATHookFunctionInfo* hook_func_info =
- reinterpret_cast<IATHookFunctionInfo*>(cookie);
- if (hook_func_info == nullptr)
- return false;
-
- // Check for the right module.
- if (module == nullptr ||
- ::strnicmp(module, hook_func_info->imported_from_module,
- ::strlen(module)) != 0)
- return true;
-
- // Check for the right function.
- if (import_name == nullptr ||
- ::strnicmp(import_name, hook_func_info->function_name,
- ::strlen(import_name)) != 0)
- return true;
-
- // At this point, the target function was found. Even if something fails now,
- // don't do any further enumerating.
- hook_func_info->finished_operation = true;
-
- // This is it. Do the hook!
- // 1) Save the old function pointer.
- *(hook_func_info->old_function) = GetIATFunctionPtr(iat);
-
- // 2) Save the IAT thunk.
- *(hook_func_info->iat_thunk) = iat;
-
- // 3) Sanity check the pointer sizes (architectures).
- if (sizeof(iat->u1.Function) != sizeof(hook_func_info->new_function)) {
- hook_func_info->return_code = ERROR_BAD_ENVIRONMENT;
-#ifdef _DEBUG
- assert(false);
-#endif // _DEBUG
- return false;
- }
-
- // 4) Sanity check that the new hook function is not actually the
- // same as the existing function for this import!
- if (*(hook_func_info->old_function) == hook_func_info->new_function) {
- hook_func_info->return_code = ERROR_INVALID_FUNCTION;
-#ifdef _DEBUG
- assert(false);
-#endif // _DEBUG
- return false;
- }
-
- // 5) Patch the function pointer.
- hook_func_info->return_code =
- PatchMem(&(iat->u1.Function), &(hook_func_info->new_function),
- sizeof(hook_func_info->new_function));
-
- return false;
-}
-
-// Applies an import-address-table hook. Returns a system winerror.h code.
-// Call RemoveIATHook() with |new_function|, |old_function| and |iat_thunk|
-// to remove the hook.
-DWORD ApplyIATHook(HMODULE module_handle,
- const char* imported_from_module,
- const char* function_name,
- void* new_function,
- void** old_function,
- IMAGE_THUNK_DATA** iat_thunk) {
- base::win::PEImage target_image(module_handle);
- if (!target_image.VerifyMagic())
- return ERROR_INVALID_PARAMETER;
-
- IATHookFunctionInfo hook_info = {false,
- imported_from_module,
- function_name,
- new_function,
- old_function,
- iat_thunk,
- ERROR_PROC_NOT_FOUND};
-
- // First go through the IAT. If we don't find the import we are looking
- // for in IAT, search delay import table.
- target_image.EnumAllImports(IATFindHookFuncCallback, &hook_info);
- if (!hook_info.finished_operation) {
- target_image.EnumAllDelayImports(IATFindHookFuncCallback, &hook_info);
- }
-
- return hook_info.return_code;
-}
-
-// Removes an import-address-table hook. Returns a system winerror.h code.
-DWORD RemoveIATHook(void* intercept_function,
- void* original_function,
- IMAGE_THUNK_DATA* iat_thunk) {
- if (GetIATFunctionPtr(iat_thunk) != intercept_function) {
-#ifdef _DEBUG
- assert(false);
-#endif // _DEBUG
- // Someone else has messed with the same target. Cannot unpatch.
- return ERROR_INVALID_FUNCTION;
- }
-
- return PatchMem(&(iat_thunk->u1.Function), &original_function,
- sizeof(original_function));
-}
-
-} // namespace
-
-namespace elf_hook {
-
-//------------------------------------------------------------------------------
-// System Service hooking support
-//------------------------------------------------------------------------------
-
-sandbox::ServiceResolverThunk* HookSystemService(bool relaxed) {
- // Create a thunk via the appropriate ServiceResolver instance.
- sandbox::ServiceResolverThunk* thunk = nullptr;
-
- // No hooking on unsupported OS versions.
- if (!::IsWindows7OrGreater())
- return thunk;
-
- // Pseudo-handle, no need to close.
- HANDLE current_process = ::GetCurrentProcess();
-
-#if defined(_WIN64)
- // ServiceResolverThunk can handle all the formats in 64-bit (instead only
- // handling one like it does in 32-bit versions).
- thunk = new sandbox::ServiceResolverThunk(current_process, relaxed);
-#else
- if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) {
- if (::IsWindows10OrGreater())
- thunk = new sandbox::Wow64W10ResolverThunk(current_process, relaxed);
- else if (::IsWindows8OrGreater())
- thunk = new sandbox::Wow64W8ResolverThunk(current_process, relaxed);
- else
- thunk = new sandbox::Wow64ResolverThunk(current_process, relaxed);
- } else if (::IsWindows8OrGreater()) {
- thunk = new sandbox::Win8ResolverThunk(current_process, relaxed);
- } else {
- thunk = new sandbox::ServiceResolverThunk(current_process, relaxed);
- }
-#endif
-
- return thunk;
-}
-
-//------------------------------------------------------------------------------
-// Import Address Table hooking support
-//------------------------------------------------------------------------------
-
-IATHook::IATHook()
- : intercept_function_(nullptr),
- original_function_(nullptr),
- iat_thunk_(nullptr) {}
-
-IATHook::~IATHook() {
- if (intercept_function_ != nullptr) {
- if (Unhook() != NO_ERROR) {
-#ifdef _DEBUG
- assert(false);
-#endif // _DEBUG
- }
- }
-}
-
-DWORD IATHook::Hook(HMODULE module,
- const char* imported_from_module,
- const char* function_name,
- void* new_function) {
- if ((module == 0 || module == INVALID_HANDLE_VALUE) ||
- imported_from_module == nullptr || function_name == nullptr ||
- new_function == nullptr)
- return ERROR_INVALID_PARAMETER;
-
- // Only hook once per object, to ensure unhook.
- if (intercept_function_ != nullptr || original_function_ != nullptr ||
- iat_thunk_ != nullptr) {
-#ifdef _DEBUG
- assert(false);
-#endif //_DEBUG
- return ERROR_SHARING_VIOLATION;
- }
-
- DWORD winerror = ApplyIATHook(module, imported_from_module, function_name,
- new_function, &original_function_, &iat_thunk_);
- if (winerror == NO_ERROR)
- intercept_function_ = new_function;
-
- return winerror;
-}
-
-DWORD IATHook::Unhook() {
- if (intercept_function_ == nullptr || original_function_ == nullptr ||
- iat_thunk_ == nullptr)
- return ERROR_INVALID_PARAMETER;
-
- DWORD winerror =
- RemoveIATHook(intercept_function_, original_function_, iat_thunk_);
-#ifdef _DEBUG
- if (winerror != NO_ERROR)
- assert(false);
-#endif //_DEBUG
-
- intercept_function_ = nullptr;
- original_function_ = nullptr;
- iat_thunk_ = nullptr;
-
- return winerror;
-}
-
-} // namespace elf_hook
« no previous file with comments | « chrome_elf/hook_util/hook_util.h ('k') | chrome_elf/hook_util/test/hook_util_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698