Chromium Code Reviews| Index: chrome_elf/blacklist/blacklist.cc |
| diff --git a/chrome_elf/blacklist/blacklist.cc b/chrome_elf/blacklist/blacklist.cc |
| index eda611db41eba3a80f35c9f15964aaaa1c6bf47e..74e9bc97df242daff95d95b1352f38bf21da1e4b 100644 |
| --- a/chrome_elf/blacklist/blacklist.cc |
| +++ b/chrome_elf/blacklist/blacklist.cc |
| @@ -266,12 +266,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; |
| @@ -296,10 +290,12 @@ bool Initialize(bool force) { |
| const bool kRelaxed = true; |
| // Create a thunk via the appropriate ServiceResolver instance. |
| - sandbox::ServiceResolverThunk* thunk; |
| + sandbox::ServiceResolverThunk* thunk = NULL; |
| #if defined(_WIN64) |
| - // TODO(robertshield): Use the appropriate thunk for 64-bit support |
| - // when said support is implemented. |
| + // Because Windows 8 and 8.1 have different stubs in 64-bit, |
| + // ServiceResolverThunk can handle all the formata in 64-bit (instead only |
|
rvargas (doing something else)
2014/01/27 19:15:32
nit: formata?
csharp
2014/02/03 16:23:09
Done.
|
| + // handling 1 like it does in 32-bit versions). |
| + thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed); |
| #else |
| if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) { |
| if (os_info.version() >= VERSION_WIN8) |
| @@ -326,23 +322,48 @@ 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 work 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::BlNtMapViewOfSection, |
| + &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, |
|
rvargas (doing something else)
2014/01/27 19:15:32
the return value is never checked.
csharp
2014/02/03 16:23:09
Fixed the code further down to do an AND with this
|
| + 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", |
| + NULL, |
| + &blacklist::BlNtMapViewOfSection, |
| + 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; |
| } |