REA 如何把 Hopper 反汇编器变成 Agent 可驱动的自动化分析后端
【免费下载链接】reaReverse engineer anything with agents, from app behavior down to native binaries.项目地址: https://gitcode.com/GitHub_Trending/rea2/rea
REA 是一个"万物皆可逆向"的分析平台,其 Hopper provider 负责对接 Hopper Disassembler:后台静默拉起分析器、串行投递分析请求、用缓存摊平反编译开销。适合想自动驱动 Hopper 做逆向的工程师阅读。
先看清没有它时你会遇到什么 🧩
Hopper 是一个交互式 GUI 反汇编器,它面向人设计,不面向程序。你的 Agent 想批量查函数、取伪代码、搜字符串,会接连撞上三堵墙。第一堵是启动:拉 Hopper 打开一个二进制,窗口会弹到前台打断你的桌面,冷启动后还要等它加载,没有确定的"就绪"信号。第二堵是并发:Hopper 内部的 Python 脚本 API 是单线程串行的,同一时刻只能处理一个请求,并发投递的请求会互相踩线。第三堵是成本:procedure.decompile()是 Hopper 里最贵的操作之一,同一个函数查十次有界投影,朴素实现就会反编译十次。
这三件事任何一件不处理,自动化分析都会退化成"看着终端猜它卡没卡死"。
Hopper provider 在 REA 中的位置 🧭
REA 的架构是"一个分析平台 + 多个可插拔 provider",Ghidra、IDA、Hopper 各占一席。Hopper provider 对上实现统一的AnalysisProvider契约,声明身份、能力清单与可用性;对下负责进程生命周期、超时、取消与清理,把上层操作翻译成对 Hopper 的调用。中间隔着一根 Unix 套接字,上面跑 NDJSON 协议,套接字另一头是注入到 Hopper 内部运行的桥接脚本。
整体编排关系见 docs/native-investigation.md,实现集中在 src/hopper/ 目录。
一次完整的分析会话怎么跑 🚀
- 准入校验:
inspectAvailability只放行 macOS 与 Linux,其他平台直接报unsupported_host;目标只接受executable与database两类,DOS MZ/COM 会明确指向 Ghidra 16 位适配器。 - 获取目标租约:macOS 上通过目标租约保证同一个二进制不会被两个 REA 会话同时打开,失败时提示"该目标已在另一个会话中打开"。
- 写引导脚本:在会话私有目录生成
bootstrap.py,权限0o600,内容只是几个常量赋值——套接字路径、32 字节随机令牌、run_id——然后编译执行 bridge/hopper_bridge.py。 - 后台拉起:先用
ps -ax探测 Hopper 是否已在运行,已运行则跳过;冷启动时执行open --hide --background,再固定等待HOPPER_BACKGROUND_STARTUP_MS = 5000毫秒预热。 - 启动与认证握手:以
--executable或--database参数启动目标,src/hopper/BridgeLauncher.ts 只拥有短命的启动器进程组,不碰 LaunchServices 管理的 Hopper GUI 主进程。客户端创建rea-前缀私有临时目录,先跑一个health请求,校验响应名为REA Hopper bridge且run_id精确匹配,全程受 120 秒启动截止约束。 - 投递请求:每个请求带自增数字 id,写入套接字形如
{ id, token, method, params }一行 JSON,响应按 id 关联。缺令牌或不匹配(hmac.compare_digest比较)直接拒收。
两个最值得展开的设计点 ⚙️
单请求并发的 FIFO 队列。src/hopper/HopperRequestQueue.ts 的类注释只有一句:"FIFO that keeps the wire serialized until Hopper actually replies"。它把 Hopper 的串行限制显式设计成队列:后到的请求不挤占线路,而是排队并上报queued behind N Hopper request(s),让你知道自己排在谁后面;每个在途请求带 1 秒心跳,持续汇报still running in Hopper (xxx ms elapsed),长操作不再是黑盒;调用方取消只取消自己——排队中的可摘除,进行中的在调用侧标记cancelled,但不打断 Hopper 正在执行的操作。任何时刻线路上有且仅有一个在途请求,超时、取消、清理都不产生竞态。
反编译缓存与失效。桥接脚本用两张字典把开销摊平:_pseudocode_cache以(document id, 入口点地址)为键,同一函数无论被投影多少次,decompile()只执行一次;_search_inventory_cache把函数、字符串、命名表整理成不可变的地址排序快照,重复搜索直接命中。缓存不是只增不清的:分析标注一旦变化(重命名、改属性),_invalidate_pseudocode与_invalidate_search_inventory按文档粒度整体失效对应条目,保证你拿到的永远是当前分析状态下的结果。
| 设计点 | 位置 | 解决的问题 |
|---|---|---|
| FIFO 串行队列 | HopperRequestQueue.ts | 串行 API 上的排队、心跳、只取消自己 |
| 伪代码/清单双缓存 | hopper_bridge.py | 昂贵 decompile 去重,变更按文档失效 |
| 目标租约 | 启动前置检查 | 同一二进制不被两个会话并发打开 |
边界与常见坑 ⚠️
- 平台与目标限制:仅 macOS/Linux 可用;
database目标在 macOS 上明确不可用——打开已保存的 Hopper 数据库时桥接脚本无法注入,只能改用executable;raw-binary、MIPS/RISC-V/PowerPC 架构目标直接拒绝并指向 Ghidra。 - 窗口仍可能被拉到前台:Hopper 官方的
hopper命令行助手内部会发 AppleScriptactivate,源码注释明确这是上游 Hopper 的约束,不代表 REA 分析失败。 - Linux 走专用演示适配器:Linux 侧启动前先校验固定构建的 SHA-256,经
verified_linux_demo模式与私有 X11 显示策略运行,未通过校验不会启动。 - 关停有 30 秒上限:清理走统一的
HOPPER_SHUTDOWN_TIMEOUT_MS = 30000握手超时,先落定在途请求,再删除会话产物;每个结果都附带"依赖 Hopper 已完成的静态分析"的局限性声明,分析没跑完时相关操作会拒绝执行。
如果你在 macOS 或 Linux 上需要让 Agent 稳定驱动 Hopper 做函数级分析、伪代码提取和字符串搜索,这套 provider 是现成的后端;但你的目标是 16 位 DOS 镜像、无头 raw 二进制,或者需要在 Windows 上跑,那就该选 REA 里的其他 provider,别在 Hopper 这条路上耗。
【免费下载链接】reaReverse engineer anything with agents, from app behavior down to native binaries.项目地址: https://gitcode.com/GitHub_Trending/rea2/rea
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考