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.
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.