WinDbg Cheat Sheet
Last modified: 2024-10-13
WinDbg is a Windows debugger distributed by Microsoft. It's a very powerful debugger, but its commands are unique, so this page has summarized it here so we can easily refer to it if we forget.
Help
See command usage by opening the help menu.
.hh
.hh <command>
# e.g.
.hh .reload
Symbols
# Search symbol path
.sympath srv*
# Set symbol file path
.symfix
# Set a directory which includes an executable ('.exe') and asymbol file ('.pdb')
.sympath+ C:\Path\To\ExampleApp\x64\Debug
# Load symbols
.reload
# Force reload
.reload /f
# Examine symbols
x ntdll!NtQueryInformationProcess
x notepad!*main*
# Resolve symbol name from address
ln 00007ff6`6c5814c0
Troubleshoot for Loading Symbols
If got the error when loading symbols, try the following to verbose output:
# Verbose listing of everything the symbol handler tries.
!sym noisy
.reload /f
Break
# Break on Access
ba w 4 /w "mymodule!globalVariable == 4" mymodule!globalVariable
Modules
# List modules
lm
# List modules whose module names start with 'a'
lm m a*
# Display module information
lm Dvm <module>
Breakpoints
# Set breakpoints
bp <address>
bu notepad!wWinMain
bu ntdll!NtCreateProcess
bu ntdll!ZwWriteFile
# List breakpoints
bl
# Clear all breakpoints
bc *
Debugging
# Run until hit a breakpoint
g
# Step Into
t
# Step Over
p
Exception Analysis
If the application crashed when debugging, use the following command to analyze it.
!analyze -v
Break
To break in, click on the Break icon at the tool menu.
Stack Trace
k
# Stack trace for thread 0
~0s
# Stack trace for thread 1
~1s
Quit and Detach
qd
Processes
# List all processes
!process 0 0
Disassembly
Select View → Disassembly on the menu.
Common
# Print the PEB (Process Environment Block)
!peb
# Print the TEB (Thread Environment Block)
!teb
Display
dt (Display Type)
Display fields and values.
# TEB (Thread Environment Block)
dt _teb
# -v: Verbose output
dt -v _teb
# PEB (Process Environment Block)
dt _peb
# @$peb: Refer to the PEB of the current process.
dt _peb @$peb
# LDR
dt _PEB_LDR_DATA
# poi: Dereference
dt _PEB_LDR_DATA poi(@$peb+0x123)
dt _LDR_DATA_TABLE_ENTRY
dt _LDR_DATA_TABLE_ENTRY 0x123
dt nt!_LIST_ENTRY
ds (Display Symbols)
# Display symbols (dword values)
dds 00007ffa`27c52920 + 0x30 L1
# Display symbols (qword values)
dqs @rbp - 0x50 L1
# Display symbols (pointer-sized values)
dps 00007ffa`27c52920 + 0x30 L1
# Structure of SSDT (System Service Descriptor Table)
dps nt!keservicedescriptortable L4
Registers
# List all registers
r
# In thread 0
~0 r
# In all threads
~* r
# Display a specified register
r rip
# Display a pseudo-register
r $peb
r $teb
# Display xmm0 in unsigned bytes 16
r xmm0:16ub
# Modify a register value
r rax=0001
# Copy RBX value to RAX
r rax = @rbx
Search Memory
# Search the DWORD 'H' in the range of 1000000 bytes from the RSP address.
s -d @rsp L1000000 'H'
# Search the string "B7" in the range of 10000000 bytes from the RSP address.
s -a @rsp L10000000 "B7"
Virtual Memory Protection Information
!vprot <address>
Unassemble
# Unassemble
u
u <address>
u <FunctionName>
# e.g.
u NtWriteVirtualMemory
# Unassemble from entrypoint
u $exentry
# Unassemble backwards
ub
ub <address>
Set Exceptions
# Enable Break: Immediately break when the exception occurs.
sxe -c "r eax" av
# Disable Break: Doesn't break for a first-chance exception.
sxd -c "r eax" av
# Notify: A message is displayed when the exception occurs instead of break.
sxn -c "r eax" av
# Ignore: Doesn't break and no message when the exception occurs.
sxi -c "r eax" av
? (Evaluate Expression)
? poi(@$peb+0x123)