Commit 84fd669f authored by pennymac's avatar pennymac Committed by Commit bot

[Chrome ELF] New NT registry API.

This CL is part of a chain of CLs:
1) "MITIGATION_EXTENSION_POINT_DISABLE support for children" (https://codereview.chromium.org/1835003003)
2) "MITIGATION_EXTENSION_POINT_DISABLE emergency off finch" (https://codereview.chromium.org/1836523004/)
-> THIS
4) "Early browser security support" (https://codereview.chromium.org/1656453002)
5) "Turn on MITIGATION_EXTENSION_POINT_DISABLE" (https://codereview.chromium.org/1854323002)

Added new chrome_elf_reg utility for a registry API that doesn't touch advapi32 (useful from DllMain).
Direct calls to ntdll.  Updated Chrome ELF to always use this new registry API.

Adjusted the existing DLL blacklist to use a REG_MULTI_SZ comma-separated list instead of lots of individual reg values.

Small changes to organize file structure and functional components under chrome_elf.  Old common code now sits under "hook_util", "nt_registry", "breakpad", "dll_hash", and "blacklist".

Fairly big changes to the chrome_elf tests (blacklist_test.cc, blacklist_test_main_dll.cc and
chrome_elf_util_unittest.cc) were needed.  Since ntdll bypasses any registry redirection
(that tests use to keep the hive safe and isolated), I added in a way for the tests to access
the redirection path (and pass that information on to the test DLL).  This way the NT reg
API can work with redirection during tests.

Tests:
1) chrome_elf_unittests, chrome_elf_util_unittest.cc: ChromeElfUtilTest.NTRegistry is new
(...but run all tests to exercise the new API being used by blacklist and utils).
2) unit_tests, chrome_elf_init_unittest_win.cc: ChromeBlacklistTrialTest*

BUG=557798
CQ_INCLUDE_TRYBOTS=tryserver.chromium.win:win10_chromium_x64_rel_ng

