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,7 +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 ULONG_PTR s_ulSystemRegionHighLowerBound = MAXULONG_PTR ;
38+ static const UNICODE_STRING g_usNtdllDll = RTL_CONSTANT_STRING ( L"ntdll.dll" ) ;
3939#else
4040_STATIC_ASSERT (SYSTEM_RESERVED_REGION_HIGHEST + 1 == 0x78000000UL );
4141_STATIC_ASSERT (SYSTEM_RESERVED_REGION_SIZE == _640MB );
@@ -116,18 +116,25 @@ detour_memory_init(VOID)
116116 {
117117#if defined(_WIN64 )
118118 /* 1GB after Ntdll.dll */
119- PLDR_DATA_TABLE_ENTRY NtdllLdrEntry ;
119+ PVOID NtdllBase = NULL ;
120+ LdrGetDllHandle (NULL , NULL , (PUNICODE_STRING )& g_usNtdllDll , & NtdllBase );
120121
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 ;
125- s_ulSystemRegionLowLowerBound = s_ulSystemRegionLowUpperBound - _1GB + 1 ;
126- if (s_ulSystemRegionLowLowerBound < SYSTEM_RESERVED_REGION_LOWEST )
122+ // Win10/Win11 ntdll virtual size is around 1.8-2.5MB, reserving 16MB should
123+ // be enough to cover future growth. Moreover, the ntdll region is already
124+ // used by ntdll, so it's merely an optimization.
125+ s_ulSystemRegionLowUpperBound = (ULONG_PTR )NtdllBase + _16MB - 1 ;
126+
127+ // Ensure the reserved region is within the system reserved range. It should
128+ // be, but be defensive just in case.
129+ if (s_ulSystemRegionLowUpperBound < SYSTEM_RESERVED_REGION_LOWEST + _1GB - 1 )
127130 {
128- s_ulSystemRegionHighLowerBound = s_ulSystemRegionLowLowerBound + SYSTEM_RESERVED_REGION_SIZE ;
129- s_ulSystemRegionLowLowerBound = SYSTEM_RESERVED_REGION_LOWEST ;
131+ s_ulSystemRegionLowUpperBound = SYSTEM_RESERVED_REGION_LOWEST + _1GB - 1 ;
132+ } else if (s_ulSystemRegionLowUpperBound > SYSTEM_RESERVED_REGION_HIGHEST )
133+ {
134+ s_ulSystemRegionLowUpperBound = SYSTEM_RESERVED_REGION_HIGHEST ;
130135 }
136+
137+ s_ulSystemRegionLowLowerBound = s_ulSystemRegionLowUpperBound - _1GB + 1 ;
131138#else
132139 s_ulSystemRegionLowUpperBound = SYSTEM_RESERVED_REGION_HIGHEST ;
133140 s_ulSystemRegionLowLowerBound = SYSTEM_RESERVED_REGION_LOWEST ;
@@ -207,13 +214,8 @@ BOOL
207214detour_memory_is_system_reserved (
208215 _In_ PVOID Address )
209216{
210- return
211- ((ULONG_PTR )Address >= s_ulSystemRegionLowLowerBound && (ULONG_PTR )Address <= s_ulSystemRegionLowUpperBound )
212- #if defined(_WIN64 )
213- || ((ULONG_PTR )Address >= s_ulSystemRegionHighLowerBound &&
214- (ULONG_PTR )Address <= SYSTEM_RESERVED_REGION_HIGHEST )
215- #endif
216- ;
217+ return (ULONG_PTR )Address >= s_ulSystemRegionLowLowerBound &&
218+ (ULONG_PTR )Address <= s_ulSystemRegionLowUpperBound ;
217219}
218220
219221_Ret_notnull_
0 commit comments