radare2 basics - sail
After installing the radare2 toolset, we've come on board.
Let's set sail with some important and frequently used commands.
First raw, then ripe. Well begun is half done.
grep(~)#
2. First Steps - 2.2. Command Format
The standard UNIX pipe |
is also available in the radare2 shell. You can use it to filter the output of an r2
command with any shell program that reads from stdin, such as grep
, less
, wc
. If you do not want to spawn anything, or you can't, or the target system does not have the basic UNIX tools you need (Windows or embedded users), you can also use the built-in grep (~
).
[0x000000000000]> @?
[0x000000000000]> ?@?
Usage: [.:"][#]<cmd>[*] [`cmd`] [@ addr] [~grep] [|syscmd] [>[>]file]
| ~? count number of lines (like wc -l)
| ~?? show internal grep help
| ~.. internal less
| ~{} json indent
| ~<> xml indent
| ~<100 ascii-art zoom of console buffer
| ~{}.. json indent and less
| ~word grep for lines matching word
| ~!word grep for lines NOT matching word
| ~word[2] grep 3rd column of lines matching word
| ~word:3[0] grep 1st column from the 4th line matching word
| >file pipe output of command to file
| >>file append to file
| |cmd pipe output to command (pd|less) (.dr*)
[0x000000000000]> ~??
Usage: [command]~[modifier][word,word][endmodifier][[column]][:line]
modifier:
The ~
character enables internal grep-like function used to filter output of any command:
Additionally, you can grep either for columns or for rows:
pd 20~call:0 ; get first row
pd 20~call:1 ; get second row
pd 20~call[0] ; get first column
pd 20~call[1] ; get second column
Or even combine them:
[0xaaaae7580754]> i~pic
pic true
[0xaaaae7580754]> i~baddr
baddr 0xaaaae7580000
# show only column 1
[0xaaaae7580754]> i~baddr[1]
0xaaaae7580000
config(e)#
Radare2 Book: 3. Configuration
Use r2 -H
to list all the environment variables that matter to know where it will be looking for files.
R2_RCFILE=
~/.radare2rc
(aka$HOME/.radare2rc
).
[0x000000000000]> e?
Usage: e [var[=value]] Evaluable vars
| e?asm.bytes show description
| e?? list config vars with description
| e a get value of var 'a'
| e a=b set var 'a' the 'b' value
| e.a=b same as 'e a=b' but without using a space
| e,[table-query] show the output in table format
| e/asm filter configuration variables by name
| e:k=v:k=v:k=v comma or colon separated k[=v]
| e- reset config vars
| e* dump config vars in r commands
| e!a invert the boolean value of 'a' var
| ec[?] [k] [color] set color for given key (prompt, offset, ...)
| ee [var] open cfg.editor to change the value of var
| ed open editor to change the ~/.radare2rc
| ed-[!] delete ~/.radare2c (Use ed-! to delete without prompting)
| ej list config vars in JSON
| eJ list config vars in verbose JSON
| en list environment vars
| env [k[=v]] get/set environment variable
| er [key] set config key as readonly. no way back
| es [space] list all eval spaces [or keys]
| et [key] show type of given config variable
| ev [key] list config vars in verbose format
| evj [key] list config vars in verbose format in JSON
Show description:
[0x004005c8]> e? asm.symbol
show symbol+delta instead of absolute offset
[0x004005c8]> e? asm.comments
show comments in disassembly view (see 'e asm.cmt.')
[0x004005c8]> e?asm.describe
show opcode description
[0x004005c8]> e?asm.pseudo # see pdc
enable pseudo syntax
Filter config vars with description: e??~whatever
# e??asm will show lots of results, grep with concrete config name
[0x000000000000]> e??~asm.pseudo
asm.pseudo: enable pseudo syntax
[0x000000000000]> e??~asm.describe
asm.describe: show opcode description
# e??~arch will match more fuzzy results with the pattern
[0x000000000000]> e??arch
arch.bits: word size in bits at arch decoder
arch.decoder: select the instruction decoder to use
arch.endian: set arch endianness
arch.platform: define arch platform to use
[0xaaaadc6e0640]> e??~endian
arch.endian: set arch endianness
cfg.bigendian: use little (false) or big (true) endianness
[0x000000000000]> e arch.endian # !echo $R2_ENDIAN
little
[0x000000000000]> e cfg.bigendian
false
List possible values/view more options with question mark like e conf.var = ?
.
[0xffffbc84ae70]> e asm.arch=?
[0xffffbc84ae70]> e bin.relocs.apply=?
[0xffffbc84ae70]> e search.in=?
[0xffffbc84ae70]> e dbg.bpinmap=?
# show offset relative instead of absolute address
[0xffffbc84ae70]> e asm.offset.relto=?
func
flag
maps
dmap
fmap
sect
symb
libs
file
Config bin.relocs.apply
:
[0xaaaadc6e0640]> e bin.relocs.apply
false
[0xaaaadc6e0640]> e bin.relocs.apply=true; e bin.relocs.apply
true
Config search.in
to search in all memory maps:
[0x000000000000]> e search.in
dbg.map
[0x000000000000]> e search.in = dbg.maps; e search.in
dbg.maps
Config cfg.bigendian=false
for temporary hexdump in BE.
# show current endianess
[0xaaaab3ce0634]> e cfg.bigendian
false
# temporally swap/invert endian
[0xaaaab3ce0634]> e!cfg.bigendian
# equivalent imp for `pfed`, `pve 1234 4`.
[0xaaaab3ce0634]> pxw $l @ pc
# reset endianness
[0xaaaab3ce0634]> e!cfg.bigendian
Set e dbg.bpinmaps=false
so Radare2 allows you to set breakpoint without that restriction.
Useful configuration variables:
- Use UTF-8 chars:
e scr.utf8 = true
- Curved UTF-8 corners:
e scr.utf8.curvy = true
- User uppercase syntax:
e asm.ucase = true
- Enable cache (r/w):
e io.cache = true
- Show opcode description:
e asm.describe = true
- Enable pseudo syntax:
e asm.pseudo = true
- Show symbol+delta before addr:
e!asm.symbol
- Don't show comments:
e!asm.comments
, seee asm.cmt.
andasm.cmt.user
.
Write configuration to file for persistence:
To configure radare the visual way, use Ve
.
expr(?)#
?v
: show hex value of math expr.
[0x000000000000]> ???
Usage: ?[?[?]] expression
| ?$ show value all the variables ($)
| ?b [num] show binary value of number
| ?P paddr get virtual address for given physical one
| ?p vaddr get physical address for given virtual address
| ?q num|expr compute expression like ? or ?v but in quiet mode
| ?v num|expr show hex value of math expr (no expr prints $?)
| ?vi[1248] num|expr show decimal value of math expr [n bytes]
| ?vx num|expr show 8 digit padding in hex
| ?w addr show what's in this address (like pxr/pxq does)
| ?X num|expr returns the hexadecimal value numeric expr
Show all representation result for expr with single question mark.
[0xffffbc190c40]> ? 1989+64 # rax2 -r 1989+64
int32 2053
uint32 2053
hex 0x805
octal 04005
unit 2.0K
segment 0000:0805
string "\x05\b"
fvalue 2053.0
float 0.000000f
double 0.000000
binary 0b0000100000000101
base36 0_1l1
ternary 0t2211001
Telescope/dereference overflowed pc as prepended debruijn pattern string.
# -e(little-endian) incompatible with -r
# use rev to reverse lines characterwise
$ echo 0x4141764141754141 | xxd -rp | rev
AAuAAvAA%
$ echo -e `rax2 -c 0x4141764141754141`
AAuAAvAA
# ? pc ~string or ? $$ ~string or rax2 -r `dr pc`
[0x4141764141754141]> ? 0x4141764141754141 ~string
string "AAuAAvAA"
# get second column, like | awk '{print $2}'
[0x4141764141754141]> ? pc ~string[1]
"AAuAAvAA"
Perform simple arithmetic on the spot, results depending on the numeric base.
[0x000000000000]> ?vi 1989+64 # rax2 -k 1989+64
2053
[0x000000000000]> ?b 16 # rax2 b16 # rax2 Bx10
10000b
[0x000000000000]> ?v 1989+64 # rax2 1989+64
0x805
[0x000000000000]> ?X 1989+64
805
[0x000000000000]> ?vx 1989+64 # 8 digit padding
0x00000805
?w <address>
: inspect what's in this address, not equivalent to info symbol ADDR
in GDB.
[0xffffb6d45c40]> ?w 0xaaaad2f50640
/home/pifan/Projects/cpp/a.out .text entry0,section..text,_start entry0 program R X 'nop' 'a.out'
?v <symbol>
acts as afo <symbol>
, show the address for the symbol, similar to info address SYM
in GDB.
[0xffff99b209d0]> ?v sym.main # afo sym.main
0xaaaae16307a0
[0xffff99b209d0]> ?v sym.func # afo sym.func
0xaaaae1630754
[0xffffa8098c40]> ?v segment.LOAD0
0xaaaade740000
env(%)#
[0x000000000000]> env?
| en list environment vars
| env [k[=v]] get/set environment variable
[0x000000000000]> %?
Usage: %[name[=value]] Set each NAME to VALUE in the environment
| % list all environment variables
[0x000000000000]> %??
Usage: %[name[=value]] Set each NAME to VALUE in the environment
| % list all environment variables
| %* show env vars as r2 commands
| %j show env vars in JSON format
| %SHELL prints SHELL value
| %TMPDIR=/tmp sets TMPDIR value to "/tmp"
Environment:
| R2_FILE file name
| R2_OFFSET 10base offset 64bit value
| R2_BYTES TODO: variable with bytes in curblock
| R2_XOFFSET same as above, but in 16 base
| R2_BSIZE block size
| R2_ENDIAN 'big' or 'little'
| R2_IOVA is io.va true? virtual addressing (1,0)
| R2_DEBUG debug mode enabled? (1,0)
| R2_BLOCK TODO: dump current block to tmp file
| R2_SIZE file size
| R2_ARCH value of asm.arch
| R2_BITS arch reg size (8, 16, 32, 64)
| RABIN2_LANG assume this lang to demangle
| RABIN2_DEMANGLE demangle or not
| RABIN2_PDBSERVER e pdb.server
[0x000000000000]> ?
Usage: [.][times][cmd][~grep][@[@iter]addr!size][|>pipe] ; ...
Append '?' to any char command to get detailed help
Prefix with number to repeat command N times (f.ex: 3x)
| %var=value alias for 'env' command
| _[?] Print last output
List/Dump Examples:
[0x000000000000]> env _ # %_
/snap/bin/r2
[0x000000000000]> env SHELL # %SHELL
/usr/bin/zsh
[0x000000000000]> _ # same as python REPL
/usr/bin/zsh
Show/filter env vars:
[0x000000000000]> %~term
TERM=xterm-256color
[0x000000000000]> %~Term
TERM_PROGRAM=WarpTerminal
[0x000000000000]> !echo $R2_FILE # %~R2_FILE
[0x000000000000]> !echo $R2_ENDIAN # %~R2_ENDIAN
# e asm.arch
[0x000000000000]> !echo $R2_ARCH # %~R2_ARCH
# e asm.bits
[0x000000000000]> !echo $R2_BITS # %~R2_BITS
Define temporary environment variables at session level for later computation.
To avoid overwriting, run
%~ENVVAR
to see if it's already there.
# check existence first: %~FP
[0x004008e0]> %FP=`xQq $w @ sp`
[0x004008e0]> %~FP
FP=0x0000ffffdf541530
[0x004008e0]> %FP
0x0000ffffdf541530
# check existence first: %~SP
[0x004008e0]> %SP=`dr sp`
[0x004008e0]> %~SP
SP=0xffffdf541500
[0x004008e0]> %SP
0xffffdf541500
Then you can refer to the vars in subsequent math expr or any r2 command.
# equivalent to ?v `xQq $w @ sp`-`dr sp`
[0x004008e0]> ?v `env FP`-`env SP` # ?v `%FP`-`%SP`
0x30
# save result(last output) in another var
[0x004008e0]> %SIZE=`_` ; %SIZE
0x30
# ref the var in r2 command
[0x004008e0]> xQ `%SIZE` @ sp
0xffffdf541500 0x0000ffffdf541530 sp+48
0xffffdf541508 0x0000ffffb7b073fc x30
0xffffdf541510 0x0000ffffdf541530 sp+48
0xffffdf541518 0x0000ffffb7b073c0
0xffffdf541520 0x0000ffffdf5416a8 x1
0xffffdf541528 0x0000000000000010 x9
var($)#
[0x000000000000]> $?
Usage: $alias[=cmd] [args...] Alias commands and data (See ?$? for help on $variables)
| $ list all defined aliases
| $* list all defined aliases and their values, with unprintable characters escaped
[0x000000000000]> ?$?
Usage: ?v [$.]
| flag offset of flag
| ${ev} get value of eval config variable
| $$ here (current virtual seek)
| $alias=value alias commands (simple macros)
| $B base address (aligned lowest map address)
| $D current debug map base address ?v $D @ rsp
| $DB same as dbg.baddr, progam base address
| $DD current debug map size
| $F same as $FB
| $FB begin of function
| $FE end of function
| $l opcode length
| $M map address (lowest map address)
| $m opcode memory reference (e.g. mov eax,[0x10] => 0x10)
| $MM map size (lowest map address)
| $r{reg} get value of named register ($r{PC} and $r:PC syntax is supported)
| $S section offset
| $SS section size
| $w get word size, 4 if asm.bits=32, 8 if 64, ...
Seek here/print current address.
# equivalent to s : print current address
# $$: here (current virtual seek)
[0xaaaac30a07a0]> ?v pc # ?v $$
0xaaaac30a07a0
Define simple macros by alias.
[0xaaaac30a07a0]> $rip=1989+64
[0xaaaac30a07a0]> $rip?
1989+64
# list all self-defined aliases
# ?$: show value all the built-in variables, prefixed with $
[0xaaaac30a07a0]> $
$rip
[0xaaaac30a07a0]> $*
$rip=1989+64
Eval map/opcode/word size related $ vars.
[0x000000000000]> ?v $MM
0x7fffffffffffffff
# display size of 1 opcode
[0x000000000000]> aos 1
4
[0x000000000000]> ?v $l
0x4
[0x000000000000]> e arch.bits
32
# display machine word size
[0x000000000000]> ?v $w
0x8
[0x000000000000]> e asm.bits
64
[0x000000000000]> !getconf LONG_BIT
64
Detect begin/end of current function:
$r{reg}
is equivalent to dr?<register>
, see drl
, dr??
and dr=
.
[0x000000000000]> ?v x0 # ?v $r{x0} # ?v $r:A0
0xfa
[0x000000000000]> ?v $r{PC} # dr?pc
0x000000000000
[0x000000000000]> ?v $r{BP} # dr bp
0xffffdca194e0
[0x000000000000]> ?v $r:SP # dr sp
0xffffdca194e0
refs#
How-To: Radare2
awesome-radare2
Radare2 vs. GDB
Radare2 Explorations
Binary Exploitation Notes
Radare2 — Keep It Or Leave It?
Disassembling with radare2.pdf
Overcoming fear: reversing with radare2.pdf
pancake - Learning Radare In Practice.pdf
BinaryAdventure - Radare2 Tutorial