2.2.1 radare2

简介

IDA Pro 昂贵的价格令很多二进制爱好者望而却步,于是在开源世界中催生出了一个新的逆向工程框架——Radare2,它拥有非常强大的功能,包括反汇编、调试、打补丁、虚拟化等等,而且可以运行在几乎所有的主流平台上(GNU/Linux、Windows、BSD、iOS、OSX……)。Radare2 开发之初仅提供了基于命令行的操作,尽管现在也有非官方的GUI,但我更喜欢直接在终端上运行它,当然这也就意味着更高陡峭的学习曲线。Radare2 是由一系列的组件构成的,这些组件赋予了 Radare2 强大的分析能力,可以在 Radare2 中或者单独被使用。

这里是 Radare2 与其他二进制分析工具的对比。(Comparison Table

安装

更新

卸载

命令行使用方法

Radare2 在命令行下有一些小工具可供使用:

  • radare2:十六进制编辑器和调试器的核心,通常通过它进入交互式界面。

  • rabin2:从可执行二进制文件中提取信息。

  • rasm2:汇编和反汇编。

  • rahash2:基于块的哈希工具。

  • radiff2:二进制文件或代码差异比对。

  • rafind2:查找字节模式。

  • ragg2:r_egg 的前端,将高级语言编写的简单程序编译成x86、x86-64和ARM的二进制文件。

  • rarun2:用于在不同环境中运行程序。

  • rax2:数据格式转换。

radare2/r2

参数很多,这里最重要是 file。如果你想 attach 到一个进程上,则使用 pid。常用参数如下:

  • -A:相当于在交互界面输入了 aaa

  • -c:运行 radare 命令。(r2 -A -q -c 'iI~pic' file

  • -d:调试二进制文件或进程。

  • -a,-b,-o:分别指定体系结构、位数和操作系统,通常是自动的,但也可以手动指定。

  • -w:使用可写模式打开。

rabin2

当我们拿到一个二进制文件时,第一步就是获取关于它的基本信息,这时候就可以使用 rabin2。rabin2 可以获取包括 ELF、PE、Mach-O、Java CLASS 文件的区段、头信息、导入导出表、数据段字符串、入口点等信息,并且支持多种格式的输出。

下面介绍一些常见的用法:(我还会列出其他实现类似功能工具的用法,你可以对比一下它们的输出)

  • -I:最常用的参数,它可以打印出二进制文件信息,其中我们需要重点关注其使用的安全防护技术,如 canary、pic、nx 等。(filechekcsec -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

rasm2 是一个内联汇编、反汇编程序。它的主要功能是获取给定机器指令操作码对应的字节。

下面是一些重要的参数:

  • -L:列出目标体系结构所支持的插件,输出中的第一列说明了插件提供的功能(a=asm, d=disasm, A=analyze, e=ESIL)。

  • -a:知道插件的名字后,就可以使用 -a` 来进行设置。

  • -b:设置CPU寄存器的位数。

  • -d:反汇编十六进制对字符串。

  • -D:反汇编并显示十六进制对和操作码。

  • -C:汇编后以 C 语言风格输出。

  • -f:从文件中读入汇编代码。

例子:

rahash2

rahash2 用于计算检验和,支持字节流、文件、字符串等形式和多种算法。

重要参数:

  • -a:指定算法。默认为 sha256,如果指定为 all,则使用所有算法。

  • -b:指定块的大小(而不是整个文件)

  • -B:打印处每个块的哈希

  • -s:指定字符串(而不是文件)

  • -a entropy:显示每个块的熵(-B -b 512 -a entropy

radiff2

radiff2 是一个基于偏移的比较工具。

重要参数:

  • -s:计算文本距离并得到相似度。

  • -AC:这两个参数通常一起使用,从函数的角度进行比较。

  • -g:得到给定的符号或两个偏移的图像对比。

    • 如:radiff2 -g main a.out b.out | xdot -(需要安装xdot)

  • -c:计算不同点的数量。

rafind2

rafind2 用于在二进制文件中查找字符模式。

重要参数:

  • -s:查找特定字符串。

  • -e:使用正则匹配。

  • -z:搜索以\0结束的字符串。

  • -x:查找十六进制字符串。

ragg2

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

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

rax2 是一个格式转换工具,在二进制、八进制、十六进制数字和字符串之间进行转换。

重要参数:

  • -e:交换字节顺序

  • -s:十六进制->字符

  • -S:字符->十六进制

  • -D, -E:base64 解码和编码

交互式使用方法

当我们进入到 Radare2 的交互式界面后,就可以使用交互式命令进行操作。

输入 ? 可以获得帮助信息,由于命令太多,我们只会重点介绍一些常用命令:

于是我们知道了 Radare2 交互命令的一般格式,如下所示:

如果你对 *nix shell, sed, awk 等比较熟悉的话,也可以帮助你很快掌握 radare2 命令。

  • 在任意字符命令后面加上 ? 可以获得关于该命令更多的细节。如 a?p?!?@?

  • 当命令以数字开头时表示重复运行的次数。如 3x

  • ! 单独使用可以显示命令使用历史记录。

  • ; 是命令分隔符,可以在一行上运行多个命令。如 px 10; pd 20

  • .. 重复运行上一条命令,使用回车键也一样。

  • / 用于在文件中进行搜索操作。

  • ! 开头可以运行 shell 命令。用法:!<cmd>

    • !ls

  • | 是管道符。用法:<r2command> | <program|H|>

    • 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 结尾的行

  • ??? 可以获得以 ? 开头的命令的细节

    • ? 可以做各种进制和格式的快速转换。如 ? 1234

    • ?p vaddr 获得虚拟地址 vaddr 的物理地址

    • ?P paddr 获得物理地址 paddr 的虚拟地址

    • ?v 以十六进制的形式显示某数学表达式的结果。如 ?v eip-0x804800

    • ?l str 获得 str 的长度,结果被临时保存,使用 ?v 可输出结果。

  • @@ foreach 迭代器,在列出的偏移处重复执行命令。

    • wx ff @@ 10 20 30 在偏移 10、20、30 处写入 ff

    • p8 4 @@ fcn.* 打印处每个函数的头 4 个字节

  • ?$? 可以显示表达式所使用变量的帮助信息。用法:?v [$.]

    • $$ 是当前所处的虚拟地址

    • $? 是最后一个运算的值

    • $s 文件大小

    • $b 块大小

    • $l 操作码长度

    • $j 跳转地址。当 $$ 处是一个类似 jmp 的指令时,$j 中保存着将要跳转到的地址

    • $f 跳转失败地址。即当前跳转没有生效,$f 中保存下一条指令的地址

    • $m 操作码内存引用。如:mov eax,[0x10] => 0x10

  • e 用于进行配置信息的修改

    • e asm.bytes=false 关闭指令 raw bytes 的显示

默认情况下,执行的每条命令都有一个参考点,通常是内存中的当前位置,由命令前的十六进制数字指示。任何的打印、写入或分析命令都在当前位置执行。例如反汇编当前位置的一条指令:

block size 是在我们没有指定行数的时候使用的默认值,输入 b 即可看到,使用 b [num] 修改字节数,这时使用打印命令如 pd 时,将反汇编相应字节的指令。

分析(analyze)

所有与分析有关的命令都以 a 开头:

  • afl:列出所有函数。

  • axt [addr]:找到对给定地址的交叉引用。

  • af [addr]:当你发现某个地址处有一个函数,但是没有被分析出来的时候,可以使用该命令重新分析。

Flags

flag 用于将给定的偏移与名称相关联,flag 被分为几个 flag spaces,用于存放不同的 flag。

常见用法:

  • f flag_name @ addr:给地址 addr 创建一个 flag,当不指定地址时则默认指定当前地址。

  • f-flag_name:删除flag。

  • fs:管理命名空间。

定位(seeking)

使用 s 命令可以改变当前位置:

  • s+,s-:重复或撤销。

  • s+ n,s- n:定位到当前位置向前或向后 n 字节的位置。

  • s/ DATA:定位到下一个出现 DATA 的位置。

信息(information)

i 系列命令用于获取文件的各种信息,这时配合上 ~ 命令来获得精确的输出,下面是一个类似 checksec 的输出:

~ 命令还有一些其他的用法,如获取某一行某一列等,另外使用 ~{} 可以使 json 的输出更好看:

打印(print) & 反汇编(disassembling)

常用参数如下:

  • px:输出十六进制数、偏移和原始数据。后跟 o,w,q 时分别表示8位、32位和64位。

  • p8:输出8位的字节流。

  • ps:输出字符串。

radare2 中反汇编操作是隐藏在打印操作中的,即使用 pd

@addr 表示一个相对寻址,这里的 addr 可以是地址、符号名等,这个操作和 s 命令不同,它不会改变当前位置,当然即使使用类似 s @addr 的命令也不会改变当前位置。

写入(write)

当你在打开 r2 时使用了参数 -w 时,才可以使用该命令,w 命令用于写入字节,它允许多种输入格式:

常见用法:

  • wa:写入操作码,如 wa jmp 0x8048320

  • wx:写入十六进制数。

  • wv:写入32或64位的值。

  • wo:有很多子命令,用于将当前位置的值做运算后覆盖原值。

调试(debugging)

在开启 r2 时使用参数 -d 即可开启调试模式,当然如果你已经加载了程序,可以使用命令 ood 重新开启调试。

视图模式

在调试时使用视图模式是十分有用的,因为你既可以查看程序当前的位置,也可以查看任何你想看的位置。输入 V 即可进入视图模式,按下 p/P 可在不同模式之间进行切换,按下 ? 即可查看帮助,想退出时按下 q

视图模式下的命令和命令行模式下的命令有很大不同,下面列出几个,更多的命令请查看帮助:

  • o:定位到给定的偏移。

  • ;:添加注释。

  • V:查看图形。

  • ::运行 radare2 命令

Web 界面使用

Radare2 的 GUI 尚在开发中,但有一个 Web 界面可以使用,如果刚开始你不习惯命令行操作,可以输入下面的命令:

默认地址为 http://localhost:9090/,这样你就可以在 Web 中进行操作了,但是我强烈建议你强迫自己使用命令行的操作方式。

cutter GUI

cutter 是 r2 官方的 GUI,已经在快速开发中,基本功能已经有了,喜欢界面操作的读者可以试一下(请确保 r2 已经正确安装):

然后就可以运行了:

在 CTF 中的运用

更多资源

Last updated

Was this helpful?