Muhtasham/decomp-goal-harness

GitHub: Muhtasham/decomp-goal-harness

面向 Codex 风格 Agent 的匹配反编译工作流编排工具,通过「编译-比对-编辑」循环驱动 AI 产出与原始二进制字节一致的源码。

Stars: 3 | Forks: 0

# decomp-goal-harness ## 关于 `decomp-goal-harness` 是一个轻量级的命令行工具,用于运行 Agent 驱动的匹配反编译目标。它有助于发现未完成的反编译目标,生成限定范围的 Codex 目标提示词,运行本地构建/diff 神谕工具,存储结构化的进度记录,并渲染一个小型进度仪表盘。 它专为硬核模式匹配项目设计,其目标是编写出能够编译回与原始二进制文件完全相同的 C/C++ 源代码。该工具不包含游戏资产,不修补二进制文件,也不自行进行反编译。它为 Codex 风格的 Agent 提供了一个紧凑、可重复的“编译-比对-编辑”循环。 预期的工作流与专注的 Codex `/goal` 运行形态相同,其灵感来自 [banteg](https://x.com/banteg) 公开的《风之杖》 匹配反编译实验。 1. 选择一个翻译单元 或函数, 2. 配置/构建本地反编译项目, 3. 运行项目神谕工具(`objdiff`、进度报告或自定义评分命令), 4. 进行小幅源代码编辑, 5. 仅提交可衡量的改进。 ## 本地安装 ``` uv sync ``` 或者,不安装直接运行: ``` uv run decomp-goal --help ``` 源码检出的玩具演示还需要本地 C 编译器可用作 `cc`。 ## 开发检查 代码仓库使用 Ruff 进行代码检查/格式化,ty 进行类型检查,以及 pre-commit 进行本地钩子管理。 ``` uv sync --dev uv run ruff check . uv run ruff format --check . uv run ty check . uv run pre-commit run --all-files ``` 安装本地 git 钩子: ``` uv run pre-commit install ``` ## 命令 从 decomp.dev 发现活跃项目: ``` decomp-goal projects --platform gc --query "Wind Waker" ``` 查找候选的 GitHub 任务议题: ``` decomp-goal issues --github zeldaret/tww --label "easy object" --unclaimed ``` 检查工作树: ``` decomp-goal inspect --repo /path/to/project ``` 列出 DTK/ZeldaRET 风格项目中的非匹配候选目标: ``` decomp-goal targets --repo /path/to/tww --limit 20 decomp-goal targets --repo /path/to/tww --rank --limit 20 ``` 筛选特定模块: ``` decomp-goal targets --repo /path/to/tww --query d_a_obj_mmrr ``` 渲染限定范围的 `/goal` 提示词: ``` decomp-goal goal \ --repo /path/to/tww \ --unit src/d/actor/d_a_obj_mmrr.cpp \ --name "Mirror object" \ --issue https://github.com/zeldaret/tww/issues/423 ``` 运行一次配置/构建/评分过程并写入 JSON 运行记录: ``` decomp-goal run --repo /path/to/project --unit attempt.c ``` 运行记录默认写入仓库的 Git 元数据路径下,例如 `.git/decomp-goal/runs/`,因此该工具不会弄脏反编译工作树。 本代码仓库包含一个连接到玩具神谕的根 `decomp-goal.toml`,因此该工具可以审计自身: ``` uv run decomp-goal gaps --repo . uv run decomp-goal run --repo . --unit attempt.c ``` 查看运行历史: ``` decomp-goal history --repo /path/to/project ``` 以最新的神谕记录作为进度提交的门控条件: ``` decomp-goal checkpoint --repo /path/to/project decomp-goal checkpoint --repo /path/to/project --commit ``` `--commit` 仅在最新保存的运行记录优于以往历史时,才暂存并提交当前未提交的工作树。请在执行一次新的 `decomp-goal run` 之后使用它,而不是将其作为神谕的替代品。 检查点还会验证当前的工作树指纹是否与最新的神谕记录匹配,因此过期的成功运行无法授权不相关的编辑。 询问该工具 Agent 是否陷入停滞以及下一步该怎么做: ``` decomp-goal coach --repo /path/to/project ``` 分类当前的 diff 并生成下一个线索: ``` decomp-goal lead --repo /path/to/project --unit attempt.start.c decomp-goal lead --repo /path/to/project --unit attempt.start.c --diff-json objdiff-export.json --diff-format objdiff ``` 编写一个有界限的最后冲刺实验队列: ``` decomp-goal experiments --repo /path/to/project --unit src/d/actor/d_a_obj_mmrr.cpp ``` 批量测试源代码补丁变体并恢复失败的变体: ``` decomp-goal variants \ --repo /path/to/project \ --unit src/d/actor/d_a_obj_mmrr.cpp \ --patch-dir .git/decomp-goal/variants ``` 仅当您希望在批处理后保留应用的最佳改进补丁时,才使用 `--keep-best`。 记录来自人类、Ghidra、IDA、Binja、GPT-Pro 或 objdiff 的外部引导线索: ``` decomp-goal steer \ --repo /path/to/project \ --unit src/d/actor/d_a_obj_mmrr.cpp \ --source ida \ --text "Decompiler agrees on the if/else shape; remaining delta looks like temp lifetime before the call." ``` 记录结构化的反编译器输出,并比较不同工具间的一致性: ``` decomp-goal decompilers \ --repo /path/to/project \ --unit src/d/actor/d_a_obj_mmrr.cpp \ --function create__6daPz_cFv \ --source ghidra \ --file ghidra-create.c \ --notes "IDA and Binja agree on branch shape; remaining delta smells like stack temp lifetime." decomp-goal decompilers --repo /path/to/project --unit src/d/actor/d_a_obj_mmrr.cpp ``` 针对 banteg 风格的循环审计当前工作流的不足: ``` decomp-goal gaps --repo /path/to/project ``` 在长时间的 tmux/Codex 会话旁运行一个轻量级监控器: ``` decomp-goal monitor \ --repo /path/to/project \ --unit src/d/actor/d_a_obj_mmrr.cpp \ --dashboard-out .git/decomp-goal/dashboard.html \ --interval 300 \ --max-ticks 999 ``` 使用 `--json` 参数,监控器将输出一个包含所有记录的有效 JSON 数组。 生成本地的 banteg 风格进度仪表盘: ``` decomp-goal dashboard --repo /path/to/project --title "Princess Zelda TU Progress" ``` 仪表盘会跟踪确切的函数、匹配的代码、模糊分数、阻碍因素,以及来自存储运行记录的提交/HEAD 更改标记。 编写目标提示词并打印 Codex CLI 运行器命令: ``` decomp-goal codex \ --repo /path/to/tww \ --unit src/d/actor/d_a_obj_mmrr.cpp \ --name "Mirror object" \ --issue https://github.com/zeldaret/tww/issues/423 \ --reasoning-effort xhigh \ --mode tmux \ --session tww-mmrr ``` ## 适配器 ### 通用 TOML 适配器 如果代码仓库中存在 `decomp-goal.toml`,该工具会从中读取 shell 命令: ``` [project] name = "toy-match" adapter = "generic" default_unit = "attempt.c" [commands] build = "uv run --project ../.. python3 score.py --candidate {unit} --build-only" score = "uv run --project ../.. python3 score.py --candidate {unit} --json" diff = "uv run --project ../.. python3 score.py --candidate {unit} --diff" ``` 评分命令应打印出至少包含以下内容的 JSON: ``` { "matched": true, "score": 1.0 } ``` ### DTK / ZeldaRET 适配器 对于包含 `configure.py` 和 `tools/project.py` 的项目,该工具会检测出 DTK 风格的项目并运行: ``` python3 configure.py ninja -v python3 configure.py progress ``` 它还会解析 `configure.py` 中的 `Object(NonMatching, "...")`、`Object(Equivalent, "...")` 以及 ZeldaRET 风格的 `ActorRel(NonMatching, "...")` 条目,以生成候选目标。 该工具不会获取或创建原始游戏输入。如果项目需要合法获取的游戏镜像或提取的文件,运行记录将报告 `missing_original_input`,而不是掩盖这一事实。 ## 玩具演示 `examples/toy_match` 是一个无版权问题的微型匹配项目,用于本代码仓库的源码检出。它使用固定标志编译 `original.c` 和候选 C 文件,比较生成的目标字节,并报告精确/模糊分数。 完全匹配: ``` uv run decomp-goal run --repo examples/toy_match --unit attempt.c ``` 已知的不匹配: ``` uv run decomp-goal run --repo examples/toy_match --unit attempt.start.c ``` 此测试夹具证明该工具的循环无需商业游戏镜像。真正的 ZeldaRET 项目仍使用项目神谕,通常是 `objdiff`。 生成玩具仪表盘: ``` uv run decomp-goal dashboard --repo examples/toy_match --title "Toy Match Progress" ``` ## 运行器模型 该工具不需要拥有 Codex。它创建任务数据包并记录神谕结果;Codex 只是其中一个运行器。 使用 `codex exec` 进行有界限的非交互式运行: ``` uv run decomp-goal codex --repo /path/to/tww --unit src/d/actor/d_a_obj_mmrr.cpp --mode exec ``` 使用 `tmux` 加上交互式 Codex 进行需要引导的长匹配会话: ``` uv run decomp-goal codex --repo /path/to/tww --unit src/d/actor/d_a_obj_mmrr.cpp --mode tmux --session tww-mmrr --launch ``` tmux 路径更接近 banteg 的工作流:让 Agent 运行,检查仪表盘/历史,并在其于近乎匹配或布局级联之后陷入停滞时注入引导。生成的提示词写在仓库的 Git 元数据路径下,以便在不创建未跟踪文件的情况下对其进行审查或重用。 对于常规的深度运行使用 `--reasoning-effort high`,对于更强的假设比成本/延迟更重要的最后冲刺阶段,使用 `--reasoning-effort xhigh`。 ## Banteg 启发的循环 该工具围绕 banteg 在《风之杖》 `d_a_pz` 运行中展示的工作流进行设计: - 一次设定一个翻译单元目标, - 不使用伪造匹配或禁止的反编译技巧, - 每次有意义的编辑后进行编译/diff/评分, - 仅提交确切的改进、模糊分数的改进或结构布局的解锁, - 在 Agent 卡住时注入外部线索:人类笔记、GPT-Pro 笔记、Ghidra、IDA、Binja、objdiff、调试映射, - 将突然出现的精确函数匹配跳跃视为可能的布局级联,直到被证明, - 在卡住时记录剩余的未匹配类别:字符串池、重定位、分支形状、寄存器分配、弱符号/模板排序、内联、缺失类型或缺失原始输入。 该工具从设计上是一个神谕包装器,而不是一个自主的源代码修改器。`/goal` Agent 可以消费其目标列表、目标数据包、JSON 运行记录和仪表盘,同时在项目工作树中进行实际的源代码编辑。 ## 减少最后冲刺的痛苦 痛苦的部分始于翻译单元 (TU) 几乎正确,但仍有少数一两个函数拒绝匹配之时。该工具试图通过强制推行更机械的循环来减轻这种痛苦: 1. `decomp-goal lead` 将 diff 分类为未匹配类别,如字符串池、分支形状、寄存器分配、重定位/调用目标、栈帧、常量/类型或未知类别。 2. 当项目可以导出时,`decomp-goal lead --diff-json` 会提取结构化的 objdiff/asm-differ 风格 JSON。 3. `decomp-goal experiments` 在仓库的 Git 元数据路径下编写一份每次只测试一个假设的变体清单。 4. `decomp-goal variants` 逐个应用补丁文件,运行神谕,记录指标,并恢复未保留的变体。 5. `decomp-goal coach` 监视运行历史以寻找高分瓶颈期,并在 Agent 陷入停滞时告诉其停止大范围重写。 6. `decomp-goal monitor` 在 tmux 会话期间定期运行该指导循环,并在需要干预时写入引导提示词。 7. `decomp-goal steer` 和 `decomp-goal decompilers` 存储外部线索,并将最新的线索注入到下一次生成的 `/goal` 提示词中。 8. `decomp-goal checkpoint` 使“提交每一项改进”变得机械化:它将最新运行与以往历史进行比较,仅当神谕有所改进时才允许提交。 这并不能消除困难的部分,但它可以防止 Agent 在达到 99% 之后随机游走。预期的行为是:首先分类,尝试有界限的变体,恢复失败,仅保留神谕改进的成果,并在相同的未匹配类别经历数次变体后,请求人类/反编译器/调试映射的线索。 剩余的非代码边界是原始游戏输入。该工具会特意报告 `missing_original_input`;它不会获取、生成或绕过受版权保护的游戏素材。 ## 致谢 核心概念和工作流灵感来自:[banteg on X](https://x.com/banteg) / [banteg on GitHub](https://github.com/banteg),尤其是公开的《风之杖》 匹配反编译运行,展示了限定范围的 `/goal` Agent 在此问题上的契合度之高。 ## TWW 目标数据包示例 ``` Get `src/d/actor/d_a_obj_mmrr.cpp` / Mirror object to 100% matching without fakematching or forbidden decomp tricks, with validation in the local worktree. Rules: - Use source-level decompilation changes; do not patch generated/original binaries. - Prefer the project’s existing macros, typedefs, headers, and naming style. - Make small commits only for measurable improvements. - Do not mark a function or TU matching unless the local diff/build oracle proves it. - When stuck, classify the mismatch: layout, string pool, branch shape, regalloc, weak/template ordering, relocation, inline, missing type, or missing original input. ``` ## 当前预期的首个真正目标 对于《风之杖》,一个干净的首个目标是: - 上游代码仓库:`zeldaret/tww` - Fork:`Muhtasham/tww` - 目标议题:https://github.com/zeldaret/tww/issues/423 - 单元:`src/d/actor/d_a_obj_mmrr.cpp` 在真正的 TWW 匹配循环运行之前,本地的 TWW 工作树需要在 `orig/GZLE01/` 下提供用户自备的原始输入,正如上游 README 中所述。
标签:C/C++, CLI, Codex, Decompilation, diff oracle, objdiff, Python, Python安全, Ruff, URL提取, uv, WiFi技术, Wind Waker, ZeldaRET, 事务性I/O, 二进制分析, 二进制发布, 云安全监控, 云安全运维, 云资产清单, 代码对比, 任务自动化, 匹配反编译, 反编译, 安全可观测性, 开源工具, 无后门, 游戏逆向, 源码还原, 版本控制, 网络安全研究, 自动化构建, 逆向工具, 逆向工程, 静态分析