ARTICLE · 1207896
REA 逆向神器,AI 时代不再有闭源软件?
闭源软件还会存在。但我们已经很难继续把「没有源码」当成一道足够可靠的理解门槛。
截至 2026 年 10 月 18 日,写这篇文章的时候,REA 的 GitHub 原仓库显示约 316K Star、80K Fork(半天增加将近 1 万 Star)。社区讨论的内容中包括如何理解一个函数,延伸到了旧软件维护、跨平台实现,以及某些商业软件是否还能维持原有优势。这些数字说明项目受到广泛关注,无法证明实际使用人数,更无法证明复杂应用已经可以被完整复现。GitHub 原仓库
当模型能够持续调用反编译器、追踪引用、检查交付包,再把结果组织成可继续查询的证据,软件的分析成本会怎样变化?技术团队此前依赖的哪些假设,需要重新评估?
这是一篇基于 REA 源码的分析文章,比读源码稍微好一些,其目的是快速了解 REA 是什么,解决了什么问题,以及如何解决这些问题的。
在开始文章之前,我们需要了解: REA 不是能独立完整逆向的工具,它只是一套模型能调用的工具(以 MCP 或 CLI 的方式),帮助 Codex 这类 Agent 调查程序。根据目标类型,调查返回模块关系、函数位置、调用线索或编译指令等信息,模型再据此解释行为、编写实现和运行检查。
逆向是什么
逆向工程从交付产物和可观察行为出发,推导程序的结构、接口与实现逻辑。输入可以是可执行文件、程序集、ASAR、APK,也可以是抓包、崩溃记录和一段运行过程。
编译会丢失部分信息。机器码通常无法直接告诉我们原始变量名、注释、项目组织和开发者意图。反编译器生成的伪代码,需要结合汇编、字符串、引用、数据布局和运行行为来解释。反编译文本足够可读,仍然可能在类型、边界和间接调用上留下问题。
因此,逆向的交付应该围绕具体问题。一个长度字段怎样编码,某个按钮怎样触发文件读写,某个版本改变了哪条分支,都能形成有限的调查范围。要求恢复一个应用的完整源码,会把目标扩大到原始工程、构建环境、资源、依赖和未观察行为,验收条件随之失去约束。
传统逆向工作流中,逆向分析者负责把这些线索连接起来:搜索字符串,定位引用,检查函数,修改假设,再设计实验。AI 参与后,大量重复查询和跨文件追踪可以交给 Agent。分析者仍需决定哪些证据足以支持结论,以及哪些未知会影响后续实现。
这里要区分「功能解释」和「复现正确」。模型能够解释一段伪代码,只完成了前者的一部分。实现通过几个样例,也只能支持已经覆盖的输入。把有限观察写成整个软件等价,会让后续开发继承一份未经验证的规格。
热度背后的需求
REA 的爆火我觉得来自两个方面:一个是逆向作为一个传统的门槛非常高的工种,当前 Agent 结合 REA 能把这个门槛降得很低;另一个是对于一个传统闭源的软件,用这套工具可以复刻一个出来,这种打破规则的禁忌也让人着迷。
REA + Agent 解决了逆向工作中的一个特别重要的问题:模型已经能读懂不少代码,工程师却仍需手动替它操作分析工具。
Ghidra、Hopper、IDA 各有自己的数据库、API 和使用方式。面对 Electron,又要处理 ASAR、模块加载、preload 和 IPC。问题一旦跨越技术层,分析者就要在多套工具之间搬运上下文,判断地址、路径和符号是否指向同一对象。
REA 把这些能力接到 CLI 和 MCP 上。人可以直接运行命令,Agent 可以调用工具,返回结果使用统一的来源和限制描述。这让调查可以围绕一个问题持续推进,减少人工整理每一次工具交互的工作。
社区期待在这里已经失控。
能够降低分析成本,与能够经济地完整复现一个大型软件,之间还有很长的距离。交互细节、异常分支、数据格式兼容和未被触发的行为,都要进入验证范围。Star 和演示很难呈现这部分成本。
GitTested 对 REA 6.2.0 的测评提供了一个约束:在四个不超过 264 KB 的去符号原生程序上,普通工具组得到 74/75 的事实检查分数,REA 组为 73/75,后者使用的 token 约为前者的 2.5 倍。这份结果针对特定版本、模型和小程序,无法外推到当前全部能力;它足以说明,增加分析工具没有自动带来更高收益。测评原文
我们做选型时,应当保留普通工具基线。复杂度较低的任务,如果文件读取、搜索和 objdump 已经能回答,额外加载大型工具目录和完整图结果,可能只是在增加任务成本。
REA 与当前的工具如何协作
REA 的生产主链没有一个必须内置的通用大模型规划器。模型通常来自 Codex、DeepSeek Harness 等调用端,负责提出下一次查询;REA 提供具体分析操作,管理目标、结果和相关资源。
当前的 6.5.0 版本总共声明了 207 个工具合约、6 个引导式 Prompt。原生路径包含函数档案、伪代码、汇编、字符串、交叉引用、调用图,以及字节和类型检查。反编译主要由外部引擎承担,REA 负责把结果转换为统一表达。
这个统一不是一模一样。不同引擎能提供的事实不同,不能为了得到整齐的返回格式,给缺失能力填上空数组。REA 会保留不可用原因和覆盖信息。调用者需要知道某个侧面没有观察到,或者该 Provider 根本不支持。
引擎选择也没有被藏起来。自动模式只有在存在唯一可用分析配置时才建立深度绑定;多个候选均可用,会报告歧义。显式选择的引擎失败,也不会悄悄换成另一个,再继续沿用原来的来源说明。
这种设计牺牲了一点使用上的顺滑,换来了可解释的结果。如果分析过程中发生了引擎切换,类型恢复、函数边界和调用关系都可能改变。让调用者作出选择,比把差异隐藏在成功响应里更适合需要复查的调查。
CLI 与 MCP 共用应用工作流,生命周期有所区别。CLI 通常执行一次便结束,MCP 可以保留目标和调查状态。连续研究同一个大目标时,会话复用与快照有价值;只有一次明确查询时,单次命令更容易控制输入和输出。
跨层分析难点
以 JavaScript 和 Electron 路径为例,其尤其能体现 REA 自身的分析工作。
一个文件导入功能可能从 renderer 进入 preload,经 contextBridge 和 IPC 到达主进程,最后调用原生扩展。搜索按钮文本只能得到入口,import 图也无法独立解释跨进程关系。
REA 会解析 AST,建立作用域、绑定、引用和模块来源,再投影为应用图与语义图。别名、解构、成员变更以及部分打包结构,都要参与判断。代码里出现同名函数,不能证明调用来自同一个模块;局部变量遮蔽之后,相同文本甚至可能对应完全不同的行为。
IPC 配对采用较保守的条件:字面量 channel 与通信模式相容,且存在唯一候选,才生成确定配对。多个候选保留歧义,动态 channel 无法证明时保持未配对。这里的静态关联也没有自动升级为运行时事实。
这种策略适合回答「应该继续查哪里」。遇到运行时计算、动态加载或不透明影响,静态图会留下缺口。继续扩大扫描范围未必能填补缺口,可能需要转向指定动作的运行观察。
源码文本进入 AST,再变成语义 IR、应用图和 Evidence,中间表示会扩大内存需求。REA 把解析分析放在独立受控进程中,使用堆限制、超时和传输预算;部分遍历、校验和摘要计算通过协作检查点响应取消。
独立进程增加了启动、序列化和数据交接成本,却能为大 bundle 提供更清楚的资源边界。面对少量文本,普通搜索更轻;面对跨模块来源和 Electron 边界,结构化分析才可能抵消这笔开销。
能力各有边界
REA 的其他模块也遵循专题分工。
.NET 路径自己读取 PE/CLI 元数据、类型成员、IL 方法体和托管原生边界,不需要运行程序集。它适合结构调查,不能因此承诺恢复完整 C# 工程。Android 又拆成 JADX 静态代码、Apktool 资源解码、ADB 设备操作和 JEB 接入,避免把看代码与安装、启动应用混成一个权限层次。
包与资源模块负责目录、ZIP、ASAR、DMG 和架构切片的清单、摘要及提取。Apple 专题进一步处理 plist、Interface Builder、动态库解析和相关元数据。输入身份从这里建立,后面的分析才能确认读取的是同一份内容。
固件依靠 Binwalk、Unblob 等外部工具识别区域和提取内容;Flutter 路径检查构建、ABI 与 Dart AOT 线索;WASM 借助 WABT 读取验证结果、结构和 WAT;EVM 借助 EVMole 提取 selector 和推断接口。它们的输出范围各不相同,统一称为「还原源码」会抹去重要限制。
Go、Rust 模块主要读取嵌入的构建或依赖信息。SQLite 检查稳定数据库及 WAL 的私有副本。抓包和录制信号模块解释已有记录。元数据缺失,不能推出依赖不存在;某个窗口没有观察到请求,也不能推出功能从不访问网络。
这些模块的价值取决于问题。需要了解依赖时,读取元数据比启动反编译器更合适;需要解释某条数据路径时,元数据又不足以代替函数和运行观察。选工具之前,先确定哪种事实能够改变当前判断。
证据决定结论
REA 的 Evidence 记录了目标摘要、Provider、分析配置、操作参数、原始与标准化结果、位置、限制及关联证据。它让模型的解释可以回到具体来源,而不只剩一段听起来合理的文字。
其中 observed、derived、inferred 区分观察、推导和推断,表达的是知识来源,不能当成概率。观察到反编译器输出某段伪代码,与证明这段伪代码准确描述所有行为,仍然是两件事。
证据 ID 根据语义内容生成。目标的展示名称和本地路径被排除,其他参数、结果或位置中的路径依然可能影响摘要。这种身份设计方便保存和交换,也要求我们理解它证明了什么:摘要匹配可以检查内容一致性,无法替代引擎正确性和解释正确性。
快照进一步绑定目标、Provider、分析配置、操作和参数。读取实时状态的能力不能被历史缓存伪装成当前观察,依赖隐含光标或文档的查询也需要额外约束。缓存命中率只能在这些条件成立之后讨论。
未知问题有独立的版本和状态。一个问题可以被验证解决,也可以被撤回或排除在范围外。后两种状态并不提供事实已经成立的证明。对需要交付分析结论的团队,这种区分应当进入评审,而不只停留在模型提示词里。
运行才有观察
静态分析留下的关键疑问,需要通过实验减少。REA 的浏览器、Inspector、PTY、LLDB、GDB 和 Frida 等模块提供了不同观察路径,各自有明确的影响范围。
被动附着页面读取信息,与启动应用、点击按钮或加载插桩脚本,涉及不同状态变化。一次动作完成后,还要分别确认截图、DOM、网络、存储等采集项是否成功,不能用动作成功代替采集完整。
程序退出、输出关闭和清理完成,也有各自的观察条件。客户端超时可能只结束等待;后台工作仍然执行。进程 leader 退出之后,后代进程可能继续存在。PID 还可能被复用,仅凭一个数字无法确认终止权限。
REA 使用运行 token、进程身份和资源 owner 管理这些边界。共享启动过程中,一个等待者取消,不应打断其他调用者;最后一个等待者离开时,又要等生产者收尾。清理失败则保留原 owner,以便后续对尚未释放的资源重试。
这部分代码增加了状态复杂度。并发、取消和最终收尾的组合很难靠正常路径测试覆盖。但逆向任务的单次执行成本可能很高,错误地重启分析器或留下后台进程,会让下一轮调查继承无法解释的环境。长会话系统需要承担这笔工程成本。
如何使用 REA
Codex、DeepSeek Harness 与 REA 可以通过 MCP 组合。我们没有必要为了接入逆向能力,再实现一套 Agent loop。
Harness 负责模型、工具执行、上下文、会话和插件生命周期;REA 负责分析目标、引擎及证据。两边都有会话,含义不同。模型会话保存了工具结果,不代表 REA 的进程和目标状态也已经被完整保存。
在 Codex 中,可以使用 REA 的 setup 先查看注册计划,再确认应用。手动方式则通过 Codex MCP 配置启动 rea mcp,并为原生分析设置合适的调用超时。
其实也可以直接把 github 的地址给 Codex,让它给你安装。
效率必须实测
分析规模越大,越需要区分计算完成与结果可用。
完整应用图和 Evidence 可能很大。MCP 同时承载文本和结构化内容,还受到传输预算、JSON 编码以及字符串表示的限制。让模型直接接收全部结果,可能把大量成本花在无关模块上。
REA 提供概要、受支持的分页视图和证据导出。超过传输预算时,部分路径会保留完整结果,再返回可继续读取的引用。分析没有被压缩成较小的事实集合,交付方式发生了变化。
但分页也有代价。模型可能先发现工具,再读概要,再取数页,再因选择错误重试。每次回复更小,整项任务的调用次数、上下文和延迟却可能增加。REA 自己的实验记录也保留了这种混合结果,回复字节减少没有稳定证明总 token 和耗时减少。
因此,性能评估应当以同一个问题的完整过程为单位:普通工具能否回答,使用 REA 后正确性是否改善,失败和重试多少次,总 token、时间与进程族内存分别是多少。冷启动和会话复用也要分开。没有这组对照,压缩输出只能算一次局部优化。
闭源边界变化
标题中的判断需要落到可讨论的范围。闭源作为分发和商业形态会继续存在;用户能否拿到原始源码,与能否推导部分实现逻辑,正在逐渐分离。
交付到本地的字节、资源、接口和运行行为,提供了调查输入。Agent 能持续利用这些输入,减少搜索、查询、整理和局部实现的人工成本。原来因为耗时而很少被分析的功能,可能因此进入更多人的调查范围。
这种变化会削弱一部分依赖信息不对称的优势。对于可以被独立描述、输入输出有限的功能,我们需要重新估计其被理解和重写的成本。仅凭实现复杂或代码不可见,已经很难为这个估计提供足够依据。
完整产品仍有不同的成本结构。兼容性、异常处理、版本演进和持续验证不会随着函数解释一同完成。远端执行、未提供的数据和未观察路径,也不会从本地文件中自动出现。分析工具可以报告边界,无法凭空补足缺失输入。
从技术管理角度,我们应当同时调整两端:研究外部软件时,把调查问题和验收范围收紧;评估自身产品时,减少对实现隐蔽性的依赖,把可验证的行为质量和持续维护能力纳入投入判断。
REA 已经把逆向工具、结构化证据和 Agent 调用连接起来,也在代码中保留了失败、歧义和未知。我们可以利用这套能力缩短调查过程,同时要求每一次功能解释都能追溯来源,每一次复现结论都能说明覆盖范围。缺少来源或覆盖声明的结论,应继续留在调查阶段,避免直接进入实现规格和验收报告。
但是,最后逆向商业软件是有可能触发法律风险的,以及当前社区已经有人反馈,因为逆向导致 Codex 封号。
以上。















































































