|
130 | 130 | #include "sanitizer_common/sanitizer_platform.h"
|
131 | 131 | #define WIN32_LEAN_AND_MEAN
|
132 | 132 | #include <windows.h>
|
| 133 | +#include <psapi.h> |
133 | 134 |
|
134 | 135 | namespace __interception {
|
135 | 136 |
|
@@ -385,7 +386,30 @@ void TestOnlyReleaseTrampolineRegions() {
|
385 | 386 | }
|
386 | 387 | }
|
387 | 388 |
|
388 |
| -static uptr AllocateMemoryForTrampoline(uptr image_address, size_t size) { |
| 389 | +static uptr AllocateMemoryForTrampoline(uptr func_address, size_t size) { |
| 390 | + uptr image_address = func_address; |
| 391 | + |
| 392 | +#if SANITIZER_WINDOWS64 |
| 393 | + // Allocate memory after the module (DLL or EXE file), but within 2GB |
| 394 | + // of the start of the module so that any address within the module can be |
| 395 | + // referenced with PC-relative operands. |
| 396 | + // This allows us to not just jump to the trampoline with a PC-relative |
| 397 | + // offset, but to relocate any instructions that we copy to the trampoline |
| 398 | + // which have references to the original module. If we can't find the base |
| 399 | + // address of the module (e.g. if func_address is in mmap'ed memory), just |
| 400 | + // use func_address as is. |
| 401 | + HMODULE module; |
| 402 | + if (::GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | |
| 403 | + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, |
| 404 | + (LPCWSTR)func_address, &module)) { |
| 405 | + MODULEINFO module_info; |
| 406 | + if (::GetModuleInformation(::GetCurrentProcess(), module, |
| 407 | + &module_info, sizeof(module_info))) { |
| 408 | + image_address = (uptr)module_info.lpBaseOfDll; |
| 409 | + } |
| 410 | + } |
| 411 | +#endif |
| 412 | + |
389 | 413 | // Find a region within 2G with enough space to allocate |size| bytes.
|
390 | 414 | TrampolineMemoryRegion *region = nullptr;
|
391 | 415 | for (size_t bucket = 0; bucket < kMaxTrampolineRegion; ++bucket) {
|
|
0 commit comments