Windows Driver 0-Day Research
Use this skill as the coordinator for closed-source Windows driver vulnerability research. Load supporting skills only when their phase is reached:
ida-reverse: binary loading, decompilation, types, xrefs, and data-flow work.
vuln-research: general fuzzing, variant analysis, and crash minimization.
patch-diff-exploit and binary-diff: cross-version and incomplete-fix hunting.
exploit-dev: primitive construction after a vulnerability is confirmed.
code-audit: use instead of binary-only analysis when source is available.
Do not begin with exploitation. First prove reachability, root cause, affected versions, and driver culpability.
Required outputs
Maintain these artifacts in a case directory without modifying the original driver:
case/
├── samples/ # Read-only copies, INF/CAT, version metadata
├── static/
│ ├── surface.md # Devices, ACLs, dispatch paths, IOCTL table
│ ├── ioctls.csv # Code, method, access, schemas, handler, confidence
│ └── types.h # Reconstructed request/object types
├── harness/ # Reproducible user-mode test or fuzzer
├── corpus/ # Valid seeds and minimized crashing inputs
├── crashes/<id>/ # Dump, debugger log, exact input, environment
└── report.md # Root cause and affected-version evidence
For every conclusion, distinguish observed, inferred, and unverified facts.
Phase 0: Preserve and fingerprint
- Copy the
.sys, INF, CAT, installer, and related DLLs into the case directory.
- Record SHA-256, file version, signer, signature status, architecture, timestamp, and source package.
- Record the analysis OS build, target VM build, virtualization settings, VBS/HVCI state, and symbol path.
- Preserve at least one clean VM snapshot before loading the driver.
- Search local notes and public vulnerability lists by hash, filename, signer, product, and version. A renamed known-vulnerable driver is not a 0-day.
Do not execute an unknown driver on the analysis host.
Phase 1: Map the externally reachable surface
Installation and access control
Recover from INF, registry setup, and code:
- Service name, start type, dependencies, filter class, altitude, and load conditions.
- Named devices, DOS symbolic links, device interfaces, control devices, and per-session devices.
- SDDL from INF
Security, IoCreateDeviceSecure, registry values, or framework configuration.
- Whether a standard user, AppContainer, low-integrity process, service account, or administrator can obtain a handle.
- Required sharing flags, desired access, privileges, session, and device state.
Test access with the lowest-privileged token first. Record the exact CreateFile/NtCreateFile parameters and resulting status.
WDM dispatch recovery
Start at the real entry point after compiler and security-cookie thunks. Recover:
DriverObject->MajorFunction[], especially CREATE, CLOSE, CLEANUP, READ, WRITE, DEVICE_CONTROL, INTERNAL_DEVICE_CONTROL, PNP, and POWER.
DriverUnload, FastIoDispatch, completion routines, cancel routines, work items, DPCs, timers, callbacks, and lower-device forwarding.
- Dispatch trampolines that route by device extension, minor function, or IOCTL family.
KMDF recovery
Find WdfDriverCreate, device/queue creation, and callback registration. Recover:
EvtDeviceAdd, EvtIoDeviceControl, EvtIoInternalDeviceControl, read/write callbacks, file-object callbacks, queue stop/resume/cancel callbacks, and cleanup callbacks.
- Queue dispatch mode, synchronization scope, execution level, request ownership, and parent-child object lifetimes.
- WDF function-table calls using symbols or types matching the exact framework version. Do not label callbacks from guessed table indexes.
Other ingress paths
Check whether the driver is also reachable through:
- Filtered IRPs from another device stack.
- File-system minifilter communication ports and callbacks.
- Network/WFP, NDIS, USB, Bluetooth, HID, storage, ACPI, or display class requests.
- Shared memory, sections, events, registry callbacks, ALPC, or companion services.
- Firmware, PCI configuration, MMIO, port I/O, or embedded command streams.
Phase 2: Reconstruct every IOCTL contract
Decode each control code into device type, function, transfer method, and required access. Record aliases and ranges, not only switch constants.
| Method |
Primary request locations |
Review focus |
METHOD_BUFFERED |
Irp->AssociatedIrp.SystemBuffer |
shared input/output buffer, returned length, partial initialization |
METHOD_IN_DIRECT |
input in SystemBuffer, MDL describes second buffer |
direction assumptions, MDL length, writable mappings |
METHOD_OUT_DIRECT |
input in SystemBuffer, MDL describes second buffer |
output bounds, mapping failures, information leaks |
METHOD_NEITHER |
Type3InputBuffer and Irp->UserBuffer |
probing, capture, exception handling, double fetch, requestor mode |
For KMDF, map WdfRequestRetrieve*Buffer, unsafe user-buffer retrieval, memory objects, MDLs, and request completion lengths back to the same model.
For every IOCTL, reconstruct:
- Minimum and maximum input/output lengths.
- Fixed header, discriminant/opcode, flags, counts, offsets, variable tails, alignment, and nested records.
- Embedded pointers, handles, physical addresses, kernel addresses, callbacks, and user-provided function pointers.
- 32-bit/WOW64 layouts and pointer-width conversions.
- State prerequisites and cross-request object IDs, cookies, or handles.
- All validation branches and the point where data is captured into trusted storage.
A successful ProbeForRead or ProbeForWrite does not make later user-memory access safe. Look for mutation between check and use.
Phase 3: Directed static vulnerability review
Trace untrusted fields to allocation, copy, mapping, arithmetic, indexing, indirect call, object lookup, and hardware-access sinks. Work backward from dangerous imports and forward from request buffers.
Prioritize:
METHOD_NEITHER, unsafe KMDF buffers, embedded pointers, and RequestorMode confusion.
- Size arithmetic, narrowing conversions, signed comparisons, count-times-stride calculations, and output-length accounting.
memcpy/memmove/RTL copies, structure tails, array indexes, and offset-plus-length checks.
- Async ownership: pending IRPs, cancellation, cleanup/close, work items, DPCs, timers, and completion routines.
- Shared state accessed from parallel queues or multiple handles without a coherent lock/refcount protocol.
- Object or handle lookup with wrong access mode, type, lifetime, or reference balancing.
MmMapIoSpace, MmMapLockedPagesSpecifyCache, MDLs, physical memory, MSRs, I/O ports, PCI config, arbitrary process attachment, and kernel virtual addresses.
- Uninitialized pool/stack data returned through output buffers or completion lengths.
- Device ACL, IOCTL access-bit, privilege, impersonation, and ownership mistakes.
- PnP/power teardown races and stale device-extension or framework-object references.
Use references/review-checklist.md during this phase.
Phase 4: Build a semantic harness
Start with a deterministic exerciser before mutation fuzzing.
- Enumerate and open each reachable interface under both standard-user and administrator tokens.
- Replay known-good application traffic when available; record request order and schemas.
- Implement one typed builder per IOCTL family. Keep serialization separate from transport.
- Log seed, iteration, device path, open flags, IOCTL, input/output sizes, bytes, thread schedule, status, returned length, and elapsed time.
- Add a watchdog and preserve the last submitted test case outside the guest when possible.
Mutation dimensions:
- Zero, one-less, exact, one-more, page-boundary, signed-boundary, and maximum lengths.
- Inconsistent count/size/offset fields; integer-wrap combinations.
- Null, low, noncanonical, kernel-range, guard-page, read-only, freed, aliased, and cross-page pointers.
- Misalignment and 32/64-bit layout confusion.
- Input/output aliasing and overlapping nested buffers.
- Valid request sequences with repeated create/use/free/close operations.
- Parallel IOCTL, cleanup, close, cancellation, and handle duplication.
- PnP/power transitions only in a disposable VM with a recoverable device setup.
Preserve enough valid structure to reach deep code. Pure random IOCTL spraying usually measures the rejection path.
Phase 5: Dynamic verification
Use a disposable VM with kernel debugging and a targeted Driver Verifier configuration. Record the exact verifier settings. Prefer the smallest set that exposes the suspected class; broad settings can change timing and obscure causality.
Useful debugger evidence includes:
lmvm <driver>
!drvobj <driver-object> 7
!devobj <device-object>
!irp <irp>
!analyze -v
.exr -1
.cxr <context>
kv
!pool <address>
!verifier
!locks
!deadlock
Set breakpoints on the recovered dispatch/callback and suspected sink. Confirm:
- The harness reaches the intended branch.
- Register and memory values match the reconstructed schema.
- The crashing access derives from controlled input or a controlled lifetime transition.
- The target driver, rather than Verifier, another filter, or malformed harness state, owns the root cause.
Repeat without unrelated instrumentation when timing permits. Keep the dump and complete debugger transcript.
Phase 6: Crash triage and minimization
For each crash:
- Hash the tuple of bugcheck/exception, faulting instruction, top target-driver frames, allocation/free stack, and semantic operation.
- Reproduce from the clean snapshot at least three times.
- Minimize bytes, lengths, request sequence, concurrency, and verifier flags independently.
- Identify the first invalid state transition or unsafe operation, not merely the final fault.
- Determine whether the condition is memory corruption, disclosure, race, authorization bypass, or intended privileged functionality.
- Test adjacent driver and OS versions with the same minimized reproducer.
Do not call a hang a deadlock without lock/wait evidence. Do not call a Verifier stop exploitable without proving the underlying invariant violation.
Phase 7: Variant and novelty analysis
Use patch-diff-exploit when fixed and vulnerable versions exist; use binary-diff to migrate names and recovered types.
Search for:
- Sibling IOCTLs missing the newly added validation.
- Checks applied before one dereference but not repeated after a user-memory re-read.
- Fixes limited to one architecture, product SKU, queue, or compatibility handler.
- Equivalent helpers in related vendor drivers.
- Error paths that bypass the fixed reference, lock, or cleanup protocol.
Novelty requires evidence. Compare hashes, versions, advisories, CVEs, vendor release notes, driver blocklists, and known-vulnerable-driver datasets. Label the result candidate 0-day until that search is complete.
Phase 8: Exploitability handoff
After confirming root cause, document:
- Attacker prerequisites and lowest token that reaches the path.
- Controlled bytes, size, offset, timing, target object, and repeatability.
- Read/write/disclosure/lifetime primitive potential.
- Pool type, allocation size/tag, allocation/free sites, IRQL, processor context, and reclaim constraints.
- Relevant mitigations: KASLR, SMEP/SMAP, CFG/KCFG, CET, VBS/HVCI, pool hardening, and driver blocklist state.
Then load exploit-dev. Keep the minimal crash PoC separate from later exploit work.
Completion gate
Do not report a finding as confirmed until all applicable items pass:
1---2name: windows-driver-0day3description: Windows kernel-driver vulnerability discovery and reverse-engineering workflow for WDM and KMDF .sys files. Use when auditing an unknown driver, recovering device and IOCTL attack surfaces, reconstructing request schemas, fuzzing IOCTL handlers, triaging Driver Verifier crashes, performing cross-version variant analysis, or assessing whether a driver flaw is a new vulnerability.4---56# Windows Driver 0-Day Research78Use this skill as the coordinator for closed-source Windows driver vulnerability research. Load supporting skills only when their phase is reached:910- `ida-reverse`: binary loading, decompilation, types, xrefs, and data-flow work.11- `vuln-research`: general fuzzing, variant analysis, and crash minimization.12- `patch-diff-exploit` and `binary-diff`: cross-version and incomplete-fix hunting.13- `exploit-dev`: primitive construction after a vulnerability is confirmed.14- `code-audit`: use instead of binary-only analysis when source is available.1516Do not begin with exploitation. First prove reachability, root cause, affected versions, and driver culpability.1718## Required outputs1920Maintain these artifacts in a case directory without modifying the original driver:2122```text23case/24├── samples/ # Read-only copies, INF/CAT, version metadata25├── static/26│ ├── surface.md # Devices, ACLs, dispatch paths, IOCTL table27│ ├── ioctls.csv # Code, method, access, schemas, handler, confidence28│ └── types.h # Reconstructed request/object types29├── harness/ # Reproducible user-mode test or fuzzer30├── corpus/ # Valid seeds and minimized crashing inputs31├── crashes/<id>/ # Dump, debugger log, exact input, environment32└── report.md # Root cause and affected-version evidence33```3435For every conclusion, distinguish `observed`, `inferred`, and `unverified` facts.3637## Phase 0: Preserve and fingerprint38391. Copy the `.sys`, INF, CAT, installer, and related DLLs into the case directory.402. Record SHA-256, file version, signer, signature status, architecture, timestamp, and source package.413. Record the analysis OS build, target VM build, virtualization settings, VBS/HVCI state, and symbol path.424. Preserve at least one clean VM snapshot before loading the driver.435. Search local notes and public vulnerability lists by hash, filename, signer, product, and version. A renamed known-vulnerable driver is not a 0-day.4445Do not execute an unknown driver on the analysis host.4647## Phase 1: Map the externally reachable surface4849### Installation and access control5051Recover from INF, registry setup, and code:5253- Service name, start type, dependencies, filter class, altitude, and load conditions.54- Named devices, DOS symbolic links, device interfaces, control devices, and per-session devices.55- SDDL from INF `Security`, `IoCreateDeviceSecure`, registry values, or framework configuration.56- Whether a standard user, AppContainer, low-integrity process, service account, or administrator can obtain a handle.57- Required sharing flags, desired access, privileges, session, and device state.5859Test access with the lowest-privileged token first. Record the exact `CreateFile`/`NtCreateFile` parameters and resulting status.6061### WDM dispatch recovery6263Start at the real entry point after compiler and security-cookie thunks. Recover:6465- `DriverObject->MajorFunction[]`, especially `CREATE`, `CLOSE`, `CLEANUP`, `READ`, `WRITE`, `DEVICE_CONTROL`, `INTERNAL_DEVICE_CONTROL`, `PNP`, and `POWER`.66- `DriverUnload`, `FastIoDispatch`, completion routines, cancel routines, work items, DPCs, timers, callbacks, and lower-device forwarding.67- Dispatch trampolines that route by device extension, minor function, or IOCTL family.6869### KMDF recovery7071Find `WdfDriverCreate`, device/queue creation, and callback registration. Recover:7273- `EvtDeviceAdd`, `EvtIoDeviceControl`, `EvtIoInternalDeviceControl`, read/write callbacks, file-object callbacks, queue stop/resume/cancel callbacks, and cleanup callbacks.74- Queue dispatch mode, synchronization scope, execution level, request ownership, and parent-child object lifetimes.75- WDF function-table calls using symbols or types matching the exact framework version. Do not label callbacks from guessed table indexes.7677### Other ingress paths7879Check whether the driver is also reachable through:8081- Filtered IRPs from another device stack.82- File-system minifilter communication ports and callbacks.83- Network/WFP, NDIS, USB, Bluetooth, HID, storage, ACPI, or display class requests.84- Shared memory, sections, events, registry callbacks, ALPC, or companion services.85- Firmware, PCI configuration, MMIO, port I/O, or embedded command streams.8687## Phase 2: Reconstruct every IOCTL contract8889Decode each control code into device type, function, transfer method, and required access. Record aliases and ranges, not only switch constants.9091| Method | Primary request locations | Review focus |92|---|---|---|93| `METHOD_BUFFERED` | `Irp->AssociatedIrp.SystemBuffer` | shared input/output buffer, returned length, partial initialization |94| `METHOD_IN_DIRECT` | input in `SystemBuffer`, MDL describes second buffer | direction assumptions, MDL length, writable mappings |95| `METHOD_OUT_DIRECT` | input in `SystemBuffer`, MDL describes second buffer | output bounds, mapping failures, information leaks |96| `METHOD_NEITHER` | `Type3InputBuffer` and `Irp->UserBuffer` | probing, capture, exception handling, double fetch, requestor mode |9798For KMDF, map `WdfRequestRetrieve*Buffer`, unsafe user-buffer retrieval, memory objects, MDLs, and request completion lengths back to the same model.99100For every IOCTL, reconstruct:101102- Minimum and maximum input/output lengths.103- Fixed header, discriminant/opcode, flags, counts, offsets, variable tails, alignment, and nested records.104- Embedded pointers, handles, physical addresses, kernel addresses, callbacks, and user-provided function pointers.105- 32-bit/WOW64 layouts and pointer-width conversions.106- State prerequisites and cross-request object IDs, cookies, or handles.107- All validation branches and the point where data is captured into trusted storage.108109A successful `ProbeForRead` or `ProbeForWrite` does not make later user-memory access safe. Look for mutation between check and use.110111## Phase 3: Directed static vulnerability review112113Trace untrusted fields to allocation, copy, mapping, arithmetic, indexing, indirect call, object lookup, and hardware-access sinks. Work backward from dangerous imports and forward from request buffers.114115Prioritize:1161171. `METHOD_NEITHER`, unsafe KMDF buffers, embedded pointers, and `RequestorMode` confusion.1182. Size arithmetic, narrowing conversions, signed comparisons, count-times-stride calculations, and output-length accounting.1193. `memcpy`/`memmove`/RTL copies, structure tails, array indexes, and offset-plus-length checks.1204. Async ownership: pending IRPs, cancellation, cleanup/close, work items, DPCs, timers, and completion routines.1215. Shared state accessed from parallel queues or multiple handles without a coherent lock/refcount protocol.1226. Object or handle lookup with wrong access mode, type, lifetime, or reference balancing.1237. `MmMapIoSpace`, `MmMapLockedPagesSpecifyCache`, MDLs, physical memory, MSRs, I/O ports, PCI config, arbitrary process attachment, and kernel virtual addresses.1248. Uninitialized pool/stack data returned through output buffers or completion lengths.1259. Device ACL, IOCTL access-bit, privilege, impersonation, and ownership mistakes.12610. PnP/power teardown races and stale device-extension or framework-object references.127128Use [references/review-checklist.md](references/review-checklist.md) during this phase.129130## Phase 4: Build a semantic harness131132Start with a deterministic exerciser before mutation fuzzing.1331341. Enumerate and open each reachable interface under both standard-user and administrator tokens.1352. Replay known-good application traffic when available; record request order and schemas.1363. Implement one typed builder per IOCTL family. Keep serialization separate from transport.1374. Log seed, iteration, device path, open flags, IOCTL, input/output sizes, bytes, thread schedule, status, returned length, and elapsed time.1385. Add a watchdog and preserve the last submitted test case outside the guest when possible.139140Mutation dimensions:141142- Zero, one-less, exact, one-more, page-boundary, signed-boundary, and maximum lengths.143- Inconsistent count/size/offset fields; integer-wrap combinations.144- Null, low, noncanonical, kernel-range, guard-page, read-only, freed, aliased, and cross-page pointers.145- Misalignment and 32/64-bit layout confusion.146- Input/output aliasing and overlapping nested buffers.147- Valid request sequences with repeated create/use/free/close operations.148- Parallel IOCTL, cleanup, close, cancellation, and handle duplication.149- PnP/power transitions only in a disposable VM with a recoverable device setup.150151Preserve enough valid structure to reach deep code. Pure random IOCTL spraying usually measures the rejection path.152153## Phase 5: Dynamic verification154155Use a disposable VM with kernel debugging and a targeted Driver Verifier configuration. Record the exact verifier settings. Prefer the smallest set that exposes the suspected class; broad settings can change timing and obscure causality.156157Useful debugger evidence includes:158159```text160lmvm <driver>161!drvobj <driver-object> 7162!devobj <device-object>163!irp <irp>164!analyze -v165.exr -1166.cxr <context>167kv168!pool <address>169!verifier170!locks171!deadlock172```173174Set breakpoints on the recovered dispatch/callback and suspected sink. Confirm:175176- The harness reaches the intended branch.177- Register and memory values match the reconstructed schema.178- The crashing access derives from controlled input or a controlled lifetime transition.179- The target driver, rather than Verifier, another filter, or malformed harness state, owns the root cause.180181Repeat without unrelated instrumentation when timing permits. Keep the dump and complete debugger transcript.182183## Phase 6: Crash triage and minimization184185For each crash:1861871. Hash the tuple of bugcheck/exception, faulting instruction, top target-driver frames, allocation/free stack, and semantic operation.1882. Reproduce from the clean snapshot at least three times.1893. Minimize bytes, lengths, request sequence, concurrency, and verifier flags independently.1904. Identify the first invalid state transition or unsafe operation, not merely the final fault.1915. Determine whether the condition is memory corruption, disclosure, race, authorization bypass, or intended privileged functionality.1926. Test adjacent driver and OS versions with the same minimized reproducer.193194Do not call a hang a deadlock without lock/wait evidence. Do not call a Verifier stop exploitable without proving the underlying invariant violation.195196## Phase 7: Variant and novelty analysis197198Use `patch-diff-exploit` when fixed and vulnerable versions exist; use `binary-diff` to migrate names and recovered types.199200Search for:201202- Sibling IOCTLs missing the newly added validation.203- Checks applied before one dereference but not repeated after a user-memory re-read.204- Fixes limited to one architecture, product SKU, queue, or compatibility handler.205- Equivalent helpers in related vendor drivers.206- Error paths that bypass the fixed reference, lock, or cleanup protocol.207208Novelty requires evidence. Compare hashes, versions, advisories, CVEs, vendor release notes, driver blocklists, and known-vulnerable-driver datasets. Label the result `candidate 0-day` until that search is complete.209210## Phase 8: Exploitability handoff211212After confirming root cause, document:213214- Attacker prerequisites and lowest token that reaches the path.215- Controlled bytes, size, offset, timing, target object, and repeatability.216- Read/write/disclosure/lifetime primitive potential.217- Pool type, allocation size/tag, allocation/free sites, IRQL, processor context, and reclaim constraints.218- Relevant mitigations: KASLR, SMEP/SMAP, CFG/KCFG, CET, VBS/HVCI, pool hardening, and driver blocklist state.219220Then load `exploit-dev`. Keep the minimal crash PoC separate from later exploit work.221222## Completion gate223224Do not report a finding as confirmed until all applicable items pass:225226- [ ] Reachable from the stated attacker context.227- [ ] Exact dispatch and data-flow path recovered.228- [ ] Minimal reproducer works from a clean snapshot.229- [ ] Root cause occurs in the target driver.230- [ ] Driver Verifier and debugger evidence preserved.231- [ ] Affected and unaffected versions tested where available.232- [ ] Known-vulnerability and duplicate search completed.233- [ ] Impact claims match the demonstrated primitive.234- [ ] Driver hash, OS build, symbols, verifier settings, and harness input recorded.