| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/debug/close_handle_hook_win.h" | 5 #include "base/debug/close_handle_hook_win.h" |
| 6 | 6 |
| 7 #include <Windows.h> | 7 #include <Windows.h> |
| 8 #include <psapi.h> | 8 #include <psapi.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 }; | 196 }; |
| 197 base::LazyInstance<HandleHooks> g_hooks = LAZY_INSTANCE_INITIALIZER; | 197 base::LazyInstance<HandleHooks> g_hooks = LAZY_INSTANCE_INITIALIZER; |
| 198 | 198 |
| 199 bool HandleHooks::AddIATPatch(HMODULE module) { | 199 bool HandleHooks::AddIATPatch(HMODULE module) { |
| 200 if (!module) | 200 if (!module) |
| 201 return false; | 201 return false; |
| 202 | 202 |
| 203 base::win::IATPatchFunction* patch = NULL; | 203 base::win::IATPatchFunction* patch = NULL; |
| 204 patch = IATPatch(module, "CloseHandle", &CloseHandleHook, | 204 patch = IATPatch(module, "CloseHandle", &CloseHandleHook, |
| 205 reinterpret_cast<void**>(&g_close_function)); | 205 reinterpret_cast<void**>(&g_close_function)); |
| 206 if (!patch) | 206 if (patch) |
| 207 return false; | 207 hooks_.push_back(patch); |
| 208 hooks_.push_back(patch); | |
| 209 | 208 |
| 210 patch = IATPatch(module, "DuplicateHandle", &DuplicateHandleHook, | 209 patch = IATPatch(module, "DuplicateHandle", &DuplicateHandleHook, |
| 211 reinterpret_cast<void**>(&g_duplicate_function)); | 210 reinterpret_cast<void**>(&g_duplicate_function)); |
| 212 if (!patch) | 211 if (patch) |
| 213 return false; | 212 hooks_.push_back(patch); |
| 214 hooks_.push_back(patch); | 213 |
| 215 return true; | 214 return true; |
| 216 } | 215 } |
| 217 | 216 |
| 218 bool HandleHooks::AddEATPatch() { | 217 bool HandleHooks::AddEATPatch() { |
| 219 // An attempt to restore the entry on the table at destruction is not safe. | 218 // An attempt to restore the entry on the table at destruction is not safe. |
| 220 // An attempt to restore the entry on the table at destruction is not safe. | 219 // An attempt to restore the entry on the table at destruction is not safe. |
| 221 return (EATPatch(GetModuleHandleA("kernel32.dll"), "CloseHandle", | 220 return (EATPatch(GetModuleHandleA("kernel32.dll"), "CloseHandle", |
| 222 &CloseHandleHook, | 221 &CloseHandleHook, |
| 223 reinterpret_cast<void**>(&g_close_function)) && | 222 reinterpret_cast<void**>(&g_close_function)) && |
| 224 EATPatch(GetModuleHandleA("kernel32.dll"), "DuplicateHandle", | 223 EATPatch(GetModuleHandleA("kernel32.dll"), "DuplicateHandle", |
| (...skipping 17 matching lines...) Expand all Loading... |
| 242 const DWORD kSize = 256; | 241 const DWORD kSize = 256; |
| 243 DWORD returned; | 242 DWORD returned; |
| 244 scoped_ptr<HMODULE[]> modules(new HMODULE[kSize]); | 243 scoped_ptr<HMODULE[]> modules(new HMODULE[kSize]); |
| 245 if (!EnumProcessModules(GetCurrentProcess(), modules.get(), | 244 if (!EnumProcessModules(GetCurrentProcess(), modules.get(), |
| 246 kSize * sizeof(HMODULE), &returned)) { | 245 kSize * sizeof(HMODULE), &returned)) { |
| 247 return false; | 246 return false; |
| 248 } | 247 } |
| 249 returned /= sizeof(HMODULE); | 248 returned /= sizeof(HMODULE); |
| 250 returned = std::min(kSize, returned); | 249 returned = std::min(kSize, returned); |
| 251 | 250 |
| 252 bool success = false; | |
| 253 | |
| 254 for (DWORD current = 0; current < returned; current++) { | 251 for (DWORD current = 0; current < returned; current++) { |
| 255 success = hooks->AddIATPatch(modules[current]); | 252 if (!hooks->AddIATPatch(modules[current])) |
| 256 if (!success) | 253 return false; |
| 257 break; | |
| 258 } | 254 } |
| 259 | 255 |
| 260 return success; | 256 return true; |
| 261 } | 257 } |
| 262 | 258 |
| 263 } // namespace | 259 } // namespace |
| 264 | 260 |
| 265 namespace base { | 261 namespace base { |
| 266 namespace debug { | 262 namespace debug { |
| 267 | 263 |
| 268 bool InstallHandleHooks() { | 264 bool InstallHandleHooks() { |
| 269 HandleHooks* hooks = g_hooks.Pointer(); | 265 HandleHooks* hooks = g_hooks.Pointer(); |
| 270 | 266 |
| 271 // Performing EAT interception first is safer in the presence of other | 267 // Performing EAT interception first is safer in the presence of other |
| 272 // threads attempting to call CloseHandle. | 268 // threads attempting to call CloseHandle. |
| 273 return (hooks->AddEATPatch() && PatchLoadedModules(hooks)); | 269 return (hooks->AddEATPatch() && PatchLoadedModules(hooks)); |
| 274 } | 270 } |
| 275 | 271 |
| 276 void RemoveHandleHooks() { | 272 void RemoveHandleHooks() { |
| 277 // We are patching all loaded modules without forcing them to stay in memory, | 273 // We are patching all loaded modules without forcing them to stay in memory, |
| 278 // removing patches is not safe. | 274 // removing patches is not safe. |
| 279 } | 275 } |
| 280 | 276 |
| 281 } // namespace debug | 277 } // namespace debug |
| 282 } // namespace base | 278 } // namespace base |
| OLD | NEW |