本节摘要:在让 AI 碰二进制之前,先弄清它接手的是一门什么样的手艺。本节第一部分还原逆向工程师的真实工作流:静态阅读(反汇编与伪代码)、动态调试(断点与轨迹)、命名直觉(从上下文猜语义),三者交替推进。第二部分对照大模型的长短板:它读伪代码快、起名稳、找模式不知疲倦,但会幻觉出不存在的函数、算错十六进制与偏移。第三部分给出立论证据——EnIGMA(ICML 2025,arXiv:2409.16165)发现给语言模型智能体接上 GDB 与反编译器这类交互式工具后,解 CTF 与找漏洞的能力大幅提升。最后落到全书立场:AI 提假设,人与工具做验证。
不管对象是 CTF 样本、固件模块还是无源码的遗留工具,逆向工程师的工作流都绕着三件事转。
┌────────────── 静态阅读 ──────────────┐ │ 反汇编 / 伪代码 / 字符串 / 交叉引用 │ └───────────────┬─────────────────────┘ │ 「这个函数像是在校验什么」 ▼ ┌──────────── 动态调试 ────────────┐ ┌──────── 命名直觉 ────────┐ │ 断点 / 单步 / 内存与轨迹观察 │◀──────▶│ 把 FUN_004011a0 改叫 │ └─────────────┬───────────────────┘ 互相喂 │ check_key,理解开始滚动 │ │ 「实际跑到这里,值确实是 X」 └─────────────────────────┘ ▼ 证据:一段反汇编、一次断点命中、一个说得通的故事
FUN_004011a0 改名为 check_key 的那一刻,理解开始滚动——名字是人脑的缓存。产出是可读性,也是最难外包的部分。三件事交替进行:静态读出假设,动态验证假设,命名把验证结果固化。这门手艺慢,但每一步都有证据。本书前两章先把静态这条腿练扎实(Ghidra 与 r2),动态与符号执行腿在第 08 章接上。
把上面三件事拆开看,大模型在不少环节上是熟练工:
| 环节 | 模型能做什么 | 产出形态 |
|---|---|---|
| 读伪代码 | 逐行解释 Ghidra 反编译出的伪 C,指出关键比较与调用 | 中文解说加行级对照 |
| 起名 | 对 FUN_xxxx 给出候选名(check_key、parse_header) |
候选名加理由 |
| 找模式 | 在几十个函数里认出「这是 TEA 加密」「这是简单的异或混淆」 | 模式判断加特征依据 |
| 写脚本 | 生成 Ghidra 脚本、r2 命令序列、批量导出代码 | 可运行脚本 |
这四件事有个共同点:输入是文本(伪代码、反汇编),输出也是文本(解释、名字、脚本)。大模型恰好活在文本世界里,而逆向工作流的相当一部分中间产物就是文本。
一个实用的判断标准:任务是否能把「需要的上下文」装进提示词、且「结果对错易于复核」。六个例子过一遍手感:
| 任务 | 交给模型? | 理由 |
|---|---|---|
| 解释单个函数的伪代码 | 适合 | 上下文一个函数,复核看反汇编 |
| 给无名函数起候选名 | 适合 | 产出可批量,逐个核对依据 |
| 认出某段代码像哪种加密算法 | 适合 | 特征比对是它的强项 |
| 追踪跨十个模块的调用链 | 不适合 | 上下文装不下,复核成本高 |
| 算出 32 位立即数的十六进制运算 | 慎用 | 心算是它的事故高发区,工具重算 |
| 判断补丁对寄存器的影响 | 不适合 | 需要精确状态跟踪,交给模拟器 |
同一个模型,换一个场景就是事故现场。三类典型错误在逆向场景里格外危险:
| 错误类型 | 典型表现 | 为什么危险 | 复核手段 |
|---|---|---|---|
| 幻觉 | 编造不存在的函数名、调用关系、导入函数 | 与真实程序对不上,结论看似专业 | 一律回到 xref 与反汇编核对 |
| 进制与偏移错误 | 十六进制算错、偏移量差一位、把栈偏移当堆偏移 | 逆向是精确到字节的行当 | 用工具重算,不信心算 |
| 上下文截断 | 长函数后半段「装作读过」,结论只覆盖前半 | 结论以偏概全却不声明 | 分段喂入,要求逐段编号 |
举个示意(伪代码为教学虚构):
# 幻觉示例 —— 模型一本正经地虚构(教学示意,非真实输出) 反汇编事实:call FUN_00401230 ;无任何字符串提示 模型解说: 这里调用了 OpenSSL 的 RSA_private_decrypt…… 问题: 导入表里根本没有 OpenSSL,模型只是「觉得像」
复核动作固定三步:找到模型引用的地址或函数名——在反汇编器里确认存在——确认语义与它的说法一致。任何一步断链,这条输出整体作废,不要「部分采信」。规则一句话:模型说的每一个地址、每一个函数名、每一次调用,都要能在反汇编器里指给同事看。
本书立意最重要的论据是 EnIGMA(ICML 2025 论文,arXiv:2409.16165)。它的出发点与本章一致:逆向需要交互式工具(GDB、反编译器),而大模型缺乏与这些工具交互的通道。论文把 GDB 与反编译器等工具封装给语言模型智能体调用,让它在真实 CTF 题与漏洞挖掘任务里自主执行——观察、下命令、读输出、再决策。
EnIGMA 式智能体循环(与老手艺一一对应) ┌──────────────────────────────────────────────┐ │ 观察:读反编译器输出 / GDB 内存与寄存器 │ │ │ │ │ ▼ │ │ 思考:当前假设是什么?下一步看哪里? │ │ │ │ │ ▼ │ │ 行动:下一条命令(反汇编某地址 / 断点某函数) │ │ │ │ │ └────── 新的观察回灌,循环直至结论 ─────────┘ 对应老手艺:观察与思考 = 静态出假设;行动 = 动态验证
核心结论用一句话讲:接入交互式工具后,智能体解 CTF 与定位漏洞的能力大幅提升;提升来自「模型加工具」的组合,而不是模型单独脑补。 这正对应老手艺里的「静态出假设、动态做验证」:模型拿到工具后,也能走完这个循环。
对本书读者的启示有两点。其一,给模型工具比给模型赞美有用:与其问「这个二进制是干什么的」,不如让它拿着反编译器自己去看。其二,工具把模型从「文本猜谜」拉回「证据世界」:它引用的是真实的反汇编片段,幻觉空间被压缩——但没有消失,验证仍然是人的职责。第 03 章的 GhidraMCP、第 04 章的 r2ai 与 r2mcp,都是这条论据的工程化落地。
把上面三部分拼起来,就是全书的立场,也是后面十一章每一节的隐含结构:
假设清单长什么样?给一个贯穿全书的样子(对象是第 0.2 节的示例程序):
# hypotheses.md —— 模型产出假设清单的目标形态(示意) H1 函数 FUN_00401160 可能是许可校验:含 strcmp 与解码调用 验证路径:pdf @ FUN_00401160,确认比较对象来源 H2 常量数据(7 字节)可能是异或混淆的期望密钥 验证路径:px 读原始字节,逐个异或 0x5a 后比对可打印字符 H3 校验函数只被 main 调用 验证路径:axt @ FUN_00401160,数调用者
注意每条假设都带「验证路径」——没有验证路径的假设是猜谜,有验证路径的假设才进得了我等验证者的门。第 4.3 节的流水线会强制要求这个格式。
(文字流程图)二进制 ──▶ 反编译 / 反汇编(工具)──▶ 模型读文本提假设 ──▶ xref / 调试 / 符号执行验证 ──▶ 人裁决 ──▶ 重命名与注释落库 ──▶ 理解滚动前进。
AI 没有取代老手艺,它把老手艺里最耗时的「通读」环节包办了,把工程师的时间留给最值钱的「验证与裁决」。
立场有了,接下来是路线与装备:下一节给出全书四篇地图、三条阅读路径、逐项环境清单,并划清与《语义代码检索》的分工——然后你就可以正式开工了。