· 7 min read ·

Ring 0 and the Attack Surface You Accept When You Install That Game

Source: lobsters

The CPU privilege model exists for good reasons. Modern x86 processors enforce four privilege rings — 0 through 3 — with Ring 0 reserved for the operating system kernel and Ring 3 for user applications. The hardware enforces this boundary. Code running in Ring 3 cannot directly access hardware registers, cannot modify page table mappings, and cannot read the memory of an arbitrary process without making a syscall that the kernel checks. Ring 0 code can do all of those things.

Kernel anti-cheat systems run at Ring 0. When you install Riot Vanguard, EasyAntiCheat, or BattlEye and launch a game, a kernel driver loads into that privileged space. That driver can enumerate every process on the system, read any process’s memory without restriction, intercept system calls, inspect driver tables, and it runs in the same address space as the Windows kernel itself. This is not a coincidence or an overreach. It is the direct consequence of roughly fifteen years of an escalating technical arms race between cheat developers and anti-cheat engineers.

How the Industry Got Here

The earliest anti-cheat tools operated entirely in user space. Valve Anti-Cheat (VAC) is the canonical example: it scans the game process from Ring 3, checks for known cheat signatures in memory, and applies delayed bans to avoid revealing exactly what triggered the detection. This model is simple and carries no kernel-level risk. It also lost to sophisticated cheaters within a few years.

The problem is symmetric access. A cheat running in Ring 3 faces exactly the same restrictions as an anti-cheat running in Ring 3. Any memory read the anti-cheat can perform, the cheat can counter by watching for it. Any process scan the anti-cheat runs, the cheat can intercept by hooking the relevant API. User-mode anti-cheat and user-mode cheats occupy the same privilege level, which means the competition in user space is purely about who has better techniques, not who has structural advantage.

Cheaters recognized this first and moved to kernel drivers. By loading a signed — or, more commonly, a bypass-signed — kernel driver, a cheat could perform direct kernel object manipulation (DKOM) to unlink its own process from the kernel’s process list, making it invisible to any user-mode enumeration. It could read game memory through MmCopyVirtualMemory without ever touching the target process’s handle table. It could hook the system service descriptor table (SSDT) to intercept and modify system calls before the kernel processed them. None of this is detectable from Ring 3.

The only effective response was to follow cheaters into the kernel. If you want to detect a driver that has unlinked itself from PsLoadedModuleList, you need to walk the alternative data structures that a Ring 0 scanner can access: KLDR_DATA_TABLE_ENTRY chains, memory-mapped region lists, the NTOSKRNL export table. You cannot do this from user space.

The Windows Driver Architecture

A Windows kernel driver is a .sys file that conforms to the Windows Driver Model (WDM) or its successor, the Windows Driver Framework (WDF). The driver exports standard dispatch routines: DriverEntry for initialization, IRP_MJ_CREATE and IRP_MJ_CLOSE for open and close events, and IRP_MJ_DEVICE_CONTROL for the IOCTL interface that user-mode software uses to send commands and receive data.

Since Windows Vista on 64-bit systems, Driver Signature Enforcement (DSE) requires that all kernel drivers carry a valid Authenticode signature from a trusted certificate authority. Microsoft further strengthened this in 2016, requiring EV (Extended Validation) certificates acquired after that date for new kernel driver submissions. Drivers can also go through WHQL certification to appear in Windows Update, though that is not required for a driver to load.

Anti-cheat vendors use this signing infrastructure legitimately. Their drivers ship signed with their own EV certificates and, in some cases, with WHQL certification. The driver exposes an IOCTL interface that the game client — running in user space — uses to query detected threats, trigger scans, and receive integrity verdicts.

At the kernel level, the anti-cheat driver does several categories of work. It enumerates loaded drivers by walking kernel structures that a Ring 3 process cannot access, looking for unsigned drivers or drivers matching known cheat signatures. It monitors handle creation events through kernel callbacks — specifically ObRegisterCallbacks — to detect processes attempting to open the game process with PROCESS_VM_READ access. It performs integrity checks on the game’s in-memory code sections to detect patches applied after load. Some systems also use minifilter drivers to monitor filesystem operations, watching for cheat-related files being written or accessed.

