ARTICLE · 1138768
想复刻一个 App 的功能却没有源码?morluto/rea 让 AI Agent 把二进制读成方案
逆向工程 · MCP · 二进制分析 · Agent 工具链 · 证据链
morluto/rea 把 Hopper、Ghidra、IDA 这些分析引擎,连同 JavaScript、Electron、 .NET、APK、浏览器页面与固件等目标,收拢成一套 AI Agent 可以直接调用的工具面。 你只需要用自然语言说清"想看懂哪个功能",剩下的查字符串、追交叉引用、跑反编译 由 Agent 完成,而且每一步都必须带上证据与局限,而不是给一个听起来合理的答案。
没源码时的理解难题
真实的工作里,需求常常长这样:某个笔记应用的离线搜索很好用,想在自己产品里做一个; 某个工具的导出文件格式想读写;某个 Electron 客户端的同步协议想搞清楚; 或者干脆是自己接手的一堆老程序,只有可执行文件,没有一行源码。
传统做法是装 Hopper 或 Ghidra,然后人肉看汇编与伪代码。 符号被 strip 之后,你只能靠一个字符串、一次交叉引用慢慢往回猜, 中间还要在多个工具之间来回导出、记录、对比,链路一断就得重来。
更大的坑是直接拿通用大模型来"逆向"。 模型没有真实观测,就会顺着上下文把不存在的结构补全, 给出的函数名和调用关系看起来煞有介事,却没有任何可核对的出处。 逆向最怕的不是慢,而是把猜测当成事实。
morluto/rea 服务的正是这批人:需要在无源码前提下做兼容实现、格式互操作、 行为审计、旧软件迁移的开发者与安全研究者,以及只想把自己的 Electron 应用结构 摸清楚的前端工程师。
上手路径与三个样例
推荐入口是一条命令:
npx rea-agents setup
它会列出检测到的 Agent(Claude Code、Codex、Cursor、Gemini CLI、Windsurf、 GitHub Copilot CLI、VS Code 等),展示将要写入的路径和备份,等你确认后才动手。 Hopper 是单独的可选项,需要你明确同意;Ghidra 与 IDA 走"自带引擎、只接路径"的方式。 重启 Agent 之后,就可以直接描述目标了。
最短的可运行流程甚至不需要任何原生引擎。对已解包的 JavaScript/Electron 目录或 ASAR:
npx -y rea-agents@latest analyze-javascript-application /absolute/path/to/app.asar --json
它返回内联证据、恢复出来的依赖图、局限与未知项,全程不执行目标程序。
样例一:静态摸清一个 Electron 应用。 输入是应用目录或 ASAR,动作是
analyze,结果拿到模块、导入关系、路由、IPC 通道与存储位置。
适合回答"这个客户端到底把登录凭证存在哪里""它连了哪些域"这类问题。
样例二:追一个原生 App 的功能。 先配好 Hopper 或 Ghidra,用
rea analyze /path/to/binary --provider ghidra 打开目标,
再让 Agent 沿固定路径推进:open_binary 与 binary_overview 建立全局认识,
search_strings、search_procedures 找线索,find_xrefs_to_name 把线索连到代码,
get_call_graph、procedure_info 还原控制流,最后 batch_decompile 批量出伪代码。
第六步"照着写一个"由你自己的编码 Agent 完成,用的是刚学到的行为而不是臆测。
样例三:观察一个已经跑起来的网页。 通过本机 CDP 端点被动读取:
rea list-browser-targets http://127.0.0.1:9222 --json
rea inspect-web-page http://127.0.0.1:9222 TARGET_ID --json
它不导航、不点击、不注入脚本,只按请求收集页面结构、网络元数据、
脚本来源与截图,适合分析一个 SPA 的接口与脚本分布。
需要交互时改用 capture-browser-scenario,用声明式场景跑 Playwright。
配套的还有对比与验收:rea compare a.json b.json 比对两份证据,
capture-process 加 compare-process-captures 比对两次进程运行的行为差异。
三个常见误区值得先说:
• 每次动手前先跑 rea doctor。 它不带 scope 时是全量审计,
会因为与你当前任务无关的引擎缺失而报 healthy: false;
静态 JavaScript 分析根本不需要任何 readiness 检查,直接跑 analyze 即可。
• 以为要把 Hopper、Ghidra、IDA 装齐。 只有原生二进制深分析需要其中之一, 同时装多个时 REA 也不会替你挑,而是要求你显式选一个。
• 以为能还原出原始源码。 任何反编译器都做不到这一点; 它给的是伪代码、符号、字符串与关系,用来解释或做兼容重建。
多引擎编排与证据链
整体链路是:Agent 或终端 -> REA(CLI 与 MCP 共用同一套应用工作流和证据契约) -> 绑定目标的 session 路由 -> 深分析 provider 注册表(确定性选择) -> Hopper / Ghidra / IDA。旁路还挂着原生 macOS 工具、artifact graph、 浏览器 CDP、Android 的 headless JADX、固件 Binwalk/Unblob,以及进程捕获。
第一个创新点在于工具面与引擎解耦,并且拒绝静默回退。
公开工具名描述的是"想学什么",provider 决定"怎么答"。
当多个引擎都能处理同一个目标时,REA 不猜,直接返回
code: "capability_unavailable"、details.selection_reason: "ambiguous"
并列出候选,由调用方选一次;这个选择在 session 内保持不变,
即使失败也不会偷偷换引擎。代价是首次多一步显式选择,换来的是可复现与可审计。
第二个创新点是证据优先的返回结构。
每条结论都带 subject 摘要(sha256、格式、架构)、provider 身份与版本、
源码位置或文件偏移、authority(shipped-artifact、controlled-replay、
analyst-inference 等)、confidence 与 limitations。
未解问题有独立的持久账本,带着 unknown_id、revision 与 contradicts 关系,
只有 verified、withdrawn、out-of-scope 才算真正闭合。
代价是输出更长更啰嗦,好处是"缺失的观测永远不会被当成通过"。
第三点是快照复用的严格性。 只有目标字节、操作、参数、分析工具与设置全部一致,缓存结果才允许复用。 这就避免了两份同一份字节的分析,因为语言、编译器或引擎版本不同而结论相左, 却又在表面上看起来"目标相同"。
第四点是副作用的前置声明。 工具用一份 ToolEffects 描述自己会不会改动目标、写文件、启动进程、 访问网络、丢弃数据,再据此派生 MCP 的只读与破坏性提示。 调用方在动手之前就知道这次调用会不会改变什么。
最后是本地优先:REA 没有托管分析服务,引擎通过本机私有 socket 通信, 截图一类操作才涉及 macOS 的辅助功能与录屏授权。
能落地的几个场景
兼容实现与数据迁移。 把闭源软件的文件格式或同步协议搞清楚, 做出可互操作的导入导出或迁移工具。REA 把"字符串线索 -> 交叉引用 -> 调用图 -> 伪代码"这条路径固定下来,比从零人肉摸索省下大量往返。
供应链与安全核查。 对随包分发的二进制依赖做行为核查, 用进程捕获对比两次运行,并把差异写进证据记录。 注意它的定位是记录行为而不是沙箱,目标以你的用户权限运行。
版本回归与漂移定位。 升级前后分别留一份 artifact、函数与浏览器捕获,
用 compare 第一时间找出行为漂移点,而不是等线上出问题再回头查。
往远处看,项目的路线图提到要补 LLDB、Frida、系统日志这类原生运行时观察, 扩展 .NET 混淆比较与移动端支持,并评估 Binary Ninja、Rizin、LIEF 等工具, 覆盖面还会继续扩。边界同样要说清楚:它面向合法的逆向研究与重建, 授权与合规由使用者负责;REA 也不声称恢复原始源码, 被阻塞或截断的观测不能用来证明两次行为一致。