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

Side by Side Diff: base/debug/close_handle_hook_win.cc

Issue 2667513003: Remove some LazyInstance use in base/ (Closed)
Patch Set: no message_window Created 3 years, 10 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 unified diff | Download patch
OLDNEW
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 #include <stddef.h> 9 #include <stddef.h>
10 10
11 #include <algorithm> 11 #include <algorithm>
12 #include <memory> 12 #include <memory>
13 #include <vector> 13 #include <vector>
14 14
15 #include "base/lazy_instance.h"
16 #include "base/macros.h" 15 #include "base/macros.h"
17 #include "base/win/iat_patch_function.h" 16 #include "base/win/iat_patch_function.h"
18 #include "base/win/pe_image.h" 17 #include "base/win/pe_image.h"
19 #include "base/win/scoped_handle.h" 18 #include "base/win/scoped_handle.h"
20 #include "build/build_config.h" 19 #include "build/build_config.h"
21 20
22 namespace { 21 namespace {
23 22
24 typedef BOOL (WINAPI* CloseHandleType) (HANDLE handle); 23 typedef BOOL (WINAPI* CloseHandleType) (HANDLE handle);
25 24
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 189
191 // Keeps track of all the hooks needed to intercept functions which could 190 // Keeps track of all the hooks needed to intercept functions which could
192 // possibly close handles. 191 // possibly close handles.
193 class HandleHooks { 192 class HandleHooks {
194 public: 193 public:
195 HandleHooks() {} 194 HandleHooks() {}
196 ~HandleHooks() {} 195 ~HandleHooks() {}
197 196
198 void AddIATPatch(HMODULE module); 197 void AddIATPatch(HMODULE module);
199 void AddEATPatch(); 198 void AddEATPatch();
200 void Unpatch();
201 199
202 private: 200 private:
203 std::vector<base::win::IATPatchFunction*> hooks_; 201 std::vector<base::win::IATPatchFunction*> hooks_;
204 DISALLOW_COPY_AND_ASSIGN(HandleHooks); 202 DISALLOW_COPY_AND_ASSIGN(HandleHooks);
205 }; 203 };
206 base::LazyInstance<HandleHooks> g_hooks = LAZY_INSTANCE_INITIALIZER;
207 204
208 void HandleHooks::AddIATPatch(HMODULE module) { 205 void HandleHooks::AddIATPatch(HMODULE module) {
209 if (!module) 206 if (!module)
210 return; 207 return;
211 208
212 base::win::IATPatchFunction* patch = NULL; 209 base::win::IATPatchFunction* patch = NULL;
213 patch = IATPatch(module, "CloseHandle", &CloseHandleHook, 210 patch = IATPatch(module, "CloseHandle", &CloseHandleHook,
214 reinterpret_cast<void**>(&g_close_function)); 211 reinterpret_cast<void**>(&g_close_function));
215 if (!patch) 212 if (!patch)
216 return; 213 return;
217 hooks_.push_back(patch); 214 hooks_.push_back(patch);
218 215
219 patch = IATPatch(module, "DuplicateHandle", &DuplicateHandleHook, 216 patch = IATPatch(module, "DuplicateHandle", &DuplicateHandleHook,
220 reinterpret_cast<void**>(&g_duplicate_function)); 217 reinterpret_cast<void**>(&g_duplicate_function));
221 if (!patch) 218 if (!patch)
222 return; 219 return;
223 hooks_.push_back(patch); 220 hooks_.push_back(patch);
224 } 221 }
225 222
226 void HandleHooks::AddEATPatch() { 223 void HandleHooks::AddEATPatch() {
227 // An attempt to restore the entry on the table at destruction is not safe. 224 // An attempt to restore the entry on the table at destruction is not safe.
228 EATPatch(GetModuleHandleA("kernel32.dll"), "CloseHandle", 225 EATPatch(GetModuleHandleA("kernel32.dll"), "CloseHandle",
229 &CloseHandleHook, reinterpret_cast<void**>(&g_close_function)); 226 &CloseHandleHook, reinterpret_cast<void**>(&g_close_function));
230 EATPatch(GetModuleHandleA("kernel32.dll"), "DuplicateHandle", 227 EATPatch(GetModuleHandleA("kernel32.dll"), "DuplicateHandle",
231 &DuplicateHandleHook, 228 &DuplicateHandleHook,
232 reinterpret_cast<void**>(&g_duplicate_function)); 229 reinterpret_cast<void**>(&g_duplicate_function));
233 } 230 }
234 231
235 void HandleHooks::Unpatch() {
236 for (std::vector<base::win::IATPatchFunction*>::iterator it = hooks_.begin();
237 it != hooks_.end(); ++it) {
238 (*it)->Unpatch();
239 delete *it;
240 }
241 }
242
243 void PatchLoadedModules(HandleHooks* hooks) { 232 void PatchLoadedModules(HandleHooks* hooks) {
244 const DWORD kSize = 256; 233 const DWORD kSize = 256;
245 DWORD returned; 234 DWORD returned;
246 std::unique_ptr<HMODULE[]> modules(new HMODULE[kSize]); 235 std::unique_ptr<HMODULE[]> modules(new HMODULE[kSize]);
247 if (!EnumProcessModules(GetCurrentProcess(), modules.get(), 236 if (!EnumProcessModules(GetCurrentProcess(), modules.get(),
248 kSize * sizeof(HMODULE), &returned)) { 237 kSize * sizeof(HMODULE), &returned)) {
249 return; 238 return;
250 } 239 }
251 returned /= sizeof(HMODULE); 240 returned /= sizeof(HMODULE);
252 returned = std::min(kSize, returned); 241 returned = std::min(kSize, returned);
253 242
254 for (DWORD current = 0; current < returned; current++) { 243 for (DWORD current = 0; current < returned; current++) {
255 hooks->AddIATPatch(modules[current]); 244 hooks->AddIATPatch(modules[current]);
256 } 245 }
257 } 246 }
258 247
259 } // namespace 248 } // namespace
260 249
261 void InstallHandleHooks() { 250 void InstallHandleHooks() {
262 HandleHooks* hooks = g_hooks.Pointer(); 251 static HandleHooks* hooks = new HandleHooks();
263 252
264 // Performing EAT interception first is safer in the presence of other 253 // Performing EAT interception first is safer in the presence of other
265 // threads attempting to call CloseHandle. 254 // threads attempting to call CloseHandle.
266 hooks->AddEATPatch(); 255 hooks->AddEATPatch();
267 PatchLoadedModules(hooks); 256 PatchLoadedModules(hooks);
268 } 257 }
269 258
270 void RemoveHandleHooks() {
271 // We are partching all loaded modules without forcing them to stay in memory,
272 // removing patches is not safe.
273 }
274
275 } // namespace debug 259 } // namespace debug
276 } // namespace base 260 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698