· 6 min read ·

The Memory War at Ring Zero: Inside Kernel Anti-Cheat Architecture

Source: hackernews

The escalation from user-mode to kernel-mode anti-cheat is the story of what happens when both sides of a technical arms race keep moving to lower software layers until they hit hardware. A recent detailed writeup on kernel anti-cheat architecture traces the mechanics clearly. The part worth dwelling on is not just how these systems work, but what the current threat landscape looks like from both sides, and what deploying this architecture at scale on consumer machines has actually cost.

Why Ring 0 Became Necessary

Windows enforces four CPU privilege rings, though it uses only two in practice. Ring 3 is where applications run: memory access is bounded by the process’s virtual address space, sensitive operations require system calls that the kernel can deny, and the environment is sandboxed in ways that are robust in the normal case. Ring 0 is where drivers run: physical memory is directly accessible, privileged CPU instructions execute without restriction, and the page tables that define every process’s view of memory are available for modification.

The first cheat software that moved to ring 0 had a decisive advantage. A kernel driver can read a game process’s virtual memory by walking the target’s EPROCESS structure and associated page tables directly, without calling ReadProcessMemory at all. It can hide itself from process listings by unlinking its own EPROCESS.ActiveProcessLinks entry via Direct Kernel Object Manipulation (DKOM). It can intercept the system calls an anti-cheat makes and return fabricated data. No user-mode protection survives a competent ring 0 adversary.

The Callback Infrastructure

Once anti-cheat vendors accepted the need for kernel drivers, their primary visibility mechanism became the Windows kernel callback API: documented, Microsoft-supported interfaces designed for exactly this kind of system monitoring.

PsSetLoadImageNotifyRoutine registers a callback that fires synchronously whenever any PE image is mapped into any process or loaded into the kernel. The IMAGE_INFO structure passed to the callback includes ImageBase, ImageSize, and a SystemModeImage flag distinguishing kernel driver loads from user-mode DLL loads. A cheat injecting a DLL into the game process appears here before the injected code executes; a cheat loading a kernel driver appears here too.

ObRegisterCallbacks is the modern replacement for the SSDT hooks that anti-cheats used on 32-bit Windows. It installs a pre-operation callback on object manager handle creation. When any process opens a handle to the protected game process, the anti-cheat callback fires and can strip PROCESS_VM_READ and PROCESS_VM_WRITE from the desired access mask before the handle is granted. The calling process receives a valid handle; it simply cannot use it for memory access.

OB_PREOP_CALLBACK_STATUS HandlePreCallback(
    PVOID Context,
    POB_PRE_OPERATION_INFORMATION Info)
{
    if (Info->ObjectType == *PsProcessType) {
        ACCESS_MASK denied = PROCESS_VM_READ
                           | PROCESS_VM_WRITE
                           | PROCESS_VM_OPERATION;
        if (!IsTrustedCaller(PsGetCurrentProcess())) {
            Info->Parameters->CreateHandleInformation
                .DesiredAccess &= ~denied;
        }
    }
    return OB_PREOP_SUCCESS;
}

This approach replaced SSDT hooking because Kernel Patch Protection (PatchGuard) made the old technique untenable. PatchGuard checksums the SSDT (KeServiceDescriptorTable), the interrupt descriptor table, the global descriptor table, and critical kernel function preambles at randomized intervals. Divergence from expected values produces bug check 0x109: CRITICAL_STRUCTURE_CORRUPTION. Crucially, PatchGuard enforces this symmetrically: it constrains cheats and anti-cheats equally, which is why callbacks became the standard approach for both.

Manual Mapping and the Detection Game

Cheat drivers that want to stay off the loaded module list use manual mapping: loading a PE directly into kernel memory without going through MmLoadSystemImage, the function that adds entries to PsLoadedModuleList. Tools like KDMapper accomplish this by abusing a signed but vulnerable driver to execute arbitrary kernel code, then performing PE loading and relocation manually. The resulting driver is invisible to any check that queries the standard module list.

Anti-cheats counter by comparing PsLoadedModuleList against physical memory directly. They scan for PE headers (MZ magic followed by valid IMAGE_NT_HEADERS) at memory regions not backed by any known module. They also audit the callback arrays themselves: PsSetLoadImageNotifyRoutine internally appends entries to the unexported PspLoadImageNotifyRoutine array. An anti-cheat that reads this array directly and checks each function pointer against the loaded module list can identify callbacks registered from manually-mapped code, where the pointer resolves to a memory region with no corresponding LDR_DATA_TABLE_ENTRY.

