A number of excellent PatchGuard articles have been written around what PatchGuard is, how to bypass it, what triggers it uses, its obfuscation techniques, and more.
But for some reason, nobody has published a full list of everything that PatchGuard actually verifies. Microsoft used to have a website that listed the initial first 7 checks, but nothing beyond that.
I asked around at conferences, and the answer I got was that the code was too complex to analyze, and nobody really wanted to take the time to figure out every single check. I had my own private list of checks I knew PatchGuard does (through runtime analysis), but I was surprised to see the real reason nobody’s bothered to analyze this…
… Microsoft’s own public debugger (known as WinDBG) tells you — why bother reversing? 🙂
Lo’ and behold, the 39 different checks in PatchGuard Windows 8.1 Update. There’s a few more in Windows 10, I guess they’re not yet documented.
CRITICAL_STRUCTURE_CORRUPTION (109) Arguments: Arg1: 00000000, Reserved Arg2: 00000000, Reserved Arg3: 00000000, Failure type dependent information Arg4: 00000000, Type of corrupted region, can be 0 : A generic data region 1 : Modification of a function or .pdata 2 : A processor IDT 3 : A processor GDT 4 : Type 1 process list corruption 5 : Type 2 process list corruption 6 : Debug routine modification 7 : Critical MSR modification 8 : Object type 9 : A processor IVT a : Modification of a system service function b : A generic session data region c : Modification of a session function or .pdata d : Modification of an import table e : Modification of a session import table f : Ps Win32 callout modification 10 : Debug switch routine modification 11 : IRP allocator modification 12 : Driver call dispatcher modification 13 : IRP completion dispatcher modification 14 : IRP deallocator modification 15 : A processor control register 16 : Critical floating point control register modification 17 : Local APIC modification 18 : Kernel notification callout modification 19 : Loaded module list modification 1a : Type 3 process list corruption 1b : Type 4 process list corruption 1c : Driver object corruption 1d : Executive callback object modification 1e : Modification of module padding 1f : Modification of a protected process 20 : A generic data region 21 : A page hash mismatch 22 : A session page hash mismatch 23 : Load config directory modification 24 : Inverted function table modification 25 : Session configuration modification 102 : Modification of win32k.sys
I have to admit, there are some things I didn’t realize PatchGuard would actually think about protecting, such as the Local APIC. It’s also interesting to see some more esoteric hooks in the list as well, such as PsEstablishWin32Callout protection. I also did not realize PatchGuard now protects the DRIVER_OBJECT structure — indeed, hooking a major function will now give you code 0x1C. And finally, the protection of protected processes means that technically something such as Mimikatz’s “MimiDrv” may crash some machines in the wild.
I usually try to avoid talking about PatchGuard since I’m glad it’s giving AV companies hell, but I can’t have been the only person that never noticed that the checks were documented in the debugger all along, hidden behind a simple command (it makes sense that Microsoft wouldn’t want their own support engineers to be wondering what on Earth they’re looking at):
!analyze -show 109
I can’t even take credit for discovering this on my own. Reading Microsoft’s famous “NT Debugging” blog made me realize that this had been there all along.