For the complete documentation index, see llms.txt. This page is also available as Markdown.

BYOVD Fundamentals

Part 1 — BYOVD Fundamentals & the Windows Kernel Attack Surface

In this part: the integrity controls BYOVD sidesteps, exactly why a signed-but-vulnerable driver defeats them, the mechanics of loading a driver from user mode, the device/DACL model, and the end-to-end operational lifecycle. Parts 2 and 3 get hands-on with reversing and exploitation.


1.1 Ring 0 and why it's the crown jewel

Windows runs code in two privilege rings that matter to us:

  • Ring 3 (user mode): every normal process. Isolated address spaces, mediated access to hardware, subject to ACLs and integrity levels.

  • Ring 0 (kernel mode): ntoskrnl.exe, the HAL, and every loaded driver. One flat, shared address space. Code here can read/write any physical page, any process's memory, disable security callbacks, and rewrite the structures that define who is SYSTEM.

There is essentially no security boundary inside ring 0. A driver is as privileged as the kernel itself. That is why Microsoft invests so heavily in controlling what gets to run there — and why an attacker who can execute even a tiny amount of logic in the kernel has effectively won the box.

The privilege ladder an attacker climbs looks like this:

Low-priv user ──► Admin/SeLoadDriver ──► Load signed driver ──► IOCTL abuse ──► Ring 0 R/W ──► SYSTEM / rootkit
                  (UAC bypass, etc.)      (BYOVD starts here)

Important framing: BYOVD is not usually a remote exploit. It's a local privilege escalation and defense-evasion primitive. The attacker already needs local admin (or at least SeLoadDriverPrivilege) to install the driver. What BYOVD buys is the jump from admin (still constrained by EDR, still ring 3) to kernel (game over). That gap — admin-to-kernel — is exactly where modern defenses (EDR, tamper protection, credential guard) live, and BYOVD tunnels underneath all of them.

1.2 The integrity controls in your way

Driver Signature Enforcement (DSE)

On 64-bit Windows, the kernel's code-integrity component (ci.dll) verifies an Authenticode signature before mapping a driver image. No valid chain to a trusted root → STATUS_INVALID_IMAGE_HASH, load refused. DSE is the wall.

A single global variable inside ci.dll — historically referred to as g_CiOptions (and the older nt!g_CiEnabled) — governs the policy. If you have a kernel write primitive, flipping that value to 0 disables enforcement and lets you load any unsigned driver. (More on this attack in Part 3; note HVCI protects this variable, see below.)

WHQL, cross-signing, and the 2015 policy

Since Windows 10 1607, newly-signed kernel drivers must carry a Microsoft attestation / WHQL signature obtained through the Hardware Dev Center. This is why attackers prize older, pre-2015 signed drivers (grandfathered in) and still-valid vendor drivers (RTCore64, dbutil, gdrv, WinRing0…) — the signature requirement is already met for them.

PatchGuard (Kernel Patch Protection, KPP)

PatchGuard periodically checks that critical kernel structures (SSDT, IDT, key ntoskrnl code, MSRs like LSTAR, GDT) haven't been tampered with. If it detects patching, it bugchecks the box (CRITICAL_STRUCTURE_CORRUPTION, 0x109). Why this matters for BYOVD: the classic "hook the syscall table" rootkit is dead on x64. Modern kernel attackers prefer data-only attacks — edit an EPROCESS token, toggle a callback array entry — which PatchGuard does not watch. BYOVD pairs naturally with data-only techniques.

HVCI / Memory Integrity (VBS)

Hypervisor-Enforced Code Integrity uses the CPU virtualization extensions to run code-integrity checks in a more-privileged context (VTL1) than even the kernel (VTL0). It enforces W^X on kernel pages: a page can be writable or executable, never both, and executable kernel pages must pass code integrity. Consequences for the attacker:

  • You cannot execute injected kernel shellcode — no allocating RWX and jumping to it. This kills a whole class of "map my code and call it" exploits.

  • g_CiOptions and other CI structures are protected — the naive DSE-flip is neutralized on HVCI systems.

  • You are pushed toward data-only exploitation — token theft, callback removal, and abusing existing signed code still work, because they don't introduce new executable kernel code.

HVCI is the modern speed bump. It's on by default on many OEM Windows 11 installs and on Secured-core PCs, but is still absent on a large fraction of the fleet — which is why BYOVD remains devastatingly effective in practice.

The Vulnerable Driver Blocklist

Microsoft ships a driver blocklist (a WDAC policy identifying known-abused drivers by hash/signer). When enabled, HVCI-capable systems refuse to load listed drivers. It historically updated slowly (a gap attackers exploited for years), but since 2023 it's on by default for new Windows 11 installs and updated more regularly. The blocklist is finite and reactive — a freshly-discovered vulnerable driver isn't on it yet, which is the entire economy of "new BYOVD driver" research.

Why BYOVD beats all of it (summary table)

Control
Does BYOVD defeat it?
How

DSE

The driver is genuinely signed.

WHQL / cross-sign

Uses drivers that already have valid MS signatures.

PatchGuard

Uses data-only edits KPP doesn't monitor.

HVCI

⚠️ Partially

Data-only attacks (token theft) still work; code-exec & DSE-flip don't.

Blocklist

⚠️ If listed

Beaten by using a not-yet-listed vulnerable driver.

EDR (ring 3)

Kernel code executes beneath EDR's user-mode hooks; can then blind it.

1.3 How a driver actually gets loaded

To reach a driver's IOCTL handler you must first get it into the kernel. There are three common mechanisms; the Service Control Manager (SCM) route is by far the most common in BYOVD tooling.

