| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome_elf/blacklist/blacklist.h" | 5 #include "chrome_elf/blacklist/blacklist.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "chrome_elf/blacklist/blacklist_interceptions.h" | 10 #include "chrome_elf/blacklist/blacklist_interceptions.h" |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 sizeof(blacklist_state)); | 155 sizeof(blacklist_state)); |
| 156 ::RegCloseKey(*key); | 156 ::RegCloseKey(*key); |
| 157 key = NULL; | 157 key = NULL; |
| 158 } | 158 } |
| 159 } | 159 } |
| 160 | 160 |
| 161 } // namespace | 161 } // namespace |
| 162 | 162 |
| 163 namespace blacklist { | 163 namespace blacklist { |
| 164 | 164 |
| 165 #if defined(_WIN64) |
| 166 // Allocate storage for the pointer to the old NtMapViewOfSectionFunction. |
| 167 #pragma section(".oldntmap",write,read) |
| 168 __declspec(allocate(".oldntmap")) |
| 169 NtMapViewOfSectionFunction g_nt_map_view_of_section_func = NULL; |
| 170 #endif |
| 171 |
| 165 bool LeaveSetupBeacon() { | 172 bool LeaveSetupBeacon() { |
| 166 HKEY key = NULL; | 173 HKEY key = NULL; |
| 167 DWORD disposition = 0; | 174 DWORD disposition = 0; |
| 168 LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER, | 175 LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER, |
| 169 kRegistryBeaconPath, | 176 kRegistryBeaconPath, |
| 170 0, | 177 0, |
| 171 NULL, | 178 NULL, |
| 172 REG_OPTION_NON_VOLATILE, | 179 REG_OPTION_NON_VOLATILE, |
| 173 KEY_QUERY_VALUE | KEY_SET_VALUE, | 180 KEY_QUERY_VALUE | KEY_SET_VALUE, |
| 174 NULL, | 181 NULL, |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 delete[] g_troublesome_dlls[i]; | 293 delete[] g_troublesome_dlls[i]; |
| 287 g_troublesome_dlls[i] = g_troublesome_dlls[blacklist_size - 1]; | 294 g_troublesome_dlls[i] = g_troublesome_dlls[blacklist_size - 1]; |
| 288 g_troublesome_dlls[blacklist_size - 1] = NULL; | 295 g_troublesome_dlls[blacklist_size - 1] = NULL; |
| 289 return true; | 296 return true; |
| 290 } | 297 } |
| 291 } | 298 } |
| 292 return false; | 299 return false; |
| 293 } | 300 } |
| 294 | 301 |
| 295 bool Initialize(bool force) { | 302 bool Initialize(bool force) { |
| 296 #if defined(_WIN64) | |
| 297 // TODO(robertshield): Implement 64-bit support by providing 64-bit | |
| 298 // interceptors. | |
| 299 return false; | |
| 300 #endif | |
| 301 | |
| 302 // Check to see that we found the functions we need in ntdll. | 303 // Check to see that we found the functions we need in ntdll. |
| 303 if (!InitializeInterceptImports()) | 304 if (!InitializeInterceptImports()) |
| 304 return false; | 305 return false; |
| 305 | 306 |
| 306 // Check to see if this is a non-browser process, abort if so. | 307 // Check to see if this is a non-browser process, abort if so. |
| 307 if (IsNonBrowserProcess()) | 308 if (IsNonBrowserProcess()) |
| 308 return false; | 309 return false; |
| 309 | 310 |
| 310 // Check to see if a beacon is present, abort if so. | 311 // Check to see if a beacon is present, abort if so. |
| 311 if (!force && !LeaveSetupBeacon()) | 312 if (!force && !LeaveSetupBeacon()) |
| (...skipping 28 matching lines...) Expand all Loading... |
| 340 kBeaconState, | 341 kBeaconState, |
| 341 0, | 342 0, |
| 342 REG_DWORD, | 343 REG_DWORD, |
| 343 reinterpret_cast<LPBYTE>(&blacklist_state), | 344 reinterpret_cast<LPBYTE>(&blacklist_state), |
| 344 sizeof(blacklist_state)); | 345 sizeof(blacklist_state)); |
| 345 } else { | 346 } else { |
| 346 key = NULL; | 347 key = NULL; |
| 347 } | 348 } |
| 348 | 349 |
| 349 // Create a thunk via the appropriate ServiceResolver instance. | 350 // Create a thunk via the appropriate ServiceResolver instance. |
| 350 sandbox::ServiceResolverThunk* thunk; | 351 sandbox::ServiceResolverThunk* thunk = NULL; |
| 351 #if defined(_WIN64) | 352 #if defined(_WIN64) |
| 352 // TODO(robertshield): Use the appropriate thunk for 64-bit support | 353 // Because Windows 8 and 8.1 have different stubs in 64-bit, |
| 353 // when said support is implemented. | 354 // ServiceResolverThunk can handle all the formats in 64-bit (instead only |
| 355 // handling 1 like it does in 32-bit versions). |
| 356 thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed); |
| 354 #else | 357 #else |
| 355 if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) { | 358 if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) { |
| 356 if (os_info.version() >= VERSION_WIN8) | 359 if (os_info.version() >= VERSION_WIN8) |
| 357 thunk = new sandbox::Wow64W8ResolverThunk(current_process, kRelaxed); | 360 thunk = new sandbox::Wow64W8ResolverThunk(current_process, kRelaxed); |
| 358 else | 361 else |
| 359 thunk = new sandbox::Wow64ResolverThunk(current_process, kRelaxed); | 362 thunk = new sandbox::Wow64ResolverThunk(current_process, kRelaxed); |
| 360 } else if (os_info.version() >= VERSION_WIN8) { | 363 } else if (os_info.version() >= VERSION_WIN8) { |
| 361 thunk = new sandbox::Win8ResolverThunk(current_process, kRelaxed); | 364 thunk = new sandbox::Win8ResolverThunk(current_process, kRelaxed); |
| 362 } else { | 365 } else { |
| 363 thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed); | 366 thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed); |
| 364 } | 367 } |
| 365 #endif | 368 #endif |
| 366 | 369 |
| 367 BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage); | 370 BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage); |
| 368 | 371 |
| 369 // Mark the thunk storage as readable and writeable, since we | 372 // Mark the thunk storage as readable and writeable, since we |
| 370 // ready to write to it. | 373 // ready to write to it. |
| 371 DWORD old_protect = 0; | 374 DWORD old_protect = 0; |
| 372 if (!VirtualProtect(&g_thunk_storage, | 375 if (!VirtualProtect(&g_thunk_storage, |
| 373 sizeof(g_thunk_storage), | 376 sizeof(g_thunk_storage), |
| 374 PAGE_EXECUTE_READWRITE, | 377 PAGE_EXECUTE_READWRITE, |
| 375 &old_protect)) { | 378 &old_protect)) { |
| 376 RecordSuccessfulThunkSetup(&key); | 379 RecordSuccessfulThunkSetup(&key); |
| 377 return false; | 380 return false; |
| 378 } | 381 } |
| 379 | 382 |
| 380 thunk->AllowLocalPatches(); | 383 thunk->AllowLocalPatches(); |
| 381 | 384 |
| 382 // Get ntdll base, target name, interceptor address, | 385 // We declare this early so it can be used in the 64-bit block below and |
| 386 // still work on 32-bit build when referenced at the end of the function. |
| 387 BOOL page_executable = false; |
| 388 |
| 389 // Replace the default NtMapViewOfSection with our patched version. |
| 390 #if defined(_WIN64) |
| 391 NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), |
| 392 reinterpret_cast<void*>(&__ImageBase), |
| 393 "NtMapViewOfSection", |
| 394 NULL, |
| 395 &blacklist::BlNtMapViewOfSection64, |
| 396 thunk_storage, |
| 397 sizeof(sandbox::ThunkData), |
| 398 NULL); |
| 399 |
| 400 // Keep a pointer to the original code, we don't have enough space to |
| 401 // add it directly to the call. |
| 402 g_nt_map_view_of_section_func = reinterpret_cast<NtMapViewOfSectionFunction>( |
| 403 thunk_storage); |
| 404 |
| 405 // Ensure that the pointer to the old function can't be changed. |
| 406 page_executable = VirtualProtect(&g_nt_map_view_of_section_func, |
| 407 sizeof(g_nt_map_view_of_section_func), |
| 408 PAGE_EXECUTE_READ, |
| 409 &old_protect); |
| 410 #else |
| 383 NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), | 411 NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), |
| 384 reinterpret_cast<void*>(&__ImageBase), | 412 reinterpret_cast<void*>(&__ImageBase), |
| 385 "NtMapViewOfSection", | 413 "NtMapViewOfSection", |
| 386 NULL, | 414 NULL, |
| 387 &blacklist::BlNtMapViewOfSection, | 415 &blacklist::BlNtMapViewOfSection, |
| 388 thunk_storage, | 416 thunk_storage, |
| 389 sizeof(sandbox::ThunkData), | 417 sizeof(sandbox::ThunkData), |
| 390 NULL); | 418 NULL); |
| 391 | 419 #endif |
| 392 delete thunk; | 420 delete thunk; |
| 393 | 421 |
| 394 // Mark the thunk storage as executable and prevent any future writes to it. | 422 // Mark the thunk storage as executable and prevent any future writes to it. |
| 395 BOOL page_executable = VirtualProtect(&g_thunk_storage, | 423 page_executable = page_executable && VirtualProtect(&g_thunk_storage, |
| 396 sizeof(g_thunk_storage), | 424 sizeof(g_thunk_storage), |
| 397 PAGE_EXECUTE_READ, | 425 PAGE_EXECUTE_READ, |
| 398 &old_protect); | 426 &old_protect); |
| 399 | 427 |
| 400 RecordSuccessfulThunkSetup(&key); | 428 RecordSuccessfulThunkSetup(&key); |
| 401 | 429 |
| 402 return NT_SUCCESS(ret) && page_executable; | 430 return NT_SUCCESS(ret) && page_executable; |
| 403 } | 431 } |
| 404 | 432 |
| 405 } // namespace blacklist | 433 } // namespace blacklist |
| OLD | NEW |