@@ -250,7 +250,7 @@ inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID *ppGlobals)
250250 // enough to hold the detour code bytes.
251251 if (pbCode[0 ] == 0xff &&
252252 pbCode[1 ] == 0x25 &&
253- *(UNALIGNED INT32 *)&pbCode[2 ] == (UNALIGNED INT32)(pbCode + 0x1000 )) { // jmp [rip +PAGE_SIZE-6]
253+ *(UNALIGNED INT32 *)&pbCode[2 ] == (UNALIGNED INT32)(pbCode + 0x1000 )) { // jmp [eip +PAGE_SIZE-6]
254254
255255 DETOUR_TRACE ((" %p->%p: OS patch encountered, reset back to long jump 5 bytes prior to target function.\n " , pbCode, pbCodeOriginal));
256256 pbCode = pbCodeOriginal;
@@ -1453,6 +1453,21 @@ static PVOID detour_alloc_region_from_hi(PBYTE pbLo, PBYTE pbHi)
14531453 return NULL ;
14541454}
14551455
1456+ // Return pbTarget clamped into [pLo, pHi] range.
1457+
1458+ static PBYTE detour_target_region_clamp (PBYTE pbTarget,
1459+ PDETOUR_TRAMPOLINE pLo,
1460+ PDETOUR_TRAMPOLINE pHi)
1461+ {
1462+ if (pbTarget < (PBYTE)pLo) {
1463+ return (PBYTE)pLo;
1464+ }
1465+ if (pbTarget > (PBYTE)pHi) {
1466+ return (PBYTE)pHi;
1467+ }
1468+ return pbTarget;
1469+ }
1470+
14561471static PVOID detour_alloc_trampoline_allocate_new (PBYTE pbTarget,
14571472 PDETOUR_TRAMPOLINE pLo,
14581473 PDETOUR_TRAMPOLINE pHi)
@@ -1468,29 +1483,29 @@ static PVOID detour_alloc_trampoline_allocate_new(PBYTE pbTarget,
14681483 s_pSystemRegion2LowerBound, s_pSystemRegion2UpperBound));
14691484 // Try looking 1GB below or lower.
14701485 if (pbTry == NULL && pbTarget > (PBYTE)0x40000000 ) {
1471- pbTry = detour_alloc_region_from_hi ((PBYTE)pLo, pbTarget - 0x40000000 );
1486+ pbTry = detour_alloc_region_from_hi ((PBYTE)pLo, detour_target_region_clamp ( pbTarget - 0x40000000 , pLo, pHi) );
14721487 }
14731488 // Try looking 1GB above or higher.
14741489 if (pbTry == NULL && pbTarget < (PBYTE)0xffffffff40000000 ) {
1475- pbTry = detour_alloc_region_from_lo (pbTarget + 0x40000000 , (PBYTE)pHi);
1490+ pbTry = detour_alloc_region_from_lo (detour_target_region_clamp ( pbTarget + 0x40000000 , pLo, pHi) , (PBYTE)pHi);
14761491 }
14771492 // Try looking 1GB below or higher.
14781493 if (pbTry == NULL && pbTarget > (PBYTE)0x40000000 ) {
1479- pbTry = detour_alloc_region_from_lo (pbTarget - 0x40000000 , pbTarget);
1494+ pbTry = detour_alloc_region_from_lo (detour_target_region_clamp ( pbTarget - 0x40000000 , pLo, pHi), detour_target_region_clamp ( pbTarget, pLo, pHi) );
14801495 }
14811496 // Try looking 1GB above or lower.
14821497 if (pbTry == NULL && pbTarget < (PBYTE)0xffffffff40000000 ) {
1483- pbTry = detour_alloc_region_from_hi (pbTarget, pbTarget + 0x40000000 );
1498+ pbTry = detour_alloc_region_from_hi (detour_target_region_clamp ( pbTarget, pLo, pHi), detour_target_region_clamp ( pbTarget + 0x40000000 , pLo, pHi) );
14841499 }
14851500#endif
14861501
14871502 // Try anything below.
14881503 if (pbTry == NULL ) {
1489- pbTry = detour_alloc_region_from_hi ((PBYTE)pLo, pbTarget);
1504+ pbTry = detour_alloc_region_from_hi ((PBYTE)pLo, detour_target_region_clamp ( pbTarget, pLo, pHi) );
14901505 }
14911506 // try anything above.
14921507 if (pbTry == NULL ) {
1493- pbTry = detour_alloc_region_from_lo (pbTarget, (PBYTE)pHi);
1508+ pbTry = detour_alloc_region_from_lo (detour_target_region_clamp ( pbTarget, pLo, pHi) , (PBYTE)pHi);
14941509 }
14951510
14961511 return pbTry;
@@ -2198,6 +2213,15 @@ LONG WINAPI DetourAttachEx(_Inout_ PVOID *ppPointer,
21982213 DETOUR_TRACE ((" ppldTarget=%p, code=%p [gp=%p]\n " ,
21992214 ppldTarget, pbTarget, pTargetGlobals));
22002215#else // DETOURS_IA64
2216+ #if defined(_M_ARM64EC)
2217+ if (RtlIsEcCode (reinterpret_cast <DWORD64>(*ppPointer))) {
2218+ DETOUR_TRACE ((" *ppPointer is an Arm64EC address (ppPointer=%p). "
2219+ " An Arm64EC address cannot be legitimately detoured with an x64 jmp. "
2220+ " Mark the target function with __declspec(hybrid_patchable) to make it detour-able. "
2221+ " We still allow an Arm64EC function to be detoured with an x64 jmp to make it easy (crash) to debug.\n " , ppPointer));
2222+ DETOUR_BREAK ();
2223+ }
2224+ #endif
22012225 pbTarget = (PBYTE)DetourCodeFromPointer (pbTarget, NULL );
22022226 pDetour = DetourCodeFromPointer (pDetour, NULL );
22032227#endif // !DETOURS_IA64
0 commit comments