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 #include "sandbox/win/src/sandbox_nt_util.h" | 5 #include "sandbox/win/src/sandbox_nt_util.h" |
6 | 6 |
7 #include "base/win/pe_image.h" | 7 #include "base/win/pe_image.h" |
8 #include "sandbox/win/src/sandbox_factory.h" | 8 #include "sandbox/win/src/sandbox_factory.h" |
9 #include "sandbox/win/src/target_services.h" | 9 #include "sandbox/win/src/target_services.h" |
10 | 10 |
11 namespace sandbox { | 11 namespace sandbox { |
12 | 12 |
13 // This is the list of all imported symbols from ntdll.dll. | 13 // This is the list of all imported symbols from ntdll.dll. |
14 SANDBOX_INTERCEPT NtExports g_nt = { NULL }; | 14 SANDBOX_INTERCEPT NtExports g_nt = { NULL }; |
15 | 15 |
16 } // namespace | 16 } // namespace sandbox |
17 | 17 |
18 namespace { | 18 namespace { |
19 | 19 |
20 #if defined(_WIN64) | 20 #if defined(_WIN64) |
21 void* AllocateNearTo(void* source, size_t size) { | 21 void* AllocateNearTo(void* source, size_t size) { |
22 using sandbox::g_nt; | 22 using sandbox::g_nt; |
23 | 23 |
24 // Start with 1 GB above the source. | 24 // Start with 1 GB above the source. |
25 const unsigned int kOneGB = 0x40000000; | 25 const size_t kOneGB = 0x40000000; |
26 void* base = reinterpret_cast<char*>(source) + kOneGB; | 26 void* base = reinterpret_cast<char*>(source) + kOneGB; |
27 SIZE_T actual_size = size; | 27 SIZE_T actual_size = size; |
28 ULONG_PTR zero_bits = 0; // Not the correct type if used. | 28 ULONG_PTR zero_bits = 0; // Not the correct type if used. |
29 ULONG type = MEM_RESERVE; | 29 ULONG type = MEM_RESERVE; |
30 | 30 |
31 if (reinterpret_cast<SIZE_T>(source) > 0x7ff80000000) { | |
32 // We are at the top of the address space. Let's try the highest available | |
33 // address. | |
34 base = NULL; | |
35 type |= MEM_TOP_DOWN; | |
36 } | |
37 | |
38 NTSTATUS ret; | 31 NTSTATUS ret; |
39 int attempts = 0; | 32 int attempts = 0; |
40 for (; attempts < 20; attempts++) { | 33 for (; attempts < 41; attempts++) { |
cpu_(ooo_6.6-7.5)
2013/09/20 02:40:39
I thought the answer was 42 :p
rvargas (doing something else)
2013/09/20 02:42:24
Better not risk melting down the computer
| |
41 ret = g_nt.AllocateVirtualMemory(NtCurrentProcess, &base, zero_bits, | 34 ret = g_nt.AllocateVirtualMemory(NtCurrentProcess, &base, zero_bits, |
42 &actual_size, type, PAGE_READWRITE); | 35 &actual_size, type, PAGE_READWRITE); |
43 if (NT_SUCCESS(ret)) { | 36 if (NT_SUCCESS(ret)) { |
44 if (base < source) { | 37 if (base < source || |
38 base >= reinterpret_cast<char*>(source) + 4 * kOneGB) { | |
45 // We won't be able to patch this dll. | 39 // We won't be able to patch this dll. |
46 VERIFY_SUCCESS(g_nt.FreeVirtualMemory(NtCurrentProcess, &base, &size, | 40 VERIFY_SUCCESS(g_nt.FreeVirtualMemory(NtCurrentProcess, &base, &size, |
47 MEM_RELEASE)); | 41 MEM_RELEASE)); |
48 return NULL; | 42 return NULL; |
49 } | 43 } |
50 break; | 44 break; |
51 } | 45 } |
52 | 46 |
47 if (attempts == 30) { | |
48 // Try the first GB. | |
49 base = reinterpret_cast<char*>(source); | |
50 } else if (attempts == 40) { | |
51 // Try the highest available address. | |
52 base = NULL; | |
53 type |= MEM_TOP_DOWN; | |
54 } | |
55 | |
53 // Try 100 MB higher. | 56 // Try 100 MB higher. |
54 base = reinterpret_cast<char*>(base) + 100 * 0x100000; | 57 base = reinterpret_cast<char*>(base) + 100 * 0x100000; |
55 }; | 58 }; |
56 | 59 |
57 if (attempts == 20) | 60 if (attempts == 41) |
58 return NULL; | 61 return NULL; |
59 | 62 |
60 ret = g_nt.AllocateVirtualMemory(NtCurrentProcess, &base, zero_bits, | 63 ret = g_nt.AllocateVirtualMemory(NtCurrentProcess, &base, zero_bits, |
61 &actual_size, MEM_COMMIT, PAGE_READWRITE); | 64 &actual_size, MEM_COMMIT, PAGE_READWRITE); |
62 | 65 |
63 if (!NT_SUCCESS(ret)) { | 66 if (!NT_SUCCESS(ret)) { |
64 VERIFY_SUCCESS(g_nt.FreeVirtualMemory(NtCurrentProcess, &base, &size, | 67 VERIFY_SUCCESS(g_nt.FreeVirtualMemory(NtCurrentProcess, &base, &size, |
65 MEM_RELEASE)); | 68 MEM_RELEASE)); |
66 base = NULL; | 69 base = NULL; |
67 } | 70 } |
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
590 UNREFERENCED_PARAMETER(type); | 593 UNREFERENCED_PARAMETER(type); |
591 return buffer; | 594 return buffer; |
592 } | 595 } |
593 | 596 |
594 void __cdecl operator delete(void* memory, void* buffer, | 597 void __cdecl operator delete(void* memory, void* buffer, |
595 sandbox::AllocationType type) { | 598 sandbox::AllocationType type) { |
596 UNREFERENCED_PARAMETER(memory); | 599 UNREFERENCED_PARAMETER(memory); |
597 UNREFERENCED_PARAMETER(buffer); | 600 UNREFERENCED_PARAMETER(buffer); |
598 UNREFERENCED_PARAMETER(type); | 601 UNREFERENCED_PARAMETER(type); |
599 } | 602 } |
OLD | NEW |