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 |