Both sides also watch the SSDT entries themselves. Even though PatchGuard detects persistent modifications, a cheat can transiently hook an SSDT entry, perform its reads, and unhook before PatchGuard’s next sweep. Anti-cheats that verify SSDT entries directly rather than relying on PatchGuard close that window.

BYOVD: When the Shield Becomes the Weapon

The Bring Your Own Vulnerable Driver (BYOVD) pattern turns driver signature enforcement against itself. An attacker with a legitimately signed driver containing an exploitable IOCTL handler can use that driver to execute arbitrary kernel code without needing to bypass signing at all. Windows loads it without complaint; the vulnerability does the rest.

The mhyprot2.sys driver from Genshin Impact is the textbook case. The driver, shipped with miHoYo’s game and remaining on disk after uninstallation, exposed IOCTL handlers that permitted arbitrary kernel memory reads and writes from unprivileged user-mode processes with no caller authentication. Trend Micro documented ransomware groups using it to kill endpoint protection software in 2022. A signed EasyAntiCheat.sys build was used similarly by the BlackByte ransomware group, as Sophos documented in 2023. loldrivers.io now catalogs hundreds of drivers with confirmed BYOVD abuse histories.

The structural problem is that any exploitable bug in a widely distributed kernel anti-cheat driver is a kernel-level vulnerability on every machine running it. For always-on, boot-start drivers like Vanguard’s vgk.sys, the exposure window is the machine’s entire uptime, not just time spent in the game.

Hardware Layer Escalation

The most recent escalation involves hardware that operates below software entirely. DMA (Direct Memory Access) cheating devices, typically FPGAs installed in a PCIe slot, read host system RAM directly over the PCIe bus, bypassing the CPU, the OS, and every callback and scan a kernel driver can implement. There is no process to detect, no handle to intercept, no entry in any module list. Projects like PCILeech document the technique; commercial implementations add PCIe device ID spoofing, allowing the FPGA to impersonate a legitimate network card or NVMe drive at the PCI configuration space level.

Anti-cheats respond with IOMMU monitoring for unexpected memory access patterns, PCI configuration space scanning for devices without corresponding drivers, and timing-based detection, since simultaneous DMA reads introduce measurable memory bus latency visible to the host. FPGA firmware that accurately spoofs legitimate device signatures degrades the reliability of hardware ID approaches, and the contest there has no obvious termination point.

Riot’s June 2023 mandate for TPM 2.0 and Secure Boot addresses a different hardware attack: bootkits that load cheat drivers before OS initialization. The TPM maintains Platform Configuration Register (PCR) values across the boot sequence; an anti-cheat can request a signed PCR attestation quote to verify that firmware and Secure Boot state were unmodified from power-on through OS load. Combined with HVCI (Hypervisor-Protected Code Integrity), which uses Hyper-V’s Extended Page Tables to prevent unsigned code from being made executable in the kernel, this covers the attack surface from boot through runtime for software-based cheats. DMA hardware operates outside the scope of what TPM attestation can address.

The Position This Creates

A gaming PC with Valorant, Fortnite, and an Escape from Tarkov installation has kernel drivers from multiple commercial vendors running simultaneously, each with ring 0 access, each updated on their own schedule outside the Windows Update channel, and each a potential BYOVD target. The technical architecture of each driver uses legitimate Windows primitives more or less as Microsoft intended. The risk is the aggregate attack surface of maintaining this configuration across millions of consumer machines where neither the vendors’ software quality nor their update cadence is subject to scrutiny equivalent to OS components.

The arms race has one more logical level available: cheats running at ring -1 in a custom hypervisor, below a kernel anti-cheat’s visibility entirely. Some competitive implementations already operate this way, using nested virtualization to intercept the anti-cheat’s own memory inspection calls. The counter is anti-cheats that also operate from the hypervisor layer, using EPT hooks to observe both the game and the ring 0 driver from above. Whether that escalation happens broadly depends on which games have stakes high enough to justify the engineering investment on both sides; for games with meaningful prize pools and active cheating economies, it seems more like a timing question than an open one.

Was this interesting?