Microsoft’s Kernel Patch Protection (PatchGuard), introduced with Windows XP x64 and significantly hardened since, complicates both sides of this. PatchGuard periodically validates the integrity of critical kernel structures: the SSDT, the IDT, the GDT, and various system call handlers. Any unauthorized modification triggers a CRITICAL_STRUCTURE_CORRUPTION bugcheck (0x109). This blocked a generation of SSDT-hooking cheats but also constrained some anti-cheat hooking techniques that relied on the same infrastructure.

The Attack Surface Problem

This deep dive on how kernel anti-cheats work covers the mechanics of what kernel anti-cheats can observe, but it is worth dwelling on what it means to have a kernel driver present that was written by a game company’s security contractors, receives regular updates, and runs continuously on your machine.

A kernel driver bug is not a user-space crash. There is no process boundary to contain the damage, no privilege check to fail gracefully. A null pointer dereference in Ring 0 is a system crash. A heap overflow in a kernel driver is a potential privilege escalation: an attacker in Ring 3 exploiting a bug in the anti-cheat driver to gain Ring 0 execution. These are not theoretical concerns.

The most documented case is mhyprot2.sys, the kernel driver from Genshin Impact’s anti-cheat system. The driver exposed an IOCTL interface that allowed any process — without authentication or privilege check — to trigger arbitrary kernel memory reads and writes. Ransomware operators discovered this and incorporated it into their tooling. By dropping and loading mhyprot2.sys (a legitimately signed driver), they could bypass endpoint detection and response tools that had no visibility into driver-level operations, terminate protected antivirus processes, and operate with effectively unrestricted system access. The driver shipped to millions of game installations and remained vulnerable for an extended period.

This technique — bringing a legitimate but vulnerable signed driver to gain kernel access — is broadly categorized as Bring Your Own Vulnerable Driver (BYOVD), and it has appeared in the arsenal of multiple ransomware groups and APT actors. The vulnerability is structural: any code signed by a trusted certificate authority can load at Ring 0, and any bug in that code is a kernel-level bug. The BYOVD pattern is well documented by security researchers, and game anti-cheat drivers have contributed multiple entries to that catalog.

Hypervisor Escalation

The cheat side of this arms race did not stop at Ring 0. Some sophisticated cheat implementations now run the game inside a Type-1 hypervisor, using Intel VT-x or AMD-V to virtualize the operating system itself. The game and its anti-cheat driver run as a guest VM. The cheat runs at the hypervisor level, below the guest OS, where it can read and modify guest physical memory without the guest OS ever seeing a page fault or a handle operation. From the perspective of any Ring 0 software inside the VM, the memory looks unmodified.

Anti-cheat vendors have responded with their own hypervisors. FACEIT, used for competitive Counter-Strike, deploys a hypervisor component. Riot’s Vanguard has incorporated hypervisor-level detection for some threat categories. The fundamental technique is using VM exit events to monitor guest behavior: detecting when a process attempts to install a hypervisor, watching for CPUID spoofing that would indicate a nested virtualization environment, and validating that the hardware timestamp counter behaves consistently with bare-metal execution.

Windows 11’s Virtualization-Based Security (VBS) and Hypervisor-Protected Code Integrity (HVCI) provide a structural counter to some of these techniques on the defender side. HVCI moves code integrity validation to a more privileged Virtual Trust Level (VTL1), which means that even kernel-mode attackers in VTL0 cannot load unsigned code. Many BYOVD attacks rely on patching g_CiEnabled — the kernel flag governing DSE — and HVCI prevents this by protecting that memory from VTL0 writes. The practical constraint is that HVCI carries meaningful performance overhead and is incompatible with some older drivers, so adoption is not universal.

What Users Are Accepting

Every kernel anti-cheat installation is a bet: the game company’s security team writes and maintains code that runs at the highest privilege level on your machine, and you trust that they have done it carefully. The mhyprot2 incident is an illustration of what happens when that trust is misplaced, but it is not unique. The driver attack surface is real, continuous, and grows with each update the anti-cheat vendor ships.

The alternative — user-mode anti-cheat — concedes the arms race to organized cheat developers who have already demonstrated willingness to operate kernel drivers. The current equilibrium, where both cheats and anti-cheats fight for Ring 0 and now the hypervisor layer below it, is a predictable outcome of that dynamic.

Reasonable people disagree about whether that tradeoff is worth it for a multiplayer game. That debate is more productive when both sides understand what kernel-level access actually means for the machines that run it.

Was this interesting?