一句话看懂
rea 把反编译器变成了 AI agent 能直接对话的工具。它用 MCP(Model Context Protocol,一种让程序和 AI 助手互相调用的协议)把 Ghidra、Hopper 这类逆向分析软件接起来,agent 发一条指令,桥接脚本在对应工具里跑完分析,再把结果连同证据一起传回来。
它解决什么问题
逆向工程师平时要在 Ghidra、Hopper、IDA 之间来回切换,手动点反编译按钮,再把输出结果复制粘贴给 AI 去读。工具操作和推理分析是两套割裂的流程,agent 没法直接伸手去点那些逆向软件的菜单。
rea 的做法是写一批桥接脚本,分别跑在 Ghidra 的无头模式、Hopper 的内部线程、LLDB 的调试会话里,对外暴露统一的 MCP 接口。agent 调用这些接口,就相当于直接操作了对应的逆向工具,不用人工中转。它还覆盖了原生二进制之外的目标,比如 JS/Electron 应用、.NET 程序、网站,这些原本需要不同工具链分别处理的场景,被收进了同一套调用方式里。
核心概念速览
MCP:一种协议,让普通程序能被 AI 助手当作工具来调用。在 rea 里,agent 通过 MCP 服务器把分析请求转发给具体的逆向工具,不需要关心底层是 Ghidra 还是 Hopper。
Bridge(桥接):连接外部工具的适配脚本。比如 ReaGhidraBridge.java 跑在 Ghidra 的无头环境里负责反编译,hopper_bridge.py 跑在 Hopper 的线程里做会话绑定。每种工具的接口差异很大,桥接脚本把这些差异屏蔽掉,统一成 MCP 能理解的调用。
Evidence(证据):REA 返回分析结论时,会附带具体的证据和尚未确定的部分。比如某个函数做了什么,会同时列出支撑这个判断的代码片段和不确定的地方。
架构拆解
整个调用链条是 agent 先发请求给 MCP 服务器,服务器根据目标类型决定转发给哪个桥接脚本。如果目标是原生二进制且要深度反编译,走 ReaGhidraBridge,它会读取会话描述符,在 Ghidra 无头模式里跑完分析再把结果吐出来。如果目标已经在 Hopper 里打开,走 hopper_bridge.py,它要先确认当前 Hopper 文档就是目标文件,再执行具体的分析动作。还有一条独立的路径是 rea_lldb_tracer,跑在 LLDB 调试会话里,专门做运行时的原生调用观察,把每次调用记录写进一个有界的日志里,不会无限增长占满内存。
三条路径分别对应静态反编译、交互式工具内分析、动态调用追踪,各自独立,但都通过 MCP 这一层对 agent 暴露统一的调用方式。
关键实现走读
def _bind_session_document(documents=None):
"""Bind this bridge to Hopper's current document for its target."""
global _rea_session_document
api = _api()
if documents is None:
documents = api.documents()
target = os.path.realpath(REA_TARGET_PATH)
def matches_target(document):
paths = (document.getExecutableFilePath(), document.getDatabaseFilePath())
return any(path and os.path.realpath(path) == target for path in paths)
current = api.current_document()
if current is not None and matches_target(current):
_rea_session_document = current
return current
matching = [document for document in documents if matches_target(document)]
if len(matching) == 1:
_rea_session_document = matching[0]
return matching[0]
if len(matching) > 1:
raise CapabilityUnavailableError(
"The REA session document is ambiguous; Hopper did not identify the launched document"
)
return None
做了什么:这段代码在 Hopper 里找到和目标文件路径一致的文档,并把它绑定为当前分析会话。它先检查 Hopper 当前打开的文档是不是目标,如果不是,再去已打开的全部文档里逐个比对可执行文件路径和数据库文件路径。
为什么这样写:Hopper 一次可能同时打开多个文件,如果同一个目标文件被打开了两次,系统没法判断该操作哪一个,这时直接抛出 CapabilityUnavailableError,把歧义暴露给调用方,而不是随便选一个继续跑。路径比对用的是 os.path.realpath,这样可以处理软链接或相对路径带来的路径不一致问题。
没有它会怎样:如果没有这层绑定逻辑,agent 发出的分析指令可能被 Hopper 应用到错误的文档上,返回的反编译结果和实际目标不是一个文件,分析结论就会是错的,而且这种错误不容易被发现,程序不会报错,只是答案对不上。
动手上手
先装好环境,确保 Node.js 版本在 22.x(>=22.23.4)、24.x(>=24.22.1)或 26.12.1 以上。
第一步,运行安装命令:
npx rea-agents setup
这一步会完成初始配置,可以验证的结果是命令执行结束后没有报错退出,且本地生成了对应的配置文件或目录。
第二步,如果想全局安装而不是每次用 npx 临时拉取:
npm install --global rea-agents
安装完成后执行 rea --help,能看到命令行帮助列表,说明全局命令已经可用。
第三步,拿一个具体的 JS/Electron 应用跑一次分析,确认整条链路通畅:
npx -y rea-agents@latest analyze-javascript-application /absolute/path/to/app --json
这里的路径要换成实际应用的绝对路径。
后续如果要更新到新版本,执行:
rea update
需要注意 updater 命令对 stdout 和 stderr 的合并输出有 4 MiB 的保留上限,超出部分会被截断。如果用 Bun 做全局安装的更新,Bun 版本要在 1.2.17 或更高。
应用场景
理解第三方 App 的功能实现,是比较直接的用法。让 agent 用 REA 去检查目标应用,解释某个功能点具体是怎么实现的,前提是分析对象已经获得授权,这个限制在工具层面没法自动核实,需要使用者自己把握。
原生二进制逆向是另一类场景,需要先把 Hopper、Ghidra 或 IDA 配置好,再通过 REA 发起反编译请求。这类场景对环境配置的依赖更重,前期准备工作比直接跑 JS 分析要多。
独立分析
独立分析:REA 返回结果时强调证据和局限并存,不只给一个结论性判断。
和单纯用 Ghidra 或 Hopper 手动分析相比,REA 通过 MCP 把多个工具的调用统一到一层接口上,agent 不需要分别学习每个工具的操作方式。手动分析和这种自动化调用之间具体在效率、准确度上差多少,现有资料没有给出对比数据,这部分留着待验证。
局限与风险
在 Linux 上跑 Ghidra、JADX 这类工具,需要 PATH 里有和 procps 兼容的 ps 命令,环境缺这个依赖会导致分析失败。Updater 命令的输出保留上限是 4 MiB,合并后的 stdout 和 stderr 超出这个大小会被截断,排查问题时如果日志刚好卡在这个边界,可能看不到完整信息。Bun 全局更新对版本有硬性要求,低于 1.2.17 跑不通。PE、ELF 这类常见二进制格式的分析,大多数情况下还是依赖 Node 或者第三方工具的支持,REA 本身不是独立的反编译引擎。
结论卡片
适合安全研究员和逆向工程师,尤其是需要分析结果可追溯、带证据支撑的工作流。不适合没有授权或法律许可的逆向场景,这类风险工具本身没法替使用者判断,需要自己把握边界。它更像是把现有逆向工具接到了 agent 能理解的协议层,而不是重新发明了一套反编译能力。
原文地址:tools.wflynn.cn/aitools/git…
关注公众号「YourTools」,每天推送 GitHub 趋势与开源工具速报: