夜雨聆风学习资料网

ARTICLE · 1138768

想复刻一个 App 的功能却没有源码?morluto/rea 让 AI Agent 把二进制读成方案

想复刻一个 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 也不声称恢复原始源码, 被阻塞或截断的观测不能用来证明两次行为一致。

相关学习资料