| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // For information about interceptions as a whole see | 5 // For information about interceptions as a whole see |
| 6 // http://dev.chromium.org/developers/design-documents/sandbox . | 6 // http://dev.chromium.org/developers/design-documents/sandbox . |
| 7 | 7 |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "sandbox/src/interception.h" | 10 #include "sandbox/src/interception.h" |
| 11 | 11 |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
| 14 #include "base/win/pe_image.h" | 14 #include "base/win/pe_image.h" |
| 15 #include "base/win/windows_version.h" | 15 #include "base/win/windows_version.h" |
| 16 #include "sandbox/src/interception_internal.h" | 16 #include "sandbox/src/interception_internal.h" |
| 17 #include "sandbox/src/interceptors.h" | 17 #include "sandbox/src/interceptors.h" |
| 18 #include "sandbox/src/sandbox.h" | 18 #include "sandbox/src/sandbox.h" |
| 19 #include "sandbox/src/sandbox_utils.h" | 19 #include "sandbox/src/sandbox_utils.h" |
| 20 #include "sandbox/src/service_resolver.h" | 20 #include "sandbox/src/service_resolver.h" |
| 21 #include "sandbox/src/target_interceptions.h" | 21 #include "sandbox/src/target_interceptions.h" |
| 22 #include "sandbox/src/target_process.h" | 22 #include "sandbox/src/target_process.h" |
| 23 #include "sandbox/src/wow64.h" | 23 #include "sandbox/src/wow64.h" |
| 24 | 24 |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 const char kMapViewOfSectionName[] = "NtMapViewOfSection"; | 27 const char kMapViewOfSectionName[] = "NtMapViewOfSection"; |
| 28 const char kUnmapViewOfSectionName[] = "NtUnmapViewOfSection"; | 28 const char kUnmapViewOfSectionName[] = "NtUnmapViewOfSection"; |
| 29 | 29 |
| 30 // Standard allocation granularity and page size for Windows. |
| 31 const size_t kAllocGranularity = 65536; |
| 32 const size_t kPageSize = 4096; |
| 33 |
| 34 // Find a random offset within 64k and aligned to ceil(log2(size)). |
| 35 size_t GetGranularAlignedRandomOffset(size_t size) { |
| 36 CHECK_LE(size, kAllocGranularity); |
| 37 unsigned int offset; |
| 38 |
| 39 do { |
| 40 rand_s(&offset); |
| 41 offset &= (kAllocGranularity - 1); |
| 42 } while (offset > (kAllocGranularity - size)); |
| 43 |
| 44 // Find an alignment between 64 and the page size (4096). |
| 45 size_t align_size = kPageSize; |
| 46 for (size_t new_size = align_size / 2; new_size >= size; new_size /= 2) { |
| 47 align_size = new_size; |
| 48 } |
| 49 return offset & ~(align_size - 1); |
| 50 } |
| 51 |
| 30 } // namespace | 52 } // namespace |
| 31 | 53 |
| 32 namespace sandbox { | 54 namespace sandbox { |
| 33 | 55 |
| 34 SANDBOX_INTERCEPT SharedMemory* g_interceptions; | 56 SANDBOX_INTERCEPT SharedMemory* g_interceptions; |
| 35 | 57 |
| 36 // Table of the unpatched functions that we intercept. Mapped from the parent. | 58 // Table of the unpatched functions that we intercept. Mapped from the parent. |
| 37 SANDBOX_INTERCEPT OriginalFunctions g_originals = { NULL }; | 59 SANDBOX_INTERCEPT OriginalFunctions g_originals = { NULL }; |
| 38 | 60 |
| 39 // Magic constant that identifies that this function is not to be patched. | 61 // Magic constant that identifies that this function is not to be patched. |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 #pragma comment(linker, "/include:TargetNtUnmapViewOfSection64") | 375 #pragma comment(linker, "/include:TargetNtUnmapViewOfSection64") |
| 354 #else | 376 #else |
| 355 #pragma comment(linker, "/include:_TargetNtMapViewOfSection@44") | 377 #pragma comment(linker, "/include:_TargetNtMapViewOfSection@44") |
| 356 #pragma comment(linker, "/include:_TargetNtUnmapViewOfSection@12") | 378 #pragma comment(linker, "/include:_TargetNtUnmapViewOfSection@12") |
| 357 #endif | 379 #endif |
| 358 #endif | 380 #endif |
| 359 ADD_NT_INTERCEPTION(NtMapViewOfSection, MAP_VIEW_OF_SECTION_ID, 44); | 381 ADD_NT_INTERCEPTION(NtMapViewOfSection, MAP_VIEW_OF_SECTION_ID, 44); |
| 360 ADD_NT_INTERCEPTION(NtUnmapViewOfSection, UNMAP_VIEW_OF_SECTION_ID, 12); | 382 ADD_NT_INTERCEPTION(NtUnmapViewOfSection, UNMAP_VIEW_OF_SECTION_ID, 12); |
| 361 } | 383 } |
| 362 | 384 |
| 385 // Reserve a full 64k memory range in the child process. |
| 386 HANDLE child = child_->Process(); |
| 387 BYTE* thunk_base = reinterpret_cast<BYTE*>( |
| 388 ::VirtualAllocEx(child, NULL, kAllocGranularity, |
| 389 MEM_RESERVE, PAGE_NOACCESS)); |
| 390 |
| 391 // Find an aligned, random location within the reserved range. |
| 363 size_t thunk_bytes = interceptions_.size() * sizeof(ThunkData) + | 392 size_t thunk_bytes = interceptions_.size() * sizeof(ThunkData) + |
| 364 sizeof(DllInterceptionData); | 393 sizeof(DllInterceptionData); |
| 394 size_t thunk_offset = GetGranularAlignedRandomOffset(thunk_bytes); |
| 365 | 395 |
| 366 // Allocate memory on the child, without specifying the desired address | 396 // Split the base and offset along page boundaries. |
| 367 HANDLE child = child_->Process(); | 397 thunk_base += thunk_offset & ~(kPageSize - 1); |
| 398 thunk_offset &= kPageSize - 1; |
| 399 |
| 400 // Make an aligned, padded allocation, and move the pointer to our chunk. |
| 401 size_t thunk_bytes_padded = (thunk_bytes + kPageSize - 1) & kPageSize; |
| 402 thunk_base = reinterpret_cast<BYTE*>( |
| 403 ::VirtualAllocEx(child, thunk_base, thunk_bytes_padded, |
| 404 MEM_COMMIT, PAGE_EXECUTE_READWRITE)); |
| 405 CHECK(thunk_base); // If this fails we'd crash anyway on an invalid access. |
| 368 DllInterceptionData* thunks = reinterpret_cast<DllInterceptionData*>( | 406 DllInterceptionData* thunks = reinterpret_cast<DllInterceptionData*>( |
| 369 ::VirtualAllocEx(child, NULL, thunk_bytes, | 407 thunk_base + thunk_offset); |
| 370 MEM_COMMIT, | |
| 371 PAGE_EXECUTE_READWRITE)); | |
| 372 | 408 |
| 373 DllInterceptionData dll_data; | 409 DllInterceptionData dll_data; |
| 374 dll_data.data_bytes = thunk_bytes; | 410 dll_data.data_bytes = thunk_bytes; |
| 375 dll_data.num_thunks = 0; | 411 dll_data.num_thunks = 0; |
| 376 dll_data.used_bytes = offsetof(DllInterceptionData, thunks); | 412 dll_data.used_bytes = offsetof(DllInterceptionData, thunks); |
| 377 | 413 |
| 378 // Reset all helpers for a new child. | 414 // Reset all helpers for a new child. |
| 379 memset(g_originals, 0, sizeof(g_originals)); | 415 memset(g_originals, 0, sizeof(g_originals)); |
| 380 | 416 |
| 381 // this should write all the individual thunks to the child's memory | 417 // this should write all the individual thunks to the child's memory |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 ::FreeLibrary(local_interceptor); | 542 ::FreeLibrary(local_interceptor); |
| 507 #endif | 543 #endif |
| 508 | 544 |
| 509 if (it != interceptions_.end()) | 545 if (it != interceptions_.end()) |
| 510 return false; | 546 return false; |
| 511 | 547 |
| 512 return true; | 548 return true; |
| 513 } | 549 } |
| 514 | 550 |
| 515 } // namespace sandbox | 551 } // namespace sandbox |
| OLD | NEW |