| Index: chrome/app/close_handle_hook_win.cc
|
| diff --git a/base/debug/close_handle_hook_win.cc b/chrome/app/close_handle_hook_win.cc
|
| similarity index 80%
|
| rename from base/debug/close_handle_hook_win.cc
|
| rename to chrome/app/close_handle_hook_win.cc
|
| index 359b758ed33924727c59136265e60b97f4ac22ab..28bfb3e8f9e6f90c54c24a3fc31c17436a8156c3 100644
|
| --- a/base/debug/close_handle_hook_win.cc
|
| +++ b/chrome/app/close_handle_hook_win.cc
|
| @@ -1,8 +1,8 @@
|
| -// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// 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 "base/debug/close_handle_hook_win.h"
|
| +#include "chrome/app/close_handle_hook_win.h"
|
|
|
| #include <Windows.h>
|
| #include <psapi.h>
|
| @@ -15,6 +15,8 @@
|
| #include "base/win/iat_patch_function.h"
|
| #include "base/win/pe_image.h"
|
| #include "base/win/scoped_handle.h"
|
| +#include "chrome/common/channel_info.h"
|
| +#include "components/version_info/version_info.h"
|
|
|
| namespace {
|
|
|
| @@ -119,25 +121,25 @@ void AutoProtectMemory::RevertProtection() {
|
| }
|
|
|
| // Performs an EAT interception.
|
| -bool EATPatch(HMODULE module, const char* function_name,
|
| +void EATPatch(HMODULE module, const char* function_name,
|
| void* new_function, void** old_function) {
|
| if (!module)
|
| - return false;
|
| + return;
|
|
|
| base::win::PEImage pe(module);
|
| if (!pe.VerifyMagic())
|
| - return false;
|
| + return;
|
|
|
| DWORD* eat_entry = pe.GetExportEntry(function_name);
|
| if (!eat_entry)
|
| - return false;
|
| + return;
|
|
|
| if (!(*old_function))
|
| *old_function = pe.RVAToAddr(*eat_entry);
|
|
|
| AutoProtectMemory memory;
|
| if (!memory.ChangeProtection(eat_entry, sizeof(DWORD)))
|
| - return false;
|
| + return;
|
|
|
| // Perform the patch.
|
| #pragma warning(push)
|
| @@ -146,7 +148,6 @@ bool EATPatch(HMODULE module, const char* function_name,
|
| *eat_entry = reinterpret_cast<DWORD>(new_function) -
|
| reinterpret_cast<DWORD>(module);
|
| #pragma warning(pop)
|
| - return true;
|
| }
|
|
|
| // Performs an IAT interception.
|
| @@ -186,9 +187,9 @@ class HandleHooks {
|
| HandleHooks() {}
|
| ~HandleHooks() {}
|
|
|
| - bool AddIATPatch(HMODULE module);
|
| - bool AddEATPatch();
|
| - bool Unpatch();
|
| + void AddIATPatch(HMODULE module);
|
| + void AddEATPatch();
|
| + void Unpatch();
|
|
|
| private:
|
| std::vector<base::win::IATPatchFunction*> hooks_;
|
| @@ -196,87 +197,89 @@ class HandleHooks {
|
| };
|
| base::LazyInstance<HandleHooks> g_hooks = LAZY_INSTANCE_INITIALIZER;
|
|
|
| -bool HandleHooks::AddIATPatch(HMODULE module) {
|
| +void HandleHooks::AddIATPatch(HMODULE module) {
|
| if (!module)
|
| - return false;
|
| + return;
|
|
|
| base::win::IATPatchFunction* patch = NULL;
|
| patch = IATPatch(module, "CloseHandle", &CloseHandleHook,
|
| reinterpret_cast<void**>(&g_close_function));
|
| if (!patch)
|
| - return false;
|
| + return;
|
| hooks_.push_back(patch);
|
|
|
| patch = IATPatch(module, "DuplicateHandle", &DuplicateHandleHook,
|
| reinterpret_cast<void**>(&g_duplicate_function));
|
| if (!patch)
|
| - return false;
|
| + return;
|
| hooks_.push_back(patch);
|
| - return true;
|
| }
|
|
|
| -bool HandleHooks::AddEATPatch() {
|
| - // An attempt to restore the entry on the table at destruction is not safe.
|
| +void HandleHooks::AddEATPatch() {
|
| // An attempt to restore the entry on the table at destruction is not safe.
|
| - return (EATPatch(GetModuleHandleA("kernel32.dll"), "CloseHandle",
|
| - &CloseHandleHook,
|
| - reinterpret_cast<void**>(&g_close_function)) &&
|
| - EATPatch(GetModuleHandleA("kernel32.dll"), "DuplicateHandle",
|
| - &DuplicateHandleHook,
|
| - reinterpret_cast<void**>(&g_duplicate_function)));
|
| + EATPatch(GetModuleHandleA("kernel32.dll"), "CloseHandle",
|
| + &CloseHandleHook, reinterpret_cast<void**>(&g_close_function));
|
| + EATPatch(GetModuleHandleA("kernel32.dll"), "DuplicateHandle",
|
| + &DuplicateHandleHook,
|
| + reinterpret_cast<void**>(&g_duplicate_function));
|
| }
|
|
|
| -bool HandleHooks::Unpatch() {
|
| - DWORD err = NO_ERROR;
|
| +void HandleHooks::Unpatch() {
|
| for (std::vector<base::win::IATPatchFunction*>::iterator it = hooks_.begin();
|
| it != hooks_.end(); ++it) {
|
| - err = (*it)->Unpatch();
|
| - if (err != NO_ERROR)
|
| - break;
|
| + (*it)->Unpatch();
|
| delete *it;
|
| }
|
| - return (err == NO_ERROR);
|
| }
|
|
|
| -bool PatchLoadedModules(HandleHooks* hooks) {
|
| +bool UseHooks() {
|
| +#if defined(ARCH_CPU_X86_64)
|
| + return false;
|
| +#elif defined(NDEBUG)
|
| + version_info::Channel channel = chrome::GetChannel();
|
| + if (channel == version_info::Channel::CANARY ||
|
| + channel == version_info::Channel::DEV) {
|
| + return true;
|
| + }
|
| +
|
| + return false;
|
| +#else // NDEBUG
|
| + return true;
|
| +#endif
|
| +}
|
| +
|
| +void PatchLoadedModules(HandleHooks* hooks) {
|
| const DWORD kSize = 256;
|
| DWORD returned;
|
| scoped_ptr<HMODULE[]> modules(new HMODULE[kSize]);
|
| if (!EnumProcessModules(GetCurrentProcess(), modules.get(),
|
| kSize * sizeof(HMODULE), &returned)) {
|
| - return false;
|
| + return;
|
| }
|
| returned /= sizeof(HMODULE);
|
| returned = std::min(kSize, returned);
|
|
|
| - bool success = false;
|
| -
|
| for (DWORD current = 0; current < returned; current++) {
|
| - success = hooks->AddIATPatch(modules[current]);
|
| - if (!success)
|
| - break;
|
| + hooks->AddIATPatch(modules[current]);
|
| }
|
| -
|
| - return success;
|
| }
|
|
|
| } // namespace
|
|
|
| -namespace base {
|
| -namespace debug {
|
| +void InstallHandleHooks() {
|
| + if (UseHooks()) {
|
| + HandleHooks* hooks = g_hooks.Pointer();
|
|
|
| -bool InstallHandleHooks() {
|
| - HandleHooks* hooks = g_hooks.Pointer();
|
| -
|
| - // Performing EAT interception first is safer in the presence of other
|
| - // threads attempting to call CloseHandle.
|
| - return (hooks->AddEATPatch() && PatchLoadedModules(hooks));
|
| + // Performing EAT interception first is safer in the presence of other
|
| + // threads attempting to call CloseHandle.
|
| + hooks->AddEATPatch();
|
| + PatchLoadedModules(hooks);
|
| + } else {
|
| + base::win::DisableHandleVerifier();
|
| + }
|
| }
|
|
|
| void RemoveHandleHooks() {
|
| - // We are patching all loaded modules without forcing them to stay in memory,
|
| + // We are partching all loaded modules without forcing them to stay in memory,
|
| // removing patches is not safe.
|
| }
|
| -
|
| -} // namespace debug
|
| -} // namespace base
|
|
|