Review-Url: https://codereview.chromium.org/1841573002
Cr-Commit-Position: refs/heads/master@{#405307}
parent b78a6a6c
...@@ -513,7 +513,9 @@ def _CheckNoNewWStrings(input_api, output_api): ...@@ -513,7 +513,9 @@ def _CheckNoNewWStrings(input_api, output_api):
for f in input_api.AffectedFiles(): for f in input_api.AffectedFiles():
if (not f.LocalPath().endswith(('.cc', '.h')) or if (not f.LocalPath().endswith(('.cc', '.h')) or
f.LocalPath().endswith(('test.cc', '_win.cc', '_win.h')) or f.LocalPath().endswith(('test.cc', '_win.cc', '_win.h')) or
'/win/' in f.LocalPath()): '/win/' in f.LocalPath() or
'chrome_elf' in f.LocalPath() or
'install_static' in f.LocalPath()):
continue continue
allowWString = False allowWString = False
......
...@@ -99,9 +99,16 @@ RegistryOverrideManager::RegistryOverrideManager( ...@@ -99,9 +99,16 @@ RegistryOverrideManager::RegistryOverrideManager(
RegistryOverrideManager::~RegistryOverrideManager() {} RegistryOverrideManager::~RegistryOverrideManager() {}
void RegistryOverrideManager::OverrideRegistry(HKEY override) { void RegistryOverrideManager::OverrideRegistry(HKEY override) {
OverrideRegistry(override, nullptr);
}
void RegistryOverrideManager::OverrideRegistry(HKEY override,
base::string16* override_path) {
base::string16 key_path = GenerateTempKeyPath(test_key_root_, timestamp_); base::string16 key_path = GenerateTempKeyPath(test_key_root_, timestamp_);
overrides_.push_back( overrides_.push_back(
base::WrapUnique(new ScopedRegistryKeyOverride(override, key_path))); base::WrapUnique(new ScopedRegistryKeyOverride(override, key_path)));
if (override_path)
override_path->assign(key_path);
} }
base::string16 GenerateTempKeyPath() { base::string16 GenerateTempKeyPath() {
......
...@@ -38,7 +38,9 @@ class RegistryOverrideManager { ...@@ -38,7 +38,9 @@ class RegistryOverrideManager {
// Override the given registry hive using a randomly generated temporary key. // Override the given registry hive using a randomly generated temporary key.
// Multiple overrides to the same hive are not supported and lead to undefined // Multiple overrides to the same hive are not supported and lead to undefined
// behavior. // behavior.
// Optional return of the registry override path.
void OverrideRegistry(HKEY override); void OverrideRegistry(HKEY override);
void OverrideRegistry(HKEY override, base::string16* override_path);
private: private:
friend class RegistryOverrideManagerTest; friend class RegistryOverrideManagerTest;
......
...@@ -130,16 +130,22 @@ void AddFinchBlacklistToRegistry() { ...@@ -130,16 +130,22 @@ void AddFinchBlacklistToRegistry() {
HKEY_CURRENT_USER, blacklist::kRegistryFinchListPath, KEY_SET_VALUE); HKEY_CURRENT_USER, blacklist::kRegistryFinchListPath, KEY_SET_VALUE);
std::map<std::string, std::string> params; std::map<std::string, std::string> params;
variations::GetVariationParams(kBrowserBlacklistTrialName, &params); std::string value = variations::GetVariationParamValue(
kBrowserBlacklistTrialName, blacklist::kRegistryFinchListValueNameStr);
for (std::map<std::string, std::string>::iterator it = params.begin(); if (value.empty())
it != params.end(); return;
++it) { base::string16 value_wcs = base::UTF8ToWide(value);
std::wstring name = base::UTF8ToWide(it->first);
std::wstring val = base::UTF8ToWide(it->second); // The dll names are comma-separated in this param value. We need to turn
// this into REG_MULTI_SZ format (double-null terminates).
finch_blacklist_registry_key.WriteValue(name.c_str(), val.c_str()); // Note that the strings are wide character in registry.
} value_wcs.push_back(L'\0');
value_wcs.push_back(L'\0');
std::replace(value_wcs.begin(), value_wcs.end(), L',', L'\0');
finch_blacklist_registry_key.WriteValue(
blacklist::kRegistryFinchListValueName, value_wcs.data(),
(value_wcs.size() * sizeof(wchar_t)), REG_MULTI_SZ);
} }
void BrowserBlacklistBeaconSetup() { void BrowserBlacklistBeaconSetup() {
......
...@@ -166,8 +166,9 @@ TEST_F(ChromeBlacklistTrialTest, AddFinchBlacklistToRegistry) { ...@@ -166,8 +166,9 @@ TEST_F(ChromeBlacklistTrialTest, AddFinchBlacklistToRegistry) {
// Set up the trial with the desired parameters. // Set up the trial with the desired parameters.
std::map<std::string, std::string> desired_params; std::map<std::string, std::string> desired_params;
desired_params["TestDllName1"] = "TestDll1.dll";
desired_params["TestDllName2"] = "TestDll2.dll"; desired_params[blacklist::kRegistryFinchListValueNameStr] =
"TestDll1.dll,TestDll2.dll";
variations::AssociateVariationParams( variations::AssociateVariationParams(
kBrowserBlacklistTrialName, kBrowserBlacklistTrialName,
...@@ -177,21 +178,23 @@ TEST_F(ChromeBlacklistTrialTest, AddFinchBlacklistToRegistry) { ...@@ -177,21 +178,23 @@ TEST_F(ChromeBlacklistTrialTest, AddFinchBlacklistToRegistry) {
// This should add the dlls in those parameters to the registry. // This should add the dlls in those parameters to the registry.
AddFinchBlacklistToRegistry(); AddFinchBlacklistToRegistry();
// Check that all the values in desired_params were added to the registry. // Check that all the dll names in desired_params were added to the registry.
std::vector<std::wstring> dlls;
base::win::RegKey finch_blacklist_registry_key( base::win::RegKey finch_blacklist_registry_key(
HKEY_CURRENT_USER, HKEY_CURRENT_USER,
blacklist::kRegistryFinchListPath, blacklist::kRegistryFinchListPath,
KEY_QUERY_VALUE | KEY_SET_VALUE); KEY_QUERY_VALUE | KEY_SET_VALUE);
ASSERT_EQ(desired_params.size(), ASSERT_TRUE(finch_blacklist_registry_key.HasValue(
finch_blacklist_registry_key.GetValueCount()); blacklist::kRegistryFinchListValueName));
ASSERT_EQ(ERROR_SUCCESS, finch_blacklist_registry_key.ReadValues(
blacklist::kRegistryFinchListValueName, &dlls));
for (std::map<std::string, std::string>::iterator it = desired_params.begin(); ASSERT_EQ((size_t)2,
it != desired_params.end(); /* Number of dll names passed in this test. */ dlls.size());
++it) { EXPECT_STREQ(L"TestDll1.dll", dlls[0].c_str());
std::wstring name = base::UTF8ToWide(it->first); EXPECT_STREQ(L"TestDll2.dll", dlls[1].c_str());
ASSERT_TRUE(finch_blacklist_registry_key.HasValue(name.c_str()));
}
} }
} // namespace } // namespace
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# The install_static_util target should only depend on functions in kernel32 # The install_static_util target should only depend on functions in kernel32.
# and advapi32. Please don't add dependencies on other system libraries. # Please don't add dependencies on other system libraries.
{ {
'target_defaults': { 'target_defaults': {
'variables': { 'variables': {
...@@ -33,15 +33,13 @@ ...@@ -33,15 +33,13 @@
'installer_static_target': 1, 'installer_static_target': 1,
}, },
'dependencies': [ 'dependencies': [
'installer_util_strings', '../chrome_elf/nt_registry/nt_registry.gyp:chrome_elf_nt_registry',
'<(DEPTH)/base/base.gyp:base',
], ],
'msvs_settings': { 'msvs_settings': {
'VCLinkerTool': { 'VCLinkerTool': {
# Please don't add dependencies on other system libraries. # Please don't add dependencies on other system libraries.
'AdditionalDependencies': [ 'AdditionalDependencies': [
'kernel32.lib', 'kernel32.lib',
'advapi32.lib',
], ],
}, },
}, },
...@@ -91,7 +89,7 @@ ...@@ -91,7 +89,7 @@
'installer_static_target': 1, 'installer_static_target': 1,
}, },
'dependencies': [ 'dependencies': [
'installer_util_strings', '../chrome_elf/nt_registry/nt_registry.gyp:chrome_elf_nt_registry_nacl_win64',
], ],
'include_dirs': [ 'include_dirs': [
'<(SHARED_INTERMEDIATE_DIR)', '<(SHARED_INTERMEDIATE_DIR)',
...@@ -106,7 +104,6 @@ ...@@ -106,7 +104,6 @@
# Please don't add dependencies on other system libraries. # Please don't add dependencies on other system libraries.
'AdditionalDependencies': [ 'AdditionalDependencies': [
'kernel32.lib', 'kernel32.lib',
'advapi32.lib',
], ],
}, },
}, },
......
...@@ -7,22 +7,19 @@ import("//testing/test.gni") ...@@ -7,22 +7,19 @@ import("//testing/test.gni")
assert(is_win) assert(is_win)
# This file only contains utility functions which must only depend on kernel32 # This file only contains utility functions which must only depend on kernel32.
# and advapi32. Please don't add dependencies on other system libraries. # Please don't add dependencies on other system libraries.
static_library("install_static_util") { static_library("install_static_util") {
public_deps = [
"//chrome_elf/nt_registry:nt_registry",
]
sources = [ sources = [
"install_util.cc", "install_util.cc",
"install_util.h", "install_util.h",
] ]
deps = [ libs = [ "kernel32.lib" ]
"//base",
]
libs = [
"kernel32.lib",
"advapi32.lib",
]
configs += [ configs += [
# TODO(jschuh): crbug.com/167187 fix size_t to int truncations. # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
......
include_rules = [ include_rules = [
# Nothing from base except the includes listed below. # Nothing from base.
"-base", "-base",
"+base/macros.h",
"+base/strings/string16.h",
"+build/build_config.h",
# Nothing from chrome. # Nothing from chrome.
"-chrome", "-chrome",
"+chrome/install_static/install_util.h", "+chrome/install_static/install_util.h",
# All registry access should go through nt_registry.
"+chrome_elf/nt_registry/nt_registry.h",
] ]
This diff is collapsed.
...@@ -12,8 +12,6 @@ ...@@ -12,8 +12,6 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "base/strings/string16.h"
namespace install_static { namespace install_static {
enum class ProcessType { enum class ProcessType {
...@@ -78,7 +76,7 @@ bool GetCollectStatsConsent(); ...@@ -78,7 +76,7 @@ bool GetCollectStatsConsent();
// Returns true if usage stats collecting is enabled for this user for the // Returns true if usage stats collecting is enabled for this user for the
// executable passed in as |exe_path|. // executable passed in as |exe_path|.
// Only used by tests. // Only used by tests.
bool GetCollectStatsConsentForTesting(const base::string16& exe_path); bool GetCollectStatsConsentForTesting(const std::wstring& exe_path);
// Returns true if if usage stats reporting is controlled by a mandatory // Returns true if if usage stats reporting is controlled by a mandatory
// policy. |metrics_is_enforced_by_policy| will be set to true accordingly. // policy. |metrics_is_enforced_by_policy| will be set to true accordingly.
...@@ -100,32 +98,32 @@ bool IsNonBrowserProcess(); ...@@ -100,32 +98,32 @@ bool IsNonBrowserProcess();
// TODO(ananta) // TODO(ananta)
// http://crbug.com/604923 // http://crbug.com/604923
// Unify this with the Browser Distribution code. // Unify this with the Browser Distribution code.
bool GetDefaultUserDataDirectory(base::string16* result); bool GetDefaultUserDataDirectory(std::wstring* result);
// Populates |crash_dir| with the default crash dump location regardless of // Populates |crash_dir| with the default crash dump location regardless of
// whether DIR_USER_DATA or DIR_CRASH_DUMPS has been overridden. // whether DIR_USER_DATA or DIR_CRASH_DUMPS has been overridden.
// TODO(ananta) // TODO(ananta)
// http://crbug.com/604923 // http://crbug.com/604923
// Unify this with the Browser Distribution code. // Unify this with the Browser Distribution code.
bool GetDefaultCrashDumpLocation(base::string16* crash_dir); bool GetDefaultCrashDumpLocation(std::wstring* crash_dir);
// Returns the contents of the specified |variable_name| from the environment // Returns the contents of the specified |variable_name| from the environment
// block of the calling process. Returns an empty string if the variable does // block of the calling process. Returns an empty string if the variable does
// not exist. // not exist.
std::string GetEnvironmentString(const std::string& variable_name); std::string GetEnvironmentString(const std::string& variable_name);
base::string16 GetEnvironmentString16(const base::string16& variable_name); std::wstring GetEnvironmentString16(const std::wstring& variable_name);
// Sets the environment variable identified by |variable_name| to the value // Sets the environment variable identified by |variable_name| to the value
// identified by |new_value|. // identified by |new_value|.
bool SetEnvironmentString(const std::string& variable_name, bool SetEnvironmentString(const std::string& variable_name,
const std::string& new_value); const std::string& new_value);
bool SetEnvironmentString16(const base::string16& variable_name, bool SetEnvironmentString16(const std::wstring& variable_name,
const base::string16& new_value); const std::wstring& new_value);
// Returns true if the environment variable identified by |variable_name| // Returns true if the environment variable identified by |variable_name|
// exists. // exists.
bool HasEnvironmentVariable(const std::string& variable_name); bool HasEnvironmentVariable(const std::string& variable_name);
bool HasEnvironmentVariable16(const base::string16& variable_name); bool HasEnvironmentVariable16(const std::wstring& variable_name);
// Gets the exe version details like the |product_name|, |version|, // Gets the exe version details like the |product_name|, |version|,
// |special_build|, |channel_name|, etc. Most of this information is read // |special_build|, |channel_name|, etc. Most of this information is read
...@@ -133,11 +131,11 @@ bool HasEnvironmentVariable16(const base::string16& variable_name); ...@@ -133,11 +131,11 @@ bool HasEnvironmentVariable16(const base::string16& variable_name);
// TODO(ananta) // TODO(ananta)
// http://crbug.com/604923 // http://crbug.com/604923
// Unify this with the Browser Distribution code. // Unify this with the Browser Distribution code.
bool GetExecutableVersionDetails(const base::string16& exe_path, bool GetExecutableVersionDetails(const std::wstring& exe_path,
base::string16* product_name, std::wstring* product_name,
base::string16* version, std::wstring* version,
base::string16* special_build, std::wstring* special_build,
base::string16* channel_name); std::wstring* channel_name);
// Gets the channel name for the current Chrome process. // Gets the channel name for the current Chrome process.
// If |add_modifier| is true the channel name is returned with the modifier // If |add_modifier| is true the channel name is returned with the modifier
...@@ -148,8 +146,7 @@ bool GetExecutableVersionDetails(const base::string16& exe_path, ...@@ -148,8 +146,7 @@ bool GetExecutableVersionDetails(const base::string16& exe_path,
// Unify this with the Browser Distribution code. // Unify this with the Browser Distribution code.
void GetChromeChannelName(bool is_per_user_install, void GetChromeChannelName(bool is_per_user_install,
bool add_modifier, bool add_modifier,
base::string16* channel_name); std::wstring* channel_name);
// Returns the version of Google Update that is installed. // Returns the version of Google Update that is installed.
// TODO(ananta) // TODO(ananta)
...@@ -162,7 +159,7 @@ std::string GetGoogleUpdateVersion(); ...@@ -162,7 +159,7 @@ std::string GetGoogleUpdateVersion();
// TODO(ananta) // TODO(ananta)
// http://crbug.com/604923 // http://crbug.com/604923
// Unify this with the Browser Distribution code. // Unify this with the Browser Distribution code.
base::string16 GetChromeInstallSubDirectory(); std::wstring GetChromeInstallSubDirectory();
// Returns the registry path where the browser crash dumps metrics need to be // Returns the registry path where the browser crash dumps metrics need to be
// written to. // written to.
...@@ -170,7 +167,7 @@ base::string16 GetChromeInstallSubDirectory(); ...@@ -170,7 +167,7 @@ base::string16 GetChromeInstallSubDirectory();
// http://crbug.com/604923 // http://crbug.com/604923
// Unify this with the version in // Unify this with the version in
// chrome\common\metrics_constants_util_win.cc // chrome\common\metrics_constants_util_win.cc
base::string16 GetBrowserCrashDumpAttemptsRegistryPath(); std::wstring GetBrowserCrashDumpAttemptsRegistryPath();
// Returns true if the |source| string matches the |pattern|. The pattern // Returns true if the |source| string matches the |pattern|. The pattern
// may contain wildcards like '?', which matches one character or a '*' // may contain wildcards like '?', which matches one character or a '*'
...@@ -178,12 +175,12 @@ base::string16 GetBrowserCrashDumpAttemptsRegistryPath(); ...@@ -178,12 +175,12 @@ base::string16 GetBrowserCrashDumpAttemptsRegistryPath();
// Please note that pattern matches the whole string. If you want to find // Please note that pattern matches the whole string. If you want to find
// something in the middle of the string then you need to specify the pattern // something in the middle of the string then you need to specify the pattern
// as '*xyz*'. // as '*xyz*'.
bool MatchPattern(const base::string16& source, const base::string16& pattern); bool MatchPattern(const std::wstring& source, const std::wstring& pattern);
// UTF8 to UTF16 and vice versa conversion helpers. // UTF8 to UTF16 and vice versa conversion helpers.
base::string16 UTF8ToUTF16(const std::string& source); std::wstring UTF8ToUTF16(const std::string& source);
std::string UTF16ToUTF8(const base::string16& source); std::string UTF16ToUTF8(const std::wstring& source);
// Tokenizes a string |str| based on single character delimiter. // Tokenizes a string |str| based on single character delimiter.
// The tokens are returned in a vector. The |trim_spaces| parameter indicates // The tokens are returned in a vector. The |trim_spaces| parameter indicates
...@@ -191,9 +188,9 @@ std::string UTF16ToUTF8(const base::string16& source); ...@@ -191,9 +188,9 @@ std::string UTF16ToUTF8(const base::string16& source);
std::vector<std::string> TokenizeString(const std::string& str, std::vector<std::string> TokenizeString(const std::string& str,
char delimiter, char delimiter,
bool trim_spaces); bool trim_spaces);
std::vector<base::string16> TokenizeString16(const base::string16& str, std::vector<std::wstring> TokenizeString16(const std::wstring& str,
base::char16 delimiter, wchar_t delimiter,
bool trim_spaces); bool trim_spaces);
// Compares version strings of the form "X.X.X.X" and returns the result of the // Compares version strings of the form "X.X.X.X" and returns the result of the
// comparison in the |result| parameter. The result is as below: // comparison in the |result| parameter. The result is as below:
......
...@@ -70,7 +70,7 @@ TEST(InstallStaticTest, TokenizeString) { ...@@ -70,7 +70,7 @@ TEST(InstallStaticTest, TokenizeString) {
// TokenizeString16 tests. // TokenizeString16 tests.
// Test if the string is tokenized correctly with all tokens stripped of // Test if the string is tokenized correctly with all tokens stripped of
// leading and trailing spaces. // leading and trailing spaces.
std::vector<base::string16> results16 = std::vector<std::wstring> results16 =
TokenizeString16(L"un |deux\t|trois\n|quatre", L'|', true); TokenizeString16(L"un |deux\t|trois\n|quatre", L'|', true);
ASSERT_EQ(4u, results16.size()); ASSERT_EQ(4u, results16.size());
EXPECT_THAT(results16, ElementsAre(L"un", L"deux", L"trois", L"quatre")); EXPECT_THAT(results16, ElementsAre(L"un", L"deux", L"trois", L"quatre"));
...@@ -194,4 +194,4 @@ TEST(InstallStaticTest, GetSwitchValueFromCommandLineTest) { ...@@ -194,4 +194,4 @@ TEST(InstallStaticTest, GetSwitchValueFromCommandLineTest) {
EXPECT_EQ(value, "bar"); EXPECT_EQ(value, "bar");
} }
} // namespace install_static } // namespace install_static
\ No newline at end of file
...@@ -2,10 +2,17 @@ ...@@ -2,10 +2,17 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# Chrome elf targets (excepting tests) should only link in kernel32.
# Please don't add dependencies on any other system libraries.
import("//build/config/win/manifest.gni") import("//build/config/win/manifest.gni")
import("//chrome/version.gni") import("//chrome/version.gni")
import("//testing/test.gni") import("//testing/test.gni")
##------------------------------------------------------------------------------
## chrome_elf
##------------------------------------------------------------------------------
process_version("chrome_elf_resources") { process_version("chrome_elf_resources") {
template_file = chrome_version_rc_template template_file = chrome_version_rc_template
sources = [ sources = [
...@@ -38,10 +45,11 @@ shared_library("chrome_elf") { ...@@ -38,10 +45,11 @@ shared_library("chrome_elf") {
":breakpad", ":breakpad",
":chrome_elf_manifest", ":chrome_elf_manifest",
":chrome_elf_resources", ":chrome_elf_resources",
":common", ":hook_util",
"//base", "//base",
"//build/config/sanitizers:deps", "//build/config/sanitizers:deps",
"//chrome/install_static:install_static_util", "//chrome/install_static:install_static_util",
"//chrome_elf/nt_registry:nt_registry",
"//components/crash/content/app", "//components/crash/content/app",
"//components/crash/core/common", "//components/crash/core/common",
"//content/public/common:result_codes", "//content/public/common:result_codes",
...@@ -66,6 +74,10 @@ shared_library("chrome_elf") { ...@@ -66,6 +74,10 @@ shared_library("chrome_elf") {
} }
} }
##------------------------------------------------------------------------------
## source sets
##------------------------------------------------------------------------------
source_set("constants") { source_set("constants") {
sources = [ sources = [
"chrome_elf_constants.cc", "chrome_elf_constants.cc",
...@@ -73,35 +85,6 @@ source_set("constants") { ...@@ -73,35 +85,6 @@ source_set("constants") {
] ]
} }
source_set("common") {
public_deps = [
":constants",
]
deps = [
"//base",
"//sandbox",
]
sources = [
"thunk_getter.cc",
"thunk_getter.h",
]
}
source_set("breakpad") {
include_dirs = [ "$target_gen_dir" ]
sources = [
"breakpad.cc",
"breakpad.h",
]
deps = [
":common",
"//base",
"//breakpad:breakpad_handler",
"//chrome/common:version_header",
"//chrome/install_static:install_static_util",
]
}
source_set("dll_hash") { source_set("dll_hash") {
deps = [ deps = [
"//base", "//base",
...@@ -112,6 +95,10 @@ source_set("dll_hash") { ...@@ -112,6 +95,10 @@ source_set("dll_hash") {
] ]
} }
##------------------------------------------------------------------------------
## chrome_elf sub targets
##------------------------------------------------------------------------------
executable("dll_hash_main") { executable("dll_hash_main") {
sources = [ sources = [
"dll_hash/dll_hash_main.cc", "dll_hash/dll_hash_main.cc",
...@@ -135,13 +122,44 @@ static_library("blacklist") { ...@@ -135,13 +122,44 @@ static_library("blacklist") {
] ]
deps = [ deps = [
":breakpad", ":breakpad",
":common",
":constants", ":constants",
":hook_util",
"//chrome/install_static:install_static_util",
"//chrome_elf/nt_registry:nt_registry",
# Still uses base/win/pe_image.h
"//base", "//base",
]
}
static_library("breakpad") {
include_dirs = [ "$target_gen_dir" ]
sources = [
"breakpad/breakpad.cc",
"breakpad/breakpad.h",
]
deps = [
"//breakpad:breakpad_handler",
"//chrome/common:version_header",
"//chrome/install_static:install_static_util", "//chrome/install_static:install_static_util",
"//chrome_elf/nt_registry:nt_registry",
] ]
} }
static_library("hook_util") {
sources = [
"hook_util/thunk_getter.cc",
"hook_util/thunk_getter.h",
]
deps = [
"//sandbox",
]
}
##------------------------------------------------------------------------------
## tests
##------------------------------------------------------------------------------
test("chrome_elf_unittests") { test("chrome_elf_unittests") {
output_name = "chrome_elf_unittests" output_name = "chrome_elf_unittests"
sources = [ sources = [
...@@ -154,12 +172,14 @@ test("chrome_elf_unittests") { ...@@ -154,12 +172,14 @@ test("chrome_elf_unittests") {
deps = [ deps = [
":blacklist", ":blacklist",
":blacklist_test_main_dll", ":blacklist_test_main_dll",
":common", ":constants",
":hook_util",
"//base", "//base",
"//base/test:test_support", "//base/test:test_support",
"//chrome", "//chrome",
"//chrome/common:version_header", "//chrome/common:version_header",
"//chrome/install_static:install_static_util", "//chrome/install_static:install_static_util",
"//chrome_elf/nt_registry:nt_registry",
"//sandbox", "//sandbox",
"//testing/gtest", "//testing/gtest",
] ]
...@@ -198,10 +218,10 @@ shared_library("blacklist_test_main_dll") { ...@@ -198,10 +218,10 @@ shared_library("blacklist_test_main_dll") {
] ]
deps = [ deps = [
":blacklist", ":blacklist",
":common",
"//base", "//base",
"//build/config/sanitizers:deps", "//build/config/sanitizers:deps",
"//chrome/install_static:install_static_util", "//chrome/install_static:install_static_util",
"//chrome_elf/nt_registry:nt_registry",
] ]
} }
......
caitkp@chromium.org caitkp@chromium.org
robertshield@chromium.org robertshield@chromium.org
# For early browser process security and nt_registry:
pennymac@chromium.org
...@@ -18,8 +18,11 @@ ...@@ -18,8 +18,11 @@
], ],
'dependencies': [ 'dependencies': [
'../base/base.gyp:base', '../base/base.gyp:base',
'../chrome/chrome.gyp:install_static_util',
'../chrome_elf/chrome_elf.gyp:chrome_elf_breakpad', '../chrome_elf/chrome_elf.gyp:chrome_elf_breakpad',
'../chrome_elf/chrome_elf.gyp:chrome_elf_constants', '../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',
'../sandbox/sandbox.gyp:sandbox', '../sandbox/sandbox.gyp:sandbox',
], ],
}, },
...@@ -32,6 +35,8 @@ ...@@ -32,6 +35,8 @@
], ],
'dependencies': [ 'dependencies': [
'../base/base.gyp:base', '../base/base.gyp:base',
'../chrome/chrome.gyp:install_static_util',
'../chrome_elf/nt_registry/nt_registry.gyp:chrome_elf_nt_registry',
'blacklist', 'blacklist',
], ],
}, },
......
This diff is collapsed.
...@@ -16,10 +16,9 @@ ...@@ -16,10 +16,9 @@
// Note that only #includes from base that are either header-only or built into // Note that only #includes from base that are either header-only or built into
// base_static (see base/base.gyp) are allowed here. // base_static (see base/base.gyp) are allowed here.
#include "base/strings/string16.h"
#include "base/win/pe_image.h" #include "base/win/pe_image.h"
#include "chrome_elf/blacklist/blacklist.h" #include "chrome_elf/blacklist/blacklist.h"
#include "chrome_elf/breakpad.h" #include "chrome_elf/breakpad/breakpad.h"
#include "sandbox/win/src/internal_types.h" #include "sandbox/win/src/internal_types.h"
#include "sandbox/win/src/nt_internals.h" #include "sandbox/win/src/nt_internals.h"
#include "sandbox/win/src/sandbox_nt_util.h" #include "sandbox/win/src/sandbox_nt_util.h"
...@@ -37,7 +36,7 @@ FARPROC GetNtDllExportByName(const char* export_name) { ...@@ -37,7 +36,7 @@ FARPROC GetNtDllExportByName(const char* export_name) {
return ::GetProcAddress(ntdll, export_name); return ::GetProcAddress(ntdll, export_name);
} }
int DllMatch(const base::string16& module_name) { int DllMatch(const std::wstring& module_name) {
if (module_name.empty()) if (module_name.empty())
return -1; return -1;
...@@ -52,7 +51,7 @@ int DllMatch(const base::string16& module_name) { ...@@ -52,7 +51,7 @@ int DllMatch(const base::string16& module_name) {
// code in sandbox_nt_util.cc. See if they can be unified. // code in sandbox_nt_util.cc. See if they can be unified.
// Native reimplementation of PSAPIs GetMappedFileName. // Native reimplementation of PSAPIs GetMappedFileName.
base::string16 GetBackingModuleFilePath(PVOID address) { std::wstring GetBackingModuleFilePath(PVOID address) {
DCHECK_NT(g_nt_query_virtual_memory_func); DCHECK_NT(g_nt_query_virtual_memory_func);
// We'll start with something close to max_path characters for the name. // We'll start with something close to max_path characters for the name.
...@@ -83,11 +82,11 @@ base::string16 GetBackingModuleFilePath(PVOID address) { ...@@ -83,11 +82,11 @@ base::string16 GetBackingModuleFilePath(PVOID address) {
UNICODE_STRING* section_string = UNICODE_STRING* section_string =
reinterpret_cast<UNICODE_STRING*>(section_name); reinterpret_cast<UNICODE_STRING*>(section_name);
return base::string16(section_string->Buffer, return std::wstring(section_string->Buffer,
section_string->Length / sizeof(wchar_t)); section_string->Length / sizeof(wchar_t));
} }
return base::string16(); return std::wstring();
} }
bool IsModuleValidImageSection(HANDLE section, bool IsModuleValidImageSection(HANDLE section,
...@@ -114,12 +113,12 @@ bool IsModuleValidImageSection(HANDLE section, ...@@ -114,12 +113,12 @@ bool IsModuleValidImageSection(HANDLE section,
return true; return true;
} }
base::string16 ExtractLoadedModuleName(const base::string16& module_path) { std::wstring ExtractLoadedModuleName(const std::wstring& module_path) {
if (module_path.empty() || module_path.back() == L'\\') if (module_path.empty() || module_path.back() == L'\\')
return base::string16(); return std::wstring();
size_t sep = module_path.find_last_of(L'\\'); size_t sep = module_path.find_last_of(L'\\');
if (sep == base::string16::npos) if (sep == std::wstring::npos)
return module_path; return module_path;
return module_path.substr(sep + 1); return module_path.substr(sep + 1);
} }
...@@ -161,11 +160,11 @@ void SafeGetImageInfo(const base::win::PEImage& pe, ...@@ -161,11 +160,11 @@ void SafeGetImageInfo(const base::win::PEImage& pe,
} }
} }
base::string16 GetImageInfoFromLoadedModule(HMODULE module, uint32_t* flags) { std::wstring GetImageInfoFromLoadedModule(HMODULE module, uint32_t* flags) {
std::string out_name; std::string out_name;
base::win::PEImage pe(module); base::win::PEImage pe(module);
SafeGetImageInfo(pe, &out_name, flags); SafeGetImageInfo(pe, &out_name, flags);
return base::string16(out_name.begin(), out_name.end()); return std::wstring(out_name.begin(), out_name.end());
} }
bool IsSameAsCurrentProcess(HANDLE process) { bool IsSameAsCurrentProcess(HANDLE process) {
...@@ -198,7 +197,7 @@ NTSTATUS BlNtMapViewOfSectionImpl( ...@@ -198,7 +197,7 @@ NTSTATUS BlNtMapViewOfSectionImpl(
if (module) { if (module) {
UINT image_flags; UINT image_flags;
base::string16 module_name_from_image(GetImageInfoFromLoadedModule( std::wstring module_name_from_image(GetImageInfoFromLoadedModule(
reinterpret_cast<HMODULE>(*base), &image_flags)); reinterpret_cast<HMODULE>(*base), &image_flags));
int blocked_index = DllMatch(module_name_from_image); int blocked_index = DllMatch(module_name_from_image);
...@@ -206,8 +205,8 @@ NTSTATUS BlNtMapViewOfSectionImpl( ...@@ -206,8 +205,8 @@ NTSTATUS BlNtMapViewOfSectionImpl(
// If the module name isn't blacklisted, see if the file name is different // If the module name isn't blacklisted, see if the file name is different
// and blacklisted. // and blacklisted.
if (blocked_index == -1) { if (blocked_index == -1) {
base::string16 file_name(GetBackingModuleFilePath(*base)); std::wstring file_name(GetBackingModuleFilePath(*base));
base::string16 module_name_from_file = ExtractLoadedModuleName(file_name); std::wstring module_name_from_file = ExtractLoadedModuleName(file_name);
if (module_name_from_image != module_name_from_file) if (module_name_from_image != module_name_from_file)
blocked_index = DllMatch(module_name_from_file); blocked_index = DllMatch(module_name_from_file);
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <memory> #include <memory>
#include "base/environment.h" #include "base/environment.h"
#include "base/files/file.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h" #include "base/files/scoped_temp_dir.h"
#include "base/i18n/case_conversion.h" #include "base/i18n/case_conversion.h"
...@@ -20,8 +21,8 @@ ...@@ -20,8 +21,8 @@
#include "base/win/registry.h" #include "base/win/registry.h"
#include "chrome/common/chrome_version.h" #include "chrome/common/chrome_version.h"
#include "chrome_elf/blacklist/blacklist.h" #include "chrome_elf/blacklist/blacklist.h"
#include "chrome_elf/blacklist/test/blacklist_test_main_dll.h"
#include "chrome_elf/chrome_elf_constants.h" #include "chrome_elf/chrome_elf_constants.h"
#include "chrome_elf/nt_registry/nt_registry.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
const wchar_t kTestDllName1[] = L"blacklist_test_dll_1.dll"; const wchar_t kTestDllName1[] = L"blacklist_test_dll_1.dll";
...@@ -33,24 +34,31 @@ const wchar_t kDll3Beacon[] = L"{9E056AEC-169E-400c-B2D0-5A07E3ACE2EB}"; ...@@ -33,24 +34,31 @@ const wchar_t kDll3Beacon[] = L"{9E056AEC-169E-400c-B2D0-5A07E3ACE2EB}";
extern const wchar_t* kEnvVars[]; extern const wchar_t* kEnvVars[];
extern "C" { namespace {
// When modifying the blacklist in the test process, use the exported test dll
// functions on the test blacklist dll, not the ones linked into the test // Functions we need from blacklist_test_main_dll.dll
// executable itself. typedef void (*TestDll_AddDllsFromRegistryToBlacklistFunction)();
__declspec(dllimport) void TestDll_AddDllsFromRegistryToBlacklist(); typedef bool (*TestDll_AddDllToBlacklistFunction)(const wchar_t* dll_name);
__declspec(dllimport) bool TestDll_AddDllToBlacklist(const wchar_t* dll_name); typedef int (*TestDll_BlacklistSizeFunction)();
__declspec(dllimport) int TestDll_BlacklistSize(); typedef void (*TestDll_BlockedDllFunction)(size_t blocked_index);
__declspec(dllimport) void TestDll_BlockedDll(size_t blocked_index); typedef int (*TestDll_GetBlacklistIndexFunction)(const wchar_t* dll_name);
__declspec(dllimport) int TestDll_GetBlacklistIndex(const wchar_t* dll_name); typedef bool (*TestDll_IsBlacklistInitializedFunction)();
__declspec(dllimport) bool TestDll_IsBlacklistInitialized(); typedef bool (*TestDll_RemoveDllFromBlacklistFunction)(const wchar_t* dll_name);
__declspec(dllimport) bool TestDll_RemoveDllFromBlacklist( typedef bool (*TestDll_SuccessfullyBlockedFunction)(
const wchar_t* dll_name);
__declspec(dllimport) bool TestDll_SuccessfullyBlocked(
const wchar_t** blocked_dlls, const wchar_t** blocked_dlls,
int* size); int* size);
} typedef void (*InitTestDllFunction)();
namespace { TestDll_AddDllsFromRegistryToBlacklistFunction
TestDll_AddDllsFromRegistryToBlacklist = nullptr;
TestDll_AddDllToBlacklistFunction TestDll_AddDllToBlacklist = nullptr;
TestDll_BlacklistSizeFunction TestDll_BlacklistSize = nullptr;
TestDll_BlockedDllFunction TestDll_BlockedDll = nullptr;
TestDll_GetBlacklistIndexFunction TestDll_GetBlacklistIndex = nullptr;
TestDll_IsBlacklistInitializedFunction TestDll_IsBlacklistInitialized = nullptr;
TestDll_RemoveDllFromBlacklistFunction TestDll_RemoveDllFromBlacklist = nullptr;
TestDll_SuccessfullyBlockedFunction TestDll_SuccessfullyBlocked = nullptr;
InitTestDllFunction InitTestDll = nullptr;
struct TestData { struct TestData {
const wchar_t* dll_name; const wchar_t* dll_name;
...@@ -63,7 +71,6 @@ struct TestData { ...@@ -63,7 +71,6 @@ struct TestData {
class BlacklistTest : public testing::Test { class BlacklistTest : public testing::Test {
protected: protected:
BlacklistTest() : override_manager_(), num_initially_blocked_(0) { BlacklistTest() : override_manager_(), num_initially_blocked_(0) {
override_manager_.OverrideRegistry(HKEY_CURRENT_USER);
} }
void CheckBlacklistedDllsNotLoaded() { void CheckBlacklistedDllsNotLoaded() {
...@@ -125,9 +132,71 @@ class BlacklistTest : public testing::Test { ...@@ -125,9 +132,71 @@ class BlacklistTest : public testing::Test {
int num_initially_blocked_; int num_initially_blocked_;
private: private:
// This function puts registry-key redirection paths into
// process-specific environment variables, for our test DLLs to access.
// This will only work as long as the IPC is within the same process.
void IpcOverrides() {
if (::wcslen(nt::HKCU_override) != 0) {
ASSERT_TRUE(
::SetEnvironmentVariableW(L"hkcu_override", nt::HKCU_override));
}
if (::wcslen(nt::HKLM_override) != 0) {
ASSERT_TRUE(
::SetEnvironmentVariableW(L"hklm_override", nt::HKLM_override));
}
}
void SetUp() override { void SetUp() override {
// Force an import from blacklist_test_main_dll. base::string16 temp;
InitBlacklistTestDll(); override_manager_.OverrideRegistry(HKEY_CURRENT_USER, &temp);
::wcsncpy(nt::HKCU_override, temp.c_str(), nt::g_kRegMaxPathLen - 1);
// Make the override path available to our test DLL.
IpcOverrides();
// Load the main test Dll now.
// Note: this has to happen after we set up the registry overrides.
HMODULE dll = nullptr;
dll = ::LoadLibraryW(L"blacklist_test_main_dll.dll");
if (!dll)
return;
TestDll_AddDllsFromRegistryToBlacklist =
reinterpret_cast<TestDll_AddDllsFromRegistryToBlacklistFunction>(
::GetProcAddress(dll, "TestDll_AddDllsFromRegistryToBlacklist"));
TestDll_AddDllToBlacklist =
reinterpret_cast<TestDll_AddDllToBlacklistFunction>(
::GetProcAddress(dll, "TestDll_AddDllToBlacklist"));
TestDll_BlacklistSize = reinterpret_cast<TestDll_BlacklistSizeFunction>(
::GetProcAddress(dll, "TestDll_BlacklistSize"));
TestDll_BlockedDll = reinterpret_cast<TestDll_BlockedDllFunction>(
::GetProcAddress(dll, "TestDll_BlockedDll"));
TestDll_GetBlacklistIndex =
reinterpret_cast<TestDll_GetBlacklistIndexFunction>(
::GetProcAddress(dll, "TestDll_GetBlacklistIndex"));
TestDll_IsBlacklistInitialized =
reinterpret_cast<TestDll_IsBlacklistInitializedFunction>(
::GetProcAddress(dll, "TestDll_IsBlacklistInitialized"));
TestDll_RemoveDllFromBlacklist =
reinterpret_cast<TestDll_RemoveDllFromBlacklistFunction>(
::GetProcAddress(dll, "TestDll_RemoveDllFromBlacklist"));
TestDll_SuccessfullyBlocked =
reinterpret_cast<TestDll_SuccessfullyBlockedFunction>(
::GetProcAddress(dll, "TestDll_SuccessfullyBlocked"));
InitTestDll = reinterpret_cast<InitTestDllFunction>(
::GetProcAddress(dll, "InitTestDll"));
if (!TestDll_AddDllsFromRegistryToBlacklist || !TestDll_AddDllToBlacklist ||
!TestDll_BlacklistSize || !TestDll_BlockedDll ||
!TestDll_GetBlacklistIndex || !TestDll_IsBlacklistInitialized ||
!TestDll_RemoveDllFromBlacklist || !TestDll_SuccessfullyBlocked ||
!InitTestDll)
return;
// We have to call this exported function every time this test setup runs.
// If the tests are running in single process mode, the test DLL does not
// get reloaded everytime - but we need to make sure it updates
// appropriately.
InitTestDll();
blacklist_registry_key_.reset( blacklist_registry_key_.reset(
new base::win::RegKey(HKEY_CURRENT_USER, new base::win::RegKey(HKEY_CURRENT_USER,
blacklist::kRegistryBeaconPath, blacklist::kRegistryBeaconPath,
...@@ -142,6 +211,9 @@ class BlacklistTest : public testing::Test { ...@@ -142,6 +211,9 @@ class BlacklistTest : public testing::Test {
TestDll_RemoveDllFromBlacklist(kTestDllName2); TestDll_RemoveDllFromBlacklist(kTestDllName2);
TestDll_RemoveDllFromBlacklist(kTestDllName3); TestDll_RemoveDllFromBlacklist(kTestDllName3);
} }
// A scoped temporary directory to be destroyed with this test.
base::ScopedTempDir reg_override_dir_;
}; };
TEST_F(BlacklistTest, Beacon) { TEST_F(BlacklistTest, Beacon) {
...@@ -254,15 +326,27 @@ TEST_F(BlacklistTest, AddDllsFromRegistryToBlacklist) { ...@@ -254,15 +326,27 @@ TEST_F(BlacklistTest, AddDllsFromRegistryToBlacklist) {
KEY_QUERY_VALUE | KEY_SET_VALUE); KEY_QUERY_VALUE | KEY_SET_VALUE);
key.DeleteKey(L""); key.DeleteKey(L"");
// Add the test dlls to the registry (with their name as both key and value). // Add the test dlls to the registry.
// (REG_MULTI_SZ: eos separated, double null terminated.)
base::win::RegKey finch_blacklist_registry_key( base::win::RegKey finch_blacklist_registry_key(
HKEY_CURRENT_USER, HKEY_CURRENT_USER,
blacklist::kRegistryFinchListPath, blacklist::kRegistryFinchListPath,
KEY_QUERY_VALUE | KEY_SET_VALUE); KEY_QUERY_VALUE | KEY_SET_VALUE);
std::vector<wchar_t>(reg_buffer);
for (size_t i = 0; i < arraysize(test_data); ++i) { for (size_t i = 0; i < arraysize(test_data); ++i) {
finch_blacklist_registry_key.WriteValue(test_data[i].dll_name, if (reg_buffer.size() > 0)
test_data[i].dll_name); reg_buffer.push_back(L'\0');
const wchar_t* dll = test_data[i].dll_name;
// Append the name, not including terminator.
reg_buffer.insert(reg_buffer.end(), dll, dll + ::wcslen(dll));
} }
reg_buffer.push_back(L'\0');
reg_buffer.push_back(L'\0');
finch_blacklist_registry_key.WriteValue(
blacklist::kRegistryFinchListValueName, reg_buffer.data(),
(DWORD)(reg_buffer.size() * sizeof(wchar_t)), REG_MULTI_SZ);
TestDll_AddDllsFromRegistryToBlacklist(); TestDll_AddDllsFromRegistryToBlacklist();
CheckBlacklistedDllsNotLoaded(); CheckBlacklistedDllsNotLoaded();
......
// Copyright 2013 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 "base/at_exit.h"
#include "chrome_elf/blacklist/test/blacklist_test_main_dll.h"
#include "testing/gtest/include/gtest/gtest.h"
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
base::AtExitManager at_exit_manager;
InitBlacklistTestDll();
RUN_ALL_TESTS();
}
...@@ -2,16 +2,49 @@ ...@@ -2,16 +2,49 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome_elf/blacklist/blacklist.h"
#include <windows.h> #include <windows.h>
#include "chrome/install_static/install_util.h" #include "chrome/install_static/install_util.h"
#include "chrome_elf/blacklist/blacklist.h" #include "chrome_elf/nt_registry/nt_registry.h"
namespace {
void GetIpcOverrides() {
DWORD buffer_size = ::GetEnvironmentVariableW(L"hkcu_override", nullptr, 0);
if (buffer_size > 0) {
wchar_t* content = new wchar_t[buffer_size];
buffer_size =
::GetEnvironmentVariableW(L"hkcu_override", content, buffer_size);
if (buffer_size)
::wcsncpy(nt::HKCU_override, content, nt::g_kRegMaxPathLen - 1);
delete[] content;
}
buffer_size = ::GetEnvironmentVariableW(L"hklm_override", nullptr, 0);
if (buffer_size > 0) {
wchar_t* content = new wchar_t[buffer_size];
buffer_size =
::GetEnvironmentVariableW(L"hklm_override", content, buffer_size);
if (buffer_size)
::wcsncpy(nt::HKLM_override, content, nt::g_kRegMaxPathLen - 1);
delete[] content;
}
return;
}
} // namespace
extern "C" void InitBlacklistTestDll() { extern "C" __declspec(dllexport) void InitTestDll() {
// Make sure we've got the latest registry overrides.
GetIpcOverrides();
} }
BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) { BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) {
if (reason == DLL_PROCESS_ATTACH) { if (reason == DLL_PROCESS_ATTACH) {
GetIpcOverrides();
install_static::InitializeProcessType(); install_static::InitializeProcessType();
blacklist::Initialize(true); // force always on, no beacon blacklist::Initialize(true); // force always on, no beacon
} }
......
...@@ -13,4 +13,3 @@ EXPORTS ...@@ -13,4 +13,3 @@ EXPORTS
TestDll_IsBlacklistInitialized=IsBlacklistInitialized TestDll_IsBlacklistInitialized=IsBlacklistInitialized
TestDll_SuccessfullyBlocked=SuccessfullyBlocked TestDll_SuccessfullyBlocked=SuccessfullyBlocked
TestDll_RemoveDllFromBlacklist=RemoveDllFromBlacklist TestDll_RemoveDllFromBlacklist=RemoveDllFromBlacklist
InitBlacklistTestDll
\ No newline at end of file
...@@ -5,15 +5,12 @@ ...@@ -5,15 +5,12 @@
// This module contains the necessary code to register the Breakpad exception // This module contains the necessary code to register the Breakpad exception
// handler. This implementation is based on Chrome's crash reporting code. // handler. This implementation is based on Chrome's crash reporting code.
#include "chrome_elf/breakpad.h" #include "chrome_elf/breakpad/breakpad.h"
#include <sddl.h>
#include "base/macros.h"
#include "base/strings/string16.h"
#include "breakpad/src/client/windows/handler/exception_handler.h" #include "breakpad/src/client/windows/handler/exception_handler.h"
#include "chrome/common/chrome_version.h" #include "chrome/common/chrome_version.h"
#include "chrome/install_static/install_util.h" #include "chrome/install_static/install_util.h"
#include "chrome_elf/nt_registry/nt_registry.h"
google_breakpad::ExceptionHandler* g_elf_breakpad = NULL; google_breakpad::ExceptionHandler* g_elf_breakpad = NULL;
...@@ -39,56 +36,33 @@ const wchar_t kSystemPrincipalSid[] = L"S-1-5-18"; ...@@ -39,56 +36,33 @@ const wchar_t kSystemPrincipalSid[] = L"S-1-5-18";
const wchar_t kNoErrorDialogs[] = L"noerrdialogs"; const wchar_t kNoErrorDialogs[] = L"noerrdialogs";
google_breakpad::CustomClientInfo* GetCustomInfo() { google_breakpad::CustomClientInfo* GetCustomInfo() {
base::string16 process = std::wstring process =
install_static::IsNonBrowserProcess() ? L"renderer" : L"browser"; install_static::IsNonBrowserProcess() ? L"renderer" : L"browser";
wchar_t exe_path[MAX_PATH] = {}; wchar_t exe_path[MAX_PATH] = {};
base::string16 channel; std::wstring channel;
if (GetModuleFileName(NULL, exe_path, arraysize(exe_path)) && if (GetModuleFileName(NULL, exe_path, MAX_PATH) &&
install_static::IsSxSChrome(exe_path)) { install_static::IsSxSChrome(exe_path)) {
channel = L"canary"; channel = L"canary";
} }
static google_breakpad::CustomInfoEntry ver_entry( static google_breakpad::CustomInfoEntry ver_entry(
kBreakpadVersionEntry, TEXT(CHROME_VERSION_STRING)); kBreakpadVersionEntry, TEXT(CHROME_VERSION_STRING));
static google_breakpad::CustomInfoEntry prod_entry( static google_breakpad::CustomInfoEntry prod_entry(kBreakpadProdEntry,
kBreakpadProdEntry, kBreakpadProductName); kBreakpadProductName);
static google_breakpad::CustomInfoEntry plat_entry( static google_breakpad::CustomInfoEntry plat_entry(kBreakpadPlatformEntry,
kBreakpadPlatformEntry, kBreakpadPlatformWin32); kBreakpadPlatformWin32);
static google_breakpad::CustomInfoEntry proc_entry( static google_breakpad::CustomInfoEntry proc_entry(kBreakpadProcessEntry,
kBreakpadProcessEntry, process.c_str()); process.c_str());
static google_breakpad::CustomInfoEntry channel_entry( static google_breakpad::CustomInfoEntry channel_entry(kBreakpadChannelEntry,
kBreakpadChannelEntry, channel.c_str()); channel.c_str());
static google_breakpad::CustomInfoEntry entries[] = { static google_breakpad::CustomInfoEntry entries[] = {
ver_entry, prod_entry, plat_entry, proc_entry, channel_entry}; ver_entry, prod_entry, plat_entry, proc_entry, channel_entry};
static google_breakpad::CustomClientInfo custom_info = { static google_breakpad::CustomClientInfo custom_info = {
entries, arraysize(entries) }; entries, (sizeof(entries) / sizeof(google_breakpad::CustomInfoEntry))};
return &custom_info; return &custom_info;
} }
base::string16 GetUserSidString() {
// Get the current token.
HANDLE token = NULL;
base::string16 user_sid;
if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token))
return user_sid;
DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE;
BYTE user_bytes[sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE] = {};
TOKEN_USER* user = reinterpret_cast<TOKEN_USER*>(user_bytes);
wchar_t* sid_string = NULL;
if (::GetTokenInformation(token, TokenUser, user, size, &size) &&
user->User.Sid &&
::ConvertSidToStringSid(user->User.Sid, &sid_string)) {
user_sid = sid_string;
::LocalFree(sid_string);
}
CloseHandle(token);
return user_sid;
}
bool IsHeadless() { bool IsHeadless() {
DWORD ret = ::GetEnvironmentVariable(L"CHROME_HEADLESS", NULL, 0); DWORD ret = ::GetEnvironmentVariable(L"CHROME_HEADLESS", NULL, 0);
if (ret != 0) if (ret != 0)
...@@ -118,7 +92,7 @@ int GenerateCrashDump(EXCEPTION_POINTERS* exinfo) { ...@@ -118,7 +92,7 @@ int GenerateCrashDump(EXCEPTION_POINTERS* exinfo) {
void InitializeCrashReporting() { void InitializeCrashReporting() {
wchar_t exe_path[MAX_PATH] = {}; wchar_t exe_path[MAX_PATH] = {};
if (!::GetModuleFileName(NULL, exe_path, arraysize(exe_path))) if (!::GetModuleFileName(NULL, exe_path, MAX_PATH))
return; return;
// Disable the message box for assertions. // Disable the message box for assertions.
...@@ -135,7 +109,7 @@ void InitializeCrashReporting() { ...@@ -135,7 +109,7 @@ void InitializeCrashReporting() {
// Minidump with stacks, PEB, TEBs and unloaded module list. // Minidump with stacks, PEB, TEBs and unloaded module list.
MINIDUMP_TYPE dump_type = static_cast<MINIDUMP_TYPE>( MINIDUMP_TYPE dump_type = static_cast<MINIDUMP_TYPE>(
MiniDumpWithProcessThreadData | // Get PEB and TEB. MiniDumpWithProcessThreadData | // Get PEB and TEB.
MiniDumpWithUnloadedModules | // Get unloaded modules when available. MiniDumpWithUnloadedModules | // Get unloaded modules when available.
MiniDumpWithIndirectlyReferencedMemory); // Get memory referenced by MiniDumpWithIndirectlyReferencedMemory); // Get memory referenced by
// stack. // stack.
...@@ -145,7 +119,7 @@ void InitializeCrashReporting() { ...@@ -145,7 +119,7 @@ void InitializeCrashReporting() {
bool is_official_chrome_build = false; bool is_official_chrome_build = false;
#endif #endif
base::string16 pipe_name; std::wstring pipe_name;
bool enabled_by_policy = false; bool enabled_by_policy = false;
bool use_policy = bool use_policy =
...@@ -161,9 +135,9 @@ void InitializeCrashReporting() { ...@@ -161,9 +135,9 @@ void InitializeCrashReporting() {
// 32-bit user: \\.\pipe\GoogleCrashServices\<user SID> // 32-bit user: \\.\pipe\GoogleCrashServices\<user SID>
// 64-bit system: \\.\pipe\GoogleCrashServices\S-1-5-18-x64 // 64-bit system: \\.\pipe\GoogleCrashServices\S-1-5-18-x64
// 64-bit user: \\.\pipe\GoogleCrashServices\<user SID>-x64 // 64-bit user: \\.\pipe\GoogleCrashServices\<user SID>-x64
base::string16 user_sid = install_static::IsSystemInstall(exe_path) std::wstring user_sid = install_static::IsSystemInstall(exe_path)
? kSystemPrincipalSid ? kSystemPrincipalSid
: GetUserSidString(); : nt::GetCurrentUserSidString();
if (user_sid.empty()) if (user_sid.empty())
return; return;
...@@ -180,14 +154,9 @@ void InitializeCrashReporting() { ...@@ -180,14 +154,9 @@ void InitializeCrashReporting() {
} }
g_elf_breakpad = new google_breakpad::ExceptionHandler( g_elf_breakpad = new google_breakpad::ExceptionHandler(
temp_directory, temp_directory, NULL, NULL, NULL,
NULL, google_breakpad::ExceptionHandler::HANDLER_ALL, dump_type,
NULL, pipe_name.c_str(), GetCustomInfo());
NULL,
google_breakpad::ExceptionHandler::HANDLER_ALL,
dump_type,
pipe_name.c_str(),
GetCustomInfo());
if (g_elf_breakpad->IsOutOfProcess()) { if (g_elf_breakpad->IsOutOfProcess()) {
// Tells breakpad to handle breakpoint and single step exceptions. // Tells breakpad to handle breakpoint and single step exceptions.
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROME_ELF_BREAKPAD_H_ #ifndef CHROME_ELF_BREAKPAD_BREAKPAD_H_
#define CHROME_ELF_BREAKPAD_H_ #define CHROME_ELF_BREAKPAD_BREAKPAD_H_
#include <windows.h> #include <windows.h>
...@@ -31,4 +31,4 @@ int GenerateCrashDump(EXCEPTION_POINTERS* exinfo); ...@@ -31,4 +31,4 @@ int GenerateCrashDump(EXCEPTION_POINTERS* exinfo);
// InitializeCrashReporting() and used by GenerateCrashDump() to record dumps. // InitializeCrashReporting() and used by GenerateCrashDump() to record dumps.
extern google_breakpad::ExceptionHandler* g_elf_breakpad; extern google_breakpad::ExceptionHandler* g_elf_breakpad;
#endif // CHROME_ELF_BREAKPAD_H_ #endif // CHROME_ELF_BREAKPAD_BREAKPAD_H_
...@@ -12,6 +12,9 @@ ...@@ -12,6 +12,9 @@
'dll_hash.gypi', 'dll_hash.gypi',
], ],
'targets': [ 'targets': [
##--------------------------------------------------------------------------
## chrome_elf
##--------------------------------------------------------------------------
{ {
'target_name': 'chrome_elf_resources', 'target_name': 'chrome_elf_resources',
'type': 'none', 'type': 'none',
...@@ -42,9 +45,12 @@ ...@@ -42,9 +45,12 @@
'<(SHARED_INTERMEDIATE_DIR)/chrome_elf/chrome_elf_version.rc', '<(SHARED_INTERMEDIATE_DIR)/chrome_elf/chrome_elf_version.rc',
], ],
'dependencies': [ 'dependencies': [
'../chrome/chrome.gyp:install_static_util',
'blacklist', 'blacklist',
'chrome_elf_breakpad', 'chrome_elf_breakpad',
'chrome_elf_hook_util',
'chrome_elf_resources', 'chrome_elf_resources',
'nt_registry/nt_registry.gyp:chrome_elf_nt_registry',
'../chrome/chrome.gyp:install_static_util', '../chrome/chrome.gyp:install_static_util',
'../components/components.gyp:crash_component', '../components/components.gyp:crash_component',
'../components/components.gyp:crash_core_common', '../components/components.gyp:crash_core_common',
...@@ -68,6 +74,52 @@ ...@@ -68,6 +74,52 @@
}, },
}, },
}, },
##--------------------------------------------------------------------------
## chrome_elf sub targets
##--------------------------------------------------------------------------
{
'target_name': 'chrome_elf_constants',
'type': 'static_library',
'include_dirs': [
'..',
],
'sources': [
'chrome_elf_constants.cc',
'chrome_elf_constants.h',
],
},
{
'target_name': 'chrome_elf_breakpad',
'type': 'static_library',
'include_dirs': [
'..',
'<(SHARED_INTERMEDIATE_DIR)',
],
'sources': [
'breakpad/breakpad.cc',
'breakpad/breakpad.h',
],
'dependencies': [
'../breakpad/breakpad.gyp:breakpad_handler',
'../chrome/chrome.gyp:install_static_util',
'../chrome/common_constants.gyp:version_header',
'nt_registry/nt_registry.gyp:chrome_elf_nt_registry',
],
},
{
'target_name': 'chrome_elf_hook_util',
'type': 'static_library',
'include_dirs': [
'..',
],
'sources': [
'hook_util/thunk_getter.cc',
'hook_util/thunk_getter.h',
],
},
##--------------------------------------------------------------------------
## tests
##--------------------------------------------------------------------------
{ {
'target_name': 'chrome_elf_unittests_exe', 'target_name': 'chrome_elf_unittests_exe',
'product_name': 'chrome_elf_unittests', 'product_name': 'chrome_elf_unittests',
...@@ -94,6 +146,8 @@ ...@@ -94,6 +146,8 @@
'blacklist_test_dll_2', 'blacklist_test_dll_2',
'blacklist_test_dll_3', 'blacklist_test_dll_3',
'blacklist_test_main_dll', 'blacklist_test_main_dll',
'chrome_elf_hook_util',
'nt_registry/nt_registry.gyp:chrome_elf_nt_registry',
], ],
'msvs_settings': { 'msvs_settings': {
'VCLinkerTool': { 'VCLinkerTool': {
...@@ -125,50 +179,10 @@ ...@@ -125,50 +179,10 @@
'chrome_elf_unittests_exe', 'chrome_elf_unittests_exe',
], ],
}, },
{
'target_name': 'chrome_elf_constants',
'type': 'static_library',
'include_dirs': [
'..',
],
'sources': [
'chrome_elf_constants.cc',
'chrome_elf_constants.h',
],
},
{
'target_name': 'chrome_elf_common',
'type': 'static_library',
'dependencies': [
'chrome_elf_constants',
],
'include_dirs': [
'..',
],
'sources': [
'thunk_getter.cc',
'thunk_getter.h',
],
},
{
'target_name': 'chrome_elf_breakpad',
'type': 'static_library',
'include_dirs': [
'..',
'<(SHARED_INTERMEDIATE_DIR)',
],
'sources': [
'breakpad.cc',
'breakpad.h',
],
'dependencies': [
'chrome_elf_common',
'../breakpad/breakpad.gyp:breakpad_handler',
'../chrome/common_constants.gyp:version_header',
'../chrome/chrome.gyp:install_static_util',
],
},
], # targets ], # targets
##----------------------------------------------------------------------------
## conditionals
##----------------------------------------------------------------------------
'conditions': [ 'conditions': [
['test_isolation_mode != "noop"', { ['test_isolation_mode != "noop"', {
'targets': [ 'targets': [
......
...@@ -21,6 +21,8 @@ const wchar_t kRegistryBeaconPath[] = ...@@ -21,6 +21,8 @@ const wchar_t kRegistryBeaconPath[] =
L"SOFTWARE\\" PRODUCT_STRING_PATH L"\\BLBeacon"; L"SOFTWARE\\" PRODUCT_STRING_PATH L"\\BLBeacon";
const wchar_t kRegistryFinchListPath[] = const wchar_t kRegistryFinchListPath[] =
L"SOFTWARE\\" PRODUCT_STRING_PATH L"\\BLFinchList"; L"SOFTWARE\\" PRODUCT_STRING_PATH L"\\BLFinchList";
const char kRegistryFinchListValueNameStr[] = "BLDlls";
const wchar_t kRegistryFinchListValueName[] = L"BLDlls";
const wchar_t kBeaconVersion[] = L"version"; const wchar_t kBeaconVersion[] = L"version";
const wchar_t kBeaconState[] = L"state"; const wchar_t kBeaconState[] = L"state";
const wchar_t kBeaconAttemptCount[] = L"failed_count"; const wchar_t kBeaconAttemptCount[] = L"failed_count";
...@@ -28,3 +30,13 @@ const wchar_t kBeaconAttemptCount[] = L"failed_count"; ...@@ -28,3 +30,13 @@ const wchar_t kBeaconAttemptCount[] = L"failed_count";
const DWORD kBeaconMaxAttempts = 2; const DWORD kBeaconMaxAttempts = 2;
} // namespace blacklist } // namespace blacklist
namespace elf_sec {
const wchar_t kRegSecurityFinchPath[] =
L"SOFTWARE\\" PRODUCT_STRING_PATH L"\\BrowserSboxFinch";
const wchar_t kRegSecurityPath[] =
L"SOFTWARE\\" PRODUCT_STRING_PATH L"\\BrowserSec";
} // namespace elf_sec
...@@ -17,6 +17,13 @@ extern const wchar_t kRegistryBeaconPath[]; ...@@ -17,6 +17,13 @@ extern const wchar_t kRegistryBeaconPath[];
// The registry path of the finch blacklist dlls. // The registry path of the finch blacklist dlls.
extern const wchar_t kRegistryFinchListPath[]; extern const wchar_t kRegistryFinchListPath[];
// The registry value name for the REG_MULTI_SZ list of blacklist dlls.
// Note the char version is handy for use as the param name when
// appending dll names to the base::FieldTrial. Can be removed
// if no longer used.
extern const char kRegistryFinchListValueNameStr[];
extern const wchar_t kRegistryFinchListValueName[];
// The properties for the blacklist beacon. // The properties for the blacklist beacon.
extern const wchar_t kBeaconVersion[]; extern const wchar_t kBeaconVersion[];
extern const wchar_t kBeaconState[]; extern const wchar_t kBeaconState[];
...@@ -41,4 +48,14 @@ enum BlacklistState { ...@@ -41,4 +48,14 @@ enum BlacklistState {
} // namespace blacklist } // namespace blacklist
namespace elf_sec {
// The registry path of the finch "emergency-off"
// switch for sandbox::MITIGATION_EXTENSION_POINT_DISABLE.
extern const wchar_t kRegSecurityFinchPath[];
// The registry path for any early-browser security settings.
extern const wchar_t kRegSecurityPath[];
}
#endif // CHROME_ELF_CHROME_ELF_CONSTANTS_H_ #endif // CHROME_ELF_CHROME_ELF_CONSTANTS_H_
...@@ -8,8 +8,7 @@ ...@@ -8,8 +8,7 @@
#include "chrome/install_static/install_util.h" #include "chrome/install_static/install_util.h"
#include "chrome_elf/blacklist/blacklist.h" #include "chrome_elf/blacklist/blacklist.h"
#include "chrome_elf/breakpad.h" #include "chrome_elf/breakpad/breakpad.h"
void SignalChromeElf() { void SignalChromeElf() {
blacklist::ResetBeacon(); blacklist::ResetBeacon();
......
This diff is collapsed.
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#include <stdint.h> #include <stdint.h>
#include <windows.h> #include <windows.h>
#include "base/macros.h"
#include "sandbox/win/src/interception_internal.h" #include "sandbox/win/src/interception_internal.h"
#include "sandbox/win/src/internal_types.h" #include "sandbox/win/src/internal_types.h"
#include "sandbox/win/src/sandbox_utils.h" #include "sandbox/win/src/sandbox_utils.h"
...@@ -30,7 +29,11 @@ enum Version { ...@@ -30,7 +29,11 @@ enum Version {
// WOW64_DISABLED for both "32-bit Chrome on 32-bit Windows" and "64-bit // WOW64_DISABLED for both "32-bit Chrome on 32-bit Windows" and "64-bit
// Chrome on 64-bit Windows". WOW64_UNKNOWN means "an error occurred", e.g. // Chrome on 64-bit Windows". WOW64_UNKNOWN means "an error occurred", e.g.
// the process does not have sufficient access rights to determine this. // the process does not have sufficient access rights to determine this.
enum WOW64Status { WOW64_DISABLED, WOW64_ENABLED, WOW64_UNKNOWN, }; enum WOW64Status {
WOW64_DISABLED,
WOW64_ENABLED,
WOW64_UNKNOWN,
};
WOW64Status GetWOW64StatusForCurrentProcess() { WOW64Status GetWOW64StatusForCurrentProcess() {
typedef BOOL(WINAPI * IsWow64ProcessFunc)(HANDLE, PBOOL); typedef BOOL(WINAPI * IsWow64ProcessFunc)(HANDLE, PBOOL);
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROME_ELF_THUNK_GETTER_H_ #ifndef CHROME_ELF_HOOK_UTIL_THUNK_GETTER_H_
#define CHROME_ELF_THUNK_GETTER_H_ #define CHROME_ELF_HOOK_UTIL_THUNK_GETTER_H_
namespace sandbox { namespace sandbox {
class ServiceResolverThunk; class ServiceResolverThunk;
...@@ -13,4 +13,4 @@ class ServiceResolverThunk; ...@@ -13,4 +13,4 @@ class ServiceResolverThunk;
// resulting thunk is passed to the caller. // resulting thunk is passed to the caller.
sandbox::ServiceResolverThunk* GetThunk(bool relaxed); sandbox::ServiceResolverThunk* GetThunk(bool relaxed);
#endif // CHROME_ELF_THUNK_GETTER_H_ #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.
import("//build/config/chrome_build.gni")
import("//testing/test.gni")
assert(is_win)
# This target only contains utility functions which must only depend on
# kernel32. Please don't add dependencies on other system libraries.
static_library("nt_registry") {
sources = [
"../../sandbox/win/src/nt_internals.h",
"nt_registry.cc",
"nt_registry.h",
]
libs = [ "kernel32.lib" ]
}
include_rules = [
# Nothing from base.
"-base",
# Nothing from chrome.
"-chrome",
"-chrome_elf",
"+chrome_elf/nt_registry/nt_registry.h",
]
This diff is collapsed.
# 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.
# The nt_registry target should only depend on functions in kernel32.
# Please don't add dependencies on other system libraries.
{
'target_defaults': {
# This part is shared between the two versions of the target.
'type': 'static_library',
'sources': [
'nt_registry.cc',
'nt_registry.h',
],
'include_dirs': [
'../..',
'<(SHARED_INTERMEDIATE_DIR)',
],
'msvs_settings': {
'VCLinkerTool': {
# Please don't add dependencies on other system libraries.
'AdditionalDependencies': [
'kernel32.lib',
],
},
},
},
'conditions': [
['OS=="win"', {
'targets': [
{
# GN version: "//chrome_elf/nt_registry",
'target_name': 'chrome_elf_nt_registry',
},
],
}],
['OS=="win" and target_arch=="ia32"', {
'targets': [
{
# GN version: "//chrome_elf/nt_registry",
'target_name': 'chrome_elf_nt_registry_nacl_win64',
'configurations': {
'Common_Base': {
'msvs_target_platform': 'x64',
},
},
},
],
}],
],
}
// 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.
// This API is a usability layer for direct registry access via NTDLL.
// It allows for "advapi32-free" registry access, which is especially
// useful for accessing registy from DllMain (holding loader lock),
// or if a dependency on/linkage of ADVAPI32.dll is not desired.
// The implementation of this API should only use ntdll and kernel32 system
// DLLs.
// Note that this API is currently lazy initialized. Any function that is
// NOT merely a wrapper function (i.e. any function that directly interacts with
// NTDLL) will immediately check:
// if (!g_initialized)
// InitNativeRegApi();
// There is currently no multi-threading lock around the lazy initialization,
// as the main client for this API (chrome_elf) does not introduce
// a multi-threading concern. This can easily be changed if needed.
#ifndef CHROME_ELF_NT_REGISTRY_NT_REGISTRY_H_
#define CHROME_ELF_NT_REGISTRY_NT_REGISTRY_H_
#include <vector>
#include "sandbox/win/src/nt_internals.h" // NTSTATUS
namespace nt {
// These globals are only used in test suites that use reg redirection
// of HKLM and/or HKCU.
extern const size_t g_kRegMaxPathLen;
extern wchar_t HKLM_override[];
extern wchar_t HKCU_override[];
// AUTO will choose depending on system install or not.
// Use HKLM or HKCU to override.
typedef enum _ROOT_KEY { AUTO = 0, HKLM, HKCU } ROOT_KEY;
// Create and/or open a registry key.
// - This function will recursively create multiple sub-keys if required for
// |key_path|.
// - If the key doesn't need to be left open, pass in nullptr for |out_handle|.
// - This function will happily succeed if the key already exists.
// - Optional |out_handle|. If nullptr, function will close handle when done.
// Otherwise, will hold the open handle to the deepest subkey.
// - Caller must call CloseRegKey on returned handle (on success).
bool CreateRegKey(ROOT_KEY root,
const wchar_t* key_path,
ACCESS_MASK access,
HANDLE* out_handle OPTIONAL);
// Open existing registry key.
// - Caller must call CloseRegKey on returned handle (on success).
// - Optional error code can be returned on failure for extra detail.
bool OpenRegKey(ROOT_KEY root,
const wchar_t* key_path,
ACCESS_MASK access,
HANDLE* out_handle,
NTSTATUS* error_code OPTIONAL);
// Delete a registry key.
// - Caller must still call CloseRegKey after the delete.
bool DeleteRegKey(HANDLE key);
// Delete a registry key.
// - WRAPPER: Function opens and closes the target key for caller.
bool DeleteRegKey(ROOT_KEY root, const wchar_t* key_path);
// Close a registry key handle that was opened with CreateRegKey or OpenRegKey.
void CloseRegKey(HANDLE key);
//------------------------------------------------------------------------------
// Getter functions
//------------------------------------------------------------------------------
// Main function to query a registry value.
// - Key handle should have been opened with CreateRegKey or OpenRegKey.
// - Types defined in winnt.h. E.g.: REG_DWORD, REG_SZ.
// - Caller is responsible for calling "delete[] *out_buffer" (on success).
bool QueryRegKeyValue(HANDLE key,
const wchar_t* value_name,
ULONG* out_type,
BYTE** out_buffer,
DWORD* out_size);
// Query DWORD value.
// - WRAPPER: Function works with DWORD data type.
// - Key handle should have been opened with CreateRegKey or OpenRegKey.
// - Handle will be left open. Caller must still call CloseRegKey when done.
bool QueryRegValueDWORD(HANDLE key,
const wchar_t* value_name,
DWORD* out_dword);
// Query DWORD value.
// - WRAPPER: Function opens and closes the target key for caller, and works
// with DWORD data type.
bool QueryRegValueDWORD(ROOT_KEY root,
const wchar_t* key_path,
const wchar_t* value_name,
DWORD* out_dword);
// Query SZ (string) value.
// - WRAPPER: Function works with SZ data type.
// - Key handle should have been opened with CreateRegKey or OpenRegKey.
// - Handle will be left open. Caller must still call CloseRegKey when done.
bool QueryRegValueSZ(HANDLE key,
const wchar_t* value_name,
std::wstring* out_sz);
// Query SZ (string) value.
// - WRAPPER: Function opens and closes the target key for caller, and works
// with SZ data type.
bool QueryRegValueSZ(ROOT_KEY root,
const wchar_t* key_path,
const wchar_t* value_name,
std::wstring* out_sz);
// Query MULTI_SZ (multiple strings) value.
// - WRAPPER: Function works with MULTI_SZ data type.
// - Key handle should have been opened with CreateRegKey or OpenRegKey.
// - Handle will be left open. Caller must still call CloseRegKey when done.
bool QueryRegValueMULTISZ(HANDLE key,
const wchar_t* value_name,
std::vector<std::wstring>* out_multi_sz);
// Query MULTI_SZ (multiple strings) value.
// - WRAPPER: Function opens and closes the target key for caller, and works
// with MULTI_SZ data type.
bool QueryRegValueMULTISZ(ROOT_KEY root,
const wchar_t* key_path,
const wchar_t* value_name,
std::vector<std::wstring>* out_multi_sz);
//------------------------------------------------------------------------------
// Setter functions
//------------------------------------------------------------------------------
// Main function to set a registry value.
// - Key handle should have been opened with CreateRegKey or OpenRegKey.
// - Types defined in winnt.h. E.g.: REG_DWORD, REG_SZ.
bool SetRegKeyValue(HANDLE key,
const wchar_t* value_name,
ULONG type,
const BYTE* data,
DWORD data_size);
// Set DWORD value.
// - WRAPPER: Function works with DWORD data type.
// - Key handle should have been opened with CreateRegKey or OpenRegKey.
// - Handle will be left open. Caller must still call CloseRegKey when done.
bool SetRegValueDWORD(HANDLE key, const wchar_t* value_name, DWORD value);
// Set DWORD value.
// - WRAPPER: Function opens and closes the target key for caller, and works
// with DWORD data type.
bool SetRegValueDWORD(ROOT_KEY root,
const wchar_t* key_path,
const wchar_t* value_name,
DWORD value);
// Set SZ (string) value.
// - WRAPPER: Function works with SZ data type.
// - Key handle should have been opened with CreateRegKey or OpenRegKey.
// - Handle will be left open. Caller must still call CloseRegKey when done.
bool SetRegValueSZ(HANDLE key,
const wchar_t* value_name,
const std::wstring& value);
// Set SZ (string) value.
// - WRAPPER: Function opens and closes the target key for caller, and works
// with SZ data type.
bool SetRegValueSZ(ROOT_KEY root,
const wchar_t* key_path,
const wchar_t* value_name,
const std::wstring& value);
// Set MULTI_SZ (multiple strings) value.
// - WRAPPER: Function works with MULTI_SZ data type.
// - Key handle should have been opened with CreateRegKey or OpenRegKey.
// - Handle will be left open. Caller must still call CloseRegKey when done.
bool SetRegValueMULTISZ(HANDLE key,
const wchar_t* value_name,
const std::vector<std::wstring>& values);
// Set MULTI_SZ (multiple strings) value.
// - WRAPPER: Function opens and closes the target key for caller, and works
// with MULTI_SZ data type.
bool SetRegValueMULTISZ(ROOT_KEY root,
const wchar_t* key_path,
const wchar_t* value_name,
const std::vector<std::wstring>& values);
//------------------------------------------------------------------------------
// Utils
//------------------------------------------------------------------------------
// Returns the current user SID in string form.
const wchar_t* GetCurrentUserSidString();
}; // namespace nt
#endif // CHROME_ELF_NT_REGISTRY_NT_REGISTRY_H_
...@@ -333,18 +333,18 @@ typedef struct _PROCESS_BASIC_INFORMATION { ...@@ -333,18 +333,18 @@ typedef struct _PROCESS_BASIC_INFORMATION {
}; };
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION; } PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
typedef NTSTATUS (WINAPI *NtQueryInformationProcessFunction)( typedef NTSTATUS(WINAPI* NtQueryInformationProcessFunction)(
IN HANDLE ProcessHandle, IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass, IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation, OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength, IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL); OUT PULONG ReturnLength OPTIONAL);
typedef NTSTATUS (WINAPI *NtSetInformationProcessFunction)( typedef NTSTATUS(WINAPI* NtSetInformationProcessFunction)(
HANDLE ProcessHandle, HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass, IN PROCESSINFOCLASS ProcessInformationClass,
IN PVOID ProcessInformation, IN PVOID ProcessInformation,
IN ULONG ProcessInformationLength); IN ULONG ProcessInformationLength);
typedef NTSTATUS (WINAPI *NtOpenThreadTokenFunction) ( typedef NTSTATUS (WINAPI *NtOpenThreadTokenFunction) (
IN HANDLE ThreadHandle, IN HANDLE ThreadHandle,
...@@ -370,21 +370,50 @@ typedef NTSTATUS (WINAPI *NtOpenProcessTokenExFunction) ( ...@@ -370,21 +370,50 @@ typedef NTSTATUS (WINAPI *NtOpenProcessTokenExFunction) (
IN ULONG HandleAttributes, IN ULONG HandleAttributes,
OUT PHANDLE TokenHandle); OUT PHANDLE TokenHandle);
typedef NTSTATUS (WINAPI * RtlCreateUserThreadFunction)( typedef NTSTATUS(WINAPI* NtQueryInformationTokenFunction)(
IN HANDLE Process, IN HANDLE TokenHandle,
IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor, IN TOKEN_INFORMATION_CLASS TokenInformationClass,
IN BOOLEAN CreateSuspended, OUT PVOID TokenInformation,
IN ULONG ZeroBits, IN ULONG TokenInformationLength,
IN SIZE_T MaximumStackSize, OUT PULONG ReturnLength);
IN SIZE_T CommittedStackSize,
IN LPTHREAD_START_ROUTINE StartAddress, typedef NTSTATUS(WINAPI* RtlCreateUserThreadFunction)(
IN PVOID Parameter, IN HANDLE Process,
OUT PHANDLE Thread, IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,
OUT PCLIENT_ID ClientId); IN BOOLEAN CreateSuspended,
IN ULONG ZeroBits,
IN SIZE_T MaximumStackSize,
IN SIZE_T CommittedStackSize,
IN LPTHREAD_START_ROUTINE StartAddress,
IN PVOID Parameter,
OUT PHANDLE Thread,
OUT PCLIENT_ID ClientId);
typedef NTSTATUS(WINAPI* RtlConvertSidToUnicodeStringFunction)(
OUT PUNICODE_STRING UnicodeString,
IN PSID Sid,
IN BOOLEAN AllocateDestinationString);
typedef VOID(WINAPI* RtlFreeUnicodeStringFunction)(
IN OUT PUNICODE_STRING UnicodeString);
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// Registry // Registry
typedef enum _KEY_VALUE_INFORMATION_CLASS {
KeyValueFullInformation = 1
} KEY_VALUE_INFORMATION_CLASS,
*PKEY_VALUE_INFORMATION_CLASS;
typedef struct _KEY_VALUE_FULL_INFORMATION {
ULONG TitleIndex;
ULONG Type;
ULONG DataOffset;
ULONG DataLength;
ULONG NameLength;
WCHAR Name[1];
} KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION;
typedef NTSTATUS (WINAPI *NtCreateKeyFunction)( typedef NTSTATUS (WINAPI *NtCreateKeyFunction)(
OUT PHANDLE KeyHandle, OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess, IN ACCESS_MASK DesiredAccess,
...@@ -408,6 +437,24 @@ typedef NTSTATUS (WINAPI *NtOpenKeyExFunction)( ...@@ -408,6 +437,24 @@ typedef NTSTATUS (WINAPI *NtOpenKeyExFunction)(
typedef NTSTATUS (WINAPI *NtDeleteKeyFunction)( typedef NTSTATUS (WINAPI *NtDeleteKeyFunction)(
IN HANDLE KeyHandle); IN HANDLE KeyHandle);
typedef NTSTATUS(WINAPI* RtlFormatCurrentUserKeyPathFunction)(
OUT PUNICODE_STRING RegistryPath);
typedef NTSTATUS(WINAPI* NtQueryValueKeyFunction)(IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
IN KEY_VALUE_INFORMATION_CLASS
KeyValueInformationClass,
OUT PVOID KeyValueInformation,
IN ULONG Length,
OUT PULONG ResultLength);
typedef NTSTATUS(WINAPI* NtSetValueKeyFunction)(IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
IN ULONG TitleIndex OPTIONAL,
IN ULONG Type,
IN PVOID Data,
IN ULONG DataSize);
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// Memory // Memory
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment