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.