Partilhar via


Driver debug breakpoint

The DebugBreak() API is the primary way to implement a breakpoint through code.  It's great to use when developing a prototype and exploring your environment.

User mode developers (such as myself) may not be aware that this can also be used from a kernel mode driver.  This enables us to explore some aspects of kernel mode behavior as it relates to our user mode code.

I use a custom-built driver whose sole purpose is to respond to IRP_MJ_DEVICE_CONTROL.  It has the basic driver packaging for registering and unregistering itself, but other than that, its sole purpose is to respond to IOCTL requests and do my bidding.

I use a Win32 app to install it through CreateService() with SERVICE_KERNEL_DRIVER.  After it is installed, I use CreateFile() to get a handle to the driver object and DeviceIoControl() to invoke it.

Once your breakpoint is hit, be sure to set process context to your user mode process, in order to see symbols for the user mode portions of your call stack:

 3: kd> !process -1 0
PROCESS afbe7040  SessionId: 0  Cid: 0cfc    Peb: 03213000  ParentCid: 0cf8
    DirBase: 7ffe0660  ObjectTable: b22e4480  HandleCount:  38.
    Image: MeasonTest.exe
3: kd> .process /p /r afbe7040
Implicit process is now afbe7040
.cache forcedecodeuser done
Loading User Symbols
DBGENG: PDB symbols loaded for 'ntdll.dll'
3: kd> k
 # ChildEBP RetAddr  
00 a8fa0bc0 81cadf43 MeasonTestDrv!DispatchDeviceControl+0x9f
01 (Inline) -------- nt!(redacted)
02 a8fa0bdc 81ef150c nt!(redacted)
03 (Inline) -------- nt!(redacted)
04 (Inline) -------- nt!(redacted)
05 a8fa0c30 81ef0f80 nt!(redacted)
06 a8fa0cf8 81ef0b8a nt!(redacted)
07 a8fa0d24 81da4097 nt!(redacted)
08 a8fa0d24 77ec2090 nt!(redacted)
09 00edf940 77ec0a8a ntdll!KiFastSystemCallRet
DBGENG: PDB symbols loaded for 'KERNELBASE.dll'
0a 00edf944 77aee0fb ntdll!NtDeviceIoControlFile+0xa
DBGENG: PDB symbols loaded for 'MeasonTest.exe'
0b 00edf9a4 011db2f0 KERNELBASE!DeviceIoControl+0x7b
0c 00edfa20 011db1b6 MeasonTest!DriverInvoke::InvokeDriver+0x40
0d 00edfa30 011dfdf8 MeasonTest!DriverInvoke::DebuggerBreak+0x16
0e 00edfb04 011e0fbf MeasonTest!main+0x128
0f 00edfb48 77e51154 MeasonTest!__mainCRTStartup+0x107
10 00edfb90 77e51114 ntdll!__RtlUserThreadStart+0x3a

For those just now learning driver development, this is also a great way to test out DDK API calls or explore kernel space.