ReAgent:用 Ghidra 加 LLM 重建 C/C++ 函数的验证闭环
Reconstruct and validate C/C++ code from compiled programs with AI.
秒懂
- 它是什么?
- ReAgent(PyPI 包名 auto-re-agent)把反编译证据、双模型互检、候选构建与一致性门禁串成一条流水线。它输出候选源码而不改原树,验证是保守的结构比对,不是语义等价证明。
- 适合谁用?
- 适合已经在用 Ghidra、并且手头有可编译可测试的工程副本的逆向或移植团队,尤其是需要按依赖顺序批量恢复一批函数、又想留下可复查证据记录的人。不适合只想要一份可读伪代码、不打算配置构建与测试命令的读者,也不适合把 LLM 输出当成最终源码直接提交的场景。
- 能商用吗?
- 可以。MIT 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
- 还在维护吗?
- 在维护。仓库最近一次提交在 6 天前。
- 用什么语言写的?
- 主要是 Python(依据 GitHub 的语言统计)。
以上回答依据项目的 GitHub 数据(最近同步于 2026年9月15日)和我们的分析,不构成法律意见。
开源项目深度解析
它解决的是反编译之后那一段空白
Ghidra 能给出伪代码,但伪代码到能编译的 C/C++ 之间还有一段人工活:补类型、还原结构体、判断调用约定、确认这段逻辑是否和原程序行为一致。ReAgent 针对的就是这一段。README 把它定义为「AI reverse-engineering agent」,任务是把编译产物里的函数重建成 C/C++ 并加以验证。
目标用户是手里已经有二进制、同时又有可构建源码工程的团队。README 里给出的 profile 名单很说明问题:generic-cpp、windows-x64、gta-reversed、openrct2。这些都是有公开源码、需要逐函数对照还原的项目形态。如果你只是想知道某个函数大概在干什么,不需要这套东西;如果你要把几百个函数按依赖顺序补回一个能编译的工程,才用得上。
需要注意的是它不自动改你的源码树。README 明确写了「generates candidate C/C++ implementations; it does not patch the original source tree automatically」。候选实现是产物,合入与否由人决定。
re-agent reverse 一次调用里发生了什么
README 给了一张流程示意。入口是 re-agent reverse --class CTrain,按类选择要处理的函数。配置来源有三层:YAML 文件、受支持的环境变量覆盖、以及命令行参数。
函数选择有三种策略,README 列出的是 dependency-order、easiest-first、high-impact。选完之后收集上下文:反编译结果、交叉引用、结构体、枚举、虚表、全局变量和字符串,加上归一化的 high P-code、CFG、汇编,以及工程里邻近的源码。
接着是 reverser 到 checker 再到 fix 的循环,轮次和调查次数都有上限。README 里的 agents 配置段支持给 checker 单独指定 provider 和 model,也就是说生成和检查可以由不同模型承担,比如正文示例里 llm 用 claude-cli 的 sonnet,checker 用 codex 的 gpt-5.4。这是这套设计里比较关键的一点:同一个模型既写又审,容易放过自己的错误。
循环之后依次过保守的结构验证器、候选 overlay、配置好的构建与测试与运行时门禁,最后是一致性门禁,结果分 GREEN、YELLOW、RED 三档。产物包括报告、每次调用的日志、轮次检查点、会话历史和知识图谱。
四道门都过了才算成功,而这不是等价性证明
README 把成功定义成四个独立条件同时成立:LLM checker 返回 PASS;客观验证器没有发现强结构不匹配;候选验证满足配置的 acceptance policy;一致性没有被配置的 RED/YELLOW 策略拦住。
这四条是并列关系,不是加权关系。任何一条不过,这次重建就不能算通过。设计意图很清楚:让模型的自评和结构比对互相牵制。
README 自己加了一句限定:「This is conservative verification, not a proof of semantic equivalence.」这句话应该被认真对待。结构不匹配检测能发现类型、控制流层面的明显偏差,但两个行为不同的实现完全可能在结构上长得一样。所以 GREEN 的含义是「按当前配置的检查没有发现问题」,不是「这段代码和原程序语义相同」。把 GREEN 当作可以直接合入的信号,是误用。
装什么、配什么、跑什么
基础安装走 PyPI,包名和仓库名不一致,注意是 auto-re-agent:
python3 -m pip install --upgrade "auto-re-agent[ghidra-bridge]>=0.4.0"
需要无头 Ghidra 导出时换成 headless extra:
python3 -m pip install --upgrade "auto-re-agent[headless]>=0.4.0"
依赖清单是 Python 3.10+、Git、Ghidra 加配置好的 Ghidra Bridge,以及至少一种 LLM 接入方式:ANTHROPIC_API_KEY、OPENAI_API_KEY、本地已认证的 claude 命令,或本地已认证的 codex 命令。
证据准备在目标工程目录里做:ghidra-bridge init 生成 ghidra-bridge.yaml,然后编辑里面的 Ghidra 工程和程序路径;ghidra-bridge export all 导出;有反向源码或 hook 模式时跑 ghidra-bridge build-map,README 说这一步虽可选但推荐;ghidra-bridge info 确认导出和配置可见。
配置用 re-agent init --profile generic-cpp 生成,README 提示不带 --profile 时会保留 GTA-reversed 的旧默认值,新项目应当显式指定 profile。re-agent.yaml 里至少要改的地方是 llm.provider 与 llm.model、backend.cli_path 指向已安装的 bridge 可执行文件、project_profile 下的 source_root 等路径,以及验证相关配置。
0.4.0 新增了 re-agent plan、re-agent reverse --manifest、re-agent evidence --manifest、re-agent status --manifest 四个按 manifest 工作的子命令,分别用来在无模型调用的情况下生成函数清单、跨类重建、导出证据为 JSON 包与 TSV 索引、以及报告覆盖率与过期结果。
0.4.0 把验证命令从 shell 字符串改成参数数组
这一版的改动集中在验证命令的可移植性上。构建、测试和运行时验证现在支持参数数组,在 Windows 和 POSIX 上直接执行。原生 Windows 上需要把 shell 字符串转成数组,遗留的字符串形式仍然依赖 /bin/sh;re-agent doctor 会报告缺少 shell 的情况。
这不是纯粹的语法糖。字符串形式意味着命令要经过一层 shell 解析,引号、路径分隔符和转义规则在不同平台上不一致,而参数数组绕开了这一层。对跨平台团队来说,这个改动决定了同一份 re-agent.yaml 能不能在 Windows 和 Linux 上共用。
同一版还修了几个具体问题:Clang 索引处理 CRLF 偏移;Codex CLI 请求对大提示改用 UTF-8 stdin。后者指向一个实际约束,命令行参数长度在部分平台有上限,大提示走 stdin 才稳。另外 README 提到后端报错且消息为空时 manifest 仍保持可读,证据缺口保持显式记录,不会因为一次失败把整份清单写坏。
它依赖 Ghidra Bridge,且证据质量决定上限
ReAgent 不直接读二进制,它通过 Dryxio/ghidra-bridge 取证据。这意味着两件事。第一,Ghidra 装不好或者 bridge 配不对,整个流程跑不起来,而 bridge 是独立仓库、独立版本,两边要各自维护。第二,反编译质量直接决定重建质量的上限,符号被剥离、间接跳转密集、有混淆的二进制,喂进去的证据本身就残缺,模型再强也补不回来。
成本是另一个现实约束。README 明确建议在给 AI 的引导语里「set a small model-call limit」,并且要解释清楚会用哪个 provider 和产生什么 API 费用。reverser 与 checker 是两套模型调用,加上有界的 fix 循环和调查次数,单个函数的调用次数会成倍增长。批量重建之前,先用一个函数量一下实际消耗,比事后看账单合理。
还有一个容易忽略的点:验证门禁需要你配置构建、测试和运行时命令。README 把候选验证放在 overlay 里,跑的是「configured build, test, and runtime gates」。如果目标工程本身编不过,或者没有可用的测试,这道门就形同虚设,剩下的只有 LLM checker 和结构验证器。对没有测试的二进制,这套流程的验证强度会明显下降。
和直接用 Ghidra 反编译的差别在哪
最直接的替代方案就是 Ghidra 自带的反编译器加上人工还原。两者的差别不在反编译质量,Ghidra 的伪代码是 ReAgent 的输入之一,而在后面那段。
纯 Ghidra 工作流里,判断一段伪代码还原得对不对,靠的是人的经验,结论留在脑子里或者零散的笔记里。ReAgent 的做法是把判断外化成可执行的检查:结构验证器给客观比对,构建和测试门禁给行为证据,一致性门禁给一个 GREEN、YELLOW、RED 的离散结论,全部落进报告、日志、轮次检查点、会话历史和知识图谱。
代价是前置投入。你要配 Ghidra Bridge、写 re-agent.yaml、准备可构建的工程副本和验证命令,还要接受模型调用费用。如果只是偶尔看一两个函数,这些投入收不回来。反过来,如果目标是成批恢复并且需要留下可复查的记录,人工流程的瓶颈恰恰在记录和复核上,这套东西才有意义。
另一类替代是更轻量的 LLM 辅助反编译,把伪代码丢给模型让它改写。差别在于没有 checker 分离、没有客观验证器、没有构建门禁,输出质量完全依赖单次生成,也没有 GREEN/YELLOW/RED 这样的判定可供复核。
许可与维护成本
仓库采用 MIT 许可,README 顶部的徽章和仓库元数据一致。MIT 允许商用和修改,具体义务以 LICENSE 文件原文为准,这里不构成法律意见。有一点值得单独确认:ReAgent 通过 bridge 调用 Ghidra,Ghidra 自身是 Apache 2.0,与 MIT 不冲突,但如果你的流程里还串联了别的组件,各自的许可需要分别核对。
维护成本主要落在三处。一是版本节奏,从 v0.2.1 到 v0.3.0 到 v0.4.0,0.4.0 引入了四个新的 manifest 子命令并改了验证命令的表示方式,说明接口还在动,锁定版本号比跟随 main 稳。二是双仓库依赖,auto-re-agent 与 ghidra-bridge 需要匹配,README 给出的从 GitHub 直接安装的写法是把两个仓库的 main 一起装,这在生产环境里风险偏高。三是 LLM provider 侧的变化,模型名和 CLI 认证方式由外部决定,re-agent.yaml 里的 provider 和 model 字段需要跟着调整。
编辑结论
适合已经在用 Ghidra、并且手头有可编译可测试的工程副本的逆向或移植团队,尤其是需要按依赖顺序批量恢复一批函数、又想留下可复查证据记录的人。不适合只想要一份可读伪代码、不打算配置构建与测试命令的读者,也不适合把 LLM 输出当成最终源码直接提交的场景。上手前先确认三件事:ghidra-bridge info 能否列出导出结果、re-agent doctor 报出的 shell 与后端状态、以及 re-agent.yaml 里 validation 段的构建和测试命令在目标平台上真的能跑通。
社区笔记