Skip to content

Latest commit

 

History

History
56 lines (40 loc) · 4.54 KB

File metadata and controls

56 lines (40 loc) · 4.54 KB
English (en-US) 简体中文 (zh-CN)

Avoid Occupying System Reserved Region When Allocating Trampoline

Windows reserved region for system DLLs

Windows introduced ASLR since NT6, a region has been reserved for system DLLs, so that the same system DLL can be mapped at the same location in the reserved region inside different processes, the relocation information can be reused after being loaded once to avoid the relocation operation again on subsequent loading.

This mechanism is introduced in detail in the "Image randomization" section of Chapter 5 "Memory management" in "Windows Internals 7th Part 1", here will not go into details, but the exact reserved region that I have obtained by referring to the book and analyzing is given:
32-bit process:[0x50000000 ... 0x78000000], a total of 640MB
64-bit process:[0x00007FF7FFFF0000 ... 0x00007FFFFFFF0000], a total of 32GB

Hooking libraries usually preferred to find available memory space near the hook target function when allocating trampoline, so it's very prone to occupy this reserved region when hooking system APIs, causing the system DLL that should be loaded to that location to be loaded to another place and perform additional relocation operations.

Other hooking libraries' practices

Detours as Microsoft's official hooking library, has taken into account that the system reserved region cannot be used for trampolines, but it hardcodes the [0x70000000 ... 0x80000000] address range to circumvent which is for NT5 only:

//////////////////////////////////////////////////////////////////////////////
//
// Region reserved for system DLLs, which cannot be used for trampolines.
//
static PVOID    s_pSystemRegionLowerBound   = (PVOID)(ULONG_PTR)0x70000000;
static PVOID    s_pSystemRegionUpperBound   = (PVOID)(ULONG_PTR)0x80000000;

jdu2600 is also aware of this issue and has opened an unofficial PR microsoft/Detours PR #307 for Detours wants to update this range to adapt the latest Windows.

MinHook and mhook are both well-known Windows API hooking libraries, but unfortunately they don't seem to take this issue into account.

SlimDetours implementation

ASLR only reserves a range of 640MB in size for 32-bit systems, which can be directly circumvented. For 64-bit systems, it's a bit more complicated, ASLR reserves a range of of 32GB in size, which is too large to circumvent completely. Consider the ASLR layout rules and the location requirements of trampolines, treat 1GB range after Ntdll.dll as a reserved range to be circumvented is make sense, this consideration is consistent with the PR mentioned above. Note that this range may be split into two blocks, for example, the following layout:

Address Load Order System DLL Name Size
(Top)
0x00007FFFFFFF0000
...
0x00007FFFFF9E0000
#3 B.dll 6,208KB
0x00007FFFFF9E0000
...
0x00007FFFFF820000
#4 C.dll 1,792KB
... ... ...
0x00007FF800690000
...
0x00007FF800480000
#1 Ntdll.dll 2,112KB
0x00007FF800480000
...
0x00007FF7FFFF0000
(Bottom)
#2 A.dll 4,672KB

Ntdll.dll is randomly loaded by ASLR to a memory address lower in the reserved range, and when the subsequent DLL layout bottoms out, it will wrap to the top of the reserved range and continue to be arranged, in which case the "1GB range after Ntdll.dll" is 2 discontinuous regions.

SlimDetours' implementation details and circumvention range are different from the above PR, furthermore, NT5 and NT6+ are considered separately, and calls NtQuerySystemInformation to obtain a more accurate user address space range than hardcoded to help constrain the location of trampolines, see KNSoft.SlimDetours/Source/SlimDetours/Memory.c at main · KNSoft/KNSoft.SlimDetours.



This work is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0).

Ratin <[email protected]>
China national certified senior system architect
ReactOS contributor