Skip to content

Commit 5d67817

Browse files
committed
Improve x64 system region calculation
InInitializationOrderModuleList might be unreliable due to security products. Also, use a more defensive approach for unusual Ntdll.dll base addresses.
1 parent 6745f6d commit 5d67817

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

Source/KNSoft.SlimDetours/Memory.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*
1515
* The region is [0x50000000 ... 0x78000000) (640MB) on 32-bit Windows;
1616
* and [0x00007FF7FFFF0000 ... 0x00007FFFFFFF0000) (32GB) on 64-bit Windows, which is too large to avoid.
17-
* In this case, avoiding 1GB range starting at Ntdll.dll is make sense.
17+
* In this case, avoiding 1GB range starting at Ntdll.dll makes sense.
1818
* If ASLR is disabled on NT6.0 or NT6.1, we reserve the top 1GB or 640MB region.
1919
*
2020
* The original Microsoft Detours always assumes and reserves [0x70000000 ... 0x80000000] (256MB) for system DLLs,
@@ -35,6 +35,7 @@ _STATIC_ASSERT(SYSTEM_RESERVED_REGION_HIGHEST + 1 == 0x00007FFFFFFF0000ULL);
3535
_STATIC_ASSERT(SYSTEM_RESERVED_REGION_SIZE == _32GB);
3636
_STATIC_ASSERT(SYSTEM_RESERVED_REGION_LOWEST == 0x00007FF7FFFF0000ULL);
3737

38+
static const UNICODE_STRING g_usNtdllDll = RTL_CONSTANT_STRING(L"ntdll.dll");
3839
static ULONG_PTR s_ulSystemRegionHighLowerBound = MAXULONG_PTR;
3940
#else
4041
_STATIC_ASSERT(SYSTEM_RESERVED_REGION_HIGHEST + 1 == 0x78000000UL);
@@ -116,12 +117,19 @@ detour_memory_init(VOID)
116117
{
117118
#if defined(_WIN64)
118119
/* 1GB after Ntdll.dll */
119-
PLDR_DATA_TABLE_ENTRY NtdllLdrEntry;
120+
PVOID NtdllBase = NULL;
121+
LdrGetDllHandle(NULL, NULL, (PUNICODE_STRING)&g_usNtdllDll, &NtdllBase);
122+
123+
// Win10/Win11 ntdll virtual size is around 1.8-2.5MB, reserving 16MB should
124+
// be enough to cover future growth. Moreover, the ntdll region is already
125+
// used by ntdll, so it's merely an optimization.
126+
s_ulSystemRegionLowUpperBound = (ULONG_PTR)NtdllBase + _16MB - 1;
127+
if (s_ulSystemRegionLowUpperBound < SYSTEM_RESERVED_REGION_LOWEST ||
128+
s_ulSystemRegionLowUpperBound > SYSTEM_RESERVED_REGION_HIGHEST)
129+
{
130+
s_ulSystemRegionLowUpperBound = SYSTEM_RESERVED_REGION_HIGHEST;
131+
}
120132

121-
NtdllLdrEntry = CONTAINING_RECORD(NtCurrentPeb()->Ldr->InInitializationOrderModuleList.Flink,
122-
LDR_DATA_TABLE_ENTRY,
123-
InInitializationOrderLinks);
124-
s_ulSystemRegionLowUpperBound = (ULONG_PTR)NtdllLdrEntry->DllBase + NtdllLdrEntry->SizeOfImage - 1;
125133
s_ulSystemRegionLowLowerBound = s_ulSystemRegionLowUpperBound - _1GB + 1;
126134
if (s_ulSystemRegionLowLowerBound < SYSTEM_RESERVED_REGION_LOWEST)
127135
{

Source/KNSoft.SlimDetours/SlimDetours.NDK.inl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ C_ASSERT((ULONG_PTR)MI_ASLR_HIGHEST_SYSTEM_RANGE_ADDRESS - (ULONG_PTR)MI_ASLR_LO
100100
#define _GB(x) ((x) * _1GB)
101101

102102
#define _512KB _KB(512)
103+
#define _16MB _MB(16)
103104
#define _640MB _MB(640)
104105
#define _2GB _GB(2)
105106
#define _32GB _GB(32)

0 commit comments

Comments
 (0)