pwndbg Cheatsheet
Commands
Gathering info
info functions
Obtain the functions that are stored in the binary.
info functions- Example output:
pwndbg> info functions
All defined functions:
Non-debugging symbols:
0x0000000000400528 _init
0x0000000000400550 puts@plt
0x0000000000400560 system@plt
0x0000000000400570 printf@plt
0x0000000000400580 memset@plt
0x0000000000400590 read@plt
0x00000000004005a0 setvbuf@plt
0x00000000004005b0 _start
0x00000000004005e0 _dl_relocate_static_pie
0x00000000004005f0 deregister_tm_clones
0x0000000000400620 register_tm_clones
0x0000000000400660 __do_global_dtors_aux
0x0000000000400690 frame_dummy
0x0000000000400697 main
0x00000000004006e8 pwnme
0x0000000000400756 ret2win
0x0000000000400780 __libc_csu_init
0x00000000004007f0 __libc_csu_fini
0x00000000004007f4 _finiinfo registers
Obtain the information of the registers at the current state of the application execution.
info registers- Example output:
pwndbg> info registers
rax 0xb 0xb
rbx 0x7fffffffdf68 0x7fffffffdf68
rcx 0x7ffff7ea5976 0x7ffff7ea5976
rdx 0x0 0x0
rsi 0x7ffff7f87643 0x7ffff7f87643
rdi 0x7ffff7f887b0 0x7ffff7f887b0
rbp 0x7fffffffde50 0x7fffffffde50
rsp 0x7fffffffde50 0x7fffffffde50
r8 0x0 0x0
r9 0x0 0x0
r10 0x0 0x0
r11 0x202 0x202
r12 0x0 0x0
r13 0x7fffffffdf78 0x7fffffffdf78
r14 0x7ffff7ffd000 0x7ffff7ffd000
r15 0x0 0x0
rip 0x4006d7 0x4006d7 <main+64>
eflags 0x206 [ PF IF ]
cs 0x33 0x33
ss 0x2b 0x2b
ds 0x0 0x0
es 0x0 0x0
fs 0x0 0x0
gs 0x0 0x0
fs_base 0x7ffff7d9e740 0x7ffff7d9e740
gs_base 0x0 0x0
pwndbg> info breakpoints
Obtain the information of the breakpoints that has been set.
info breakpoints- Example output:
pwndbg> info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004006d2 <main+59>
breakpoint already hit 1 time
2 breakpoint keep y 0x00000000004006d7 <main+64>Disassemble
disas main
Disassemble a function
disas main- Example output:
pwndbg> disas main
Dump of assembler code for function main:
0x0000000000001139 <+0>: push %rbp
0x000000000000113a <+1>: mov %rsp,%rbp
0x000000000000113d <+4>: sub $0x210,%rsp
0x0000000000001144 <+11>: mov %edi,-0x204(%rbp)
0x000000000000114a <+17>: mov %rsi,-0x210(%rbp)
0x0000000000001151 <+24>: mov -0x210(%rbp),%rax
0x0000000000001158 <+31>: add $0x8,%rax
0x000000000000115c <+35>: mov (%rax),%rdx
0x000000000000115f <+38>: lea -0x200(%rbp),%rax
0x0000000000001166 <+45>: mov %rdx,%rsi
0x0000000000001169 <+48>: mov %rax,%rdi
0x000000000000116c <+51>: call 0x1030 <strcpy@plt>
0x0000000000001171 <+56>: mov $0x0,%eax
0x0000000000001176 <+61>: leave
0x0000000000001177 <+62>: ret
End of assembler dump.disas <beginning>, <end>
Disassemble a range of memory addresses
disas 0x1144,0x115f- Example output:
pwndbg> disas 0x1144,0x115f
Dump of assembler code from 0x1144 to 0x115f:
0x0000000000001144 <main+11>: mov %edi,-0x204(%rbp)
0x000000000000114a <main+17>: mov %rsi,-0x210(%rbp)
0x0000000000001151 <main+24>: mov -0x210(%rbp),%rax
0x0000000000001158 <main+31>: add $0x8,%rax
0x000000000000115c <main+35>: mov (%rax),%rdx
End of assembler dump.Alternatively, we can do this:
disas main+13,main+36- Example output:
pwndbg> disas main+13,main+36
Dump of assembler code from 0x1186 to 0x119d:
0x0000000000001186 <main+13>: call 0x1070 <malloc@plt>
0x000000000000118b <main+18>: mov %rax,-0x8(%rbp)
0x000000000000118f <main+22>: mov -0x8(%rbp),%rax
0x0000000000001193 <main+26>: mov %rax,%rsi
0x0000000000001196 <main+29>: lea 0xe6b(%rip),%rax # 0x2008
End of assembler dump.
(gdb)layout asm
Display a table that show the assembly code:
layout asm
PD: To close the table you must press Ctrl + x and a.
set disassembly-flavor intel
Change the syntax of the assembly language:
set disassembly-flavor intel- Example output:
pwndbg> set disassembly-flavor intel
pwndbg> disas 0x1144,0x115f
Dump of assembler code from 0x1144 to 0x115f:
0x0000000000001144 <main+11>: mov DWORD PTR [rbp-0x204],edi
0x000000000000114a <main+17>: mov QWORD PTR [rbp-0x210],rsi
0x0000000000001151 <main+24>: mov rax,QWORD PTR [rbp-0x210]
0x0000000000001158 <main+31>: add rax,0x8
0x000000000000115c <main+35>: mov rdx,QWORD PTR [rax]
End of assembler dump.
pwndbg>Breakpoints
break
Set a breakpoint in a specific memory address
break *0x0000000000001169- Example output:
pwndbg> break *0x0000000000001169
Breakpoint 1 at 0x1169: file vuln.c, line 6.delete
Delete the all breakpoints
delete- Example output:
pwndbg> delete
Delete all breakpoints, watchpoints, tracepoints, and catchpoints? (y or n) yExecuting the binary
run
Executes the binary that's being debugged inside the own debugger. If a breakpoint has been set, the execution will stop on the previous instruction of the breakpoint.
run- Example output:
pwndbg> run
Starting program: /home/usuario/daemon/labs/ropemporium/ret2win/ret2win
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
...run <<< command
You can run the binary and, if it asks for input, you can use <<< in order to fetch input to the running program. Also, you can execute commands from the shell inside the debugger in order to fetch the binary a specific input. This is demonstrated in the following post:

