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 |