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

Side by Side Diff: base/iat_patch.cc

Issue 21453: Try a new approach to fixing IAT unpatch crashes when the DLL is gone. (Closed)
Patch Set: DCHECK Created 11 years, 9 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 (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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/iat_patch.h" 5 #include "base/iat_patch.h"
6 #include "base/logging.h" 6 #include "base/logging.h"
7 7
8 namespace iat_patch { 8 namespace iat_patch {
9 9
10 struct InterceptFunctionInformation { 10 struct InterceptFunctionInformation {
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 intercept_function_(NULL) { 174 intercept_function_(NULL) {
175 } 175 }
176 176
177 IATPatchFunction::~IATPatchFunction() { 177 IATPatchFunction::~IATPatchFunction() {
178 if (NULL != intercept_function_) { 178 if (NULL != intercept_function_) {
179 DWORD error = Unpatch(); 179 DWORD error = Unpatch();
180 DCHECK_EQ(NO_ERROR, error); 180 DCHECK_EQ(NO_ERROR, error);
181 } 181 }
182 } 182 }
183 183
184 DWORD IATPatchFunction::Patch(HMODULE module_handle, 184 DWORD IATPatchFunction::Patch(const wchar_t* module,
185 const char* imported_from_module, 185 const char* imported_from_module,
186 const char* function_name, 186 const char* function_name,
187 void* new_function) { 187 void* new_function) {
188 DCHECK_EQ(static_cast<void*>(NULL), original_function_); 188 DCHECK_EQ(static_cast<void*>(NULL), original_function_);
189 DCHECK_EQ(static_cast<IMAGE_THUNK_DATA*>(NULL), iat_thunk_); 189 DCHECK_EQ(static_cast<IMAGE_THUNK_DATA*>(NULL), iat_thunk_);
190 DCHECK_EQ(static_cast<void*>(NULL), intercept_function_); 190 DCHECK_EQ(static_cast<void*>(NULL), intercept_function_);
191 191
192 HMODULE module_handle = LoadLibraryW(module);
193
194 if (module_handle == NULL) {
195 NOTREACHED();
196 return GetLastError();
197 }
198
192 DWORD error = InterceptImportedFunction(module_handle, 199 DWORD error = InterceptImportedFunction(module_handle,
193 imported_from_module, 200 imported_from_module,
194 function_name, 201 function_name,
195 new_function, 202 new_function,
196 &original_function_, 203 &original_function_,
197 &iat_thunk_); 204 &iat_thunk_);
198 205
199 if (NO_ERROR == error) { 206 if (NO_ERROR == error) {
200 DCHECK_NE(original_function_, intercept_function_); 207 DCHECK_NE(original_function_, intercept_function_);
208 module_handle_ = module_handle;
201 intercept_function_ = new_function; 209 intercept_function_ = new_function;
210 } else {
211 FreeLibrary(module_handle);
202 } 212 }
203 213
204 return error; 214 return error;
205 } 215 }
206 216
207 DWORD IATPatchFunction::Unpatch() { 217 DWORD IATPatchFunction::Unpatch() {
208 DWORD error = 0; 218 DWORD error = RestoreImportedFunction(intercept_function_,
209 MEMORY_BASIC_INFORMATION memory_info = {0}; 219 original_function_,
210 220 iat_thunk_);
211 // If the module has already unloaded, no point trying to unpatch.
212 if (!VirtualQuery(original_function_, &memory_info,
213 sizeof(memory_info))) {
214 error = GetLastError();
215 NOTREACHED();
216 return error;
217 }
218
219 if ((memory_info.State & MEM_COMMIT) != MEM_COMMIT) {
220 NOTREACHED();
221 return ERROR_ACCESS_DENIED;
222 }
223
224 error = RestoreImportedFunction(intercept_function_,
225 original_function_,
226 iat_thunk_);
227 DCHECK(NO_ERROR == error); 221 DCHECK(NO_ERROR == error);
228 222
229 // Hands off the intercept if we fail to unpatch. 223 // Hands off the intercept if we fail to unpatch.
230 // If IATPatchFunction::Unpatch fails during RestoreImportedFunction 224 // If IATPatchFunction::Unpatch fails during RestoreImportedFunction
231 // it means that we cannot safely unpatch the import address table 225 // it means that we cannot safely unpatch the import address table
232 // patch. In this case its better to be hands off the intercept as 226 // patch. In this case its better to be hands off the intercept as
233 // trying to unpatch again in the destructor of IATPatchFunction is 227 // trying to unpatch again in the destructor of IATPatchFunction is
234 // not going to be any safer 228 // not going to be any safer
229 if (module_handle_)
230 FreeLibrary(module_handle_);
231 module_handle_ = NULL;
235 intercept_function_ = NULL; 232 intercept_function_ = NULL;
236 original_function_ = NULL; 233 original_function_ = NULL;
237 iat_thunk_ = NULL; 234 iat_thunk_ = NULL;
238 235
239 return error; 236 return error;
240 } 237 }
241 238
242 } // namespace iat_patch 239 } // namespace iat_patch
243
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698