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

Side by Side Diff: chrome/app/close_handle_hook_win.cc

Issue 1545473002: Revert Active Verifier tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 12 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
« no previous file with comments | « chrome/app/close_handle_hook_win.h ('k') | chrome/chrome_dll.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "chrome/app/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>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/lazy_instance.h" 13 #include "base/lazy_instance.h"
14 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_ptr.h"
15 #include "base/win/iat_patch_function.h" 15 #include "base/win/iat_patch_function.h"
16 #include "base/win/pe_image.h" 16 #include "base/win/pe_image.h"
17 #include "base/win/scoped_handle.h" 17 #include "base/win/scoped_handle.h"
18 #include "chrome/common/channel_info.h"
19 #include "components/version_info/version_info.h"
18 20
19 namespace { 21 namespace {
20 22
21 typedef BOOL (WINAPI* CloseHandleType) (HANDLE handle); 23 typedef BOOL (WINAPI* CloseHandleType) (HANDLE handle);
22 24
23 typedef BOOL (WINAPI* DuplicateHandleType)(HANDLE source_process, 25 typedef BOOL (WINAPI* DuplicateHandleType)(HANDLE source_process,
24 HANDLE source_handle, 26 HANDLE source_handle,
25 HANDLE target_process, 27 HANDLE target_process,
26 HANDLE* target_handle, 28 HANDLE* target_handle,
27 DWORD desired_access, 29 DWORD desired_access,
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 DCHECK(bytes_); 114 DCHECK(bytes_);
113 115
114 VirtualProtect(address_, bytes_, old_protect_, &old_protect_); 116 VirtualProtect(address_, bytes_, old_protect_, &old_protect_);
115 changed_ = false; 117 changed_ = false;
116 address_ = NULL; 118 address_ = NULL;
117 bytes_ = 0; 119 bytes_ = 0;
118 old_protect_ = 0; 120 old_protect_ = 0;
119 } 121 }
120 122
121 // Performs an EAT interception. 123 // Performs an EAT interception.
122 bool EATPatch(HMODULE module, const char* function_name, 124 void EATPatch(HMODULE module, const char* function_name,
123 void* new_function, void** old_function) { 125 void* new_function, void** old_function) {
124 if (!module) 126 if (!module)
125 return false; 127 return;
126 128
127 base::win::PEImage pe(module); 129 base::win::PEImage pe(module);
128 if (!pe.VerifyMagic()) 130 if (!pe.VerifyMagic())
129 return false; 131 return;
130 132
131 DWORD* eat_entry = pe.GetExportEntry(function_name); 133 DWORD* eat_entry = pe.GetExportEntry(function_name);
132 if (!eat_entry) 134 if (!eat_entry)
133 return false; 135 return;
134 136
135 if (!(*old_function)) 137 if (!(*old_function))
136 *old_function = pe.RVAToAddr(*eat_entry); 138 *old_function = pe.RVAToAddr(*eat_entry);
137 139
138 AutoProtectMemory memory; 140 AutoProtectMemory memory;
139 if (!memory.ChangeProtection(eat_entry, sizeof(DWORD))) 141 if (!memory.ChangeProtection(eat_entry, sizeof(DWORD)))
140 return false; 142 return;
141 143
142 // Perform the patch. 144 // Perform the patch.
143 #pragma warning(push) 145 #pragma warning(push)
144 #pragma warning(disable : 4311 4302) 146 #pragma warning(disable : 4311 4302)
145 // These casts generate truncation warnings because they are 32 bit specific. 147 // These casts generate truncation warnings because they are 32 bit specific.
146 *eat_entry = reinterpret_cast<DWORD>(new_function) - 148 *eat_entry = reinterpret_cast<DWORD>(new_function) -
147 reinterpret_cast<DWORD>(module); 149 reinterpret_cast<DWORD>(module);
148 #pragma warning(pop) 150 #pragma warning(pop)
149 return true;
150 } 151 }
151 152
152 // Performs an IAT interception. 153 // Performs an IAT interception.
153 base::win::IATPatchFunction* IATPatch(HMODULE module, const char* function_name, 154 base::win::IATPatchFunction* IATPatch(HMODULE module, const char* function_name,
154 void* new_function, void** old_function) { 155 void* new_function, void** old_function) {
155 if (!module) 156 if (!module)
156 return NULL; 157 return NULL;
157 158
158 base::win::IATPatchFunction* patch = new base::win::IATPatchFunction; 159 base::win::IATPatchFunction* patch = new base::win::IATPatchFunction;
159 __try { 160 __try {
(...skipping 19 matching lines...) Expand all
179 return patch; 180 return patch;
180 } 181 }
181 182
182 // Keeps track of all the hooks needed to intercept functions which could 183 // Keeps track of all the hooks needed to intercept functions which could
183 // possibly close handles. 184 // possibly close handles.
184 class HandleHooks { 185 class HandleHooks {
185 public: 186 public:
186 HandleHooks() {} 187 HandleHooks() {}
187 ~HandleHooks() {} 188 ~HandleHooks() {}
188 189
189 bool AddIATPatch(HMODULE module); 190 void AddIATPatch(HMODULE module);
190 bool AddEATPatch(); 191 void AddEATPatch();
191 bool Unpatch(); 192 void Unpatch();
192 193
193 private: 194 private:
194 std::vector<base::win::IATPatchFunction*> hooks_; 195 std::vector<base::win::IATPatchFunction*> hooks_;
195 DISALLOW_COPY_AND_ASSIGN(HandleHooks); 196 DISALLOW_COPY_AND_ASSIGN(HandleHooks);
196 }; 197 };
197 base::LazyInstance<HandleHooks> g_hooks = LAZY_INSTANCE_INITIALIZER; 198 base::LazyInstance<HandleHooks> g_hooks = LAZY_INSTANCE_INITIALIZER;
198 199
199 bool HandleHooks::AddIATPatch(HMODULE module) { 200 void HandleHooks::AddIATPatch(HMODULE module) {
200 if (!module) 201 if (!module)
201 return false; 202 return;
202 203
203 base::win::IATPatchFunction* patch = NULL; 204 base::win::IATPatchFunction* patch = NULL;
204 patch = IATPatch(module, "CloseHandle", &CloseHandleHook, 205 patch = IATPatch(module, "CloseHandle", &CloseHandleHook,
205 reinterpret_cast<void**>(&g_close_function)); 206 reinterpret_cast<void**>(&g_close_function));
206 if (!patch) 207 if (!patch)
207 return false; 208 return;
208 hooks_.push_back(patch); 209 hooks_.push_back(patch);
209 210
210 patch = IATPatch(module, "DuplicateHandle", &DuplicateHandleHook, 211 patch = IATPatch(module, "DuplicateHandle", &DuplicateHandleHook,
211 reinterpret_cast<void**>(&g_duplicate_function)); 212 reinterpret_cast<void**>(&g_duplicate_function));
212 if (!patch) 213 if (!patch)
213 return false; 214 return;
214 hooks_.push_back(patch); 215 hooks_.push_back(patch);
215 return true;
216 } 216 }
217 217
218 bool HandleHooks::AddEATPatch() { 218 void HandleHooks::AddEATPatch() {
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. 219 // An attempt to restore the entry on the table at destruction is not safe.
221 return (EATPatch(GetModuleHandleA("kernel32.dll"), "CloseHandle", 220 EATPatch(GetModuleHandleA("kernel32.dll"), "CloseHandle",
222 &CloseHandleHook, 221 &CloseHandleHook, reinterpret_cast<void**>(&g_close_function));
223 reinterpret_cast<void**>(&g_close_function)) && 222 EATPatch(GetModuleHandleA("kernel32.dll"), "DuplicateHandle",
224 EATPatch(GetModuleHandleA("kernel32.dll"), "DuplicateHandle", 223 &DuplicateHandleHook,
225 &DuplicateHandleHook, 224 reinterpret_cast<void**>(&g_duplicate_function));
226 reinterpret_cast<void**>(&g_duplicate_function)));
227 } 225 }
228 226
229 bool HandleHooks::Unpatch() { 227 void HandleHooks::Unpatch() {
230 DWORD err = NO_ERROR;
231 for (std::vector<base::win::IATPatchFunction*>::iterator it = hooks_.begin(); 228 for (std::vector<base::win::IATPatchFunction*>::iterator it = hooks_.begin();
232 it != hooks_.end(); ++it) { 229 it != hooks_.end(); ++it) {
233 err = (*it)->Unpatch(); 230 (*it)->Unpatch();
234 if (err != NO_ERROR)
235 break;
236 delete *it; 231 delete *it;
237 } 232 }
238 return (err == NO_ERROR);
239 } 233 }
240 234
241 bool PatchLoadedModules(HandleHooks* hooks) { 235 bool UseHooks() {
236 #if defined(ARCH_CPU_X86_64)
237 return false;
238 #elif defined(NDEBUG)
239 version_info::Channel channel = chrome::GetChannel();
240 if (channel == version_info::Channel::CANARY ||
241 channel == version_info::Channel::DEV) {
242 return true;
243 }
244
245 return false;
246 #else // NDEBUG
247 return true;
248 #endif
249 }
250
251 void PatchLoadedModules(HandleHooks* hooks) {
242 const DWORD kSize = 256; 252 const DWORD kSize = 256;
243 DWORD returned; 253 DWORD returned;
244 scoped_ptr<HMODULE[]> modules(new HMODULE[kSize]); 254 scoped_ptr<HMODULE[]> modules(new HMODULE[kSize]);
245 if (!EnumProcessModules(GetCurrentProcess(), modules.get(), 255 if (!EnumProcessModules(GetCurrentProcess(), modules.get(),
246 kSize * sizeof(HMODULE), &returned)) { 256 kSize * sizeof(HMODULE), &returned)) {
247 return false; 257 return;
248 } 258 }
249 returned /= sizeof(HMODULE); 259 returned /= sizeof(HMODULE);
250 returned = std::min(kSize, returned); 260 returned = std::min(kSize, returned);
251 261
252 bool success = false;
253
254 for (DWORD current = 0; current < returned; current++) { 262 for (DWORD current = 0; current < returned; current++) {
255 success = hooks->AddIATPatch(modules[current]); 263 hooks->AddIATPatch(modules[current]);
256 if (!success)
257 break;
258 } 264 }
259
260 return success;
261 } 265 }
262 266
263 } // namespace 267 } // namespace
264 268
265 namespace base { 269 void InstallHandleHooks() {
266 namespace debug { 270 if (UseHooks()) {
271 HandleHooks* hooks = g_hooks.Pointer();
267 272
268 bool InstallHandleHooks() { 273 // Performing EAT interception first is safer in the presence of other
269 HandleHooks* hooks = g_hooks.Pointer(); 274 // threads attempting to call CloseHandle.
270 275 hooks->AddEATPatch();
271 // Performing EAT interception first is safer in the presence of other 276 PatchLoadedModules(hooks);
272 // threads attempting to call CloseHandle. 277 } else {
273 return (hooks->AddEATPatch() && PatchLoadedModules(hooks)); 278 base::win::DisableHandleVerifier();
279 }
274 } 280 }
275 281
276 void RemoveHandleHooks() { 282 void RemoveHandleHooks() {
277 // We are patching all loaded modules without forcing them to stay in memory, 283 // We are partching all loaded modules without forcing them to stay in memory,
278 // removing patches is not safe. 284 // removing patches is not safe.
279 } 285 }
280
281 } // namespace debug
282 } // namespace base
OLDNEW
« no previous file with comments | « chrome/app/close_handle_hook_win.h ('k') | chrome/chrome_dll.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698