summaryrefslogtreecommitdiffstats
path: root/chrome_elf
diff options
context:
space:
mode:
Diffstat (limited to 'chrome_elf')
-rw-r--r--chrome_elf/blacklist/blacklist.cc50
-rw-r--r--chrome_elf/blacklist/blacklist.h6
-rw-r--r--chrome_elf/blacklist/blacklist_interceptions.cc59
3 files changed, 111 insertions, 4 deletions
diff --git a/chrome_elf/blacklist/blacklist.cc b/chrome_elf/blacklist/blacklist.cc
index f9eb065..34a498e 100644
--- a/chrome_elf/blacklist/blacklist.cc
+++ b/chrome_elf/blacklist/blacklist.cc
@@ -142,6 +142,22 @@ bool IsNonBrowserProcess() {
return (command_line && wcsstr(command_line, L"--type"));
}
+// Record that the thunk setup completed succesfully and close the registry
+// key handle since it is no longer needed.
+void RecordSuccessfulThunkSetup(HKEY* key) {
+ if (key != NULL) {
+ DWORD blacklist_state = blacklist::BLACKLIST_SETUP_RUNNING;
+ ::RegSetValueEx(*key,
+ blacklist::kBeaconState,
+ 0,
+ REG_DWORD,
+ reinterpret_cast<LPBYTE>(&blacklist_state),
+ sizeof(blacklist_state));
+ ::RegCloseKey(*key);
+ key = NULL;
+ }
+}
+
} // namespace
namespace blacklist {
@@ -238,7 +254,7 @@ bool ResetBeacon() {
int BlacklistSize() {
int size = -1;
- while(blacklist::g_troublesome_dlls[++size] != NULL);
+ while (blacklist::g_troublesome_dlls[++size] != NULL) {}
return size;
}
@@ -248,7 +264,7 @@ bool AddDllToBlacklist(const wchar_t* dll_name) {
// We need to leave one space at the end for the null pointer.
if (blacklist_size + 1 >= kTroublesomeDllsMaxCount)
return false;
- for (int i=0; i < blacklist_size; ++i) {
+ for (int i = 0; i < blacklist_size; ++i) {
if (!_wcsicmp(g_troublesome_dlls[i], dll_name))
return true;
}
@@ -306,6 +322,30 @@ bool Initialize(bool force) {
// Tells the resolver to patch already patched functions.
const bool kRelaxed = true;
+ // Record that we are starting the thunk setup code.
+ HKEY key = NULL;
+ DWORD disposition = 0;
+ LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER,
+ kRegistryBeaconPath,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_QUERY_VALUE | KEY_SET_VALUE,
+ NULL,
+ &key,
+ &disposition);
+ if (result == ERROR_SUCCESS) {
+ DWORD blacklist_state = BLACKLIST_THUNK_SETUP;
+ ::RegSetValueEx(key,
+ kBeaconState,
+ 0,
+ REG_DWORD,
+ reinterpret_cast<LPBYTE>(&blacklist_state),
+ sizeof(blacklist_state));
+ } else {
+ key = NULL;
+ }
+
// Create a thunk via the appropriate ServiceResolver instance.
sandbox::ServiceResolverThunk* thunk;
#if defined(_WIN64)
@@ -332,8 +372,10 @@ bool Initialize(bool force) {
if (!VirtualProtect(&g_thunk_storage,
sizeof(g_thunk_storage),
PAGE_EXECUTE_READWRITE,
- &old_protect))
+ &old_protect)) {
+ RecordSuccessfulThunkSetup(&key);
return false;
+ }
thunk->AllowLocalPatches();
@@ -355,6 +397,8 @@ bool Initialize(bool force) {
PAGE_EXECUTE_READ,
&old_protect);
+ RecordSuccessfulThunkSetup(&key);
+
return NT_SUCCESS(ret) && page_executable;
}
diff --git a/chrome_elf/blacklist/blacklist.h b/chrome_elf/blacklist/blacklist.h
index 17a511d..7e01354 100644
--- a/chrome_elf/blacklist/blacklist.h
+++ b/chrome_elf/blacklist/blacklist.h
@@ -27,6 +27,12 @@ enum BlacklistState {
// The blacklist setup code is running. If this is still set at startup,
// it means the last setup crashed.
BLACKLIST_SETUP_RUNNING,
+ // The blacklist thunk setup code is running. If this is still set at startup,
+ // it means the last setup crashed during thunk setup.
+ BLACKLIST_THUNK_SETUP,
+ // The blacklist code is currently intercepting MapViewOfSection. If this is
+ // still set at startup, it means we crashed during interception.
+ BLACKLIST_INTERCEPTING,
// Always keep this at the end.
BLACKLIST_STATE_MAX,
};
diff --git a/chrome_elf/blacklist/blacklist_interceptions.cc b/chrome_elf/blacklist/blacklist_interceptions.cc
index 6b01438..2be44e1 100644
--- a/chrome_elf/blacklist/blacklist_interceptions.cc
+++ b/chrome_elf/blacklist/blacklist_interceptions.cc
@@ -166,6 +166,21 @@ bool IsSameAsCurrentProcess(HANDLE process) {
(::GetProcessId(process) == ::GetCurrentProcessId());
}
+// Record that the interception completed succesfully and close the registry
+// key handle since it is no longer needed.
+void RecordSuccessfulInterception(HKEY* key, DWORD old_state) {
+ if (key != NULL) {
+ ::RegSetValueEx(*key,
+ blacklist::kBeaconState,
+ 0,
+ REG_DWORD,
+ reinterpret_cast<LPBYTE>(&old_state),
+ sizeof(old_state));
+ ::RegCloseKey(*key);
+ key = NULL;
+ }
+}
+
} // namespace
namespace blacklist {
@@ -196,12 +211,53 @@ SANDBOX_INTERCEPT NTSTATUS WINAPI BlNtMapViewOfSection(
SECTION_INHERIT inherit,
ULONG allocation_type,
ULONG protect) {
+ // Record that we are starting an interception.
+ HKEY key = NULL;
+ DWORD disposition = 0;
+ LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER,
+ kRegistryBeaconPath,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_QUERY_VALUE | KEY_SET_VALUE,
+ NULL,
+ &key,
+ &disposition);
+
+ DWORD old_blacklist_state = BLACKLIST_DISABLED;
+ if (result == ERROR_SUCCESS) {
+ DWORD old_blacklist_state_size = sizeof(old_blacklist_state);
+ DWORD type = 0;
+ result = ::RegQueryValueEx(key,
+ kBeaconState,
+ 0,
+ &type,
+ reinterpret_cast<LPBYTE>(&old_blacklist_state),
+ &old_blacklist_state_size);
+
+ if (result != ERROR_SUCCESS) {
+ old_blacklist_state = BLACKLIST_ENABLED;
+ }
+
+ DWORD blacklist_state = BLACKLIST_INTERCEPTING;
+ ::RegSetValueEx(key,
+ kBeaconState,
+ 0,
+ REG_DWORD,
+ reinterpret_cast<LPBYTE>(&blacklist_state),
+ sizeof(blacklist_state));
+ } else {
+ key = NULL;
+ }
+
+
NTSTATUS ret = orig_MapViewOfSection(section, process, base, zero_bits,
commit_size, offset, view_size, inherit,
allocation_type, protect);
if (!NT_SUCCESS(ret) || !IsSameAsCurrentProcess(process) ||
!IsModuleValidImageSection(section, base, offset, view_size)) {
+ RecordSuccessfulInterception(&key, old_blacklist_state);
return ret;
}
@@ -224,8 +280,9 @@ SANDBOX_INTERCEPT NTSTATUS WINAPI BlNtMapViewOfSection(
g_nt_unmap_view_of_section_func(process, *base);
ret = STATUS_UNSUCCESSFUL;
}
-
}
+
+ RecordSuccessfulInterception(&key, old_blacklist_state);
return ret;
}