BugChecker: kernel and user debugger for Windows 11
BugChecker is a SoftICE-like kernel and user debugger for Windows 11 (and Windows XP as well: it supports Windows versions from XP to 11, both x86 and x64). BugChecker doesn’t require a second machine to be connected to the system being debugged, like in the case of WinDbg and KD. This version of BugChecker (unlike the original version developed 20 years ago) leverages the internal and undocumented KD API in NTOSKRNL. KD API allows WinDbg/KD to do calls like read/write virtual memory, read/write registers, place a breakpoint at an address, etc.
By contrast, the original BugChecker, like SoftICE as well, used to “take over” the system, by hooking several kernel APIs (both exported and private), taking control of the APIC, sending IPIs, etc. This approach increases complexity exponentially (and lowers system stability), since the implementation must be compatible with all the supported versions and sub-version of Windows (at the function signature level) as well as all the possible supported hardware configurations. Moreover, 20 years later, PatchGuard makes this solution impossible.
By contrast, this version of BugChecker, by intercepting calls to KdSendPacket and KdReceivePacket in the kernel, presents itself to the machine being debugged as a second system running an external kernel debugger, but, in reality, everything happens on the same machine. Typically this is achieved by replacing KDCOM.DLL (which is the module that implements serial cable communication for the KD API in Windows) and by starting the system in kernel debugging mode. This approach (inspired by VirtualKD) lowers complexity and increases stability and compatibility (and portability, for example, to ARM – and modularity, since the lower level debugger capabilities are implemented behind KdXxxPacket and could be replaced with a custom implementation). Moreover, the presence of a kernel debugger at boot time (although “fake”) makes Windows disable PatchGuard.
At the moment, BugChecker requires a PS/2 keyboard for input and a linear framebuffer to write its output.
- Support for Windows XP up to Windows 11, x86 and x64, and SMP kernels. Support for WOW64 processes on x64.
- Integration of QuickJSPP, which is a port of QuickJS to MSVC++. Before calling QuickJS, BugChecker saves the FPU state (on x86) and switches to an expanded stack of 128KB.
- Support for PDB symbol files. PDB files can be specified manually or Symbol Loader can download them from a symbol server.
- Breakpoints can have a JS condition: if condition evaluates to 0, no “breakin” happens. This allows to set “Logpoints” and breakpoints that can change the flow of execution.
- Log window shows the messages sent to the kernel debugger (for example DbgPrint messages).
- The tab key allows, given few digits, to cycle through all the hex numbers on the screen or, given few characters, to cycle through all the symbols containing those characters.
- EASTL and C++20 coroutines make creating new commands a breeze. Feel free to send your pull requests!
Copyright (C) 2023 vitoplantamura