radare2::cutter

tool radare2 static · dynamic
OpenInfoNavigate DisasmAnalyzeSearch DebugPatchr2pipe rzpipeCutter
01Open & Modes
Launch radare2
# Open binary
r2 ./challenge
r2 -A ./challenge          # open + auto-analyze (aa)
r2 -d ./challenge          # open in debug mode
r2 -d -A ./challenge       # debug + analyze
r2 -w ./challenge          # open for writing (patching)
r2 -n ./challenge          # no analysis at open
r2 -q -c "aaa; pdf @ main" ./challenge  # batch mode

# Open remote / special
r2 tcp://host:port         # remote binary
r2 malloc://256            # scratch memory

# Rizin (r2 fork) — same syntax
rizin ./challenge
rizin -A ./challenge
r2 visual modes
# Inside r2 shell:
V         # enter Visual mode (hex view)
VV        # enter Visual Graph (CFG)
v         # visual panels

# In Visual mode keybindings:
p / P     # rotate display (hex/disasm/debug...)
c         # cursor mode
q         # quit Visual, back to shell
:         # run r2 command
/         # search
n / N     # next / prev search result
g         # go to address
u         # undo seek
;         # add comment at cursor
A         # assemble at cursor
i         # insert mode (write)
02Info & Metadata
i* commands
# File / binary info
i          # general file info
iI         # binary info (arch, bits, os, type)
iz         # strings in data sections
izz        # all strings in binary
iS         # sections
iSS        # segments
il         # linked libraries
ii         # imports
iE         # exports
is         # symbols
ih         # headers
iM         # main address
ie         # entry points

# Security
i~canary   # check canary (grep output)
iI~pic     # PIE status
rabin2 -I ./challenge   # full binary info (external)
rabin2 -z ./challenge   # strings
f* flags & symbols
# Flags (named addresses)
f          # list all flags
f~main     # grep flags for 'main'
f~str.     # string flags
f~fcn.     # function flags
f~sym.     # symbol flags
f~imp.     # import flags

# Set a custom flag (bookmark)
f myaddr = 0x401234
f myaddr 4 0x401234   # name, size, addr

# Filter (tilde ~ = grep)
iz~flag    # strings containing 'flag'
ii~puts    # imports containing 'puts'
s — seek
# Seek to address or symbol
s main           # seek to main
s 0x401234       # seek to address
s sym.win        # seek to symbol
s fcn.main+10    # offset from function
s $              # current position
s -              # previous position

# Relative seek
s +4             # seek forward 4 bytes
s -8             # seek backward 8 bytes

# Seek history
s!               # seek undo stack
sh               # seek history list

# s with expressions
s [0x404060]     # seek to value at address (dereference)
s esp+0x10       # register arithmetic
p* print / display
# Print from current position
pd 20            # disasm 20 instructions
pdc              # decompile current function (pdc)
pdf              # disasm entire function
pdf @ main       # disasm main (@ = temporary seek)
px 64            # hex dump 64 bytes
pxw 32           # hex dump as 32-bit words
pxq 32           # hex dump as 64-bit qwords
ps 32            # print string (32 chars)
pf               # print formatted struct
pi 10            # print 10 instructions (no addresses)
04Disassembly & Decompile
Disassemble
# Functions
pdf @ main            # disasm main
pdf @ sym.win         # specific function
pdf @ fcn.0x401234    # by address

# Around current/arbitrary address
pd 20                 # 20 instrs from here
pd 20 @ 0x401234      # 20 instrs from addr
pd -10                # 10 instrs backwards

# Decompile (requires r2ghidra or r2dec)
pdg                   # r2ghidra decompile
pdg @ main
pdc                   # r2dec pseudo-C
pdc @ main

# Install r2ghidra
# r2pm -ci r2ghidra
Cross-references
# Find what calls a function
axt sym.win           # xrefs TO win
axt 0x401234          # xrefs to address

# Find what a function calls
axf main              # xrefs FROM main

# All cross-references
ax                    # list all xrefs
ax~puts               # xrefs to puts

# String cross-references
iz~flag               # find flag strings
axt @ str.flag        # who references "flag" string

# Call graph
agc                   # function call graph (dot)
agcd                  # call graph as dot output
05Analysis
a* analysis commands
# Analysis levels (run after opening)
aa                    # basic analysis
aaa                   # deeper analysis (recommended)
aaaa                  # maximum analysis (slow)
aab                   # basic block analysis
aar                   # analyze references

# Functions
afl                   # list all functions
afl~win               # grep for 'win'
afn newname 0x401234  # rename function
af                    # analyze function at cursor
afi                   # function info (size, locals)
afv                   # function local variables

# Rename variable
afvn old_name new     # rename local var
afan old new          # rename function arg
Types & structures
# Types
t                     # list all types
t uint32_t            # info on type

# Structures
ts                    # list structs
ts mystruct           # show struct

# Print memory as struct
pf 4xz num name       # 4-byte hex + string

# Variables
avd                   # display variables

# Comments
CC my comment         # add comment at current addr
CC                    # list comments
CC- @ 0x401234        # remove comment
/ search commands
# Search bytes / strings
/ flag                # search string "flag"
/x deadbeef          # search hex bytes
/x de?dbeef          # ? = wildcard byte
/x 90 90 90          # NOP sled
/r 0x401234          # refs to address
/R pop rdi           # ROP gadget search
/R/ pop rdi; ret     # multi-gadget ROP

# Search in range
/x deadbeef @ 0x400000:0x500000

