diff options
-rw-r--r-- | app/app_base.gypi | 7 | ||||
-rw-r--r-- | app/win/iat_patch_function.cc (renamed from base/iat_patch.cc) | 111 | ||||
-rw-r--r-- | app/win/iat_patch_function.h | 73 | ||||
-rw-r--r-- | base/base.gypi | 3 | ||||
-rw-r--r-- | base/iat_patch.h | 123 | ||||
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_edit_view_win.cc | 6 | ||||
-rw-r--r-- | chrome/renderer/render_process_impl.cc | 6 | ||||
-rw-r--r-- | chrome/utility/utility_thread.cc | 14 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl_win.cc | 8 |
9 files changed, 172 insertions, 179 deletions
diff --git a/app/app_base.gypi b/app/app_base.gypi index 67f3f5f..b9d2f6c 100644 --- a/app/app_base.gypi +++ b/app/app_base.gypi @@ -220,6 +220,8 @@ 'throb_animation.h', 'tween.cc', 'tween.h', + 'win/iat_patch_function.cc', + 'win/iat_patch_function.h', 'x11_util.cc', 'x11_util.h', 'x11_util_internal.h', @@ -306,6 +308,11 @@ 'gfx/native_theme_win.cc', 'gfx/native_theme_win.h', 'os_exchange_data.cc', + 'win/iat_patch_function.cc', + 'win/iat_patch_function.h', + ], + 'sources/': [ + ['exclude', '/win/*'], ], }], ['OS=="linux"', { diff --git a/base/iat_patch.cc b/app/win/iat_patch_function.cc index fa5109f..3f90d81 100644 --- a/base/iat_patch.cc +++ b/app/win/iat_patch_function.cc @@ -2,10 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/iat_patch.h" +#include "app/win/iat_patch_function.h" + #include "base/logging.h" -namespace iat_patch { +namespace app { +namespace win { + +namespace { struct InterceptFunctionInformation { bool finished_operation; @@ -17,7 +21,7 @@ struct InterceptFunctionInformation { DWORD return_code; }; -static void* GetIATFunction(IMAGE_THUNK_DATA* iat_thunk) { +void* GetIATFunction(IMAGE_THUNK_DATA* iat_thunk) { if (NULL == iat_thunk) { NOTREACHED(); return NULL; @@ -35,10 +39,49 @@ static void* GetIATFunction(IMAGE_THUNK_DATA* iat_thunk) { iat_function.thunk = *iat_thunk; return iat_function.pointer; } +// Change the page protection (of code pages) to writable and copy +// the data at the specified location +// +// Arguments: +// old_code Target location to copy +// new_code Source +// length Number of bytes to copy +// +// Returns: Windows error code (winerror.h). NO_ERROR if successful +DWORD ModifyCode(void* old_code, void* new_code, int length) { + if ((NULL == old_code) || (NULL == new_code) || (0 == length)) { + NOTREACHED(); + return ERROR_INVALID_PARAMETER; + } + + // Change the page protection so that we can write. + DWORD error = NO_ERROR; + DWORD old_page_protection = 0; + if (VirtualProtect(old_code, + length, + PAGE_READWRITE, + &old_page_protection)) { + + // Write the data. + CopyMemory(old_code, new_code, length); + + // Restore the old page protection. + error = ERROR_SUCCESS; + VirtualProtect(old_code, + length, + old_page_protection, + &old_page_protection); + } else { + error = GetLastError(); + NOTREACHED(); + } + + return error; +} -static bool InterceptEnumCallback(const PEImage &image, const char* module, - DWORD ordinal, const char* name, DWORD hint, - IMAGE_THUNK_DATA* iat, void* cookie) { +bool InterceptEnumCallback(const PEImage &image, const char* module, + DWORD ordinal, const char* name, DWORD hint, + IMAGE_THUNK_DATA* iat, void* cookie) { InterceptFunctionInformation* intercept_information = reinterpret_cast<InterceptFunctionInformation*>(cookie); @@ -79,6 +122,20 @@ static bool InterceptEnumCallback(const PEImage &image, const char* module, return true; } +// Helper to intercept a function in an import table of a specific +// module. +// +// Arguments: +// module_handle Module to be intercepted +// imported_from_module Module that exports the symbol +// function_name Name of the API to be intercepted +// new_function Interceptor function +// old_function Receives the original function pointer +// iat_thunk Receives pointer to IAT_THUNK_DATA +// for the API from the import table. +// +// Returns: Returns NO_ERROR on success or Windows error code +// as defined in winerror.h DWORD InterceptImportedFunction(HMODULE module_handle, const char* imported_from_module, const char* function_name, void* new_function, @@ -116,6 +173,14 @@ DWORD InterceptImportedFunction(HMODULE module_handle, return intercept_information.return_code; } +// Restore intercepted IAT entry with the original function. +// +// Arguments: +// intercept_function Interceptor function +// original_function Receives the original function pointer +// +// Returns: Returns NO_ERROR on success or Windows error code +// as defined in winerror.h DWORD RestoreImportedFunction(void* intercept_function, void* original_function, IMAGE_THUNK_DATA* iat_thunk) { @@ -137,36 +202,7 @@ DWORD RestoreImportedFunction(void* intercept_function, sizeof(original_function)); } -DWORD ModifyCode(void* old_code, void* new_code, int length) { - if ((NULL == old_code) || (NULL == new_code) || (0 == length)) { - NOTREACHED(); - return ERROR_INVALID_PARAMETER; - } - - // Change the page protection so that we can write. - DWORD error = NO_ERROR; - DWORD old_page_protection = 0; - if (VirtualProtect(old_code, - length, - PAGE_READWRITE, - &old_page_protection)) { - - // Write the data. - CopyMemory(old_code, new_code, length); - - // Restore the old page protection. - error = ERROR_SUCCESS; - VirtualProtect(old_code, - length, - old_page_protection, - &old_page_protection); - } else { - error = GetLastError(); - NOTREACHED(); - } - - return error; -} +} // namespace IATPatchFunction::IATPatchFunction() : module_handle_(NULL), @@ -237,4 +273,5 @@ DWORD IATPatchFunction::Unpatch() { return error; } -} // namespace iat_patch +} // namespace win +} // namespace app diff --git a/app/win/iat_patch_function.h b/app/win/iat_patch_function.h new file mode 100644 index 0000000..37961dd --- /dev/null +++ b/app/win/iat_patch_function.h @@ -0,0 +1,73 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef APP_WIN_IAT_PATCH_FUNCTION_H_ +#define APP_WIN_IAT_PATCH_FUNCTION_H_ +#pragma once + +#include <windows.h> + +#include "base/basictypes.h" +#include "base/pe_image.h" + +namespace app { +namespace win { + +// A class that encapsulates Import Address Table patching helpers and restores +// the original function in the destructor. +// +// It will intercept functions for a specific DLL imported from another DLL. +// This is the case when, for example, we want to intercept +// CertDuplicateCertificateContext function (exported from crypt32.dll) called +// by wininet.dll. +class IATPatchFunction { + public: + IATPatchFunction(); + ~IATPatchFunction(); + + // Intercept a function in an import table of a specific + // module. Save the original function and the import + // table address. These values will be used later + // during Unpatch + // + // Arguments: + // module Module to be intercepted + // imported_from_module Module that exports the 'function_name' + // function_name Name of the API to be intercepted + // + // Returns: Windows error code (winerror.h). NO_ERROR if successful + // + // Note: Patching a function will make the IAT patch take some "ownership" on + // |module|. It will LoadLibrary(module) to keep the DLL alive until a call + // to Unpatch(), which will call FreeLibrary() and allow the module to be + // unloaded. The idea is to help prevent the DLL from going away while a + // patch is still active. + DWORD Patch(const wchar_t* module, + const char* imported_from_module, + const char* function_name, + void* new_function); + + // Unpatch the IAT entry using internally saved original + // function. + // + // Returns: Windows error code (winerror.h). NO_ERROR if successful + DWORD Unpatch(); + + bool is_patched() const { + return (NULL != intercept_function_); + } + + private: + HMODULE module_handle_; + void* intercept_function_; + void* original_function_; + IMAGE_THUNK_DATA* iat_thunk_; + + DISALLOW_COPY_AND_ASSIGN(IATPatchFunction); +}; + +} // namespace win +} // namespace app + +#endif // APP_WIN_IAT_PATCH_FUNCTION_H_ diff --git a/base/base.gypi b/base/base.gypi index 9329ccb..180a1f9 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -95,8 +95,6 @@ 'gtk_util.cc', 'gtk_util.h', 'hash_tables.h', - 'iat_patch.cc', - 'iat_patch.h', 'id_map.h', 'json/json_reader.cc', 'json/json_reader.h', @@ -504,7 +502,6 @@ 'debug_on_start.cc', 'event_recorder.cc', 'file_version_info.cc', - 'iat_patch.cc', 'image_util.cc', 'object_watcher.cc', 'pe_image.cc', diff --git a/base/iat_patch.h b/base/iat_patch.h deleted file mode 100644 index c2cbbcb..0000000 --- a/base/iat_patch.h +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file declares a helpers to intercept functions from a DLL. -// -// This set of functions are designed to intercept functions for a -// specific DLL imported from another DLL. This is the case when, -// for example, we want to intercept CertDuplicateCertificateContext -// function (exported from crypt32.dll) called by wininet.dll. - -#ifndef BASE_IAT_PATCH_H__ -#define BASE_IAT_PATCH_H__ -#pragma once - -#include <windows.h> -#include "base/basictypes.h" -#include "base/pe_image.h" - -namespace iat_patch { - -// Helper to intercept a function in an import table of a specific -// module. -// -// Arguments: -// module_handle Module to be intercepted -// imported_from_module Module that exports the symbol -// function_name Name of the API to be intercepted -// new_function Interceptor function -// old_function Receives the original function pointer -// iat_thunk Receives pointer to IAT_THUNK_DATA -// for the API from the import table. -// -// Returns: Returns NO_ERROR on success or Windows error code -// as defined in winerror.h -// -DWORD InterceptImportedFunction(HMODULE module_handle, - const char* imported_from_module, - const char* function_name, - void* new_function, - void** old_function, - IMAGE_THUNK_DATA** iat_thunk); - -// Restore intercepted IAT entry with the original function. -// -// Arguments: -// intercept_function Interceptor function -// original_function Receives the original function pointer -// -// Returns: Returns NO_ERROR on success or Windows error code -// as defined in winerror.h -// -DWORD RestoreImportedFunction(void* intercept_function, - void* original_function, - IMAGE_THUNK_DATA* iat_thunk); - -// Change the page protection (of code pages) to writable and copy -// the data at the specified location -// -// Arguments: -// old_code Target location to copy -// new_code Source -// length Number of bytes to copy -// -// Returns: Windows error code (winerror.h). NO_ERROR if successful -// -DWORD ModifyCode(void* old_code, - void* new_code, - int length); - -// A class that encapsulates IAT patching helpers and restores -// the original function in the destructor. -class IATPatchFunction { - public: - IATPatchFunction(); - ~IATPatchFunction(); - - // Intercept a function in an import table of a specific - // module. Save the original function and the import - // table address. These values will be used later - // during Unpatch - // - // Arguments: - // module Module to be intercepted - // imported_from_module Module that exports the 'function_name' - // function_name Name of the API to be intercepted - // - // Returns: Windows error code (winerror.h). NO_ERROR if successful - // - // Note: Patching a function will make the IAT patch take some "ownership" on - // |module|. It will LoadLibrary(module) to keep the DLL alive until a call - // to Unpatch(), which will call FreeLibrary() and allow the module to be - // unloaded. The idea is to help prevent the DLL from going away while a - // patch is still active. - // - DWORD Patch(const wchar_t* module, - const char* imported_from_module, - const char* function_name, - void* new_function); - - // Unpatch the IAT entry using internally saved original - // function. - // - // Returns: Windows error code (winerror.h). NO_ERROR if successful - // - DWORD Unpatch(); - - bool is_patched() const { - return (NULL != intercept_function_); - } - - private: - HMODULE module_handle_; - void* intercept_function_; - void* original_function_; - IMAGE_THUNK_DATA* iat_thunk_; - - DISALLOW_COPY_AND_ASSIGN(IATPatchFunction); -}; - -} // namespace iat_patch - -#endif // BASE_IAT_PATCH_H__ diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc index 4823d2e..e57a96d 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc @@ -19,12 +19,12 @@ #include "app/os_exchange_data.h" #include "app/os_exchange_data_provider_win.h" #include "app/win_util.h" +#include "app/win/iat_patch_function.h" #include "base/auto_reset.h" #include "base/base_drag_source.h" #include "base/base_drop_target.h" #include "base/basictypes.h" #include "base/i18n/rtl.h" -#include "base/iat_patch.h" #include "base/lazy_instance.h" #include "base/ref_counted.h" #include "base/string_util.h" @@ -371,8 +371,8 @@ class PaintPatcher { private: size_t refcount_; - iat_patch::IATPatchFunction begin_paint_; - iat_patch::IATPatchFunction end_paint_; + app::win::IATPatchFunction begin_paint_; + app::win::IATPatchFunction end_paint_; DISALLOW_COPY_AND_ASSIGN(PaintPatcher); }; diff --git a/chrome/renderer/render_process_impl.cc b/chrome/renderer/render_process_impl.cc index 2350213..735a962 100644 --- a/chrome/renderer/render_process_impl.cc +++ b/chrome/renderer/render_process_impl.cc @@ -41,7 +41,7 @@ #if defined(OS_MACOSX) #include "base/mac_util.h" #elif defined(OS_WIN) -#include "base/iat_patch.h" +#include "app/win/iat_patch_function.h" #endif namespace { @@ -80,7 +80,7 @@ bool LaunchNaClProcessMultiFD(const char* alleged_url, #if defined(OS_WIN) -static iat_patch::IATPatchFunction g_iat_patch_createdca; +static app::win::IATPatchFunction g_iat_patch_createdca; HDC WINAPI CreateDCAPatch(LPCSTR driver_name, LPCSTR device_name, LPCSTR output, @@ -94,7 +94,7 @@ HDC WINAPI CreateDCAPatch(LPCSTR driver_name, return CreateCompatibleDC(NULL); } -static iat_patch::IATPatchFunction g_iat_patch_get_font_data; +static app::win::IATPatchFunction g_iat_patch_get_font_data; DWORD WINAPI GetFontDataPatch(HDC hdc, DWORD table, DWORD offset, diff --git a/chrome/utility/utility_thread.cc b/chrome/utility/utility_thread.cc index 4392557..81e7ff4 100644 --- a/chrome/utility/utility_thread.cc +++ b/chrome/utility/utility_thread.cc @@ -7,11 +7,9 @@ #include <vector> #include "base/file_util.h" -#if defined(OS_WIN) -#include "base/iat_patch.h" -#endif #include "base/path_service.h" #include "base/values.h" +#include "build/build_config.h" #include "chrome/common/child_process.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/extensions/extension_unpacker.h" @@ -25,9 +23,13 @@ #include "printing/page_range.h" #include "printing/units.h" #include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/WebKit/WebKit/chromium/public/WebSerializedScriptValue.h" #include "webkit/glue/idb_bindings.h" #include "webkit/glue/image_decoder.h" -#include "third_party/WebKit/WebKit/chromium/public/WebSerializedScriptValue.h" + +#if defined(OS_WIN) +#include "app/win/iat_patch_function.h" +#endif namespace { @@ -156,7 +158,7 @@ typedef bool (*GetPDFDocInfoProc)(const unsigned char* pdf_buffer, // The 2 below IAT patch functions are almost identical to the code in // render_process_impl.cc. This is needed to work around specific Windows APIs // used by the Chrome PDF plugin that will fail in the sandbox. -static iat_patch::IATPatchFunction g_iat_patch_createdca; +static app::win::IATPatchFunction g_iat_patch_createdca; HDC WINAPI UtilityProcess_CreateDCAPatch(LPCSTR driver_name, LPCSTR device_name, LPCSTR output, @@ -170,7 +172,7 @@ HDC WINAPI UtilityProcess_CreateDCAPatch(LPCSTR driver_name, return CreateDCA(driver_name, device_name, output, init_data); } -static iat_patch::IATPatchFunction g_iat_patch_get_font_data; +static app::win::IATPatchFunction g_iat_patch_get_font_data; DWORD WINAPI UtilityProcess_GetFontDataPatch( HDC hdc, DWORD table, DWORD offset, LPVOID buffer, DWORD length) { int rv = GetFontData(hdc, table, offset, buffer, length); diff --git a/webkit/glue/plugins/webplugin_delegate_impl_win.cc b/webkit/glue/plugins/webplugin_delegate_impl_win.cc index c9500d1..115a494 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_win.cc +++ b/webkit/glue/plugins/webplugin_delegate_impl_win.cc @@ -8,8 +8,8 @@ #include <string> #include <vector> +#include "app/win/iat_patch_function.h" #include "base/file_util.h" -#include "base/iat_patch.h" #include "base/lazy_instance.h" #include "base/message_loop.h" #include "base/metrics/stats_counters.h" @@ -70,15 +70,15 @@ base::LazyInstance<std::map<HWND, WNDPROC> > g_window_handle_proc_map( // Helper object for patching the TrackPopupMenu API. -base::LazyInstance<iat_patch::IATPatchFunction> g_iat_patch_track_popup_menu( +base::LazyInstance<app::win::IATPatchFunction> g_iat_patch_track_popup_menu( base::LINKER_INITIALIZED); // Helper object for patching the SetCursor API. -base::LazyInstance<iat_patch::IATPatchFunction> g_iat_patch_set_cursor( +base::LazyInstance<app::win::IATPatchFunction> g_iat_patch_set_cursor( base::LINKER_INITIALIZED); // Helper object for patching the RegEnumKeyExW API. -base::LazyInstance<iat_patch::IATPatchFunction> g_iat_patch_reg_enum_key_ex_w( +base::LazyInstance<app::win::IATPatchFunction> g_iat_patch_reg_enum_key_ex_w( base::LINKER_INITIALIZED); // http://crbug.com/16114 |