1. 逆向工程这件事,为什么值得用 AI Agent 重做一遍
逆向工程这个词,在安全研究、竞品分析、老旧系统维护、协议对接这些场景里出现的频率非常高。传统做法无非是几条路:静态反汇编看汇编指令、动态调试跟寄存器、抓包分析网络协议、Hook 关键函数看入参出参。每一条路都要求从业者对目标平台的指令集、运行时环境、文件格式有相当深的理解,门槛不低,而且极其耗时。一个中等复杂度的移动端应用,从拿到安装包到理清核心业务逻辑,熟练工也得花上几天甚至几周。
我之所以关注“用 AI Agent 做逆向工程”这个方向,是因为过去两年大模型在代码理解、模式识别、跨语言翻译上的能力已经跨过了一个临界点。以前我们让工具去“猜”一段混淆过的代码在干什么,基本靠规则匹配和启发式,误报率高得离谱。现在把反汇编片段、调用图、字符串常量、API 调用序列一起喂给一个具备推理能力的 Agent,它能给出的语义级判断,已经接近一个中级逆向工程师的水平。这不是说 AI 能替代人,而是说它能把人从大量重复的、低信息密度的劳动里解放出来,让人专注于真正需要创造力和深度经验的环节。
REA 这个思路的核心,就是构建一个能自主规划、自主执行、自主验证的 AI Agent 流水线,把“行为分析”和“二进制破解”这两个原本割裂的阶段串起来。行为分析负责回答“这个 app 在做什么”,二进制破解负责回答“它是怎么做到的”。两者结合,才能形成完整的逆向认知。适合读这篇内容的人包括:做安全评估的工程师、需要对接第三方协议的后端开发、维护遗留系统的架构师,以及对自动化逆向感兴趣的技术爱好者。哪怕你之前没碰过反汇编,只要理解基本的编程概念和系统调用原理,也能从这套方法论里拿到可复用的思路。
2. 整体设计思路:Agent 流水线怎么搭
2.1 为什么不是“一个大模型包打天下”
很多人第一反应是:直接把二进制丢给大模型不就行了?实测下来这条路走不通。原因有三。第一,二进制文件动辄几十兆,上下文窗口根本放不下。第二,原始字节流对模型来说信息密度极低,大部分是数据段和填充,真正有意义的指令占比很小。第三,逆向是一个多阶段、有依赖关系的任务,单次推理无法完成“先定位关键函数、再分析控制流、最后还原算法”这样的链式操作。
所以 REA 的设计必须是流水线式的:把逆向工程拆解成若干可独立执行的子任务,每个子任务由一个专门的 Agent 或工具负责,中间结果通过结构化格式传递。这就像工厂流水线,每个工位只做一件事,但整体串起来能完成复杂产品。
2.2 四层架构拆解
我把这套系统分成四层,从下到上依次是:
- 采集层:负责获取目标 app 的各类原始数据。包括安装包解压、可执行文件提取、动态运行时抓取的 API 调用序列、网络流量记录、文件系统访问日志等。这一层的工具都是成熟的,比如静态分析用反汇编器,动态分析用调试器和 Hook 框架。
- 预处理层:把采集层拿到的原始数据转成 Agent 能消化的格式。反汇编输出要切成函数粒度的片段,调用图要转成邻接表,字符串要提取并分类,API 序列要按时间窗口聚合。这一层的关键是“降噪”,把无关信息过滤掉,保留高信号密度的特征。
- 推理层:这是 AI Agent 的主场。多个 Agent 分工协作,有的负责函数语义标注,有的负责控制流还原,有的负责协议格式推断,有的负责漏洞模式识别。每个 Agent 有自己的系统提示词和工具集,可以调用预处理层的数据,也可以互相通信。
- 验证层:Agent 给出的结论不能直接信,必须验证。验证手段包括:动态执行验证(构造输入看输出是否符合预期)、符号执行验证(用约束求解器检查路径可达性)、交叉验证(多个 Agent 对同一问题独立判断,取共识)。
2.3 行为分析与二进制破解的衔接点
行为分析产出的是“黑盒视角”的认知:这个 app 在什么条件下发什么请求、读写哪些文件、调用哪些系统 API。二进制破解产出的是“白盒视角”的认知:这些行为对应哪些函数、算法逻辑是什么、关键判断条件在哪里。
两者的衔接点在于行为锚点。比如行为分析发现 app 在登录时会发送一个特定格式的加密串,那么这个加密串的生成位置就是二进制破解的重点目标。Agent 可以用行为分析得到的输入输出对,去二进制里搜索匹配的常量、查找被调用的加密相关函数、追踪数据流。这种“从行为反推实现”的路径,比盲目翻汇编效率高得多。
3. 核心细节解析:每个环节的实操要点
3.1 静态分析阶段的数据准备
静态分析的第一步是拿到可执行文件。对于移动端应用,通常是解压安装包后从特定目录提取;对于桌面应用,直接定位主模块即可。拿到文件后,用反汇编工具生成汇编代码和调用图。这里有个经验:不要一上来就全量反汇编,先看文件头和段表,确认架构、位数、是否加壳。加壳的应用直接反汇编出来的是壳代码,没有意义,得先脱壳。
脱壳本身是个大话题,简单说就是让应用在内存中完全解密后,把内存镜像 dump 出来再重建可执行文件。这一步目前还是半自动的,Agent 能辅助判断壳的类型和推荐脱壳策略,但具体操作往往需要人工介入。
反汇编完成后,把输出按函数切分。每个函数作为一个独立单元,包含:函数签名、汇编指令序列、引用的字符串常量、调用的子函数列表、被哪些函数调用。这个结构化的函数档案,就是后续 Agent 推理的基本素材。
3.2 动态行为采集的关键配置
动态采集要在受控环境里进行,通常是模拟器或真机沙箱。核心是三类数据:
- API 调用序列:用 Hook 框架拦截关键系统调用和库函数,记录调用时间、参数、返回值。重点关注的 API 包括文件操作、网络通信、加密相关、进程管理、权限检查。
- 网络流量:抓取应用发出的所有网络请求,记录目标地址、端口、协议、载荷。对于加密流量,能解密的尽量解密,不能解密的至少记录元数据(包大小、时序、频率)。
- 文件系统访问:监控应用读写了哪些文件、读写模式、数据内容。很多应用的配置和缓存里藏着关键信息。
采集时要注意:环境要干净,避免其他进程干扰;时间戳要统一,方便后续关联分析;数据量会很大,要设计好存储和索引方案。
3.3 Agent 提示词的设计原则
Agent 的表现很大程度上取决于提示词。我总结了几条原则:
- 角色明确:每个 Agent 要有清晰的角色定义,比如“你是一个专注于 ARM64 汇编分析的逆向工程师”。
- 输出结构化:要求 Agent 以 JSON 或特定格式输出,方便后续程序化处理。比如函数语义标注要求输出
{function_name, purpose, confidence, evidence}。 - 证据链要求:Agent 的每个结论都必须附带证据,比如“该函数是 AES 加密,依据是引用了 AES 的 S-box 常量表,且调用了密钥扩展函数”。
- 不确定性表达:允许 Agent 说“不确定”,并给出置信度。低置信度的结论会进入人工复核队列。
3.4 二进制破解中的算法还原
算法还原是逆向工程里最考验功力的部分。传统做法是人肉读汇编,理解寄存器变化和内存操作,逐步还原出高级语言逻辑。Agent 在这里能帮上大忙,尤其是对常见算法模式的识别。
比如看到一个函数对输入做了多轮异或、移位、查表操作,Agent 可以快速匹配到已知的加密算法模板(AES、DES、RC4、TEA 等),并给出密钥调度和轮函数的对应关系。对于非标准算法,Agent 可以生成伪代码,再由人工审核和修正。
这里有个实用技巧:让 Agent 同时生成伪代码和 Python 复现脚本。伪代码用于理解逻辑,Python 脚本用于验证。如果 Python 脚本对相同输入能产生相同输出,说明还原基本正确。
4. 实操过程:从零跑通一条逆向流水线
4.1 环境搭建与工具选型
先列一下我实际用到的工具栈,都是开源或免费可用的:
| 环节 | 工具 | 用途 |
|---|---|---|
| 反汇编 | 某开源反汇编框架 | 生成汇编和调用图 |
| 动态 Hook | 某开源 Hook 框架 | 拦截 API 调用 |
| 抓包 | 某开源代理工具 | 记录网络流量 |
| 符号执行 | 某开源符号执行引擎 | 路径约束求解 |
| Agent 框架 | 某开源 Agent 编排库 | 多 Agent 协作 |
| 大模型 | 某代码理解能力强的模型 | 语义推理 |
选型逻辑:反汇编框架要支持多架构且 API 友好;Hook 框架要稳定且社区活跃;Agent 编排库要支持工具调用和消息传递。大模型的选择很关键,代码理解能力弱的模型在汇编分析上基本不可用,必须选在代码任务上表现好的。
4.2 第一步:静态提取与函数切分
假设目标是一个模拟的移动端应用安装包。操作流程:
- 解压安装包,定位主可执行文件。
- 检查文件头,确认架构为 ARM64,未加壳。
- 用反汇编框架加载文件,生成全量反汇编。
- 遍历所有函数,提取函数边界、指令序列、字符串引用、调用关系。
- 输出为 JSON 格式的函数档案库。
这一步的代码示意(Python 风格):
import disasm_framework binary = disasm_framework.load("target_binary") functions = [] for func in binary.functions: functions.append({ "name": func.name, "address": func.address, "instructions": [str(i) for i in func.instructions], "strings": func.referenced_strings, "callees": func.callees, "callers": func.callers }) save_json(functions, "functions.json")函数档案库建好后,先做一轮粗筛:过滤掉编译器生成的库函数、异常处理桩、明显的填充代码。剩下的才是业务相关函数,数量可能从几千降到几百。
4.3 第二步:动态行为采集与锚点定位
在沙箱里运行应用,同时启动 Hook 和抓包。模拟用户操作:启动、登录、浏览、下单、退出。每个操作阶段打上时间戳标签。
采集完成后,把 API 调用序列和网络请求按时间对齐。比如发现登录操作后 200ms 内有一个发往特定地址的 POST 请求,载荷是加密的。那么这个时间窗口内的 API 调用就是重点:可能包括随机数生成、密钥读取、加密函数调用。
把这些“行为锚点”整理成列表,每个锚点包含:触发条件、时间窗口、相关 API、网络载荷特征。这些锚点就是二进制破解阶段的搜索线索。
4.4 第三步:Agent 推理与交叉验证
现在把函数档案库和行为锚点一起交给 Agent 流水线。我设计了三个 Agent:
- 定位 Agent:根据行为锚点,在函数档案库里搜索可能相关的函数。策略包括:字符串匹配(搜索加密相关字符串)、调用图距离(离网络发送函数近的函数优先级高)、API 序列匹配(动态调用过的函数优先)。
- 分析 Agent:对定位到的候选函数做深度分析,生成语义标注和伪代码。
- 验证 Agent:检查分析 Agent 的结论是否自洽,比如伪代码的逻辑是否与汇编一致、输入输出是否符合动态观测。
三个 Agent 的输出汇总后,按置信度排序。高置信度的结论直接采纳,低置信度的进入人工复核。
4.5 第四步:算法还原与脚本复现
以登录加密为例,假设定位 Agent 找到了一个可疑函数,分析 Agent 判断它是某种变种加密算法。接下来:
- 让分析 Agent 输出详细的伪代码,标注每一步的输入输出。
- 根据伪代码写 Python 复现脚本。
- 用动态采集时记录的输入输出对验证脚本。
- 如果匹配,说明还原成功;如果不匹配,回到分析 Agent 重新检查,可能是某轮密钥或初始向量搞错了。
验证通过的脚本可以直接用于后续的协议对接或安全测试。
5. 常见问题与排查技巧实录
5.1 Agent 给出错误结论怎么办
这是最常见的问题。Agent 不是神,它会犯错,尤其是面对高度混淆的代码时。排查思路:
- 检查证据链:Agent 的结论有没有证据支撑?如果它说“这是 AES”,但找不到 S-box 或密钥扩展,那结论就不可靠。
- 多 Agent 交叉:让两个独立的 Agent 分析同一个函数,如果结论不一致,说明有歧义,需要人工介入。
- 动态验证:构造输入让应用执行该函数,看实际输出是否与 Agent 预测一致。这是最硬的验证手段。
5.2 混淆代码怎么处理
混淆是逆向的常态。常见手段包括:控制流平坦化、虚假分支、字符串加密、函数内联、指令替换。Agent 对轻度混淆有一定抵抗力,但重度混淆还是需要先做去混淆。
去混淆的策略:先用符号执行或动态执行收集实际执行路径,把未执行的虚假分支剪掉;字符串加密可以用 Hook 在运行时 dump 解密后的字符串;控制流平坦化可以用模式识别还原原始控制流。这些操作可以部分自动化,但复杂情况仍需人工。
5.3 动态采集被反调试拦截
很多应用有反调试机制,检测到调试器或 Hook 框架就退出或行为异常。应对方法:
- 用更隐蔽的 Hook 方式,比如内核级 Hook 或硬件断点。
- 修改应用的反调试检测逻辑,让它以为环境是干净的。
- 在模拟器层面做隐藏,让应用检测不到模拟器特征。
这些操作涉及具体技术细节,这里不展开,核心思路是“让应用相信它在正常环境运行”。
5.4 问题速查表
| 问题现象 | 可能原因 | 排查方向 |
|---|---|---|
| Agent 无法识别函数语义 | 混淆严重或架构不支持 | 先脱壳/去混淆,确认架构 |
| 动态采集无数据 | Hook 未生效或被检测 | 检查 Hook 配置,换 Hook 方式 |
| 算法还原结果不匹配 | 密钥/IV 错误或轮数不对 | 核对动态观测的输入输出 |
| 网络载荷无法解密 | 加密算法未还原或密钥缺失 | 回到二进制破解阶段补全 |
| Agent 结论置信度低 | 证据不足或代码歧义 | 增加动态验证,人工复核 |
5.5 几个踩过的坑
第一个坑:一开始想让一个 Agent 干所有事,结果提示词太长,模型注意力分散,效果很差。后来拆成多个专职 Agent,每个只关注一个子任务,效果明显提升。
第二个坑:动态采集时没打时间戳,导致 API 调用和网络请求对不上。后来统一用高精度时钟,所有数据都带时间戳,关联分析才顺畅。
第三个坑:过度信任 Agent 的结论,没有做动态验证,结果在一个关键算法上还原错了,导致后续所有分析都偏了。从那以后,任何关键结论都必须过动态验证这一关。
6. 影响范围与能力边界
6.1 这套方法能用在哪些场景
REA 这套思路的适用面比想象中广。安全评估是最直接的应用,可以快速定位应用中的加密实现、认证逻辑、权限检查点,评估是否存在弱加密或逻辑漏洞。竞品分析也很常见,通过行为分析和二进制破解理解对手的功能实现和协议设计。老旧系统维护时,源码丢失但二进制还在,可以用这套方法还原核心逻辑,指导迁移或重写。协议对接场景下,第三方接口没有文档,只能从客户端逆向出协议格式和加密方式。
6.2 当前的能力边界
必须诚实地说,这套方法不是万能的。面对重度混淆加反调试加服务端强校验的应用,Agent 能提供的帮助有限,最终还是依赖高水平的人工逆向。另外,Agent 的推理能力受限于训练数据,对于极其小众的架构或自研虚拟机保护的代码,识别率会大幅下降。
还有一个现实约束是算力成本。大模型推理不便宜,一个中等规模应用的完整分析可能消耗大量 token。实际使用时要有取舍,优先分析高价值目标,低价值部分用传统方法快速过。
6.3 后续可以扩展的方向
一个方向是把符号执行和 Agent 结合得更紧密。现在符号执行主要用于验证,其实它也可以用于引导 Agent 的搜索方向,把路径约束作为 Agent 的额外输入。另一个方向是引入强化学习,让 Agent 从每次逆向任务的成功和失败中学习,逐步优化搜索策略和提示词。
我个人在实际操作中的体会是,AI Agent 在逆向工程里的角色更像是一个不知疲倦的初级分析师,它能快速处理大量数据、给出初步判断、标记可疑点,但最终的决策和深度分析还是得靠人。把 Agent 当助手而不是替代品,心态摆正了,效率提升会非常明显。最后分享一个小技巧:每次逆向任务结束后,把 Agent 的错误结论和人工修正结果整理成反馈数据,用来迭代优化提示词,几轮下来 Agent 的准确率会有肉眼可见的提升。