# 2.4 Radare2 - [简介](#简介) - [安装](#安装) - [命令行使用方法](#命令行使用方法) - [radare2/r2](#radare2r2) - [rabin2](#rabin2) - [rasm2](#rasm2) - [rahash2](#rahash2) - [radiff2](#radiff2) - [rafind2](#rafind2) - [ragg2](#ragg2) - [rarun2](#rarun2) - [rax2](rax2) - [交互式使用方法](#交互式使用方法) - [分析(analyze)](#分析analyze) - [Flags](#flags) - [定位(seeking)](#定位seeking) - [信息(information)](#信息information) - [打印(print) & 反汇编(disassembling)](#打印print--反汇编disassembling) - [写入(write)](#写入write) - [视图模式](#视图模式) - [Web 界面使用](#web-界面使用) - [在 CTF 中的运用](#在-ctf-中的运用) ## 简介 IDA Pro 昂贵的价格令很多二进制爱好者望而却步,于是在开源世界中催生出了一个新的逆向工程框架——Radare2,它拥有非常强大的功能,包括反汇编、调试、打补丁、虚拟化等等,而且可以运行在几乎所有的主流平台上(GNU/Linux、Windows、BSD、iOS、OSX……)。Radare2 开发之初仅提供了基于命令行的操作,尽管现在也有非官方的GUI,但我更喜欢直接在终端上运行它,当然这也就意味着更高陡峭的学习曲线。Radare2 是由一系列的组件构成的,这些组件赋予了 Radare2 强大的分析能力,可以在 Radare2 中或者单独被使用。 这里是 Radare2 与其他二进制分析工具的对比。([Comparison Table](http://rada.re/r/cmp.html)) ## 安装 #### 安装 ```bash $ git clone https://github.com/radare/radare2.git $ cd radare2 $ ./sys/install.sh ``` #### 更新 ```bash $ ./sys/install.sh ``` #### 卸载 ```bash $ make uninstall $ make purge ``` ## 命令行使用方法 Radare2 在命令行下有一些小工具可供使用: - radare2:十六进制编辑器和调试器的核心,通常通过它进入交互式界面。 - rabin2:从可执行二进制文件中提取信息。 - rasm2:汇编和反汇编。 - rahash2:基于块的哈希工具。 - radiff2:二进制文件或代码差异比对。 - rafind2:查找字节模式。 - ragg2:r_egg 的前端,将高级语言编写的简单程序编译成x86、x86-64和ARM的二进制文件。 - rarun2:用于在不同环境中运行程序。 - rax2:数据格式转换。 #### radare2/r2 ```text $ r2 -h Usage: r2 [-ACdfLMnNqStuvwzX] [-P patch] [-p prj] [-a arch] [-b bits] [-i file] [-s addr] [-B baddr] [-M maddr] [-c cmd] [-e k=v] file|pid|-|--|= -- run radare2 without opening any file - same as 'r2 malloc://512' = read file from stdin (use -i and -c to run cmds) -= perform !=! command to run all commands remotely -0 print \x00 after init and every command -a [arch] set asm.arch -A run 'aaa' command to analyze all referenced code -b [bits] set asm.bits -B [baddr] set base address for PIE binaries -c 'cmd..' execute radare command -C file is host:port (alias for -c+=http://%s/cmd/) -d debug the executable 'file' or running process 'pid' -D [backend] enable debug mode (e cfg.debug=true) -e k=v evaluate config var -f block size = file size -F [binplug] force to use that rbin plugin -h, -hh show help message, -hh for long -H ([var]) display variable -i [file] run script file -I [file] run script file before the file is opened -k [k=v] perform sdb query into core->sdb -l [lib] load plugin file -L list supported IO plugins -m [addr] map file at given address (loadaddr) -M do not demangle symbol names -n, -nn do not load RBin info (-nn only load bin structures) -N do not load user settings and scripts -o [OS/kern] set asm.os (linux, macos, w32, netbsd, ...) -q quiet mode (no prompt) and quit after -i -p [prj] use project, list if no arg, load if no file -P [file] apply rapatch file and quit -R [rarun2] specify rarun2 profile to load (same as -e dbg.profile=X) -s [addr] initial seek -S start r2 in sandbox mode -t load rabin2 info in thread -u set bin.filter=false to get raw sym/sec/cls names -v, -V show radare2 version (-V show lib versions) -w open file in write mode -X [rr2rule] specify custom rarun2 directive -z, -zz do not load strings or load them even in raw ``` #### rabin2 ```text $ rabin2 -h Usage: rabin2 [-AcdeEghHiIjlLMqrRsSvVxzZ] [-@ at] [-a arch] [-b bits] [-B addr] [-C F:C:D] [-f str] [-m addr] [-n str] [-N m:M] [-P[-P] pdb] [-o str] [-O str] [-k query] [-D lang symname] | file -@ [addr] show section, symbol or import at addr -A list sub-binaries and their arch-bits pairs -a [arch] set arch (x86, arm, .. or _) -b [bits] set bits (32, 64 ...) -B [addr] override base address (pie bins) -c list classes -C [fmt:C:D] create [elf,mach0,pe] with Code and Data hexpairs (see -a) -d show debug/dwarf information -D lang name demangle symbol name (-D all for bin.demangle=true) -e entrypoint -E globally exportable symbols -f [str] select sub-bin named str -F [binfmt] force to use that bin plugin (ignore header check) -g same as -SMZIHVResizcld (show all info) -G [addr] load address . offset to header -h this help message -H header fields -i imports (symbols imported from libraries) -I binary info -j output in json -k [sdb-query] run sdb query. for example: '*' -K [algo] calculate checksums (md5, sha1, ..) -l linked libraries -L [plugin] list supported bin plugins or plugin details -m [addr] show source line at addr -M main (show address of main symbol) -n [str] show section, symbol or import named str -N [min:max] force min:max number of chars per string (see -z and -zz) -o [str] output file/folder for write operations (out by default) -O [str] write/extract operations (-O help) -p show physical addresses -P show debug/pdb information -PP download pdb file for binary -q be quiet, just show fewer data -qq show less info (no offset/size for -z for ex.) -Q show load address used by dlopen (non-aslr libs) -r radare output -R relocations -s symbols -S sections -u unfiltered (no rename duplicated symbols/sections) -v display version and quit -V Show binary version information -x extract bins contained in file -X [fmt] [f] .. package in fat or zip the given files and bins contained in file -z strings (from data section) -zz strings (from raw bins [e bin.rawstr=1]) -zzz dump raw strings to stdout (for huge files) -Z guess size of binary program ``` 当我们拿到一个二进制文件时,第一步就是获取关于它的基本信息,这时候就可以使用 rabin2。rabin2 可以获取包括 ELF、PE、Mach-O、Java CLASS 文件的区段、头信息、导入导出表、数据段字符串、入口点等信息,并且支持多种格式的输出。 下面介绍一些常见的用法:(我还会列出其他实现类似功能工具的用法,你可以对比一下它们的输出) - `-I`:最常用的参数,它可以打印出二进制文件信息,其中我们需要重点关注其使用的安全防护技术,如 canary、pic、nx 等。(`file`、`chekcsec -f`) - `-e`:得到二进制文件的入口点。(`readelf -h`) - `-i`:获得导入符号表,RLT中的偏移等。(`readelf -r`) - `-E`:获得全局导出符号表。 - `-s`:获得符号表。(`readelf -s`) - `-l`:获得二进制文件使用到的动态链接库。(`ldd`) - `-z`:从 ELF 文件的 .rodare 段或 PE 文件的 .text 中获得字符串。(`strings -d`) - `-S`:获得完整的段信息。(`readelf -S`) - `-c`:列出所有类,在分析 Java 程序是很有用。 最后还要提到的一个参数 `-r`,它可以将我们得到的信息以 radare2 可读的形式输出,在后续的分析中可以将这样格式的信息输入 radare2,这是非常有用的。 #### rasm2 ```text $ rasm2 -h Usage: rasm2 [-ACdDehLBvw] [-a arch] [-b bits] [-o addr] [-s syntax] [-f file] [-F fil:ter] [-i skip] [-l len] 'code'|hex|- -a [arch] Set architecture to assemble/disassemble (see -L) -A Show Analysis information from given hexpairs -b [bits] Set cpu register size (8, 16, 32, 64) (RASM2_BITS) -c [cpu] Select specific CPU (depends on arch) -C Output in C format -d, -D Disassemble from hexpair bytes (-D show hexpairs) -e Use big endian instead of little endian -E Display ESIL expression (same input as in -d) -f [file] Read data from file -F [in:out] Specify input and/or output filters (att2intel, x86.pseudo, ...) -h, -hh Show this help, -hh for long -i [len] ignore/skip N bytes of the input buffer -k [kernel] Select operating system (linux, windows, darwin, ..) -l [len] Input/Output length -L List Asm plugins: (a=asm, d=disasm, A=analyze, e=ESIL) -o [offset] Set start address for code (default 0) -O [file] Output file name (rasm2 -Bf a.asm -O a) -p Run SPP over input for assembly -s [syntax] Select syntax (intel, att) -B Binary input/output (-l is mandatory for binary input) -v Show version information -w What's this instruction for? describe opcode -q quiet mode ``` rasm2 是一个内联汇编、反汇编程序。它的主要功能是获取给定机器指令操作码对应的字节。 下面是一些重要的参数: - `-L`:列出目标体系结构所支持的插件,输出中的第一列说明了插件提供的功能(a=asm, d=disasm, A=analyze, e=ESIL)。 - `-a`:知道插件的名字后,就可以使用 -a` 来进行设置。 - `-b`:设置CPU寄存器的位数。 - `-d`:反汇编十六进制对字符串。 - `-D`:反汇编并显示十六进制对和操作码。 - `-C`:汇编后以 C 语言风格输出。 - `-f`:从文件中读入汇编代码。 例子: ``` $ rasm2 -a x86 -b 32 'mov eax,30' b81e000000 $ rasm2 -a x86 -b 32 'mov eax,30' -C "\xb8\x1e\x00\x00\x00" $ rasm2 -d b81e000000 mov eax, 0x1e $ rasm2 -D b81e000000 0x00000000 5 b81e000000 mov eax, 0x1e $ rasm2 -a x86 -b 32 -d 'b81e000000' mov eax, 0x1e $ cat a.asm mov eax,30 $ rasm2 -f a.asm b81e000000 ``` #### rahash2 ```text $ rahash2 -h Usage: rahash2 [-rBhLkv] [-b S] [-a A] [-c H] [-E A] [-s S] [-f O] [-t O] [file] ... -a algo comma separated list of algorithms (default is 'sha256') -b bsize specify the size of the block (instead of full file) -B show per-block hash -c hash compare with this hash -e swap endian (use little endian) -E algo encrypt. Use -S to set key and -I to set IV -D algo decrypt. Use -S to set key and -I to set IV -f from start hashing at given address -i num repeat hash N iterations -I iv use give initialization vector (IV) (hexa or s:string) -S seed use given seed (hexa or s:string) use ^ to prefix (key for -E) (- will slurp the key from stdin, the @ prefix points to a file -k show hash using the openssh's randomkey algorithm -q run in quiet mode (-qq to show only the hash) -L list all available algorithms (see -a) -r output radare commands -s string hash this string instead of files -t to stop hashing at given address -x hexstr hash this hexpair string instead of files -v show version information ``` rahash2 用于计算检验和,支持字节流、文件、字符串等形式和多种算法。 重要参数: - `-a`:指定算法。默认为 sha256,如果指定为 all,则使用所有算法。 - `-b`:指定块的大小(而不是整个文件) - `-B`:打印处每个块的哈希 - `-s`:指定字符串(而不是文件) - `-a entropy`:显示每个块的熵(`-B -b 512 -a entropy`) #### radiff2 ```text $ radiff2 -h Usage: radiff2 [-abcCdjrspOxuUvV] [-A[A]] [-g sym] [-t %] [file] [file] -a [arch] specify architecture plugin to use (x86, arm, ..) -A [-A] run aaa or aaaa after loading each binary (see -C) -b [bits] specify register size for arch (16 (thumb), 32, 64, ..) -c count of changes -C graphdiff code (columns: off-A, match-ratio, off-B) (see -A) -d use delta diffing -D show disasm instead of hexpairs -e [k=v] set eval config var value for all RCore instances -g [sym|off1,off2] graph diff of given symbol, or between two offsets -G [cmd] run an r2 command on every RCore instance created -i diff imports of target files (see -u, -U and -z) -j output in json format -n print bare addresses only (diff.bare=1) -O code diffing with opcode bytes only -p use physical addressing (io.va=0) -q quiet mode (disable colors, reduce output) -r output in radare commands -s compute text distance -ss compute text distance (using levenstein algorithm) -S [name] sort code diff (name, namelen, addr, size, type, dist) (only for -C or -g) -t [0-100] set threshold for code diff (default is 70%) -x show two column hexdump diffing -u unified output (---+++) -U unified output using system 'diff' -v show version information -V be verbose (current only for -s) -z diff on extracted strings ``` radiff2 是一个基于偏移的比较工具。 重要参数: - `-s`:计算文本距离并得到相似度。 - `-AC`:这两个参数通常一起使用,从函数的角度进行比较。 - `-g`:得到给定的符号或两个偏移的图像对比。 - 如:`radiff2 -g main a.out b.out | xdot -`(需要安装xdot) - `-c`:计算不同点的数量。 #### rafind2 ```text $ rafind2 -h Usage: rafind2 [-mXnzZhv] [-a align] [-b sz] [-f/t from/to] [-[m|s|S|e] str] [-x hex] file .. -a [align] only accept aligned hits -b [size] set block size -e [regex] search for regular expression string matches -f [from] start searching from address 'from' -h show this help -m magic search, file-type carver -M [str] set a binary mask to be applied on keywords -n do not stop on read errors -r print using radare commands -s [str] search for a specific string (can be used multiple times) -S [str] search for a specific wide string (can be used multiple times) -t [to] stop search at address 'to' -v print version and exit -x [hex] search for hexpair string (909090) (can be used multiple times) -X show hexdump of search results -z search for zero-terminated strings -Z show string found on each search hit ``` rafind2 用于在二进制文件中查找字符模式。 重要参数: - `-s`:查找特定字符串。 - `-e`:使用正则匹配。 - `-z`:搜索以`\0`结束的字符串。 - `-x`:查找十六进制字符串。 #### ragg2 ```text $ ragg2 -h Usage: ragg2 [-FOLsrxhvz] [-a arch] [-b bits] [-k os] [-o file] [-I path] [-i sc] [-e enc] [-B hex] [-c k=v] [-C file] [-p pad] [-q off] [-q off] [-dDw off:hex] file|f.asm|- -a [arch] select architecture (x86, mips, arm) -b [bits] register size (32, 64, ..) -B [hexpairs] append some hexpair bytes -c [k=v] set configuration options -C [file] append contents of file -d [off:dword] patch dword (4 bytes) at given offset -D [off:qword] patch qword (8 bytes) at given offset -e [encoder] use specific encoder. see -L -f [format] output format (raw, pe, elf, mach0) -F output native format (osx=mach0, linux=elf, ..) -h show this help -i [shellcode] include shellcode plugin, uses options. see -L -I [path] add include path -k [os] operating system's kernel (linux,bsd,osx,w32) -L list all plugins (shellcodes and encoders) -n [dword] append 32bit number (4 bytes) -N [dword] append 64bit number (8 bytes) -o [file] output file -O use default output file (filename without extension or a.out) -p [padding] add padding after compilation (padding=n10s32) ntas : begin nop, trap, 'a', sequence NTAS : same as above, but at the end -P [size] prepend debruijn pattern -q [fragment] debruijn pattern offset -r show raw bytes instead of hexpairs -s show assembler -v show version -w [off:hex] patch hexpairs at given offset -x execute -z output in C string syntax ``` ragg2 可以将高级语言编写的简单程序编译成 x86、x86-64 或 ARM 的二进制文件。 重要参数: - `-a`:设置体系结构。 - `-b`:设置体系结构位数(32/64)。 - `-P`:生成某种模式的字符串,常用于输入到某程序中并寻找溢出点。 - `-r`:使用原始字符而不是十六进制对。 - ragg2 -P 50 -r` - `-i`:生成指定的 shellcode。查看 `-L`。 - `ragg2 -a x86 -b 32 -i exec` - `-e`:使用指定的编码器。查看 `-L`。 #### rarun2 ```text $ rarun2 -h Usage: rarun2 -v|-t|script.rr2 [directive ..] program=/bin/ls arg1=/bin # arg2=hello # arg3="hello\nworld" # arg4=:048490184058104849 # arg5=:!ragg2 -p n50 -d 10:0x8048123 # arg6=@arg.txt # arg7=@300@ABCD # 300 chars filled with ABCD pattern # system=r2 - # aslr=no setenv=FOO=BAR # unsetenv=FOO # clearenv=true # envfile=environ.txt timeout=3 # timeoutsig=SIGTERM # or 15 # connect=localhost:8080 # listen=8080 # pty=false # fork=true # bits=32 # pid=0 # pidfile=/tmp/foo.pid # #sleep=0 # #maxfd=0 # #execve=false # #maxproc=0 # #maxstack=0 # #core=false # #stdio=blah.txt # #stderr=foo.txt # stdout=foo.txt # stdin=input.txt # or !program to redirect input to another program # input=input.txt # chdir=/ # chroot=/mnt/chroot # libpath=$PWD:/tmp/lib # r2preload=yes # preload=/lib/libfoo.so # setuid=2000 # seteuid=2000 # setgid=2001 # setegid=2001 # nice=5 ``` rarun2 是一个可以使用不同环境、参数、标准输入、权限和文件描述符的启动器。 常用的参数设置: - `program` - `arg1`, `arg2`,... - `setenv` - `stdin`, `stdout` 例子: - `rarun2 program=a.out arg1=$(ragg2 -P 300 -r)` - `rarun2 program=a.out stdin=$(python a.py)` #### rax2 ```text $ rax2 -h Usage: rax2 [options] [expr ...] =[base] ; rax2 =10 0x46 -> output in base 10 int -> hex ; rax2 10 hex -> int ; rax2 0xa -int -> hex ; rax2 -77 -hex -> int ; rax2 0xffffffb3 int -> bin ; rax2 b30 int -> ternary ; rax2 t42 bin -> int ; rax2 1010d float -> hex ; rax2 3.33f hex -> float ; rax2 Fx40551ed8 oct -> hex ; rax2 35o hex -> oct ; rax2 Ox12 (O is a letter) bin -> hex ; rax2 1100011b hex -> bin ; rax2 Bx63 hex -> ternary ; rax2 Tx23 raw -> hex ; rax2 -S < /binfile hex -> raw ; rax2 -s 414141 -b bin -> str ; rax2 -b 01000101 01110110 -B str -> bin ; rax2 -B hello -d force integer ; rax2 -d 3 -> 3 instead of 0x3 -e swap endianness ; rax2 -e 0x33 -D base64 decode ; -E base64 encode ; -f floating point ; rax2 -f 6.3+2.1 -F stdin slurp C hex ; rax2 -F < shellcode.c -h help ; rax2 -h -k keep base ; rax2 -k 33+3 -> 36 -K randomart ; rax2 -K 0x34 1020304050 -n binary number ; rax2 -n 0x1234 # 34120000 -N binary number ; rax2 -N 0x1234 # \x34\x12\x00\x00 -r r2 style output ; rax2 -r 0x1234 -s hexstr -> raw ; rax2 -s 43 4a 50 -S raw -> hexstr ; rax2 -S < /bin/ls > ls.hex -t tstamp -> str ; rax2 -t 1234567890 -x hash string ; rax2 -x linux osx -u units ; rax2 -u 389289238 # 317.0M -w signed word ; rax2 -w 16 0xffff -v version ; rax2 -v ``` rax2 是一个格式转换工具,在二进制、八进制、十六进制数字和字符串之间进行转换。 重要参数: - `-e`:交换字节顺序。 - `-s`:十六进制->字符 - `-S`:字符->十六进制 - `-D`, `-E`:base64 解码和编码 ## 交互式使用方法 当我们进入到 Radare2 的交互式界面后,就可以使用交互式命令进行操作。 输入 `?` 可以获得帮助信息,由于命令太多,我们只会重点介绍一些常用命令: ```text [0x00000000]> ? 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 =valueAlias for 'env' command | *[?] off[=[0x]value] Pointer read/write data/values (see ?v, wx, wv) | (macro arg0 arg1) Manage scripting macros | .[?] [-|(m)|f|!sh|cmd] Define macro or load r2, cparse or rlang file | =[?] [cmd] Send/Listen for Remote Commands (rap://, http://, ) | /[?] Search for bytes, regexps, patterns, .. | ![?] [cmd] Run given command as in system(3) | #[?] !lang [..] Hashbang to run an rlang script | a[?] Analysis commands | b[?] Display or change the block size | c[?] [arg] Compare block with given data | C[?] Code metadata (comments, format, hints, ..) | d[?] Debugger commands | e[?] [a[=b]] List/get/set config evaluable vars | f[?] [name][sz][at] Add flag at current address | g[?] [arg] Generate shellcodes with r_egg | i[?] [file] Get info about opened file from r_bin | k[?] [sdb-query] Run sdb-query. see k? for help, 'k *', 'k **' ... | L[?] [-] [plugin] list, unload load r2 plugins | m[?] Mountpoints commands | o[?] [file] ([offset]) Open file at optional address | p[?] [len] Print current block with format and length | P[?] Project management utilities | q[?] [ret] Quit program with a return value | r[?] [len] Resize file | s[?] [addr] Seek to address (also for '0x', '0x1' == 's 0x1') | S[?] Io section manipulation information | t[?] Types, noreturn, signatures, C parser and more | T[?] [-] [num|msg] Text log utility | u[?] uname/undo seek/write | V Enter visual mode (V! = panels, VV = fcngraph, VVV = callgraph) | w[?] [str] Multiple write operations | x[?] [len] Alias for 'px' (print hexadecimal) | y[?] [len] [[[@]addr Yank/paste bytes from/to memory | z[?] Zignatures management | ?[??][expr] Help or evaluate math expression | ?$? Show available '$' variables and aliases | ?@? Misc help for '@' (seek), '~' (grep) (see ~??) | ?:? List and manage core plugins ``` 于是我们知道了 Radare2 交互命令的一般格式,如下所示: ```text [.][times][cmd][~grep][@[@iter]addr!size][|>pipe] ; ... ``` - 在任意字符命令后面加上 `?` 可以获得关于该命令更多的细节。如 `a?`、`p?`、`!?`、`@?`。 - 当命令以数字开头时表示重复运行的次数。如 `3x`。 - `!` 单独使用可以显示命令使用历史记录。 - `;` 是命令分隔符,可以在一行上运行多个命令。如 `px 10; pd 20`。 - `..` 重复运行上一条命令,使用回车键也一样。 - 以 `!` 开头可以运行 shell 命令。用法:`!`。 - `!ls` - `|` 是管道符。用法:` | `。 - `pd | less` - `~` 用于文本比配(grep)。用法:`[command]~[modifier][word,word][endmodifier][[column]][:line]`。 - `i~:0` 显示 `i` 输出的第一行 - `pd~mov,eax` 反汇编并匹配 mov 或 eax 所在行 - `pi~mov&eax` 匹配 mov 和 eax 都有的行 - `i~0x400$` 匹配以 0x400 结尾的行 - `???` 可以获得以 `?` 开头的命令的细节 - `?p vaddr` 获得虚拟地址 vaddr 的物理地址 - `?P paddr` 获得物理地址 paddr 的虚拟地址 - `?v` 以十六进制的形式显示某数学表达式的结果。如 `?v eip-0x804800`。 - `?l str` 获得 str 的长度,结果被临时保存,使用 `?v` 可输出结果。 - `@@` foreach 迭代器,在列出的偏移处重复执行命令。 - `wx ff @@ 10 20 30` 在偏移 10、20、30 处写入 ff - `?$?` 可以显示表达式所使用变量的帮助信息。用法:`?v [$.]`。 - `$$` 是当前所处的虚拟地址 - `$?` 是最后一个运算的值 - `$s` 文件大小 - `$b` 块大小 - `$l` 操作码长度 - `$j` 跳转地址。当 `$$` 处是一个类似 `jmp` 的指令时,`$j` 中保存着将要跳转到的地址 - `$f` 跳转失败地址。即当前跳转没有生效,`$f` 中保存下一条指令的地址 - `$m` 操作码内存引用。如:`mov eax,[0x10] => 0x10` #### 分析(analyze) ```text [0x00000000]> a? |Usage: a[abdefFghoprxstc] [...] | ab [hexpairs] analyze bytes | abb [len] analyze N basic blocks in [len] (section.size by default) | aa[?] analyze all (fcns + bbs) (aa0 to avoid sub renaming) | ac [cycles] analyze which op could be executed in [cycles] | ad[?] analyze data trampoline (wip) | ad [from] [to] analyze data pointers to (from-to) | ae[?] [expr] analyze opcode eval expression (see ao) | af[?] analyze Functions | aF same as above, but using anal.depth=1 | ag[?] [options] output Graphviz code | ah[?] analysis hints (force opcode size, ...) | ai [addr] address information (show perms, stack, heap, ...) | ao[?] [len] analyze Opcodes (or emulate it) | aO Analyze N instructions in M bytes | ar[?] like 'dr' but for the esil vm. (registers) | ap find prelude for current offset | ax[?] manage refs/xrefs (see also afx?) | as[?] [num] analyze syscall using dbg.reg | at[?] [.] analyze execution traces | av[?] [.] show vtables ``` ```text [0x00000000]> aa? |Usage: aa[0*?] # see also 'af' and 'afna' | aa alias for 'af@@ sym.*;af@entry0;afva' | aa* analyze all flags starting with sym. (af @@ sym.*) | aaa[?] autoname functions after aa (see afna) | aab aab across io.sections.text | aac [len] analyze function calls (af @@ `pi len~call[1]`) | aad [len] analyze data references to code | aae [len] ([addr]) analyze references with ESIL (optionally to address) | aai[j] show info of all analysis parameters | aar[?] [len] analyze len bytes of instructions for references | aan autoname functions that either start with fcn.* or sym.func.* | aas [len] analyze symbols (af @@= `isq~[0]`) | aat [len] analyze all consecutive functions in section | aaT [len] analyze code after trap-sleds | aap find and analyze function preludes | aav [sat] find values referencing a specific section or map | aau [len] list mem areas (larger than len bytes) not covered by functions ``` #### Flags ```text [0x00000000]> f? |Usage: f [?] [flagname] # Manage offset-name flags | f list flags (will only list flags from selected flagspaces) | f?flagname check if flag exists or not, See ?? and ?! | f. [*[*]] list local per-function flags (*) as r2 commands | f.blah=$$+12 set local function label named 'blah' | f* list flags in r commands | f name 12 @ 33 set flag 'name' with length 12 at offset 33 | f name = 33 alias for 'f name @ 33' or 'f name 1 33' | f name 12 33 [cmt] same as above + optional comment | f-.blah@fcn.foo delete local label from function at current seek (also f.-) | f-- delete all flags and flagspaces (deinit) | f+name 12 @ 33 like above but creates new one if doesnt exist | f-name remove flag 'name' | f-@addr remove flag at address expression | f. fname list all local labels for the given function | f= [glob] list range bars graphics with flag offsets and sizes | fa [name] [alias] alias a flag to evaluate an expression | fb [addr] set base address for new flags | fb [addr] [flag*] move flags matching 'flag' to relative addr | fc[?][name] [color] set color for given flag | fC [name] [cmt] set comment for given flag | fd addr return flag+delta | fe- resets the enumerator counter | fe [name] create flag name.#num# enumerated flag. See fe? | fi [size] | [from] [to] show flags in current block or range | fg bring visual mode to foreground | fj list flags in JSON format | fl (@[flag]) [size] show or set flag length (size) | fla [glob] automatically compute the size of all flags matching glob | fm addr move flag at current offset to new address | fn list flags displaying the real name (demangled) | fo show fortunes | fr [old] [[new]] rename flag (if no new flag current seek one is used) | fR[?] [f] [t] [m] relocate all flags matching f&~m 'f'rom, 't'o, 'm'ask | fs[?]+-* manage flagspaces | fS[on] sort flags by offset or name | fV[*-] [nkey] [offset] dump/restore visual marks (mK/'K) | fx[d] show hexdump (or disasm) of flag:flagsize | fz[?][name] add named flag zone -name to delete. see fz?[name] ``` #### 定位(seeking) ```text [0x00000000]> s? |Usage: s # Seek commands | s Print current address | s:pad Print current address with N padded zeros (defaults to 8) | s addr Seek to address | s- Undo seek | s- n Seek n bytes backward | s-- Seek blocksize bytes backward | s+ Redo seek | s+ n Seek n bytes forward | s++ Seek blocksize bytes forward | s[j*=!] List undo seek history (JSON, =list, *r2, !=names, s==) | s/ DATA Search for next occurrence of 'DATA' | s/x 9091 Search for next occurrence of \x90\x91 | s.hexoff Seek honoring a base from core->offset | sa [[+-]a] [asz] Seek asz (or bsize) aligned to addr | sb Seek aligned to bb start | sC[?] string Seek to comment matching given string | sf Seek to next function (f->addr+f->size) | sf function Seek to address of specified function | sg/sG Seek begin (sg) or end (sG) of section or file | sl[?] [+-]line Seek to line | sn/sp Seek to next/prev location, as specified by scr.nkey | so [N] Seek to N next opcode(s) | sr pc Seek to register | ss Seek silently (without adding an entry to the seek history) ``` #### 信息(information) ```text [0x00000000]> i? |Usage: i Get info from opened file (see rabin2's manpage) | Output mode: | '*' Output in radare commands | 'j' Output in json | 'q' Simple quiet output | Actions: | i|ij Show info of current file (in JSON) | iA List archs | ia Show all info (imports, exports, sections..) | ib Reload the current buffer for setting of the bin (use once only) | ic List classes, methods and fields | iC Show signature info (entitlements, ...) | id[?] Debug information (source lines) | iD lang sym demangle symbolname for given language | ie Entrypoint | iE Exports (global symbols) | ih Headers (alias for iH) | iHH Verbose Headers in raw text | ii Imports | iI Binary info | ik [query] Key-value database from RBinObject | il Libraries | iL [plugin] List all RBin plugins loaded or plugin details | im Show info about predefined memory allocation | iM Show main address | io [file] Load info from file (or last opened) use bin.baddr | ir Relocs | iR Resources | is Symbols | iS [entropy,sha1] Sections (choose which hash algorithm to use) | iV Display file version info | iz|izj Strings in data sections (in JSON/Base64) | izz Search for Strings in the whole binary | iZ Guess size of binary program ``` #### 打印(print) & 反汇编(disassembling) ```text [0x00000000]> p? |Usage: p[=68abcdDfiImrstuxz] [arg|len] [@addr] | p=[?][bep] [blks] [len] [blk] show entropy/printable chars/chars bars | p2 [len] 8x8 2bpp-tiles | p3 [file] print stereogram (3D) | p6[de] [len] base64 decode/encode | p8[?][j] [len] 8bit hexpair list of bytes | pa[edD] [arg] pa:assemble pa[dD]:disasm or pae: esil from hexpairs | pA[n_ops] show n_ops address and type | p[b|B|xb] [len] ([skip]) bindump N bits skipping M | pb[?] [n] bitstream of N bits | pB[?] [n] bitstream of N bytes | pc[?][p] [len] output C (or python) format | pC[d] [rows] print disassembly in columns (see hex.cols and pdi) | pd[?] [sz] [a] [b] disassemble N opcodes (pd) or N bytes (pD) | pf[?][.nam] [fmt] print formatted data (pf.name, pf.name $) | ph[?][=|hash] ([len]) calculate hash for a block | p[iI][df] [len] print N ops/bytes (f=func) (see pi? and pdi) | pm[?] [magic] print libmagic data (see pm? and /m?) | pr[?][glx] [len] print N raw bytes (in lines or hexblocks, 'g'unzip) | p[kK] [len] print key in randomart (K is for mosaic) | ps[?][pwz] [len] print pascal/wide/zero-terminated strings | pt[?][dn] [len] print different timestamps | pu[?][w] [len] print N url encoded bytes (w=wide) | pv[?][jh] [mode] show variable/pointer/value in memory | p-[?][jh] [mode] bar|json|histogram blocks (mode: e?search.in) | px[?][owq] [len] hexdump of N bytes (o=octal, w=32bit, q=64bit) | pz[?] [len] print zoom view (see pz? for help) | pwd display current working directory ``` ```text [0x00000000]> pd? |Usage: p[dD][ajbrfils] [sz] [arch] [bits] # Print Disassembly | NOTE: len parameter can be negative | NOTE: Pressing ENTER on empty command will repeat last pd command and also seek to end of disassembled range. | pd N disassemble N instructions | pd -N disassemble N instructions backward | pD N disassemble N bytes | pda disassemble all possible opcodes (byte per byte) | pdb disassemble basic block | pdc pseudo disassembler output in C-like syntax | pdC show comments found in N instructions | pdk disassemble all methods of a class | pdj disassemble to json | pdr recursive disassemble across the function graph | pdf disassemble function | pdi like 'pi', with offset and bytes | pdl show instruction sizes | pds[?] disassemble summary (strings, calls, jumps, refs) (see pdsf and pdfs) | pdt disassemble the debugger traces (see atd) ``` #### 写入(write) ```text [0x00000000]> w? |Usage: w[x] [str] [ seek aligned to block size (seek cursor in cursor mode) a/A (a)ssemble code, visual (A)ssembler b toggle breakpoint B enumerate and inspect classes c/C toggle (c)ursor and (C)olors d[f?] define function, data, code, .. D enter visual diff mode (set diff.from/to) e edit eval configuration variables f/F set/unset or browse flags. f- to unset, F to browse, .. gG go seek to begin and end of file (0-$s) hjkl move around (or HJKL) (left-down-up-right) i insert hex or string (in hexdump) use tab to toggle mK/'K mark/go to Key (any key) M walk the mounted filesystems n/N seek next/prev function/flag/hit (scr.nkey) o go/seek to given offset O toggle asm.esil p/P rotate print modes (hex, disasm, debug, words, buf) q back to radare shell r refresh screen / in cursor mode browse comments R randomize color palette (ecr) sS step / step over t browse types T enter textlog chat console (TT) uU undo/redo seek v visual function/vars code analysis menu V (V)iew graph using cmd.graph (agv?) wW seek cursor to next/prev word xX show xrefs/refs of current function from/to data/code yY copy and paste selection z fold/unfold comments in disassembly Z toggle zoom mode Enter follow address of jump/call Function Keys: (See 'e key.'), defaults to: F2 toggle breakpoint F4 run to cursor F7 single step F8 step over F9 continue ``` ## Web 界面使用 Radare2 的 GUI 尚在开发中,但有一个 Web 界面可以使用,如果刚开始你不习惯命令行操作,可以输入下面的命令: ``` $ r2 -c=H [filename] ``` 默认地址为 `http://localhost:9090/`,这样你就可以在 Web 中进行操作了,但是我强烈建议你强迫自己使用命令行的操作方式。 ## 在 CTF 中的运用 #### IOLI crackme [Write-up](https://github.com/firmianay/Life-long-Learner/blob/master/binary-security/IOLI-crackme-Writeup.md) ## 更多资源 - [The radare2 book](https://www.gitbook.com/book/radare/radare2book) - [Radare2 intro](https://github.com/radare/radare2/blob/master/doc/intro.md)