第三章 静态分析工具链:Ghidra 入门与项目设置、IDA Pro 基础操作、Radare2 快速上手、二进制比较工具(Bindiff)

做固件逆向,说白了就是跟一堆二进制代码较劲。你手里没有源码,只有一堆十六进制数字。这时候,工具链就是你的眼睛和手。我个人习惯把这套工具链分成四块:反汇编器、反编译器、调试器、比较器。今天咱们就聊聊这四块里的核心代表。

3.1 Ghidra:NSA 的开源利器

Ghidra 是 NSA 开源的逆向框架。我第一次用的时候,心里还犯嘀咕:政府机构出的东西,能好用吗?结果一上手就真香了。它最大的优势是免费、开源、而且有强大的反编译器。

3.1.1 项目创建与基础设置

打开 Ghidra,第一步就是创建项目。我建议你养成好习惯:每个固件单独建一个项目,别把所有东西堆在一起。

# 创建项目的步骤
1. File -> New Project
2. 选择 Non-Shared Project(单机用这个就够了)
3. 填项目名,选存储路径
4. 把固件拖进项目窗口
5. 双击固件,开始分析
我的小技巧: 分析选项里,我一般会勾上「Apply Function ID」和「Demangler」。前者能帮你识别标准库函数,后者能解开 C++ 的名字修饰。这两个选项能省你不少时间。

3.1.2 反编译器的使用

Ghidra 的反编译器叫 Decompiler,按 F5 就能调出来。嗯,这里要注意:反编译出来的 C 代码不是完美的,它只是机器码的一种高级表示。我曾经在分析一个 RTOS 固件时,反编译器把任务切换函数识别成了普通函数调用,差点把我带沟里。

我个人习惯是:先看反编译代码找逻辑,再对照汇编确认细节。别完全相信反编译器,它也会犯错。

3.2 IDA Pro:行业标杆

IDA Pro 是逆向界的瑞士军刀。贵,但值。如果你做商业逆向,IDA 几乎是必备工具。

3.2.1 基础操作

IDA 的操作逻辑跟 Ghidra 不太一样。它更强调交互性,你得手动告诉它很多东西。

操作 快捷键 说明
反编译 F5 调用 Hex-Rays 反编译器
重命名 N 给变量或函数改名
添加注释 ; 行注释,我习惯用中文写
跳转到地址 G 直接输入十六进制地址
交叉引用 X 看谁调用了这个函数
避坑指南: 我曾经在分析一个加密固件时,IDA 自动分析把数据段识别成了代码段。结果反编译出来一堆乱码。解决办法是:选中数据区域,按 D 键强制转成数据,再按 U 键取消代码定义。

3.2.2 脚本与插件

IDA 的强大在于它的脚本系统。IDAPython 能让你批量处理很多事。比如,我写过一个脚本,自动给所有外部函数调用加上注释,省了我半天时间。

# 一个简单的 IDAPython 示例
import idautils
import idc

for func_addr in idautils.Functions():
    func_name = idc.get_func_name(func_addr)
    if "memcpy" in func_name:
        print(f"Found memcpy at 0x{func_addr:x}")
        idc.set_cmt(func_addr, "注意:这里可能有缓冲区溢出", 0)

3.3 Radare2:终端里的逆向神器

Radare2 是命令行工具,没有 GUI。很多人一听命令行就头疼,但说实话,一旦你习惯了,它的效率比 GUI 工具高得多。我一般在服务器上做逆向时,全靠 Radare2。

3.3.1 快速上手

启动 Radare2 很简单:r2 ./firmware.bin。进去之后,你面对的是一个命令行界面。

# 常用命令
[0x00000000]> aaaa          # 自动分析(多几个 a 表示深度分析)
[0x00000000]> afl           # 列出所有函数
[0x00000000]> s main        # 跳转到 main 函数
[0x00000000]> V             # 进入可视化模式
[0x00000000]> pdc @ main    # 反编译 main 函数

你想想看,这些命令敲起来多快。不用鼠标点来点去,纯键盘操作。我个人习惯把常用命令写成别名,比如 aa 代表 aaaa,省得每次都敲那么多 a。

3.3.2 脚本化分析

Radare2 的脚本语言是 r2pipe,支持 Python、Node.js 等。我写过一个小脚本,自动提取固件里的字符串,然后跟已知的漏洞特征做匹配。

# r2pipe 示例
import r2pipe

r2 = r2pipe.open("./firmware.bin")
r2.cmd("aaaa")
strings = r2.cmd("izz").split("\n")
for s in strings:
    if "password" in s.lower():
        print(f"Found: {s}")

3.4 Bindiff:二进制比较的艺术

Bindiff 是 Zynamics 出品的二进制比较工具,后来被 Google 收购了。它的核心功能是:比较两个二进制文件,找出它们的差异和相似之处。

3.4.1 什么时候用 Bindiff?

我遇到过三种场景,Bindiff 特别好用:

  • 漏洞修复分析: 比较有漏洞的版本和修复后的版本,看补丁改了哪里。
  • 固件版本对比: 比较两个固件版本,看新增了什么功能。
  • 代码复用检测: 看一个固件里有没有复用已知的开源代码。
实战案例: 我曾经分析过一个 IoT 设备的固件更新。新版本修复了一个缓冲区溢出漏洞。我用 Bindiff 比较了新旧版本,发现只有三个函数变了。其中一个函数里多了一个长度检查。嗯,漏洞点就在那里。

3.4.2 基本操作流程

Bindiff 需要配合 IDA 或 Ghidra 使用。流程是这样的:

  1. 用 IDA 分别分析新旧两个固件,生成 .i64 或 .idb 文件。
  2. 打开 Bindiff,选择两个数据库文件。
  3. 点击「Compare」,等它算完。
  4. 看结果:绿色表示匹配的函数,红色表示不匹配的,灰色表示新增或删除的。

我个人习惯先看红色部分。那些不匹配的函数,往往就是漏洞修复的地方。再看灰色部分,新增的函数可能意味着新功能或新的攻击面。

3.5 工具链的选择与搭配

说了这么多,你可能会问:到底该用哪个?我的建议是:

  • 日常分析: Ghidra 就够了,免费且功能强大。
  • 商业项目: IDA Pro + Hex-Rays,效率最高。
  • 远程或自动化: Radare2,命令行无敌。
  • 版本对比: Bindiff,没有替代品。

其实,工具只是手段。真正重要的是你的分析思路和经验。我见过有人用记事本加十六进制编辑器也能找到漏洞。工具再好,脑子不转也是白搭。

静态分析工具链知识体系 固件静态分析 Ghidra IDA Pro Radare2 Bindiff 反编译器 项目化管理 Hex-Rays IDAPython 命令行操作 r2pipe脚本 版本对比 补丁分析

这张图展示了本章的知识体系。四个工具各有侧重,但又能互相配合。我个人习惯是:用 Ghidra 做初步分析,遇到复杂逻辑切到 IDA,批量处理用 Radare2,版本对比用 Bindiff。工具链搭好了,逆向效率能翻倍。

最后说一句: 别贪多嚼不烂。先把一个工具用熟,再学下一个。我见过太多人每个工具都只会皮毛,结果哪个都用不好。先精通一个,再触类旁通。
专注资料整理