Method A — Service Control Manager (needs admin)

A kernel driver is just a service of type SERVICE_KERNEL_DRIVER (1). The SCM creates a registry key under HKLM\SYSTEM\CurrentControlSet\Services\<name> and, on start, calls NtLoadDriver, which triggers the CI signature check and maps the image.

From the command line the same thing is a two-liner — this is what most real-world BYOVD loaders do under the hood:

Detection note (previewing Part 3): CreateService with a kernel type and a binPath outside C:\Windows\System32\drivers is a loud signal. Event ID 4697 (service installed) and Sysmon 13 (registry set on ...\Services\*\ImagePath) both fire. Serious operators know this and try to minimize the on-disk/registry footprint.

Method B — NtLoadDriver directly (needs SeLoadDriverPrivilege)

You can skip the SCM and call NtLoadDriver yourself, pointing it at a registry key you create under \Registry\Machine\System\CurrentControlSet\Services\.... This requires SeLoadDriverPrivilege, which admins have (disabled by default, enable it with AdjustTokenPrivileges). Slightly quieter than SCM but still touches the registry.

Method C — abusing an already-loaded driver

The cleanest BYOVD variant loads no new driver at all: it targets a vulnerable driver that's already present (shipped by an OEM, a game anticheat, an installed utility). No CreateService, no new .sys on disk, far less telemetry. Enumerate loaded modules (NtQuerySystemInformation(SystemModuleInformation)) and check them against a known-vulnerable list.

1.4 The device object and its DACL — a subtle attack surface

When a driver initializes it typically calls IoCreateDevice and then IoCreateSymbolicLink to expose a name like \??\RTCore64, reachable from user mode as \\.\RTCore64. Two properties decide who can talk to it:

  1. The device's DACL. If the driver uses IoCreateDeviceSecure with a tight SDDL string, only SYSTEM/Administrators can open it. Many vulnerable drivers instead use plain IoCreateDevice, which inherits a permissive default — so even a low-integrity or non-admin process can CreateFile the device. Combined with an FILE_ANY_ACCESS IOCTL, that turns a "need admin" bug into a "any user" LPE.

  2. The IOCTL's Access field (bits 15–14 of the code). FILE_ANY_ACCESS means the I/O manager won't require read/write access on the handle to dispatch the IOCTL.

If CreateFile succeeds from a medium-integrity, non-admin shell, you've discovered a device with a weak DACL — worth checking on every target driver.

1.5 The complete BYOVD operational lifecycle

Putting the pieces together, an end-to-end operation looks like this:

Each stage has both an offensive technique and a defensive tripwire — we map them fully in Part 3 (see the detection map). Keep the lifecycle in mind: most BYOVD detections don't target the exploit itself (which is invisible, running in the kernel) — they target the noisy setup and teardown around it.

1.6 The toolchain & the ecosystem

A few resources define the modern BYOVD landscape. Know them:

  • LOLDrivers (loldrivers.io) — the canonical, community-maintained catalog of known-vulnerable and malicious drivers, with hashes, sample IOCTLs, and detection artifacts. Your first stop for both offense (candidates) and defense (blocklist source, hunting IOCs).

  • Microsoft's recommended driver block rules — the official blocklist WDAC policy XML; diffable to see what's newly covered.

  • sc.exe / OpenSCManager — loading.

  • IDA Pro / Ghidra — reversing (Part 2).

  • WinDbg (windbg, kd) — kernel debugging, resolving offsets, validating primitives against live memory.

  • DeviceIoControl fuzzers (e.g. IOCTLbf-style, ioctlfuzzer, custom harnesses) — discovering reachable/buggy IOCTLs (Part 2).

  • Public research frameworks & write-ups: KDU (Kernel Driver Utility) by hfiref0x, the Physmem primitives collection, and numerous EDR-killer write-ups (AuKill, Terminator, Backstab, Spyboy).

The canonical vulnerable drivers you'll see referenced

Driver
Vendor / origin
Notable primitive

RTCore64.sys

MSI Afterburner / Micro-Star

Arbitrary R/W via MmMapIoSpace (MSR + phys). CVE‑2019‑16098

dbutil_2_3.sys

Dell

Arbitrary R/W. CVE‑2021‑21551

gdrv.sys

GIGABYTE

Arbitrary phys R/W, MSR write. CVE‑2018‑19320 etc.

Capcom.sys

Capcom (game DRM)

IOCTL that calls a user-supplied pointer in ring 0

WinRing0.sys

OpenLibSys (many OEM tools)

MSR + phys read/write

AsrDrv10x.sys

ASRock

phys R/W, MSR

iqvw64e.sys

Intel

Used by RobbinHood ransomware to disable AV

procexp.sys

Sysinternals Process Explorer

Handle/kill primitives (EDR-kill abuse)

Each of these is a case study in a different vulnerability class — which is exactly what Part 2 dissects.


Key takeaways for Part 1

  • BYOVD wins because the driver's signature is real; the bug is in the driver, not the kernel, so DSE/WHQL/PatchGuard are all satisfied.

  • HVCI is the one control that meaningfully constrains BYOVD, pushing attackers from code-exec to data-only techniques.

  • Loading is loud (CreateService/registry/ImageLoad); the exploit itself is quiet. Defense concentrates on the setup.

  • The whole game is finding the ring‑3‑to‑ring‑0 bridge inside a signed driver.

Continue to Part 2 — Reversing Drivers to Find IOCTLs & Vulnerability Classes →

Last updated