Commit 5446d89c authored by pennymac's avatar pennymac Committed by Commit bot

[chrome_elf] Big cleanup and removing dependencies that recently crept in. PART 1.

- Moving all crash related APIs into one place (and out of chrome_elf_main).
- Started to clean up external dependencies - starting with hook_utils.
- Removed dependency on base/win/iat_patch_function.

BUG=631771

Committed: https://crrev.com/d2767f8b41a8f7f70bddbd0783a8ef27a9370e58
Review-Url: https://codereview.chromium.org/2183263003
Cr-Original-Commit-Position: refs/heads/master@{#411982}
Cr-Commit-Position: refs/heads/master@{#414898}
parent cf429990
......@@ -33,9 +33,6 @@ windows_manifest("chrome_elf_manifest") {
# in the world.
shared_library("chrome_elf") {
sources = [
"//chrome/app/chrome_crash_reporter_client_win.cc",
"//chrome/app/chrome_crash_reporter_client_win.h",
"//chrome/common/chrome_result_codes.h",
"chrome_elf.def",
"chrome_elf_main.cc",
"chrome_elf_main.h",
......@@ -44,31 +41,24 @@ shared_library("chrome_elf") {
":blacklist",
":chrome_elf_manifest",
":chrome_elf_resources",
":chrome_elf_security",
":constants",
":crash",
":hook_util",
"//base",
":security",
"//build/config/sanitizers:deps",
"//chrome/install_static:install_static_util",
"//chrome_elf/nt_registry:nt_registry",
"//components/crash/content/app",
"//components/crash/core/common",
"//content/public/common:result_codes",
"//third_party/crashpad/crashpad/client:client",
]
configs += [ "//build/config/win:windowed" ]
configs -= [ "//build/config/win:console" ]
# Delay loads in this list will prevent user32.dll
# from loading too early.
ldflags = [
"/NODEFAULTLIB:user32.lib",
"/DELAYLOAD:advapi32.dll",
"/DELAYLOAD:dbghelp.dll",
"/DELAYLOAD:ole32.dll",
"/DELAYLOAD:psapi.dll",
"/DELAYLOAD:rpcrt4.dll",
"/DELAYLOAD:shell32.dll",
"/DELAYLOAD:user32.dll",
"/DELAYLOAD:winhttp.dll",
"/DELAYLOAD:winmm.dll",
"/DELAYLOAD:ws2_32.dll",
]
if (current_cpu == "x86") {
# Don"t set an x64 base address (to avoid breaking HE-ASLR).
......@@ -80,7 +70,7 @@ shared_library("chrome_elf") {
## source sets
##------------------------------------------------------------------------------
source_set("chrome_elf_security") {
source_set("security") {
sources = [
"chrome_elf_security.cc",
"chrome_elf_security.h",
......@@ -129,30 +119,48 @@ static_library("blacklist") {
"blacklist/blacklist.h",
"blacklist/blacklist_interceptions.cc",
"blacklist/blacklist_interceptions.h",
"blacklist/crashpad_helper.cc",
"blacklist/crashpad_helper.h",
]
public_deps = [
"//sandbox",
]
deps = [
":constants",
":crash",
":hook_util",
"//base:base_static", # pe_image
"//chrome/install_static:install_static_util",
"//chrome_elf/nt_registry:nt_registry",
]
}
# Still uses base/win/pe_image.h
"//base",
"//third_party/crashpad/crashpad/client:client",
static_library("crash") {
sources = [
"../chrome/app/chrome_crash_reporter_client_win.cc",
"../chrome/app/chrome_crash_reporter_client_win.h",
"../chrome/common/chrome_result_codes.h",
"crash/crash_helper.cc",
"crash/crash_helper.h",
]
deps = [
":hook_util",
"//base:base", # This needs to go. DEP of app, crash_keys, client.
"//base:base_static", # pe_image
"//chrome/install_static:install_static_util",
"//components/crash/content/app:app",
"//components/crash/core/common", # crash_keys
"//content/public/common:result_codes",
"//third_party/crashpad/crashpad/client:client", # DumpWithoutCrash
]
}
static_library("hook_util") {
sources = [
"hook_util/thunk_getter.cc",
"hook_util/thunk_getter.h",
"../base/macros.h",
"hook_util/hook_util.cc",
"hook_util/hook_util.h",
]
deps = [
"//base:base_static", # pe_image
"//sandbox",
]
}
......@@ -167,15 +175,18 @@ test("chrome_elf_unittests") {
"blacklist/test/blacklist_test.cc",
"chrome_elf_util_unittest.cc",
"elf_imports_unittest.cc",
"hook_util/test/hook_util_test.cc",
"run_all_unittests.cc",
]
include_dirs = [ "$target_gen_dir" ]
deps = [
":blacklist",
":blacklist_test_main_dll",
":chrome_elf_security",
":constants",
":crash",
":hook_util",
":hook_util_test_dll",
":security",
"//base",
"//base/test:test_support",
"//chrome",
......@@ -199,17 +210,15 @@ test("chrome_elf_unittests") {
":blacklist_test_dll_3",
":chrome_elf",
]
# Don't want the test-specific dependencies to affect ChromeElfLoadSanityTest.
# In particular, a few system DLLs cause user32 to be loaded, which is bad.
ldflags = [
"/DELAYLOAD:dbghelp.dll",
"/DELAYLOAD:advapi32.dll",
"/DELAYLOAD:ole32.dll",
"/DELAYLOAD:psapi.dll",
"/DELAYLOAD:rpcrt4.dll",
"/DELAYLOAD:shell32.dll",
"/DELAYLOAD:shlwapi.dll",
"/DELAYLOAD:user32.dll",
"/DELAYLOAD:winhttp.dll",
"/DELAYLOAD:winmm.dll",
"/DELAYLOAD:ws2_32.dll",
]
}
......@@ -225,18 +234,6 @@ shared_library("blacklist_test_main_dll") {
"//chrome/install_static:install_static_util",
"//chrome_elf/nt_registry:nt_registry",
]
ldflags = [
"/NODEFAULTLIB:user32.lib",
"/DELAYLOAD:dbghelp.dll",
"/DELAYLOAD:ole32.dll",
"/DELAYLOAD:psapi.dll",
"/DELAYLOAD:rpcrt4.dll",
"/DELAYLOAD:shell32.dll",
"/DELAYLOAD:user32.dll",
"/DELAYLOAD:winhttp.dll",
"/DELAYLOAD:winmm.dll",
"/DELAYLOAD:ws2_32.dll",
]
}
loadable_module("blacklist_test_dll_1") {
......@@ -272,3 +269,13 @@ loadable_module("blacklist_test_dll_3") {
"//build/config/sanitizers:deps",
]
}
shared_library("hook_util_test_dll") {
sources = [
"hook_util/test/hook_util_test_dll.cc",
"hook_util/test/hook_util_test_dll.h",
]
deps = [
"//build/config/sanitizers:deps",
]
}
......@@ -15,8 +15,6 @@
'blacklist/blacklist.h',
'blacklist/blacklist_interceptions.cc',
'blacklist/blacklist_interceptions.h',
'blacklist/crashpad_helper.cc',
'blacklist/crashpad_helper.h',
],
'dependencies': [
'../base/base.gyp:base',
......@@ -24,7 +22,6 @@
'../chrome_elf/chrome_elf.gyp:chrome_elf_constants',
'../chrome_elf/chrome_elf.gyp:chrome_elf_hook_util',
'../chrome_elf/nt_registry/nt_registry.gyp:chrome_elf_nt_registry',
'../components/components.gyp:crash_component',
'../sandbox/sandbox.gyp:sandbox',
],
},
......@@ -38,6 +35,7 @@
'dependencies': [
'../base/base.gyp:base',
'../chrome/chrome.gyp:install_static_util',
'../chrome_elf/chrome_elf.gyp:chrome_elf_crash',
'../chrome_elf/nt_registry/nt_registry.gyp:chrome_elf_nt_registry',
'blacklist',
],
......
......@@ -12,7 +12,7 @@
#include "chrome/install_static/install_util.h"
#include "chrome_elf/blacklist/blacklist_interceptions.h"
#include "chrome_elf/chrome_elf_constants.h"
#include "chrome_elf/hook_util/thunk_getter.h"
#include "chrome_elf/hook_util/hook_util.h"
#include "chrome_elf/nt_registry/nt_registry.h"
#include "sandbox/win/src/interception_internal.h"
#include "sandbox/win/src/internal_types.h"
......@@ -291,7 +291,7 @@ bool Initialize(bool force) {
const bool kRelaxed = false;
// Create a thunk via the appropriate ServiceResolver instance.
sandbox::ServiceResolverThunk* thunk = GetThunk(kRelaxed);
sandbox::ServiceResolverThunk* thunk = elf_hook::HookSystemService(kRelaxed);
// Don't try blacklisting on unsupported OS versions.
if (!thunk)
......
......@@ -18,7 +18,7 @@
// base_static (see base/base.gyp) are allowed here.
#include "base/win/pe_image.h"
#include "chrome_elf/blacklist/blacklist.h"
#include "chrome_elf/blacklist/crashpad_helper.h"
#include "chrome_elf/crash/crash_helper.h"
#include "sandbox/win/src/internal_types.h"
#include "sandbox/win/src/nt_internals.h"
#include "sandbox/win/src/sandbox_nt_util.h"
......@@ -262,7 +262,7 @@ BlNtMapViewOfSection(NtMapViewOfSectionFunction orig_MapViewOfSection,
base, zero_bits, commit_size, offset,
view_size, inherit, allocation_type,
protect);
} __except(GenerateCrashDump(GetExceptionInformation())) {
} __except (elf_crash::GenerateCrashDump(GetExceptionInformation())) {
}
return ret;
......
......@@ -40,20 +40,16 @@
'chrome_elf.def',
'chrome_elf_main.cc',
'chrome_elf_main.h',
'../chrome/app/chrome_crash_reporter_client_win.cc',
'../chrome/app/chrome_crash_reporter_client_win.h',
'<(SHARED_INTERMEDIATE_DIR)/chrome_elf/chrome_elf_version.rc',
],
'dependencies': [
'../chrome/chrome.gyp:install_static_util',
'blacklist',
'chrome_elf_crash',
'chrome_elf_hook_util',
'chrome_elf_resources',
'chrome_elf_security',
'nt_registry/nt_registry.gyp:chrome_elf_nt_registry',
'../chrome/chrome.gyp:install_static_util',
'../components/components.gyp:crash_component',
'../components/components.gyp:crash_core_common',
],
'msvs_settings': {
'VCLinkerTool': {
......@@ -88,6 +84,28 @@
'chrome_elf_constants.h',
],
},
{
'target_name': 'chrome_elf_crash',
'type': 'static_library',
'include_dirs': [
'..',
],
'sources': [
'../chrome/app/chrome_crash_reporter_client_win.cc',
'../chrome/app/chrome_crash_reporter_client_win.h',
'../chrome/common/chrome_result_codes.h',
'crash/crash_helper.cc',
'crash/crash_helper.h',
],
'dependencies': [
'../base/base.gyp:base', # This needs to go.
'../base/base.gyp:base_static', # pe_image
'../chrome/chrome.gyp:install_static_util',
'../components/components.gyp:crash_component',
'../components/components.gyp:crash_core_common', #crash_keys
'chrome_elf_hook_util',
],
},
{
'target_name': 'chrome_elf_hook_util',
'type': 'static_library',
......@@ -95,8 +113,13 @@
'..',
],
'sources': [
'hook_util/thunk_getter.cc',
'hook_util/thunk_getter.h',
'../base/macros.h',
'hook_util/hook_util.cc',
'hook_util/hook_util.h',
],
'dependencies': [
'../base/base.gyp:base_static', # pe_image
'../sandbox/sandbox.gyp:sandbox',
],
},
{
......@@ -143,6 +166,7 @@
'blacklist_test_dll_2',
'blacklist_test_dll_3',
'blacklist_test_main_dll',
'chrome_elf_crash',
'chrome_elf_hook_util',
'chrome_elf_security',
'nt_registry/nt_registry.gyp:chrome_elf_nt_registry',
......
......@@ -4,102 +4,40 @@
#include "chrome_elf/chrome_elf_main.h"
#include <assert.h>
#include <windows.h>
#include <algorithm>
#include "base/lazy_instance.h"
#include "base/strings/string16.h"
#include "base/win/iat_patch_function.h"
#include "build/build_config.h"
#include "chrome/app/chrome_crash_reporter_client_win.h"
#include "chrome/install_static/install_util.h"
#include "chrome_elf/blacklist/blacklist.h"
#include "chrome_elf/blacklist/crashpad_helper.h"
#include "chrome_elf/chrome_elf_constants.h"
#include "components/crash/content/app/crashpad.h"
#include "components/crash/core/common/crash_keys.h"
namespace {
base::LazyInstance<std::vector<crash_reporter::Report>>::Leaky g_crash_reports =
LAZY_INSTANCE_INITIALIZER;
#if !defined(ADDRESS_SANITIZER)
// chrome_elf loads early in the process and initializes Crashpad. That in turn
// uses the SetUnhandledExceptionFilter API to set a top level exception
// handler for the process. When the process eventually initializes, CRT sets
// an exception handler which calls TerminateProcess which effectively bypasses
// us. Ideally we want to be at the top of the unhandled exception filter
// chain. However we don't have a good way of intercepting the
// SetUnhandledExceptionFilter API in the sandbox. EAT patching kernel32 or
// kernelbase should ideally work. However the kernel32 kernelbase dlls are
// prebound which causes EAT patching to not work. Sidestep works. However it
// is only supported for 32 bit. For now we use IAT patching for the
// executable.
// TODO(ananta).
// Check if it is possible to fix EAT patching or use sidestep patching for
// 32 bit and 64 bit for this purpose.
base::win::IATPatchFunction g_set_unhandled_exception_filter;
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI
SetUnhandledExceptionFilterPatch(LPTOP_LEVEL_EXCEPTION_FILTER filter) {
// Don't set the exception filter. Please see above for comments.
return nullptr;
}
// Please refer above to more information about why we intercept the
// SetUnhandledExceptionFilter API.
void DisableSetUnhandledExceptionFilter() {
DWORD patched = g_set_unhandled_exception_filter.PatchFromModule(
GetModuleHandle(nullptr), "kernel32.dll", "SetUnhandledExceptionFilter",
SetUnhandledExceptionFilterPatch);
CHECK(patched == 0);
}
#endif // !defined(ADDRESS_SANITIZER)
} // namespace
#include "chrome_elf/crash/crash_helper.h"
void SignalChromeElf() {
blacklist::ResetBeacon();
}
// This helper is invoked by code in chrome.dll to retrieve the crash reports.
// See CrashUploadListCrashpad. Note that we do not pass an std::vector here,
// because we do not want to allocate/free in different modules. The returned
// pointer is read-only.
extern "C" __declspec(dllexport) void GetCrashReportsImpl(
const crash_reporter::Report** reports,
size_t* report_count) {
crash_reporter::GetReports(g_crash_reports.Pointer());
*reports = g_crash_reports.Pointer()->data();
*report_count = g_crash_reports.Pointer()->size();
}
// This helper is invoked by debugging code in chrome to register the client
// id.
extern "C" __declspec(dllexport) void SetMetricsClientId(
const char* client_id) {
if (client_id)
crash_keys::SetMetricsClientIdFromGUID(client_id);
}
BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) {
if (reason == DLL_PROCESS_ATTACH) {
ChromeCrashReporterClient::InitializeCrashReportingForProcess();
// CRT on initialization installs an exception filter which calls
// TerminateProcess. We need to hook CRT's attempt to set an exception
// handler and ignore it. Don't do this when ASan is present, or ASan will
// fail to install its own unhandled exception filter.
if (!elf_crash::InitializeCrashReporting()) {
#ifdef _DEBUG
assert(false);
#endif // _DEBUG
}
// CRT on initialization installs an exception filter which calls
// TerminateProcess. We need to hook CRT's attempt to set an exception.
// NOTE: Do not hook if ASan is present, or ASan will fail to install
// its own unhandled exception filter.
#if !defined(ADDRESS_SANITIZER)
DisableSetUnhandledExceptionFilter();
#endif
elf_crash::DisableSetUnhandledExceptionFilter();
#endif // !defined (ADDRESS_SANITIZER)
install_static::InitializeProcessType();
__try {
blacklist::Initialize(false); // Don't force, abort if beacon is present.
} __except(GenerateCrashDump(GetExceptionInformation())) {
} __except (elf_crash::GenerateCrashDump(GetExceptionInformation())) {
}
} else if (reason == DLL_PROCESS_DETACH) {
elf_crash::ShutdownCrashReporting();
}
return TRUE;
}
......@@ -11,6 +11,8 @@
#include "chrome_elf/chrome_elf_constants.h"
#include "chrome_elf/nt_registry/nt_registry.h"
namespace elf_security {
void EarlyBrowserSecurity() {
typedef decltype(SetProcessMitigationPolicy)* SetProcessMitigationPolicyFunc;
......@@ -47,3 +49,4 @@ void EarlyBrowserSecurity() {
}
return;
}
} // namespace elf_security
......@@ -5,7 +5,11 @@
#ifndef CHROME_ELF_CHROME_ELF_SECURITY_H_
#define CHROME_ELF_CHROME_ELF_SECURITY_H_
namespace elf_security {
// Setup any early browser-process security.
void EarlyBrowserSecurity();
} // namespace elf_security
#endif // CHROME_ELF_CHROME_ELF_SECURITY_H_
......@@ -112,12 +112,12 @@ TEST(ChromeElfUtilTest, BrowserProcessSecurityTest) {
// First, ensure that the emergency-off finch signal works.
EXPECT_TRUE(SetSecurityFinchFlag(true));
EarlyBrowserSecurity();
elf_security::EarlyBrowserSecurity();
EXPECT_FALSE(IsSecuritySet());
EXPECT_TRUE(SetSecurityFinchFlag(false));
// Second, test that the process mitigation is set when no finch signal.
EarlyBrowserSecurity();
elf_security::EarlyBrowserSecurity();
EXPECT_TRUE(IsSecuritySet());
}
......
// Copyright 2016 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.
#include "chrome_elf/crash/crash_helper.h"
#include <assert.h>
#include <windows.h>
#include <algorithm>
#include <string>
#include <vector>
#include "chrome/app/chrome_crash_reporter_client_win.h"
#include "chrome_elf/hook_util/hook_util.h"
#include "components/crash/content/app/crashpad.h"
#include "components/crash/core/common/crash_keys.h"
#include "third_party/crashpad/crashpad/client/crashpad_client.h"
namespace {
// Crash handling from elf is only enabled for the chrome.exe process.
// Use this global to safely handle the rare case where elf may not be in that
// process (e.g. tests).
bool g_crash_helper_enabled = false;
// Global pointer to a vector of crash reports.
// This structure will be initialized in InitializeCrashReportingForProcess()
// and cleaned up in DllDetachCrashReportingCleanup().
std::vector<crash_reporter::Report>* g_crash_reports = nullptr;
// chrome_elf loads early in the process and initializes Crashpad. That in turn
// uses the SetUnhandledExceptionFilter API to set a top level exception
// handler for the process. When the process eventually initializes, CRT sets
// an exception handler which calls TerminateProcess which effectively bypasses
// us. Ideally we want to be at the top of the unhandled exception filter
// chain. However we don't have a good way of intercepting the
// SetUnhandledExceptionFilter API in the sandbox. EAT patching kernel32 or
// kernelbase should ideally work. However the kernel32 kernelbase dlls are
// prebound which causes EAT patching to not work. Sidestep works. However it
// is only supported for 32 bit. For now we use IAT patching for the
// executable.
// TODO(ananta).
// Check if it is possible to fix EAT patching or use sidestep patching for
// 32 bit and 64 bit for this purpose.
elf_hook::IATHook* g_set_unhandled_exception_filter = nullptr;
// Hook function, which ignores the request to set an unhandled-exception
// filter.
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI
SetUnhandledExceptionFilterPatch(LPTOP_LEVEL_EXCEPTION_FILTER filter) {
// Don't set the exception filter. Please see above for comments.
return nullptr;
}
} // namespace
//------------------------------------------------------------------------------
// Public chrome_elf crash APIs
//------------------------------------------------------------------------------
namespace elf_crash {
// NOTE: This function will be called from DllMain during DLL_PROCESS_ATTACH
// (while we have the loader lock), so do not misbehave.
bool InitializeCrashReporting() {
#ifdef _DEBUG
assert(g_crash_reports == nullptr);
assert(g_set_unhandled_exception_filter == nullptr);
#endif // _DEBUG
// No global objects with destructors, so using global pointers.
// DllMain on detach will clean these up.
g_crash_reports = new std::vector<crash_reporter::Report>;
g_set_unhandled_exception_filter = new elf_hook::IATHook();
ChromeCrashReporterClient::InitializeCrashReportingForProcess();
g_crash_helper_enabled = true;
return true;
}
// NOTE: This function will be called from DllMain during DLL_PROCESS_DETACH
// (while we have the loader lock), so do not misbehave.
void ShutdownCrashReporting() {
if (g_crash_reports != nullptr) {
g_crash_reports->clear();
delete g_crash_reports;
}
if (g_set_unhandled_exception_filter != nullptr) {
delete g_set_unhandled_exception_filter;
}
}
// Please refer to the comment on g_set_unhandled_exception_filter for more
// information about why we intercept the SetUnhandledExceptionFilter API.
void DisableSetUnhandledExceptionFilter() {
if (!g_crash_helper_enabled)
return;
if (g_set_unhandled_exception_filter->Hook(
::GetModuleHandle(nullptr), "kernel32.dll",
"SetUnhandledExceptionFilter",
SetUnhandledExceptionFilterPatch) != NO_ERROR) {
#ifdef _DEBUG
assert(false);
#endif //_DEBUG
}
}
int GenerateCrashDump(EXCEPTION_POINTERS* exception_pointers) {
if (g_crash_helper_enabled)
crashpad::CrashpadClient::DumpWithoutCrash(
*(exception_pointers->ContextRecord));
return EXCEPTION_CONTINUE_SEARCH;
}
} // namespace elf_crash
//------------------------------------------------------------------------------
// Exported crash APIs for the rest of the process.
//------------------------------------------------------------------------------
// This helper is invoked by code in chrome.dll to retrieve the crash reports.
// See CrashUploadListCrashpad. Note that we do not pass a std::vector here,
// because we do not want to allocate/free in different modules. The returned
// pointer is read-only.
//
// NOTE: Since the returned pointer references read-only memory that will be
// cleaned up when this DLL unloads, be careful not to reference the memory
// beyond that point (e.g. during tests).
extern "C" __declspec(dllexport) void GetCrashReportsImpl(
const crash_reporter::Report** reports,
size_t* report_count) {
if (!g_crash_helper_enabled)
return;
crash_reporter::GetReports(g_crash_reports);
*reports = g_crash_reports->data();
*report_count = g_crash_reports->size();
}
// This helper is invoked by debugging code in chrome to register the client
// id.
extern "C" __declspec(dllexport) void SetMetricsClientId(
const char* client_id) {
if (!g_crash_helper_enabled)
return;
if (client_id)
crash_keys::SetMetricsClientIdFromGUID(client_id);
}
......@@ -2,14 +2,31 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_ELF_BLACKLIST_CRASHPAD_HELPER_H_
#define CHROME_ELF_BLACKLIST_CRASHPAD_HELPER_H_
#ifndef CHROME_ELF_CRASH_CRASH_HELPER_H_
#define CHROME_ELF_CRASH_CRASH_HELPER_H_
#include <windows.h>
// Keep all crash-related APIs here. All other chrome_elf code should call here
// for crash support.
namespace elf_crash {
// Init the crash handling system for entire process.
bool InitializeCrashReporting();
// Any late cleanup of the crash handling system.
void ShutdownCrashReporting();
// Permanently disables subsequent calls to
// kernel32!SetUnhandledExceptionFilter(), see comment in .cc for why this is
// needed.
void DisableSetUnhandledExceptionFilter();
// Exception handler for exceptions in chrome_elf which need to be passed on to
// the next handler in the chain. Examples include exceptions in DllMain,
// blacklist interception code, etc.
// Note: the handler takes a minidump.
int GenerateCrashDump(EXCEPTION_POINTERS* exception_pointers);
}
#endif // CHROME_ELF_BLACKLIST_CRASHPAD_HELPER_H_
#endif // CHROME_ELF_CRASH_CRASH_HELPER_H_
......@@ -144,7 +144,9 @@ TEST_F(ELFImportsTest, DISABLED_ChromeElfLoadSanityTestImpl) {
// We don't expect user32 to be loaded in chrome_elf_unittests. If this test
// case fails, then it means that a dependency on user32 has crept into the
// chrome_elf_unittests executable, which needs to be removed.
EXPECT_EQ(nullptr, ::GetModuleHandle(L"user32.dll"));
// NOTE: it may be a secondary dependency of another system DLL. If so,
// try adding a "/DELAYLOAD:<blah>.dll" to the build.gn file.
ASSERT_EQ(nullptr, ::GetModuleHandle(L"user32.dll"));
HMODULE chrome_elf_module_handle = ::LoadLibrary(dll.value().c_str());
EXPECT_TRUE(chrome_elf_module_handle != nullptr);
......
This diff is collapsed.
// Copyright 2014 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 CHROME_ELF_HOOK_UTIL_THUNK_GETTER_H_
#define CHROME_ELF_HOOK_UTIL_THUNK_GETTER_H_
#include <windows.h>
#include "base/macros.h"
namespace sandbox {
class ServiceResolverThunk;
}
namespace elf_hook {
//------------------------------------------------------------------------------
// System Service hooking support
//------------------------------------------------------------------------------
// Creates a |ServiceResolverThunk| based on the OS version. Ownership of the
// resulting thunk is passed to the caller.
sandbox::ServiceResolverThunk* HookSystemService(bool relaxed);
//------------------------------------------------------------------------------
// Import Address Table hooking support
//------------------------------------------------------------------------------
class IATHook {
public:
IATHook();
~IATHook();
// Intercept a function in an import table of a specific
// module. Saves everything needed to Unhook.
//
// NOTE: Hook can only be called once at a time, to enable Unhook().
//
// Arguments:
// module Module to be intercepted
// imported_from_module Module that exports the 'function_name'
// function_name Name of the API to be intercepted
// new_function New function pointer
//
// Returns: Windows error code (winerror.h). NO_ERROR if successful.
DWORD Hook(HMODULE module,
const char* imported_from_module,
const char* function_name,
void* new_function);
// Unhook the IAT entry.
//
// Returns: Windows error code (winerror.h). NO_ERROR if successful.
DWORD Unhook();
private:
void* intercept_function_;
void* original_function_;
IMAGE_THUNK_DATA* iat_thunk_;
DISALLOW_COPY_AND_ASSIGN(IATHook);
};
} // namespace elf_hook
#endif // CHROME_ELF_HOOK_UTIL_THUNK_GETTER_H_
// Copyright 2016 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.
#include <windows.h>
#include "chrome_elf/hook_util/hook_util.h"
// Compile in this test DLL, so that it's in the IAT.
#include "chrome_elf/hook_util/test/hook_util_test_dll.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
// IATHook test constants.
const char kIATTestDllName[] = "hook_util_test_dll.dll";
const char kIATExportedApiFunction[] = "ExportedApi";