run <<< $(command)- Example output:
pwndbg> run <<< $(whoami)
Starting program: /home/usuario/daemon/labs/ropemporium/ret2win/ret2win <<< $(whoami)
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
ret2win by ROP Emporium
x86_64
For my first trick, I will attempt to fit 56 bytes of user input into 32 bytes of stack buffer!
What could possibly go wrong?
You there, may I have your input please? And don't worry about null bytes, we're using read()!
> Thank you!
Exiting
[Inferior 1 (process 656030) exited normally]Detect offsets
cyclic
With cyclic it is possible to create a string that uses the Bruijn sequence in order to perform ROP or buffer overflows.
cyclic- Example output:
pwndbg> cyclic 100
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa
pwndbg> This can be used to fetch the the input of a program in order to perform a stack/buffer overflow.
$(python3 -c 'from pwn import *; print(cyclic(100).decode())')- Example output:
pwndbg> run <<< $(python3 -c 'from pwn import *; print(cyclic(100).decode())')
Starting program: /home/usuario/daemon/labs/ropemporium/ret2win/ret2win <<< $(python3 -c 'from pwn import *; print(cyclic(100).decode())')
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
ret2win by ROP Emporium
x86_64
For my first trick, I will attempt to fit 56 bytes of user input into 32 bytes of stack buffer!
What could possibly go wrong?
You there, may I have your input please? And don't worry about null bytes, we're using read()!
> Thank you!
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400755 in pwnme ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
─────────────────────────────────────────────────────────────────────────────[ LAST SIGNAL ]──────────────────────────────────────────────────────────────────────────────
Program received signal SIGSEGV (fault address: 0x0).step
Makes the program run into the next instruction.
step- Example output:
pwndbg> run
Starting program: /home/usuario/daemon/labs/ropemporium/callme/callme <<< $(python3 -c 'from pwn import *; print(cyclic(100).decode())')
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
callme by ROP Emporium
x86_64
Breakpoint 1, 0x0000000000400882 in main ()
pwndbg> step
Hope you read the instructions...
> cyclic_find / cyclic -l
This can be used to find the offset after receiving a SIGSEGV (crash) from the program using the hex value that is left in the RIP after the crash.
cyclic -l <hex_value_inside_rip>- Example output:
pwndbg> cyclic -l 0x6161616c6161616b
Finding cyclic pattern of 4 bytes: b'kaaa' (hex: 0x6b616161)
Found at offset 40
pwndbg> Examining memory
x/o
Displays the memory inside the specified address/register in octal format.
x/o <memory_address/register>- Example output:
pwndbg> x/o 0x0000555555555141
0x555555555141 <main+8>: 077042707x/x
Displays the memory inside the specified address/register in hexadecimal format.
x/x <memory_address/register>- Example output:
pwndbg> x/x $rip
0x555555555141 <main+8>: 0x00fc45c7x/u
Displays the memory inside the specified address/register in unsigned standard base-10 decimal format.
x/u <memory_address/register>- Example output:
pwndbg> x/u $rip
0x555555555141 <main+8>: 16532935x/t
Displays the memory inside the specified address/register in binary format.
x/t <memory_address/register>- Example output:
pwndbg> x/t $rip
0x555555555141 <main+8>: 00000000111111000100010111000111x/b
Displays the memory inside the specified address/register in single byte format.
x/b <memory_address/register>- Example output:
pwndbg> x/b $rip
0x555555555141 <main+8>: 0xc7x/h
Displays the memory inside the specified address/register in halfword format (two bytes).
x/h <memory_address/register>- Example output:
pwndbg> x/h $rip
0x555555555141 <main+8>: 0x45c7x/w
Displays the memory inside the specified address/register in word format (four bytes).
x/w <memory_address/register>- Example output:
pwndbg> x/w $rip
0x555555555141 <main+8>: 0xfc45c7x/g
Displays the memory inside the specified address/register in giant format (eight bytes).
x/g <memory_address/register>- Example output:
pwndbg> x/g $rip
0x555555555141 <main+8>: 0xeb00000000fc45c7Additional info
Not only is it possible to examine what's inside an address, but also the addresses that follow them. For example, it is possible to examine the address range from 0x0000555555555141 to the address 0x0000555555555160 (32 bytes in memory) using the following command:
x/32<o/h/u/t/b> <memory address>- Example output:
pwndbg> x/32b $rip
0x555555555141 <main+8>: 0307 0105 0374 0 0 0 0 0353
0x555555555149 <main+16>: 023 0110 0215 05 0263 016 0 0
0x555555555151 <main+24>: 0110 0211 0307 0350 0327 0376 0377 0377
0x555555555159 <main+32>: 0203 0105 0374 01 0203 0175 0374 011It is also possible to mix formats, for example, to print 32 bytes formatted in hexadecimal, I'd do this:
x/32xb <address/register>- Example output:
pwndbg> x/32xb $rip
0x555555555141 <main+8>: 0xc7 0x45 0xfc 0x00 0x00 0x00 0x00 0xeb
0x555555555149 <main+16>: 0x13 0x48 0x8d 0x05 0xb3 0x0e 0x00 0x00
0x555555555151 <main+24>: 0x48 0x89 0xc7 0xe8 0xd7 0xfe 0xff 0xff
0x555555555159 <main+32>: 0x83 0x45 0xfc 0x01 0x83 0x7d 0xfc 0x09