# Grep (tilde ~)
afl~win               # functions named win
iz~picoCTF            # strings containing picoCTF
pd 20~call            # disasm lines with 'call'
i~nx                  # info lines with 'nx'
ROP gadget search
# Built-in ROP search
/R pop rdi
/R ret
/R jmp rsp
/R syscall

# ropchain plugin
r2pm -ci ropper       # install
# then use ropper external tool with r2 output

# ragg2 — shellcode/rop framework
ragg2 -a x86 -b 64 -i exec   # generate execve shellcode
ragg2 -a x86 -b 64 -i bind   # bind shell
ragg2 -p nop -l 32           # 32-byte NOP sled

# rasm2 — standalone assembler
rasm2 -a x86 -b 64 "xor rax, rax; ret"
rasm2 -a x86 -b 64 -d 90 c3  # disasm bytes
07Debugging (r2 -d)
Debug commands
# Open in debug mode: r2 -d ./challenge

# Breakpoints
db 0x401234           # set breakpoint
db sym.main           # bp at symbol
db                    # list breakpoints
db- 0x401234          # remove bp
db-*                  # remove all bps

# Execution
dc                    # continue (run)
dso                   # step over
ds                    # step into
dsu 0x401234          # step until address
dcr                   # continue until ret

# Registers
dr                    # show all registers
dr rax                # show rax
dr rax=0x41           # set rax
Debug memory & process
# Memory maps
dm                    # memory maps
dm~heap               # filter heap region
dmi libc puts         # puts address in libc
dmi*                  # all imported symbols in memory

# Stack
pxq 64 @ rsp          # hex dump stack

# Backtrace
dbt                   # backtrace

# Process info
dp                    # process info
dpt                   # threads

# Watchpoints
drw rax 0x41          # watch register

# Input during debug
dor stdin=input.txt   # redirect stdin
08Patching
Write & patch
# Open writable: r2 -w ./challenge

# Write bytes
wx 90                 # write NOP at current
wx 9090              # two NOPs
wx deadbeef @ 0x401234

# Write string
w hello world @ 0x402000

# Assemble and write
wa nop               # assemble + write at current
wa jmp 0x401234 @ 0x401230
wa xor rax, rax; ret

# Change one instruction
wai jmp 0x401234     # wa inline (no side effects)

# Fill region with NOPs
wx 90 @ 0x401234!32  # fill 32 bytes with 0x90

# Undo write
wu                   # undo last write
rabin2 & radiff2
# rabin2 — binary info tool
rabin2 -I ./challenge   # info (checksec equivalent)
rabin2 -z ./challenge   # strings
rabin2 -i ./challenge   # imports
rabin2 -E ./challenge   # exports
rabin2 -S ./challenge   # sections
rabin2 -x ./challenge   # extract classes (ObjC/Java)

# radiff2 — binary diffing
radiff2 original patched
radiff2 -C orig patched # code diff (function level)
radiff2 -s orig patched # similarity score

# rahash2 — hashing
rahash2 -a md5 file.bin
rahash2 -a sha256 file.bin
09r2pipe Scripting (Python)
pythonr2pipe automation
# Install: pip install r2pipe
import r2pipe, json

r = r2pipe.open('./challenge')          # open binary
r = r2pipe.open('./challenge', flags=['-A'])  # auto-analyze
r = r2pipe.open('./challenge', flags=['-d'])  # debug mode

# Run command → raw string output
print(r.cmd('aaa'))                     # analyze
print(r.cmd('pdf @ main'))              # disasm main
print(r.cmd('afl'))                     # list functions

# Run command → JSON (append j to most commands)
funcs = r.cmdj('aflj')                  # functions as list
info  = r.cmdj('iIj')                   # binary info as dict
strs  = r.cmdj('izj')                   # strings as list
disas = r.cmdj('pdj 20 @ main')        # disasm as list

# Example: find win function and get address
r.cmd('aaa')
funcs = r.cmdj('aflj')
win = [f for f in funcs if 'win' in f['name']]
if win: print(f"win @ {win[0]['offset']:#x}")

# Example: extract all strings
strs = r.cmdj('izj')
for s in strs:
    print(f"{s['vaddr']:#x}: {s['string']}")

r.quit()
10Cutter (GUI)
Cutter workflow
# Install Cutter (r2 GUI)
# https://cutter.re — AppImage / package
# pip install cutter  (rizin version)

# Key panels:
# Disassembly  — main code view
# Decompiler   — requires r2ghidra plugin
# Graph        — CFG view
# Functions    — sidebar list
# Strings      — string search
# Imports      — linked functions
# Hexdump      — raw bytes

# Useful keyboard shortcuts:
# G           → Go to address
# N           → Rename function/var
# X           → Cross-references
# Space       → Toggle graph/linear
# Ctrl+F      → Search
r2 tips & tricks
# Pipe to system command
pdf @ main | grep call
afl | wc -l

# Save output to file
pdf @ main > disasm.txt

# Evaluate expressions
? 0x401234 - 0x400000    # arithmetic
? 1024 / 4
? rax                     # register value

# Configuration
e                         # list all config
e asm.syntax=intel        # Intel syntax
e asm.pseudo=true         # pseudo-C in disasm
e asm.comments=true
e scr.color=true

# Run r2 command from bash
r2 -q -c "aaa; pdf @ main" ./challenge 2>/dev/null
QUICK REFERENCE →  r2 -A open+analyze  · aaa analyze  · afl~win find functions  · pdf @ main disasm  · iz~flag search strings  · /R pop rdi ROP gadgets  · axt sym.win xrefs to win  · VV graph mode  · wx 90 patch NOP  · r2 -q -c "aaa;pdf@main" batch