Debugging
Remote debugging - gdbserver
If you want to connect to a gdb session from a remote machine, then you can run a gdbserver.
The 22222 is the port in this case.
Or, if you want to attach to an existing process:
Connecting with radare2, for example:
Pwntools
You can load the executable in GDB like this:
It also starts up a gdbserver, but trying to connect to it with radare2 fails (waits forever)
GDB
Although I really prefer Radare2's user interface in just about every way, GDB is the only debugger that actually works consistently.
Watching
You can watch addresses for changes and stop when a change was made to that address. Can be useful if you're not sure where exactly a value is changed.
rwatch
stops when the specified address is accessed for readingwatch
stops when it's accessed for writingawatch
stops on both reads and writes.
Radare2
Usage tips
Run it in debug mode:
Don’t forget to analyze using aaa
. Alternatively, you can pass the -A
flag when running radare2.
Random Basics
You can pipe with |
and redirect with >
You can run commands at certain addresses with @
( pd @ main
)
If you want to modify binaries on disk, then you have to use -w
flag.
Help: ?
Help about debugging: d?
Running r2 command: :
. For example :aaa
You can use ctrl+r
to do a reverse search for previous commands
Analysis and Disassembly
You have to analyze before you can disassemble. Analyze everything: aaa
List functions: afl
Rename location: afn new_name_here loc.140011790
Move to location: s?
Move to main: s main
Print stuff: p?
Disassemble the current function: pdf
Disassemble the next N opcodes (pdf
might not work when running shellcode on the stack): pd number_of_opcodes
Print stack: pxr optional_byte_amount @ esp
(rsp
for 64 bit programs). Stack grows downwards, so the latest pushes are at the top.
Debugging
Debugging: d?
Place a breakpoint at either an address or function name: db address_or_function
Remove breakpoint: db - address_or_function
Print registers: dr
Continue: dc
Continue until address: dcu address
Stepping: ds?
Reload process: do
(alias for oo
)
Reload process in debugger mode with arguments (alias for ood
): doo
Set register: dr eax = 0x00000000X
Visuals
Basic visual mode: V
, use p
to cycle. Not too useful.
Graph view: VV
. Zoom: +-
Visual panels: V!
Exit back to command line mode: q
Configuration
Change configuration variables with e
.
The utf8 ones create a nicer graph view and nicer arrows.
Show opcode description appends a comment after each instruction to explain what it’s doing.
iocache allows you to modify files that haven’t been opened with the write flag. But it still won’t be written to disk, just in memory.
Forking
Note: I haven’t been able to get forking following working correctly in r2. I’ve used GDB for that. But I’ve probably just been using r2 wrong
Environment variables:
e dbg.forks=true
e dbg.follow.child = true
Commands:
dcf
: continue until forkdp
: list processes
Finding ROP Gadgets
You can use the /R
syntax to find ROP gadgets:
Though, msfelfscan might give much better results. Radare2 didn’t find a jmp esp
while msfelfscan did.
Remote usage
On the remote server:
On the local server:
Searching
You can search for hex values in the binary like this:
Rabin2
Rabin2 can be super useful for finding things in a binary.
For example, I used it to find static variable addresses by listing exported symbols:
Feed input from a file
Create a file ~/input.rr2
:
Then put some shellcode in the input file for example:
Then run the program using that configuration:
You can reload it (and restart the process) with doo
Last updated