The article attempts to cover fundamentals of kernel debugging with WinDbg Preview and KDNET

April 29th, 2022

THE LAB SETUP: Windows 10 Pro 21H1 debugger host (physical machine) with Hyper-V guest (a VM that is being debugged remotely).

The following abbreviations are used in later parts of the article:

  • Kernel debugger: KD
  • Local kernel debugger: LKD
The following steps are required to enable KDNET kernel debugging:
  • Install Debugging tools for Windows
  • The default folder for WinDbg Preview and KDNET executable is C:\Program Files (x86)\Windows Kits\10\Debuggers\x64
Hyper-V VM: Go to the default KDNET folder and run as the administrator "kdnet.exe IP 50005". Replace "IP" with your debugger host machine IPv4 address.

To debug this VM, run the following command on your DEBUGGER HOST machine:

windbg -k net:port=50005,key=<string>

If the IP address of the host machine (DEBUGGER) stays the same. There is need to run "shutdown -r -t 0" to reboot this VM if you previously enabled kernel kernel debugging with "bcdedit -debug on" and rebooted that VM.

As shown in below screenshot, PatchGuard integrity checks gets disabled by design once the kernel debugger is attached to the kernel in kernel mode. The following flag will be applied as a bitwise operator to the code integrity (CI) options in kernel memory:

#define CODEINTEGRITY_OPTION_DEBUGMODE_ENABLED 0x80

When kernel debugging is enabled, the byte at "ntoskrnl!KdDebuggerEnabled" is set to "1" and the byte at KUSER_SHARED_DATA 0xFFFFF780000002D4 is set to "1" as well. After the KD is actually attached, the value of the same byte is set to "3". The value of a byte at CI!G_CiOptions is set to "7" if you did not disabled the DSE before attaching the KD to the kernel.

KDNET Kernel Debugging

You should see DbgPrintEx messages on KDNET console in the same way as in the local kernel debugging mode.

If you get "could not resolve symbol" error in local or remote kernel debugging mode, you can fix the issue by typing below commands:

lkd> .symfix
lkd> .reload

WinDbg comes with a built-in up to date symbols for the kernel and system modules loaded by the kernel.

If you have not specifically disabled kernel driver digital signature enforcement (DSE). You can enable test signing with the following command:

  • Bcdedit.exe -set TESTSIGNING ON
  • Bcdedit.exe -set TESTSIGNING OFF

The following breakpoint may occur several times when loading an unsigned driver when KD is attached:

CI!CipReportAndReprieveDriverAndProtectedImageFailure

Additionally for your convenience you may want to disable driver signature enforcement (DSE) by enabling test signing mode before enabling KDNET. There are also non-standard ways to disable DSE. I may cover those options later in the article.

Breakpoint options:

  • Read: ba r 1 <address> /1
  • Write: ba w 1 <address> /1
  • Execute: ba e 1 <address>

Select from the menu Debug->Break, and set a breakpoint. At this point you will lose connectivity to VM. Once you've setup the desired breakpoint and whenever a breakpoint has been hit. To continue, you need to press the 'g' or use the option in the menu (Debug->Go). Use the bl command to view current breakpoints.

If you want to debug kernel routines, use "bp nt!KdTrap". To view global variables values in WinDbg Preview, run "db nt!KdpTrap". This command displays only the first reference to this variable.

This is where multi-threaded disassembler is coming from in HEX DEREF software. The tool provides similar functionality to IDA PRO's disassembler, where you can see all code execution references at once dynamically in both modes (DATA or DISASSEMBLY).

Local kernel debugging

To enable kernel debugging, run either command as an administrator and reboot. After that Start Windbg Preview and select "Start debugging->Attach to kernel" and select the local tab.

  • bcdedit -debug on
  • bcdedit -debug off

If you get "Levels not implemented for this platform" with the !pte command. You need to restart your machine until you get results. The default WinDbg Preview symbols folder is C:\ProgramData\Dbg\sym.

The value of a byte at CI!G_CiOptions specifies whether or not to allow unsigned drivers to load. Setting the value to zero will turn off the DSE. The modification is subject to PatchGuard BSDO but if you restore the byte immediately back to the original value after loading an unsigned driver, as far as I've tested, in most of cases BSDO should not occur.

You can also use the debugger to modify the kernel memory:

kd> dd CI!g_CiOptions L1
kd> ed CI!g_CiOptions 0 0

The above command sets the first byte to 0 at that address.

Kernel crash dumps

The memory referenced in the minidump is in kernel crash dump which is the same as kernel physical memory dump (MEMORY.DMP). You can change crash dump options in Startup and Recovery.
Kernel crash dump
The default folder for kernel crash dumps is C:\Windows\Minidump.

WinDbg Preview commands

If you want to debug driver routines with the kernel debugger. You can use the uf command to disassemble the routine in the driver:

kd> uf Driver!MyExceptionHandler
kd> !drvobj MsSecFlt 2
  • Show the first 512 bytes of a specific address: db <address> L 0n1512
  • Debug driver DRIVER_OBJECT: !drvobj MsSecFlt 2
// Spoof kernel debugging

Spoof kernel debugging

The above command sets the first byte to 0 at that address.

The HEX DEREF software C kernel driver enables arbitrary kernel memory to be read and written (R W) without the need to enable kernel debugging, and you can also scan the entire user space memory and the kernel physical memory with the tool.



And that's not all. You can browse and edit the kernel arbitrary memory. The memory viewer is able to draw the kernel memory in real time.

You can purchase the professional version of the software using this link: HEX DEREF PRO