Index: chrome_elf/blacklist/blacklist.cc |
diff --git a/chrome_elf/blacklist/blacklist.cc b/chrome_elf/blacklist/blacklist.cc |
index c7d1a5d77d16857dff3c874dc103c5b68c1ddad7..9fd6bf0a812b20862b4d51f047f12f4114164388 100644 |
--- a/chrome_elf/blacklist/blacklist.cc |
+++ b/chrome_elf/blacklist/blacklist.cc |
@@ -197,12 +197,6 @@ bool RemoveDllFromBlacklist(const wchar_t* dll_name) { |
} |
bool Initialize(bool force) { |
-#if defined(_WIN64) |
- // TODO(robertshield): Implement 64-bit support by providing 64-bit |
- // interceptors. |
- return false; |
-#endif |
- |
// Check to see that we found the functions we need in ntdll. |
if (!InitializeInterceptImports()) |
return false; |
@@ -227,23 +221,24 @@ bool Initialize(bool force) { |
const bool kRelaxed = true; |
// Create a thunk via the appropriate ServiceResolver instance. |
- sandbox::ServiceResolverThunk* thunk; |
-#if defined(_WIN64) |
- // TODO(robertshield): Use the appropriate thunk for 64-bit support |
- // when said support is implemented. |
-#else |
+ sandbox::ServiceResolverThunk* thunk = NULL; |
+#if !defined(_WIN64) |
if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) { |
if (os_info.version() >= VERSION_WIN8) |
thunk = new sandbox::Wow64W8ResolverThunk(current_process, kRelaxed); |
else |
thunk = new sandbox::Wow64ResolverThunk(current_process, kRelaxed); |
- } else if (os_info.version() >= VERSION_WIN8) { |
- thunk = new sandbox::Win8ResolverThunk(current_process, kRelaxed); |
- } else { |
- thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed); |
} |
#endif |
+ if (!thunk) { |
+ if (os_info.version() >= VERSION_WIN8) { |
+ thunk = new sandbox::Win8ResolverThunk(current_process, kRelaxed); |
+ } else { |
+ thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed); |
+ } |
+ } |
+ |
BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage); |
// Mark the thunk storage as readable and writeable, since we |
@@ -257,7 +252,32 @@ bool Initialize(bool force) { |
thunk->AllowLocalPatches(); |
- // Get ntdll base, target name, interceptor address, |
+ // We declare this early so it can be used in the 64-bit block below and |
+ // still works on 32-bit build when referenced at the end of the function. |
+ BOOL page_executable; |
+ |
+ // Replace the default NtMapViewOfSection with our patched version. |
+#if defined(_WIN64) |
+ NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), |
+ reinterpret_cast<void*>(&__ImageBase), |
+ "NtMapViewOfSection", |
+ NULL, |
+ &blacklist::BlNtMapViewOfSection64, |
+ thunk_storage, |
+ sizeof(sandbox::ThunkData), |
+ NULL); |
+ |
+ // Keep a pointer to the original code, we don't have enough space to |
+ // add it directly to the call. |
+ g_nt_map_view_of_section_func = reinterpret_cast<NtMapViewOfSectionFunction>( |
+ thunk_storage); |
+ |
+ // Ensure that the pointer to the old function can't be changed. |
+ page_executable = VirtualProtect(&g_nt_map_view_of_section_func, |
+ sizeof(g_nt_map_view_of_section_func), |
+ PAGE_EXECUTE_READ, |
+ &old_protect); |
+#else |
NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), |
reinterpret_cast<void*>(&__ImageBase), |
"NtMapViewOfSection", |
@@ -266,14 +286,14 @@ bool Initialize(bool force) { |
thunk_storage, |
sizeof(sandbox::ThunkData), |
NULL); |
- |
+#endif |
delete thunk; |
// Mark the thunk storage as executable and prevent any future writes to it. |
- BOOL page_executable = VirtualProtect(&g_thunk_storage, |
- sizeof(g_thunk_storage), |
- PAGE_EXECUTE_READ, |
- &old_protect); |
+ page_executable = VirtualProtect(&g_thunk_storage, |
+ sizeof(g_thunk_storage), |
+ PAGE_EXECUTE_READ, |
+ &old_protect); |
return NT_SUCCESS(ret) && page_executable; |
} |