##Support System
= Win8 (Win8 - Win10 21H4)
as we know, patchguard execution chain:
On pgentry -> CmpAppendDllSection(decrypt context)-> ExQueueWorkItem -> FsRtlMdlReadCompleteDevEx -> MmAllocateIndependentPages/ExAllocatePoolWithTag -> re encrypt context -> Insert New context -> FreePool/Page current context.
some pgentry(apc,dpc,..):
00 fffffd0c`0d40d868 fffff802`0a52410d 0xffffc405`84a020d8 01 fffffd0c`0d40d870 fffff802`0a467de5 nt!KiDispatchCallout+0x1cd 02 fffffd0c`0d40d8e0 fffff802`0a465b77 nt!KiDeliverApc+0x2b5 03 fffffd0c`0d40d990 fffff802`0a464d7f nt!KiSwapThread+0x827 04 fffffd0c`0d40da40 fffff802`0a464623 nt!KiCommitThreadWait+0x14f 05 fffffd0c`0d40dae0 fffff802`0a5c7b12 nt!KeWaitForSingleObject+0x233 06 fffffd0c`0d40dbd0 fffff802`0a517e25 nt!PopIrpWorkerControl+0x22 07 fffffd0c`0d40dc10 fffff802`0a5fd0d8 nt!PspSystemThreadStartup+0x55 08 fffffd0c`0d40dc60 00000000`00000000 nt!KiStartSystemThread+0x28 06 ffffc381`53d460f0 fffff803`137cc052 nt!ExpTimerDpcRoutine$filt$1+0x493 07 ffffc381`53d46130 fffff803`137fe942 nt!_C_specific_handler+0xa2 08 ffffc381`53d461a0 fffff803`1372bf97 nt!RtlpExecuteHandlerForException+0x12 09 ffffc381`53d461d0 fffff803`1372ab86 nt!RtlDispatchException+0x297 0a ffffc381`53d468f0 fffff803`137f6912 nt!KiDispatchException+0x186 0b ffffc381`53d46fb0 fffff803`137f68e0 nt!KxExceptionDispatchOnExceptionStack+0x12 0c ffffd88a`c62452c8 fffff803`13807ba5 nt!KiExceptionDispatchOnExceptionStackContinue 0d ffffd88a`c62452d0 fffff803`138038e0 nt!KiExceptionDispatch+0x125 0e ffffd88a`c62454b0 fffff803`1380014d nt!KiGeneralProtectionFault+0x320 0f ffffd88a`c6245640 fffff803`13800182 nt!KiCustomRecurseRoutine0+0xd 10 ffffd88a`c6245670 fffff803`13873ce9 nt!KiCustomAccessRoutine0+0x22 11 ffffd88a`c62456a0 fffff803`1360781e nt!ExpTimerDpcRoutine+0x155d29 12 ffffd88a`c6245860 fffff803`13606b04 nt!KiExecuteAllDpcs+0x30e 13 ffffd88a`c62459d0 fffff803`137f95ee nt!KiRetireDpcList+0x1f4 14 ffffd88a`c6245c60 00000000`00000000 nt!KiIdleLoop+0x9e 0d fffff802`29b82b80 fffff802`247cc154 nt!CmpEnableLazyFlushDpcRoutine$fin$1+0x16a 0e fffff802`29b82be0 fffff802`247fe9c2 nt!_C_specific_handler+0x1a4 0f fffff802`29b82c50 fffff802`2472c484 nt!RtlpExecuteHandlerForUnwind+0x12 10 fffff802`29b82c80 fffff802`24720574 nt!RtlUnwindEx+0x2c4 11 fffff802`29b833a0 fffff802`247cd6d3 nt!RtlUnwind+0xa4 12 fffff802`29b83900 fffff802`24810701 nt!local_unwind+0x23 13 fffff802`29b83930 fffff802`247cc154 nt!CmpEnableLazyFlushDpcRoutine$fin$0+0x34 14 fffff802`29b83970 fffff802`247fe9c2 nt!_C_specific_handler+0x1a4 15 fffff802`29b839e0 fffff802`2472c484 nt!RtlpExecuteHandlerForUnwind+0x12 16 fffff802`29b83a10 fffff802`247cc095 nt!RtlUnwindEx+0x2c4 17 fffff802`29b84130 fffff802`247fe942 nt!_C_specific_handler+0xe5 18 fffff802`29b841a0 fffff802`2472bf97 nt!RtlpExecuteHandlerForException+0x12 19 fffff802`29b841d0 fffff802`2472ab86 nt!RtlDispatchException+0x297 1a fffff802`29b848f0 fffff802`247f6912 nt!KiDispatchException+0x186 1b fffff802`29b84fb0 fffff802`247f68e0 nt!KxExceptionDispatchOnExceptionStack+0x12 1c fffff802`29b6f348 fffff802`24807ba5 nt!KiExceptionDispatchOnExceptionStackContinue 1d fffff802`29b6f350 fffff802`248038e0 nt!KiExceptionDispatch+0x125 1e fffff802`29b6f530 fffff802`247fff0d nt!KiGeneralProtectionFault+0x320 1f fffff802`29b6f6c0 fffff802`247ffd8d nt!KiCustomRecurseRoutine7+0xd 20 fffff802`29b6f6f0 fffff802`247ffa8d nt!KiCustomRecurseRoutine6+0xd 21 fffff802`29b6f720 fffff802`247ffb4d nt!KiCustomRecurseRoutine5+0xd 22 fffff802`29b6f750 fffff802`247ffb82 nt!KiCustomRecurseRoutine4+0xd 23 fffff802`29b6f780 fffff802`24723877 nt!KiCustomAccessRoutine4+0x22 24 fffff802`29b6f7b0 fffff802`24644f12 nt!CmpEnableLazyFlushDpcRoutine+0x97 25 fffff802`29b6f8e0 fffff802`24606eed nt!KiProcessExpiredTimerList+0x172 26 fffff802`29b6f9d0 fffff802`247f95ee nt!KiRetireDpcList+0x5dd 27 fffff802`29b6fc60 00000000`00000000 nt!KiIdleLoop+0x9e
execute pgentry:
{
v32 = *(_QWORD *)pg_entry ^ 0x85131481131482Ei64;
*(_DWORD *)pg_entry = 0xAD1B6FF5;
*(_DWORD *)pg_entry ^= 0xBC2A27DB; //decrypt to xor qword ptr cs:[rcx],rdx
((void (__fastcall *)(unsigned __int64, __int64, _QWORD, _QWORD))pg_entry)(pg_entry, v32, 0i64, 0i64);
}asm:
.text:00000001403240F9 movrdx,[rbp+arg_0] .text:00000001403240FD xoreax,0BC2A27DBh .text:0000000140324102mov[r10],eax .text:0000000140324105movrax,r10 .text:0000000140324108call _guard_dispatch_icall
CmpAppendDllSection and FsRtlMdlReadCompleteDevEx executes very fast. Most of the time is the encrypted context state. so we hook _guard_dispatch_icall and check target is 2e483111 xor qword ptr cs:[rcx],rdx
cmp dword ptr ds:[rax],0x1131482E jeret: jmprax ret
0: kd> u guard_dispatch_icall nt!guard_dispatch_icall: fffff803`3c7fe620 81382e483111 cmp dword ptr [rax],1131482Eh fffff803`3c7fe626 7402je nt!guard_dispatch_icall+0xa (fffff803`3c7fe62a) fffff803`3c7fe628 ffe0 jmprax fffff803`3c7fe62a c3 ret fffff803`3c7fe62b 8d7a00 leaedi,[rdx] fffff803`3c7fe62e 0000add byte ptr [rax],al fffff803`3c7fe630 4d85db testr11,r11 fffff803`3c7fe633 741c je nt!guard_dispatch_icall+0x31 (fffff803`3c7fe651) 0: kd> bp fffff803`3c7fe62a 0: kd> g nt!DbgBreakPointWithStatus: fffff803`3c7fd920 cc int3 0: kd> g Breakpoint 2 hit nt!guard_dispatch_icall+0xa: fffff803`3c7fe62a c3 ret 0: kd> kn # Child-SP RetAddr Call Site 00 fffff803`42b838a8 fffff803`3c810bcf nt!guard_dispatch_icall+0xa 01 fffff803`42b838b0 fffff803`3c7cc154 nt!IopIrpStackProfilerDpcRoutine$fin$1+0x153 02 fffff803`42b83910 fffff803`3c7f16f2 nt!_C_specific_handler+0x1a4 03 fffff803`42b83980 fffff803`3c7fe9c2 nt!_GSHandlerCheck_SEH+0x6a 04 fffff803`42b839b0 fffff803`3c72c484 nt!RtlpExecuteHandlerForUnwind+0x12 05 fffff803`42b839e0 fffff803`3c7cc095 nt!RtlUnwindEx+0x2c4 06 fffff803`42b84100 fffff803`3c7f16f2 nt!_C_specific_handler+0xe5 07 fffff803`42b84170 fffff803`3c7fe942 nt!_GSHandlerCheck_SEH+0x6a 08 fffff803`42b841a0 fffff803`3c72bf97 nt!RtlpExecuteHandlerForException+0x12 09 fffff803`42b841d0 fffff803`3c72ab86 nt!RtlDispatchException+0x297 0a fffff803`42b848f0 fffff803`3c7f6912 nt!KiDispatchException+0x186 0b fffff803`42b84fb0 fffff803`3c7f68e0 nt!KxExceptionDispatchOnExceptionStack+0x12 0c fffff803`42b6f1c8 fffff803`3c807ba5 nt!KiExceptionDispatchOnExceptionStackContinue 0d fffff803`42b6f1d0 fffff803`3c8038e0 nt!KiExceptionDispatch+0x125 0e fffff803`42b6f3b0 fffff803`3c7ffa8d nt!KiGeneralProtectionFault+0x320 0f fffff803`42b6f540 fffff803`3c7ffb4d nt!KiCustomRecurseRoutine5+0xd 10 fffff803`42b6f570 fffff803`3c7ffe4d nt!KiCustomRecurseRoutine4+0xd 11 fffff803`42b6f5a0 fffff803`3c7ffccd nt!KiCustomRecurseRoutine3+0xd 12 fffff803`42b6f5d0 fffff803`3c7ffd02 nt!KiCustomRecurseRoutine2+0xd 13 fffff803`42b6f600 fffff803`3c723b1a nt!KiCustomAccessRoutine2+0x22 14 fffff803`42b6f630 fffff803`3c60781e nt!IopIrpStackProfilerDpcRoutine+0x23a 15 fffff803`42b6f860 fffff803`3c606b04 nt!KiExecuteAllDpcs+0x30e 16 fffff803`42b6f9d0 fffff803`3c7f95ee nt!KiRetireDpcList+0x1f4 17 fffff803`42b6fc60 00000000`00000000 nt!KiIdleLoop+0x9e 0: kd> g Breakpoint 2 hit nt!guard_dispatch_icall+0xa: fffff803`3c7fe62a c3 ret 0: kd> kn # Child-SP RetAddr Call Site 00 fffff803`42b840e8 fffff803`3c80fa6f nt!guard_dispatch_icall+0xa 01 fffff803`42b840f0 fffff803`3c7cc052 nt!CmpLazyFlushDpcRoutine$filt$1+0x517 02 fffff803`42b84130 fffff803`3c7fe942 nt!_C_specific_handler+0xa2 03 fffff803`42b841a0 fffff803`3c72bf97 nt!RtlpExecuteHandlerForException+0x12 04 fffff803`42b841d0 fffff803`3c72ab86 nt!RtlDispatchException+0x297 05 fffff803`42b848f0 fffff803`3c7f6912 nt!KiDispatchException+0x186 06 fffff803`42b84fb0 fffff803`3c7f68e0 nt!KxExceptionDispatchOnExceptionStack+0x12 07 fffff803`42b6f368 fffff803`3c807ba5 nt!KiExceptionDispatchOnExceptionStackContinue 08 fffff803`42b6f370 fffff803`3c8038e0 nt!KiExceptionDispatch+0x125 09 fffff803`42b6f550 fffff803`3c7ffa8d nt!KiGeneralProtectionFault+0x320 0a fffff803`42b6f6e0 fffff803`3c7ffac2 nt!KiCustomRecurseRoutine5+0xd 0b fffff803`42b6f710 fffff803`3c8729fb nt!KiCustomAccessRoutine5+0x22 0c fffff803`42b6f740 fffff803`3c644f12 nt!CmpLazyFlushDpcRoutine+0x1574ab 0d fffff803`42b6f8e0 fffff803`3c6072e9 nt!KiProcessExpiredTimerList+0x172 0e fffff803`42b6f9d0 fffff803`3c7f95ee nt!KiRetireDpcList+0x9d9 0f fffff803`42b6fc60 00000000`00000000 nt!KiIdleLoop+0x9e
- Wait in a loop until there is no pg workitem running
for(;;){ if(find_decrypt_context() == 0) break; KeSleep(100); }
- fix KiTimerDispatch entry check
- fix KiDpcDispatch entry check