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 hooks_.push_back(patch); | 207 return false; |
| 208 hooks_.push_back(patch); |
208 | 209 |
209 patch = IATPatch(module, "DuplicateHandle", &DuplicateHandleHook, | 210 patch = IATPatch(module, "DuplicateHandle", &DuplicateHandleHook, |
210 reinterpret_cast<void**>(&g_duplicate_function)); | 211 reinterpret_cast<void**>(&g_duplicate_function)); |
211 if (patch) | 212 if (!patch) |
212 hooks_.push_back(patch); | 213 return false; |
213 | 214 hooks_.push_back(patch); |
214 return true; | 215 return true; |
215 } | 216 } |
216 | 217 |
217 bool HandleHooks::AddEATPatch() { | 218 bool HandleHooks::AddEATPatch() { |
218 // 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. |
219 // 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. |
220 return (EATPatch(GetModuleHandleA("kernel32.dll"), "CloseHandle", | 221 return (EATPatch(GetModuleHandleA("kernel32.dll"), "CloseHandle", |
221 &CloseHandleHook, | 222 &CloseHandleHook, |
222 reinterpret_cast<void**>(&g_close_function)) && | 223 reinterpret_cast<void**>(&g_close_function)) && |
223 EATPatch(GetModuleHandleA("kernel32.dll"), "DuplicateHandle", | 224 EATPatch(GetModuleHandleA("kernel32.dll"), "DuplicateHandle", |
(...skipping 17 matching lines...) Expand all Loading... |
241 const DWORD kSize = 256; | 242 const DWORD kSize = 256; |
242 DWORD returned; | 243 DWORD returned; |
243 scoped_ptr<HMODULE[]> modules(new HMODULE[kSize]); | 244 scoped_ptr<HMODULE[]> modules(new HMODULE[kSize]); |
244 if (!EnumProcessModules(GetCurrentProcess(), modules.get(), | 245 if (!EnumProcessModules(GetCurrentProcess(), modules.get(), |
245 kSize * sizeof(HMODULE), &returned)) { | 246 kSize * sizeof(HMODULE), &returned)) { |
246 return false; | 247 return false; |
247 } | 248 } |
248 returned /= sizeof(HMODULE); | 249 returned /= sizeof(HMODULE); |
249 returned = std::min(kSize, returned); | 250 returned = std::min(kSize, returned); |
250 | 251 |
| 252 bool success = false; |
| 253 |
251 for (DWORD current = 0; current < returned; current++) { | 254 for (DWORD current = 0; current < returned; current++) { |
252 if (!hooks->AddIATPatch(modules[current])) | 255 success = hooks->AddIATPatch(modules[current]); |
253 return false; | 256 if (!success) |
| 257 break; |
254 } | 258 } |
255 | 259 |
256 return true; | 260 return success; |
257 } | 261 } |
258 | 262 |
259 } // namespace | 263 } // namespace |
260 | 264 |
261 namespace base { | 265 namespace base { |
262 namespace debug { | 266 namespace debug { |
263 | 267 |
264 bool InstallHandleHooks() { | 268 bool InstallHandleHooks() { |
265 HandleHooks* hooks = g_hooks.Pointer(); | 269 HandleHooks* hooks = g_hooks.Pointer(); |
266 | 270 |
267 // Performing EAT interception first is safer in the presence of other | 271 // Performing EAT interception first is safer in the presence of other |
268 // threads attempting to call CloseHandle. | 272 // threads attempting to call CloseHandle. |
269 return (hooks->AddEATPatch() && PatchLoadedModules(hooks)); | 273 return (hooks->AddEATPatch() && PatchLoadedModules(hooks)); |
270 } | 274 } |
271 | 275 |
272 void RemoveHandleHooks() { | 276 void RemoveHandleHooks() { |
273 // We are patching all loaded modules without forcing them to stay in memory, | 277 // We are patching all loaded modules without forcing them to stay in memory, |
274 // removing patches is not safe. | 278 // removing patches is not safe. |
275 } | 279 } |
276 | 280 |
277 } // namespace debug | 281 } // namespace debug |
278 } // namespace base | 282 } // namespace base |
OLD | NEW |