已经说了三种反汇编引擎了,再一起学习一种radare2,这个开源项目不仅仅时做反汇编,还有其他功能等着我们去发掘,当然可以根据自己的需求选择合适的反汇编引擎,因为之前的文章都是简单的把反汇编引擎简单跑起来,并没有去讲到所有的API的使用,有兴趣的同学可以深入研究一下,记得一起分享下鸭;
Radare2,拥有非常强大的功能,包括反汇编、调试、打补丁、虚拟化等等,而且可以运行在几乎所有的主流平台上(GNU/Linux、Windows、BSD、iOS、OSX……)
github:https://github.com/radareorg/radare2
官网:
0x01:官网有提供二进制文件的下载,不过作者还是建议在本地去编译;
//cd master --> cd sys --> ./install.sh
curits@curits-virtual-machine:~/Desktop/radare2-master/sys$ ./install.sh
LD libr_socket.so
make[1]: curl: Command not found
Makefile:266: recipe for target 'capstone-4.0.2.tar.gz' failed
make[1]: *** [capstone-4.0.2.tar.gz] Error 127
make[1]: *** Waiting for unfinished jobs....
ar: creating libr_winkd.a
Makefile:56: recipe for target 'all' failed
make: *** [all] Error 2
//报错了,没有curl那就安装
curits@curits-virtual-machine:~/Desktop/radare2-master/sys$ sudo apt-get install curl
//curl 安装成功之后
curits@curits-virtual-machine:~/Desktop/radare2-master/sys$ ./install.sh
...........................
mkdir -p "/usr/local/share/radare2/4.6.0-git/"
/bin/sh sys/ldconfig.sh
/bin/sh ./configure-plugins --rm-static //usr/local/lib/radare2/last/
configure-plugins: Loading ./plugins.cfg ..
Removed 0 shared plugins that are already static
0x02:命令行使用方法
Radare2 在命令行下有一些小工具可供使用:
radare2:十六进制编辑器和调试器的核心,通常通过它进入交互式界面;
rabin2:从可执行二进制文件中提取信息;
rasm2:汇编和反汇编;
rahash2:基于块的哈希工具;
radiff2:二进制文件或代码差异比对;
rafind2:查找字节模式;
ragg2:r_egg 的前端,将高级语言编写的简单程序编译成x86、x86-64和ARM的二进制文件;
rarun2:用于在不同环境中运行程序;
rax2:数据格式转换;
curits@curits-virtual-machine:~/Desktop/radare2-master$ ra
rabin2 radiff2 ragg2 ranlib rasign2 rasttopnm rawtopgm rax2
radare2 rafind2 rahash2 rarun2 rasm2 raw rawtoppm
radare2
curits@curits-virtual-machine:~/Desktop/radare2-master$ radare2 -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
-2 close stderr file descriptor (silent warning messages)
-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 [OS/kern] set asm.os (linux, macos, w32, netbsd, ...)
-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
-NN do not load any script or plugin
-q quiet mode (no prompt) and quit after -i
-qq quit after running all -c and -i
-Q quiet mode (no prompt) and quit faster (quickLeak=true)
-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)
-R [rr2rule] specify custom rarun2 directive
-s [addr] initial seek
-S start r2 in sandbox mode
-T do not compute file hashes
-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 open without exec-flag (asm.emu will not work), See io.exec
-X same as -e bin.usextr=false (useful for dyldcache)
-z, -zz do not load strings or load them even in raw
//调试二进制文件或进程
curits@curits-virtual-machine:~/Desktop/radare2-master$ sudo radare2 -d "/home/curits/Desktop/a.out"
Process with PID 30648 started...
= attach 30648 30648
bin.baddr 0x560384b60000
Using 0x560384b60000
asm.bits 64
-- Remember that word: C H A I R
[0x7fe205753090]>
[0x7fe205753090]>
rabin2
curits@curits-virtual-machine:~/Desktop/radare2-master$ rabin2 -h
Usage: rabin2 [-AcdeEghHiIjlLMqrRsSUvVxzZ] [-@ 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 <arch>_<bits>)
-b [bits] set bits (32, 64 ...)
-B [addr] override base address (pie bins)
-c list classes
-cc list classes in header format
-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
-ee constructor/destructor entrypoints
-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 -SS -SSS -ee (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
-SS segments
-SSS sections mapping to segments
-t display file hashes
-T display file signature
-u unfiltered (no rename duplicated symbols/sections)
-U resoUrces
-v display version and quit
-V Show binary version information
-w display try/catch blocks
-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
Environment:
RABIN2_LANG: e bin.lang # assume lang for demangling
RABIN2_NOPLUGINS: # do not load shared plugins (speedup loading)
RABIN2_DEMANGLE=0:e bin.demangle # do not demangle symbols
RABIN2_MAXSTRBUF: e bin.maxstrbuf # specify maximum buffer size
RABIN2_STRFILTER: e bin.str.filter # r2 -qc 'e bin.str.filter=??' -
RABIN2_STRPURGE: e bin.str.purge # try to purge false positives
RABIN2_DEBASE64: e bin.debase64 # try to debase64 all strings
RABIN2_DMNGLRCMD: e bin.demanglercmd # try to purge false positives
RABIN2_PDBSERVER: e pdb.server # use alternative PDB server
RABIN2_SYMSTORE: e pdb.symstore # path to downstream symbol store
RABIN2_PREFIX: e bin.prefix # prefix symbols/sections/relocs with a specific string
R2_CONFIG: # sdb config file
//得到二进制文件信息
curits@curits-virtual-machine:~/Desktop/radare2-master$ rabin2 -I /home/curits/Desktop/a.out
arch x86
baddr 0x0
binsz 6441
bintype elf
bits 64
canary false
class ELF64
compiler GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
crypto false
endian little
havecode true
intrp /lib64/ld-linux-x86-64.so.2
laddr 0x0
lang c
linenum true
lsyms true
machine AMD x86-64 architecture
maxopsz 16
minopsz 1
nx true
os linux
pcalign 0
pic true
relocs true
relro full
rpath NONE
sanitiz false
static false
stripped false
subsys linux
va true
当我们拿到一个二进制文件时,第一步就是获取关于它的基本信息,这时候就可以使用 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 程序是很有用。
下面要讲到的就是本文的主题辣,反汇编引擎的使用;
0x03:具体的使用方法可以参照 https://book.rada.re/tools/rasm2/disassemble.html
使用rasm2进行反汇编:
curits@curits-virtual-machine:~/Desktop/radare2-master$ 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)
-B Binary input/output (-l is mandatory for binary input)
-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
-j output in json format
-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,-@ [addr] 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
-q quiet mode
-r output in radare commands
-s [syntax] Select syntax (intel, att)
-v Show version information
-x Use hex dwords instead of hex pairs when assembling.
-w What's this instruction for? describe opcode
If '-l' value is greater than output length, output is padded with nops
If the last argument is '-' reads from stdin
Environment:
RASM2_NOPLUGINS do not load shared plugins (speedup loading)
RASM2_ARCH same as rasm2 -a
RASM2_BITS same as rasm2 -b
R_DEBUG if defined, show error messages and crash signal
curits@curits-virtual-machine:~/Desktop$ sudo rasm2 -a x86 -b 64 -d "488d 2551 3f60 01e8 d400 0000"
lea rsp, [rip + 0x1603f51]
call 0xe0
curits@curits-virtual-machine:~/Desktop/radare2-master$ rasm2 -a x86 -b 64 'mov ebx,520'
bb08020000
curits@curits-virtual-machine:~/Desktop/radare2-master$ rasm2 -d bb08020000
mov ebx, 0x208
curits@curits-virtual-machine:~/Desktop/radare2-master$ rasm2 -D bb08020000
0x00000000 5 bb08020000 mov ebx, 0x208