Chromium Code Reviews| 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 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 269 delete[] g_troublesome_dlls[i]; | 269 delete[] g_troublesome_dlls[i]; |
| 270 g_troublesome_dlls[i] = g_troublesome_dlls[blacklist_size - 1]; | 270 g_troublesome_dlls[i] = g_troublesome_dlls[blacklist_size - 1]; |
| 271 g_troublesome_dlls[blacklist_size - 1] = NULL; | 271 g_troublesome_dlls[blacklist_size - 1] = NULL; |
| 272 return true; | 272 return true; |
| 273 } | 273 } |
| 274 } | 274 } |
| 275 return false; | 275 return false; |
| 276 } | 276 } |
| 277 | 277 |
| 278 bool Initialize(bool force) { | 278 bool Initialize(bool force) { |
| 279 #if defined(_WIN64) | |
| 280 // TODO(robertshield): Implement 64-bit support by providing 64-bit | |
| 281 // interceptors. | |
| 282 return false; | |
| 283 #endif | |
| 284 | |
| 285 // Check to see that we found the functions we need in ntdll. | 279 // Check to see that we found the functions we need in ntdll. |
| 286 if (!InitializeInterceptImports()) | 280 if (!InitializeInterceptImports()) |
| 287 return false; | 281 return false; |
| 288 | 282 |
| 289 // Check to see if this is a non-browser process, abort if so. | 283 // Check to see if this is a non-browser process, abort if so. |
| 290 if (IsNonBrowserProcess()) | 284 if (IsNonBrowserProcess()) |
| 291 return false; | 285 return false; |
| 292 | 286 |
| 293 // Check to see if a beacon is present, abort if so. | 287 // Check to see if a beacon is present, abort if so. |
| 294 if (!force && !LeaveSetupBeacon()) | 288 if (!force && !LeaveSetupBeacon()) |
| 295 return false; | 289 return false; |
| 296 | 290 |
| 297 // Don't try blacklisting on unsupported OS versions. | 291 // Don't try blacklisting on unsupported OS versions. |
| 298 OSInfo os_info; | 292 OSInfo os_info; |
| 299 if (os_info.version() <= VERSION_PRE_XP_SP2) | 293 if (os_info.version() <= VERSION_PRE_XP_SP2) |
| 300 return false; | 294 return false; |
| 301 | 295 |
| 302 // Pseudo-handle, no need to close. | 296 // Pseudo-handle, no need to close. |
| 303 HANDLE current_process = ::GetCurrentProcess(); | 297 HANDLE current_process = ::GetCurrentProcess(); |
| 304 | 298 |
| 305 // Tells the resolver to patch already patched functions. | 299 // Tells the resolver to patch already patched functions. |
| 306 const bool kRelaxed = true; | 300 const bool kRelaxed = true; |
| 307 | 301 |
| 308 // Create a thunk via the appropriate ServiceResolver instance. | 302 // Create a thunk via the appropriate ServiceResolver instance. |
| 309 sandbox::ServiceResolverThunk* thunk; | 303 sandbox::ServiceResolverThunk* thunk = NULL; |
| 310 #if defined(_WIN64) | 304 #if defined(_WIN64) |
| 311 // TODO(robertshield): Use the appropriate thunk for 64-bit support | 305 // Because Windows 8 and 8.1 have different stubs in 64-bit, |
| 312 // when said support is implemented. | 306 // ServiceResolverThunk can handle all the formats in 64-bit (instead only |
| 307 // handling 1 like it does in 32-bit versions). | |
| 308 thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed); | |
| 313 #else | 309 #else |
| 314 if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) { | 310 if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) { |
| 315 if (os_info.version() >= VERSION_WIN8) | 311 if (os_info.version() >= VERSION_WIN8) |
| 316 thunk = new sandbox::Wow64W8ResolverThunk(current_process, kRelaxed); | 312 thunk = new sandbox::Wow64W8ResolverThunk(current_process, kRelaxed); |
| 317 else | 313 else |
| 318 thunk = new sandbox::Wow64ResolverThunk(current_process, kRelaxed); | 314 thunk = new sandbox::Wow64ResolverThunk(current_process, kRelaxed); |
| 319 } else if (os_info.version() >= VERSION_WIN8) { | 315 } else if (os_info.version() >= VERSION_WIN8) { |
| 320 thunk = new sandbox::Win8ResolverThunk(current_process, kRelaxed); | 316 thunk = new sandbox::Win8ResolverThunk(current_process, kRelaxed); |
| 321 } else { | 317 } else { |
| 322 thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed); | 318 thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed); |
| 323 } | 319 } |
| 324 #endif | 320 #endif |
| 325 | 321 |
| 326 BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage); | 322 BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage); |
| 327 | 323 |
| 328 // Mark the thunk storage as readable and writeable, since we | 324 // Mark the thunk storage as readable and writeable, since we |
| 329 // ready to write to it. | 325 // ready to write to it. |
| 330 DWORD old_protect = 0; | 326 DWORD old_protect = 0; |
| 331 if (!VirtualProtect(&g_thunk_storage, | 327 if (!VirtualProtect(&g_thunk_storage, |
| 332 sizeof(g_thunk_storage), | 328 sizeof(g_thunk_storage), |
| 333 PAGE_EXECUTE_READWRITE, | 329 PAGE_EXECUTE_READWRITE, |
| 334 &old_protect)) | 330 &old_protect)) |
| 335 return false; | 331 return false; |
| 336 | 332 |
| 337 thunk->AllowLocalPatches(); | 333 thunk->AllowLocalPatches(); |
| 338 | 334 |
| 339 // Get ntdll base, target name, interceptor address, | 335 // We declare this early so it can be used in the 64-bit block below and |
| 336 // still work on 32-bit build when referenced at the end of the function. | |
| 337 BOOL page_executable; | |
|
robertshield
2014/02/06 20:04:33
initialize to FALSE.
csharp
2014/02/06 22:29:24
Done.
| |
| 338 | |
| 339 // Replace the default NtMapViewOfSection with our patched version. | |
| 340 #if defined(_WIN64) | |
| 341 NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), | |
| 342 reinterpret_cast<void*>(&__ImageBase), | |
| 343 "NtMapViewOfSection", | |
| 344 NULL, | |
| 345 &blacklist::BlNtMapViewOfSection64, | |
| 346 thunk_storage, | |
| 347 sizeof(sandbox::ThunkData), | |
| 348 NULL); | |
| 349 | |
| 350 // Keep a pointer to the original code, we don't have enough space to | |
| 351 // add it directly to the call. | |
| 352 g_nt_map_view_of_section_func = reinterpret_cast<NtMapViewOfSectionFunction>( | |
| 353 thunk_storage); | |
| 354 | |
| 355 // Ensure that the pointer to the old function can't be changed. | |
| 356 page_executable = VirtualProtect(&g_nt_map_view_of_section_func, | |
| 357 sizeof(g_nt_map_view_of_section_func), | |
| 358 PAGE_EXECUTE_READ, | |
| 359 &old_protect); | |
| 360 #else | |
| 340 NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), | 361 NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), |
| 341 reinterpret_cast<void*>(&__ImageBase), | 362 reinterpret_cast<void*>(&__ImageBase), |
| 342 "NtMapViewOfSection", | 363 "NtMapViewOfSection", |
| 343 NULL, | 364 NULL, |
| 344 &blacklist::BlNtMapViewOfSection, | 365 &blacklist::BlNtMapViewOfSection, |
| 345 thunk_storage, | 366 thunk_storage, |
| 346 sizeof(sandbox::ThunkData), | 367 sizeof(sandbox::ThunkData), |
| 347 NULL); | 368 NULL); |
| 348 | 369 #endif |
| 349 delete thunk; | 370 delete thunk; |
| 350 | 371 |
| 351 // Mark the thunk storage as executable and prevent any future writes to it. | 372 // Mark the thunk storage as executable and prevent any future writes to it. |
| 352 BOOL page_executable = VirtualProtect(&g_thunk_storage, | 373 page_executable &= VirtualProtect(&g_thunk_storage, |
|
robertshield
2014/02/06 20:04:33
This might be clearer: page_executable = page_exec
csharp
2014/02/06 22:29:24
Done.
| |
| 353 sizeof(g_thunk_storage), | 374 sizeof(g_thunk_storage), |
| 354 PAGE_EXECUTE_READ, | 375 PAGE_EXECUTE_READ, |
| 355 &old_protect); | 376 &old_protect); |
| 356 | 377 |
| 357 return NT_SUCCESS(ret) && page_executable; | 378 return NT_SUCCESS(ret) && page_executable; |
| 358 } | 379 } |
| 359 | 380 |
| 360 } // namespace blacklist | 381 } // namespace blacklist |
| OLD | NEW |