Core Capabilities of the WinDbg Debugger
WinDbg, the Windows Application Debugger, is a powerful tool for debugging software on the Windows operating system. Its lineage traces back to the Debug.exe utility from the DOS era. While modern WinDbg has evolved far beyond its predecessor, its fundamental operations remain rooted in core debugging concepts: inspecting and modifying CPU registers, examining and altering memory contents, assembling and disassembling machine code, and controlling program execution through stepping and breakpoints.
To illustrate WinDbg's expanded capabilities in a modern context, we will examine two scenarios: analyzing the loaded modules of a native Windows application and previewing its interaction with managed code environments.
Analyzing a Loaded Executable Image
When a Windows executable (PE image) is launched, the operating system loads it and its dependencies into memory. Using the 32-bit Notepad application (C:\Windows\SysWOW64\notepad.exe) as an example, we can inspect its runtime environment after attaching WinDbg.
The lm (List Modules) command displays all modules loaded for the process:
0:007> lm
start end module name
001b0000 00201000 notepad (pdb symbols) C:\ProgramData\Dbg\sym\notepad.pdb\2B40059F9CBA6BEC6A7041000A7683421\notepad.pdb
63170000 6326e000 textinputframework (deferred)
63270000 632c4000 oleacc (deferred)
... [additional modules listed] ...
77d70000 77f22000 ntdll (pdb symbols) C:\ProgramData\Dbg\sym\wntdll.pdb\16D25128F0923461692F09D5A2DA14291\wntdll.pdb
The output reveals that Notepad's image is loaded in the virtual address range 001b0000 to 00201000. To calculate the size of this memory region, use the expression evaluator with the ? command:
0:007> ? 00201000-001b0000
Evaluate expression: 331776 = 00051000
The result, 00051000 in hexadecimal, represents the image size. The lmDvm command provides detailed information about a specific module:
0:007> lmDvm notepad
Browse full module list
start end module name
001b0000 00201000 notepad (pdb symbols) C:\ProgramData\Dbg\sym\notepad.pdb\2B40059F9CBA6BEC6A7041000A7683421\notepad.pdb
Loaded symbol image file: C:\Windows\SysWOW64\notepad.exe
Image path: notepad.exe
Image name: notepad.exe
...
ImageSize: 00051000
File version: 10.0.22621.3672
...
To view the raw bytes of the loaded image in memory, the db (Display Memory Bytes) command can be used:
0:007> db 001b0000 001b0040
001b0000 4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00 MZ..............
001b0010 b8 00 00 00 00 00 00 00-40 00 00 00 00 00 00 00 ........@.......
001b0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
001b0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
The initial bytes 4D 5A ("MZ") represent the DOS header signature of the Portable Executable (PE) file format.
Previewing Managed Code Debugging
WinDbg extends its functionality to managed environments like .NET through debugging extensions. While a full debugging sesion will be detailed later, a key preparatory step is loading the appropriate runtime analysis extension. For .NET Framework applications, this is often done with the .loadby command to load the sos (Son of Strike) extension from the Common Language Runtime (CLR) module:
0:007> .loadby sos clr
Once loaded, commands specific to the managed runtime become available, allowing inspection of the Common Language Runtime heap, managed threads, and .NET objects, bridging the gap between native and managed code debugging.