If you're more familiar with Linux and GDB than with Windows, but find yourself needing/wanting to learn Windows debugging, this is the cheat sheet for you.
GDB Command | WinDBG Command | Description | Usage/Examples |
---|---|---|---|
b/break |
bp |
Set breakpoint | |
disable |
bd # |
Disable breakpoint | |
enable |
be # |
Enable breakpoint | |
info breakpoints /ib |
bl |
List breakpoints | |
watch |
ba |
Break on access(read/write) | ba [r|w|e] [Size] Addr |
GDB Command | WinDBG Command | Description |
---|---|---|
r/run |
g .restart |
Run program |
s/si |
p |
Step over |
n/ni |
t |
Step into |
finish |
pt |
Step to next return |
None | pc |
Step to next call |
u |
pa |
Step to address |
GDB Command | WinDBG Command | Description | Usage/Example |
---|---|---|---|
x* |
d* |
Dump memory at address | a = ascii chars u = Unicode chars b = byte + ascii w = word (2b) W = word (2b) + ascii d = dword (4b) c = dword (4b) + ascii q = qword (8b) dd 0x1000000 |
set {int}addr = |
e* |
Edit memory | ed 0x1000000 deadbeef a = ascii string za = ascii string (NULL-terminated) u = Unicode string zu = Unicode string (NULL-terminated) e[a|u|za|zu] addr "String" |
print /p |
dt/dv |
Print variable | dt ntdll!_PEB dt ntdll!_PEB @$peb |
disasm |
u |
Disassemble at address/symbol | u kernel32!CreateProcessAStub |
* (deref) |
poi |
Dereference pointer | u poi(ebp+4) |
None | x |
Examine symbols | x *! x /t /v MyDll!* list symbols in MyDll with data type, symbol type, and size |
GDB Command | WinDBG Command | Description | Usage/Example |
---|---|---|---|
p (Datatype *) &variable |
dx (Datatype *) &variable |
displays a C++ expression | dx (nt!_EPROCESS *) &nt!PsIdleProcess |
p [expression] |
?? |
Evaluate C++ expressions. Used with the C++ expression parser - @@c++() , that supports operators, registers, macros. etc. See docs for a full list |
?? @@c++(1+2) |
Access registers with @
, like @eip
.
GDB Command | WinDBG Command | Description | Usage/Example |
---|---|---|---|
info registers |
r |
Show registers | r Reg1 Reg2 r Reg:Type Type = data format in which to display the register (i.e.: r eax:uw ) ib = Signed byte ub = Unsigned byte iw = Signed word (2b) uw = Unsigned word (2b) id = Signed dword (4b) ud = Unsigned dword (4b) iq = Signed qword (8b) uq = Unsigned qword (8b) f = 32-bit floating-point d = 64-bit floating-point |
set reg = |
r Reg=Value |
Set register |
GDB Command | WinDBG Command | Description | Usage/Example |
---|---|---|---|
info proc mappings |
!address |
Show virtual memory map and permissions | !address addr |
print /p |
x |
Examine symbols | x kernel32!*CreateProcess* |
None | ln |
List nearest symbol to address | |
backtrace /bt |
k |
Stack backtrace | |
None | !exchain |
View SEH Chain | |
!peb
– dumps Process Environment Block
dt ntdll!_PEB @$peb
— dumps more PEB info of our process
The WinDBG executable is installed in C:\Program Files (x86)\Windows Kits\10\Debuggers\x86[64]/
. If it's not in your path, add it by going to the Edit system environment variables
menu, and append to the Path
variable.
$peb
is a "pseudo-register", and there are others that hold useful values. Some are $teb
, $csp
, $curprocess
.