CONTENTS
0 why we need a driver
1 required software
2 system configuration
3 first project — kmdf hello world
4 running the driver
5 kernel debugging with windbg
──[ 0. Why We Need a Driver ]──
A device driver is what lets an OS talk to hardware. For what we want — kernel
callbacks, minifilters, EDR internals — we need kernel-mode code, so a driver.
Windows Driver Frameworks (WDF) sits on top of the raw WDM (Windows Driver
Model) and handles a chunk of boilerplate for you:
KMDF (Kernel-Mode Driver Framework)
Runs in Ring 0. Full kernel access. One bug = BSOD.
What you need for callbacks, minifilters, DKOM, etc.
UMDF (User-Mode Driver Framework)
Runs in Ring 3. Much safer, very limited scope.
Useless for EDR work.
This series uses KMDF throughout.
──[ 1. Required Software ]──
Target OS: Windows 11 Pro (what this course was built on).
Visual Studio 2022
Microsoft's standard IDE. During setup, pick:
"Desktop Development with C++"
Then add these individual components:
MSVC v143 — VS 2022 C++ x64/x86 Spectre-mitigated libs
MSVC v143 — VS 2022 C++ ARM64/ARM64EC Spectre-mitigated libs
C++ ATL for latest v143 build tools with Spectre (x86 & x64)
C++ ATL for latest v143 build tools with Spectre (ARM64/ARM64EC)
C++ MFC for latest v143 build tools with Spectre (x86 & x64)
C++ MFC for latest v143 build tools with Spectre (ARM64/ARM64EC)
Windows Driver Kit
Windows SDK
Goes with the WDK. ~3.5 GB. Install it before the WDK.
Windows Driver Kit (WDK)
~2 GB. Kernel headers, libs, driver build system. Needs Visual Studio
and the SDK installed first.
──[ 2. System Configuration ]──
Two system settings have to change before you can do anything.
Test Signing Mode
Windows refuses unsigned drivers by default (DSE). Test signing lets
you load self-signed or unsigned drivers:
bcdedit /set testsigning on
Note: Secure Boot has to be off first — test signing and Secure Boot
don't cohabit (see the ELAM article for why).
Kernel Debug Output
Drivers write debug output via KdPrintEx(). To see it, enable kernel
debugging:
bcdedit /debug on
Then create the debug filter in the registry:
Registry key: HKLMSYSTEMCurrentControlSetControl
Session ManagerDebug Print Filter
New DWORD: DEFAULT = 8
──[ 3. First Project — KMDF Hello World ]──
Create a new KMDF driver project in Visual Studio, add a .c source file.
If ntddk.h isn't found, add the include path manually:
C:Program Files (x86)Windows Kits10Include<build>km
#include <ntddk.h>
#include <wdf.h>
DRIVER_INITIALIZE DriverEntry;
EVT_WDF_DRIVER_DEVICE_ADD KmdfHelloWorldEvtDeviceAdd;
NTSTATUS DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath)
{
NTSTATUS status;
WDF_DRIVER_CONFIG config;
KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"HelloWorld: DriverEntry\n"));
WDF_DRIVER_CONFIG_INIT(&config, KmdfHelloWorldEvtDeviceAdd);
status = WdfDriverCreate(
DriverObject, RegistryPath,
WDF_NO_OBJECT_ATTRIBUTES, &config, WDF_NO_HANDLE);
return status;
}
NTSTATUS KmdfHelloWorldEvtDeviceAdd(
_In_ WDFDRIVER Driver,
_Inout_ PWDFDEVICE_INIT DeviceInit)
{
UNREFERENCED_PARAMETER(Driver);
NTSTATUS status;
WDFDEVICE hDevice;
KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,
"HelloWorld: DeviceAdd\n"));
status = WdfDeviceCreate(&DeviceInit,
WDF_NO_OBJECT_ATTRIBUTES, &hDevice);
return status;
}
──[ 4. Running the Driver ]──
Build: Build → Build Solution in Visual Studio.
Load via Service Control Manager (admin terminal):
sc.exe create MyDriver type=kernel binPath="C:\path\to\driver.sys"
sc.exe start MyDriver
Unload:
sc.exe stop MyDriver
sc.exe delete MyDriver
──[ 5. Kernel Debugging with WinDbg ]──
Real debugging needs two machines: a host (WinDbg) and a target (your driver).
The kernel debugger gives you breakpoints, memory inspection, live kernel
introspection.
Setup on the target machine
Same bcdedit commands as step 2, plus the network target:
bcdedit /dbgsettings net hostip:<HOST_IP> port:50000
Install the WDK test target MSI on the target:
"C:\Program Files (x86)\Windows Kits\10\Remote\x64\
WDK Test Target Setup x64-x64_en-us.msi"
Crank up debug verbosity:
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\
Debug Print Filter" /v IHVDRIVER /t REG_DWORD /d 0xFFFFFFFF /f
Setup on the host
Install WinDbg from the Microsoft Store.
Configure the remote debugging target in Visual Studio.
Hook WinDbg up to the target over the network.
Useful WinDbg commands
bu MyDriver!DriverEntry Breakpoint on DriverEntry
g Continue until next breakpoint
t Step Into (enters called functions)
p Step Over (skips called functions)
lm List loaded modules
!process 0 0 List all processes
db <addr> Dump bytes at address
Once the debugger is attached you can pause the target kernel, inspect registers
and memory, and step through your driver code instruction by instruction.