Modern Windows Kernel Protections: PatchGuard, DSE, and HVCI

Windows Internals
Time it takes to read this article 5 minutes.

The Windows kernel is the ultimate prize on any host: code running in ring 0 can read and write any memory, forge tokens, and hide from every user-mode defense. Over the last two decades Microsoft has answered this threat not with a single control but with layers — each closing off a technique that attackers and, historically, even antivirus vendors once relied on. This article surveys the major kernel-integrity protections in modern Windows, what each one actually defends, and how they combine to make kernel compromise far harder than it was in the Windows XP era. Everything here is described for defensive understanding and authorized testing only.

Driver Signature Enforcement (DSE)

The first line of defense is simply controlling what code is allowed into the kernel at all. On 64-bit Windows, Driver Signature Enforcement requires that every kernel-mode driver be signed by a certificate chaining to a trusted authority before the kernel will load it. As covered in the boot-process and driver-model articles, this check happens as each driver image is mapped, extending the chain of trust that begins in firmware and the boot loader all the way to third-party drivers.

DSE can be relaxed for development through test-signing mode (enabled with a BCD flag), which allows self-signed drivers to load. This is invaluable for driver developers, but it is also a red flag on a production system: a machine booted with testsigning on has effectively lowered the bar for loading unsigned kernel code, and defenders should treat its presence as suspicious. The same is true of the nointegritychecks flag.

Kernel Patch Protection (PatchGuard)

Signing controls what loads, but says nothing about what happens afterward. In the 32-bit era it was common for both rootkits and antivirus products to patch the running kernel — hooking the System Service Descriptor Table (SSDT), the interrupt table, or key routines to intercept behavior. Kernel Patch Protection, also called PatchGuard or KPP, was introduced on x64 to end that practice.

PatchGuard periodically and unpredictably verifies that a set of critical structures has not been modified. Among the things it watches:

  • The SSDT (KiServiceTable) and the GDT/IDT.
  • Key kernel and HAL code sections.
  • Important processor registers and MSRs (such as the syscall entry MSR).
  • Selected global variables and function pointers.

If PatchGuard detects that any of these has been tampered with, it does not try to repair anything — it immediately issues a bugcheck, CRITICAL_STRUCTURE_CORRUPTION (stop code 0x109), taking the machine down. Because the checks fire at randomized intervals from contexts that are deliberately hard to predict or hook, reliably defeating PatchGuard is difficult and fragile. Its practical effect was to force everyone — malware and security vendors alike — off of kernel patching and onto documented, supported extensibility mechanisms such as kernel callbacks and minifilters.

Code Integrity and HVCI

PatchGuard is a detective control — it notices tampering after the fact. Hypervisor-protected Code Integrity (HVCI) is a preventive one. Building on Virtualization-Based Security (discussed next), HVCI moves the code-integrity decision out of the kernel and into a more trusted context protected by the hypervisor. Its central guarantee is W^X (write-xor-execute) for kernel memory: no kernel page is ever both writable and executable at the same time, and any page that is to become executable must first pass a code-integrity check enforced from outside the normal kernel.

This has a profound effect on exploitation. Even an attacker who achieves an arbitrary kernel read/write primitive through a driver bug cannot simply allocate a page, write shellcode into it, and execute it — the hypervisor will not allow that page to become executable, because the code was never validated. HVCI thereby neutralizes a whole class of “inject and run kernel shellcode” techniques and pushes attackers toward data-only manipulation instead.

Virtualization-Based Security and VTLs

Virtualization-Based Security (VBS) is the foundation the strongest modern protections stand on. Using the Hyper-V hypervisor, Windows partitions execution into Virtual Trust Levels (VTLs). The normal operating system — the kernel we have discussed throughout this series — runs in VTL0. A smaller, hardened Secure Kernel runs in VTL1, more privileged than the normal kernel and isolated from it by the hypervisor. Even ring-0 code in VTL0 cannot read or write VTL1 memory.

This isolation is what makes several features meaningful. HVCI’s code-integrity enforcement lives in the secure world. Credential Guard moves the most sensitive secrets — the derived credentials that LSASS would otherwise hold in VTL0 memory — into a VTL1 trustlet, so that even a full compromise of the normal kernel cannot simply read them out (a direct mitigation of the credential-theft techniques discussed in the access-tokens and authentication articles). The Secure Kernel also underpins protections like Kernel-mode Hardware-enforced Stack Protection (shadow stacks) on capable hardware.

