Chromium Code Reviews| 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 |