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

Unified Diff: chrome/app/close_handle_hook_win.cc

Issue 510633002: Improve the ScopedHandle verifier. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add comment to the lock Created 6 years, 3 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
Index: chrome/app/close_handle_hook_win.cc
diff --git a/chrome/app/close_handle_hook_win.cc b/chrome/app/close_handle_hook_win.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b5b3d857569041789e6e91097f589a6d97255f08
--- /dev/null
+++ b/chrome/app/close_handle_hook_win.cc
@@ -0,0 +1,118 @@
+// 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 "chrome/app/close_handle_hook_win.h"
+
+#include <Windows.h>
+
+#include <vector>
+
+#include "base/files/file_path.h"
+#include "base/lazy_instance.h"
+#include "base/strings/string16.h"
+#include "base/win/iat_patch_function.h"
+#include "base/win/scoped_handle.h"
+#include "chrome/common/chrome_version_info.h"
+
+namespace {
+
+typedef BOOL (WINAPI* CloseHandleType) (HANDLE handle);
+CloseHandleType g_close_function = NULL;
+
+// The entry point for CloseHandle interception. This function notifies the
+// verifier about the handle that is being closed, and calls the original
+// function.
+BOOL WINAPI CloseHandleHook(HANDLE handle) {
+ base::win::OnHandleBeingClosed(handle);
+ return g_close_function(handle);
+}
+
+// Keeps track of all the hooks needed to intercept CloseHandle.
+class CloseHandleHooks {
+ public:
+ CloseHandleHooks() {}
+ ~CloseHandleHooks() {}
+
+ void AddIATPatch(const base::string16& module);
+ void Unpatch();
+
+ private:
+ std::vector<base::win::IATPatchFunction*> hooks_;
+ DISALLOW_COPY_AND_ASSIGN(CloseHandleHooks);
+};
+base::LazyInstance<CloseHandleHooks> g_hooks = LAZY_INSTANCE_INITIALIZER;
+
+void CloseHandleHooks::AddIATPatch(const base::string16& module) {
+ if (module.empty())
+ return;
+
+ base::win::IATPatchFunction* patch = new base::win::IATPatchFunction;
+ patch->Patch(module.c_str(), "kernel32.dll", "CloseHandle", CloseHandleHook);
+ hooks_.push_back(patch);
+ if (!g_close_function) {
+ // Things are probably messed up if each intercepted function points to
+ // a different place, but we need only one function to call.
+ g_close_function =
+ reinterpret_cast<CloseHandleType>(patch->original_function());
+ }
+}
+
+void CloseHandleHooks::Unpatch() {
+ for (std::vector<base::win::IATPatchFunction*>::iterator it = hooks_.begin();
+ it != hooks_.end(); ++it) {
+ (*it)->Unpatch();
+ }
+}
+
+bool UseHooks() {
+ chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
+ if (channel == chrome::VersionInfo::CHANNEL_CANARY ||
+ channel == chrome::VersionInfo::CHANNEL_DEV) {
+ return true;
+ }
+
+ return false;
+}
+
+base::string16 GetModuleName(HMODULE module) {
+ base::string16 name;
+ if (!module)
+ return name;
+ wchar_t buffer[MAX_PATH];
+ int rv = GetModuleFileName(module, buffer, MAX_PATH);
+ if (rv == MAX_PATH)
+ return name;
+
+ buffer[MAX_PATH - 1] = L'\0';
+ name.assign(buffer);
+ base::FilePath path(name);
+ return path.BaseName().AsUTF16Unsafe();
+}
+
+HMODULE GetChromeDLLModule() {
+ HMODULE module;
+ if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
+ GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
+ reinterpret_cast<wchar_t*>(&GetChromeDLLModule),
+ &module)) {
+ return NULL;
+ }
+ return module;
+}
+
+} // namespace
+
+void InstallCloseHandleHooks() {
+ if (UseHooks()) {
+ CloseHandleHooks* hooks = g_hooks.Pointer();
+ hooks->AddIATPatch(L"chrome.exe");
+ hooks->AddIATPatch(GetModuleName(GetChromeDLLModule()));
+ } else {
+ base::win::DisableHandleVerifier();
+ }
+}
+
+void RemoveCloseHandleHooks() {
+ g_hooks.Get().Unpatch();
+}

Powered by Google App Engine
This is Rietveld 408576698