Supporting CPU and Kernel Mitigations

Around these headline features sits a ring of lower-level mitigations, many of them enforced by the CPU:

  • SMEP (Supervisor Mode Execution Prevention) stops the kernel from executing code located in user-mode pages, killing the old trick of pointing a corrupted kernel pointer at a user-mode payload.
  • SMAP (Supervisor Mode Access Prevention) similarly restricts the kernel from casually reading or writing user memory except through controlled accessors.
  • Kernel Control Flow Guard (kCFG) validates indirect calls in the kernel against a set of legitimate targets, hardening against control-flow hijacking.
  • NonPagedPoolNx makes the default non-paged pool non-executable, so pool allocations cannot be used as a place to run code.
  • KASLR randomizes the load addresses of the kernel and drivers, forcing an information leak before absolute kernel addresses can be used.

None of these is a silver bullet alone, but together they remove the cheap, reliable primitives that kernel exploits once assumed.

The Vulnerable Driver Problem (BYOVD)

With unsigned code blocked, patching detected, and shellcode execution prevented, attackers increasingly turn to the one thing that is still trusted: legitimately signed drivers that happen to contain vulnerabilities. In a Bring Your Own Vulnerable Driver (BYOVD) attack, an adversary with administrative rights loads a real, signed driver known to expose a powerful IOCTL — often an arbitrary kernel read/write or a physical-memory mapping primitive — and uses it as a ready-made gateway to ring 0. Because the driver is properly signed, DSE is satisfied.

Microsoft’s answer is attack-surface reduction through blocklisting. The Microsoft Vulnerable Driver Blocklist, enforced by HVCI and the code-integrity system, refuses to load known-bad driver versions. Keeping that blocklist enabled and up to date, minimizing which third-party drivers are installed, and monitoring for suspicious driver loads (Event ID 6 in the kernel-driver telemetry and Sysmon) are the practical defenses. BYOVD is precisely why the earlier layers matter: they push attackers into a narrow, increasingly monitored corridor.

Verifying What Is Enabled

Several of these protections are configurable, so verifying their state is an essential audit step. The following commands report whether VBS, HVCI, and Credential Guard are actually running, and whether any signing checks have been weakened:

# PowerShell: is VBS running, and which features are active?
# VirtualizationBasedSecurityStatus: 2 = running
# SecurityServicesRunning: 1 = Credential Guard, 2 = HVCI
Get-CimInstance -ClassName Win32_DeviceGuard `
  -Namespace root\Microsoft\Windows\DeviceGuard |
  Select-Object VirtualizationBasedSecurityStatus, `
                SecurityServicesRunning, `
                CodeIntegrityPolicyEnforcementStatus

# Quick GUI summary: run msinfo32 and read the
# "Virtualization-based security" and "... Services Running" lines
msinfo32

# Check for weakened boot-time signing/integrity flags
bcdedit /enum {current}
#   testsigning        Yes  -> unsigned/test-signed drivers allowed (suspicious)
#   nointegritychecks  Yes  -> integrity checks disabled (suspicious)
#   hypervisorlaunchtype Off -> VBS/HVCI cannot run

On an audited host you want to see VBS running, HVCI reported under SecurityServicesRunning, and no testsigning or nointegritychecks flags. Their absence is not proof of compromise, but it tells you which of the layers above are actually in force.

Conclusion

Modern Windows defends its kernel in depth: DSE controls what code enters, PatchGuard detects tampering with critical structures, HVCI and VBS prevent unauthorized code from ever becoming executable and wall off secrets in a hypervisor-protected world, and a ring of CPU-level mitigations removes the easy primitives exploits once relied on. The result is that the kernel-patching rootkits of twenty years ago are essentially extinct, and today’s attackers are pushed toward vulnerable-driver abuse and data-only techniques — the current battleground of the VTL boundary. For anyone studying the internals covered in this series, these protections are the context that explains why so much modern offensive and defensive research now revolves around drivers, hypervisors, and the secure kernel.

You Might Also Like

This article is part of the Windows Internals series. These related deep-dives cover adjacent parts of the system:

Comments

Copied title and URL