之前听闻学长说许多大佬都用这个工具?(雾;就没事来瞎搞一搞这个可以用来逆向或pwn的神器?感觉还是很帅的hhhh,就是用起来有点emmm

安装

git clone r2仓库即可,尽量每天使用前 ./sys/install.sh 更新一下

1
2
3
$ git clone https://github.com/radare/radare2.git
$ cd radare2
$ ./sys/install.sh

使用

之后学习使用中逐渐更新
常用包含工具:

  • radare2->整合了所有工具
  • rabin2->查看文件格式的
  • radiff2->比较文件不同的
  • rahash2->各种密码算法,hash算法集成
  • rasm2->汇编和反汇编
  • ragg2->开发shellcode工具(radare2自己编写的编译器)

radare2

随便加载个文件,会有一句欢迎语hhhh
1
2
3
$r2 pwnme
-- We only have bugs, features are an unintended side-effect
[0x08049090]> //工具找到的入口位置

rabin2

查看文件基本信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# rabin2 -I pwnme
arch x86
baddr 0x8048000
binsz 14275
bintype elf
bits 32
canary false
sanitiz false
class ELF32
crypto false
endian little
havecode true
intrp /lib/ld-linux.so.2
lang c
linenum true
lsyms true
machine Intel 80386
maxopsz 16
minopsz 1
nx true
os linux
pcalign 0
pic false
relocs true
relro partial
rpath NONE
static false
stripped false
subsys linux
va true

rahash2

支持超多加解密
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# rahash2 -L    //列举
Available Hashes:
h md5
h sha1
h sha256
h sha384
h sha512
h md4
h xor
h xorpair
h parity
h entropy
h hamdist
h pcprint
h mod255
h xxhash
h adler32
h luhn
h crc8smbus
h crc15can
h crc16
h crc16hdlc
h crc16usb
h crc16citt
h crc24
h crc32
h crc32c
h crc32ecma267
h crc32bzip2
h crc32d
h crc32mpeg2
h crc32posix
h crc32q
h crc32jamcrc
h crc32xfer
h crc64
h crc64ecma
h crc64we
h crc64xz
h crc64iso

Available Encoders/Decoders:
e base64
e base91
e punycode

Available Crypto Algos:
c rc2
c rc4
c rc6
c aes-ecb
c aes-cbc
c ror
c rol
c rot
c blowfish
c cps2
c des-ecb
c xor
c serpent-ecb

# rahash2 -a md5 ./pwnme //生成md5哈希
./pwnme: 0x00000000-0x00003c73 md5: 2569b37607fc52065f5b4e7c349d0e56

rasm2

支持汇编反汇编 

ragg2

据说可以用来快速开发shellcode?

radiff2

支持二进制文件的字节级或增量差异对比,查找基本代码块中的更改。
厂商更新漏洞时,可以寻找更新代码字段,说不定在那里还有希望挖到其他洞

rafind2

在文件中查找字节模式

rarun2

用于在不同环境中运行程序的启动器,具有不同的参数,权限,目录和
覆盖的默认文件描述符。
rarun2可用于:
* 破解小程序
* 模糊测试
* 测试组件

rax2

用于shell的简约数学表达式求值器,用于在浮点值,十六进制表示,
十六进制字符串到ASCII之间进行基本转换,八进制到整数等。
它还支持字节顺序设置,如果没有参数,可以用作交互式shell 给出。

常用命令

  • i 开头的命令主要是用来获取各种信息。iz – 列出数据段里的字符串
1
2
3
4
5
6
7
8
9
10
11
[0x08049090]> ie
[Entrypoints]
vaddr=0x08049090 paddr=0x00001090 baddr=0x08048000 laddr=0x00000000 haddr=0x00000018 type=program

1 entrypoints

[0x08049090]> iz
[Strings]
Num Vaddr Paddr Len Size Section Type String
000 0x00002008 0x0804a008 7 8 (.rodata) ascii /bin/sh
001 0x00002010 0x0804a010 5 6 (.rodata) ascii input
  • a 开头的命令主要是用来分析文件。radare2 不会主动去分析一个文件,因为这样做的代价太大了,它需要花费很多的时间。也可以在运行 radare2的使用 -A 参数来直接分析一个文件(例如 r2 -A pwnme)
1
2
3
4
5
6
7
8
# r2 -A pwnme
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Constructing a function name for fcn.* and sym.func.* functions (aan)
[x] Type matching analysis for all functions (afta)
[x] Use -AA or aaaa to perform additional experimental analysis.
-- r2OS r2pad 0.1 SMP GENERIC r2_64 GNU/r2OS
  • fs 分析完成之后, r2会将所有有用的信息和特定的名字绑定在一起,比如区段、函数、符号、字符串,这些都被称作 ‘flags’, flags 被整合进 ,一个 flag 是所有类似特征的集合。可以使用 ‘fs ‘ 加 ‘f’ 来打印出 这个 flags 下面包含的信息,使用分号来间隔多条命令(‘cmd1;cmd2;cmd3;…’).
1
2
3
4
5
6
7
8
9
10
11
[0x08049090]> fs
0 2 * strings
1 37 * symbols
2 30 * sections
3 12 * segments
4 5 * relocs
5 5 * imports
6 2 * functions
[0x08049090]> fs strings;f
0x0804a008 8 str.bin_sh
0x0804a010 6 str.input
  • axt 命令用来在 data/code段里找寻某个地址相关的引用(更多的操作,请看 ‘ax?’).‘@@’就像一个迭代器,用来在地址空间里不断地匹配后面一系列相关的命令(更多操作,请看 ‘@@?’), ‘str.*’ 是一个通配符,用来标记所有以 ‘str.’开头的信息,这个不光会列出字符串标志,同时也包括函数名,找到它们到底在哪里以及何处被调用。

  • vv 大概是会显示函数列表和入口处的函数?可以查看各个函数(花里胡哨的,很漂亮哦,不如我们。。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
-[ functions ]----------------- pdf ---
(a) add (x) xrefs (q) quit (jk) next/prev ;-- section..text:
(r) rename (c) calls (g) go (tab) column ;-- eip:
(d) delete (v) vars (?) help (:) enter cmd / (fcn) entry0 50
>* 0x08049090 50 entry0 | entry0 ();
0x080490c3 4 fcn.080490c3 | 0x08049090 xor ebp, ebp ; [14] -r-x secti
0x08049070 6 sym.imp.__libc_start_main | 0x08049092 pop esi
0x080490f0 40 sym.deregister_tm_clones | 0x08049093 mov ecx, esp
0x08049130 53 sym.register_tm_clones | 0x08049095 and esp, 0xfffffff0
0x08049170 30 sym.__do_global_dtors_aux | 0x08049098 push eax
0x080491a0 2 entry1.init | 0x08049099 push esp
0x080492b0 2 sym.__libc_csu_fini | 0x0804909a push edx
0x080490e0 4 sym.__x86.get_pc_thunk.bx | 0x0804909b call fcn.080490c3
0x080492b4 20 sym._fini | 0x080490a0 add ebx, 0x2f60 ; '`/'
0x08049250 93 sym.__libc_csu_init | 0x080490a6 lea eax, [ebx - 0x2d50]
0x080490d0 2 sym._dl_relocate_static_pie | 0x080490ac push eax ; func fini
0x08049203 65 sym.main | 0x080490ad lea eax, [ebx - 0x2db0]
0x08049244 4 sym.__x86.get_pc_thunk.ax | 0x080490b3 push eax ; func init
0x08049050 6 sym.imp.puts | 0x080490b4 push ecx ; char **ubp_av
0x080491cd 54 sym.vulnerable | 0x080490b5 push esi ; int argc
0x08049040 6 sym.imp.gets | 0x080490b6 mov eax, sym.main ; 0x8049203
0x080491a2 43 sym.flag | 0x080490bc push eax ; func main
0x08049060 6 sym.imp.system \ 0x080490bd call sym.imp.__libc_start_main ; int __libc_star
0x08049000 35 sym._init
0x08049080 6 sub.__gmon_start_80
  • s 命令可以跳转到某个地址或者已经有了符号的函 数中去。然后我们使用pdf这个命令可以打印main这个函数的汇编代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[0x08049090]> s main
[0x08049203]> pdf
;-- main:
/ (fcn) sym.main 65
| sym.main (int argc, char **argv, char **envp);
| ; var int local_8h @ ebp-0x8
| ; arg int arg_4h @ esp+0x4
| ; DATA XREF from entry0 (0x80490b6)
| 0x08049203 8d4c2404 lea ecx, [arg_4h] ; 4
| 0x08049207 83e4f0 and esp, 0xfffffff0
| 0x0804920a ff71fc push dword [ecx - 4]
| 0x0804920d 55 push ebp
| 0x0804920e 89e5 mov ebp, esp
| 0x08049210 53 push ebx
| 0x08049211 51 push ecx
| 0x08049212 e82d000000 call sym.__x86.get_pc_thunk.ax
| 0x08049217 05e92d0000 add eax, 0x2de9
| 0x0804921c 83ec0c sub esp, 0xc
| 0x0804921f 8d9010e0ffff lea edx, [eax - 0x1ff0]
| 0x08049225 52 push edx ; const char *s
| 0x08049226 89c3 mov ebx, eax
| 0x08049228 e823feffff call sym.imp.puts ; int puts(const char *s)
| 0x0804922d 83c410 add esp, 0x10
| 0x08049230 e898ffffff call sym.vulnerable
| 0x08049235 b800000000 mov eax, 0
| 0x0804923a 8d65f8 lea esp, [local_8h]
| 0x0804923d 59 pop ecx
| 0x0804923e 5b pop ebx
| 0x0804923f 5d pop ebp
| 0x08049240 8d61fc lea esp, [ecx - 4]
\ 0x08049243 c3 ret

radare2还实现了IDA的类似F5功能,我们可以使用pdc命令来实现。(目前看上去真不怎么样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[0x08049203]> pdc
function sym.main () {
// 1 basic blocks

loc_0x8049203:

//DATA XREF from entry0 (0x80490b6)
ecx = [arg_4h] //4
esp &= 0xfffffff0 //ebp
push dword [ecx - 4]
push ebp
ebp = esp
push ebx
push ecx
sym.__x86.get_pc_thunk.ax ()
eax += 0x2de9 //obj._GLOBAL_OFFSET_TABLE
esp -= 0xc
edx = [eax - 0x1ff0] //"input" str.input
push edx //const char *s ; (pstr 0x0804a010) "input"
ebx = eax //obj._GLOBAL_OFFSET_TABLE

int puts(const char * s : (*0x804a010)0x00177fe0 = input)
esp += 0x10
sym.vulnerable ()
eax = 0
esp = [local_8h]
pop ecx
pop ebx
//ebp
esp = [ecx - 4] //ebp
return
(break)

}

还有框架结构界面,我们可以使用大写的VV命令来到框架结构界面。(很赞

.---------------------------------------------------.     
| [0x8049203]                                       |     
| ;-- main:                                         |     
| ;-- eip:                                          |     
| (fcn) sym.main 65                                 |     
|   sym.main (int argc, char **argv, char **envp);  |     
| ; var int local_8h @ ebp-0x8                      |     
| ; arg int arg_4h @ esp+0x4                        |     
| ; DATA XREF from entry0 (0x80490b6)               |     
| ; 4     |     
| lea ecx, [arg_4h]                                 |     
| and esp, 0xfffffff0                               |     
| push dword [ecx - 4]                              |     
| push ebp                                          |     
| mov ebp, esp                                      |     
| push ebx                                          |     
| push ecx                                          |     
| call sym.__x86.get_pc_thunk.ax;[ga]               |     
| add eax, 0x2de9                                   |     
| sub esp, 0xc                                      |     
| lea edx, [eax - 0x1ff0]                           |     
| ; const char *s                                   |     
| push edx                                          |     
| mov ebx, eax                                      |     
| ; int puts(const char *s)                         |     
| call sym.imp.puts;[gb]                            |     
| add esp, 0x10                                     |     
| call sym.vulnerable;[gc]                          |     
| mov eax, 0                                        |     
| lea esp, [local_8h]                               |  
`---------------------------------------------------'                                          

目前就了解了这一点,参考了一些大佬的文章,之后可以尝试着去使用,仅仅局限于IDA,GDB是不行的。就这样。