本仓库是对 RATS.EXE 源代码的进行中重建项目,RATS.EXE 是 Sean O'Connor 的 Rats!(1994)的原始 Windows 版本。它使用 Microsoft Visual C++ 4.1 在 wibo 下构建 Win32 可执行文件,并可在 DREAMM 中进行测试。
该实验旨在探索在小型但真实的代码库(而非玩具示例)上,本地 LLM 能将源代码重建推进到何种程度。匹配保真度仍然参差不齐,而这在此处是有益的:目标是呈现该过程及其当前局限性的真实图景,而不是隐藏棘手的函数。
函数重建仅限于本地 LLM。Codex 和 Claude 用于仓库设置和基准测试编排,但它们不允许编写或编辑重建后的源代码。
除非另有说明,所有实验均在 2024 款 MacBook Pro(配备 Apple M4 Max,16 核 CPU、40 核 GPU,128 GB 内存)上使用 Qwen3.8 27B BF16 进行。这种方法行之有效——尽管不完美,但很实用:36 个保留函数各自重建的平均记录用时为 2m 32.1s。
使用子模块克隆,或在克隆后初始化子模块:
git submodule update --init --recursive
原始可执行文件未包含在内。从 Rats! 官方页面 下载免费的 Windows 版本,并将其 RATS.EXE 放在仓库根目录中,以使用原始可执行文件和二进制比较目标。
make # build out/RATS_RE.EXE, .map, .obj, and .asm
make toolchain # download, extract, and verify Microsoft Visual C++ 4.1
make run # launch the rebuilt executable in DREAMM
make run-original # launch the preserved original RATS.EXE
make test # bounded DREAMM smoke test of the rebuilt executable
make test-original # bounded DREAMM smoke test of the original executable
make debug # start the rebuilt executable in DREAMM's debugger
make report # report similarity for every reconstructed function
make compare-func FUNC=SaveHighScores ADDR=00409092
校验和固定的 MSVC 4.1 归档、所需的 MSVC 4.1 库、wibo 兼容的 msvcrt40.dll 以及 DREAMM 4.0x21 均按需下载。它们仍是本地构建依赖(已忽略),不会被提交。
已提交的 ghidra/ 目录包含全部 177 个内部函数的汇编和反编译器导出。汇编是比较的权威依据;反编译的 C 代码仅作为语义种子。
先安装一次 binary-recons,然后从仓库根目录运行:
python3 -m pip install -e /path/to/binary-recons
binary-recons --next-function # reconstruct the next safe missing target
binary-recons --address 0x409092 # reconstruct or improve a specific target
该工具会在标准 Hugging Face 缓存中自动发现 Qwen;BINARY_RECONS_MODEL_PATH 可以覆盖该路径。binary-recons.toml 将自动选择保持在游戏代码范围内,启动和停止 llama.cpp,并定义事务性文件和 binary-comp 命令。每次有界运行都会以 Ghidra 中的一个函数作为种子,要求 Qwen 进行有针对性的编译或汇编差异修复,并保留最佳的安全可编译候选。使用 --target-score 95 进行更深入的遍历,或使用 --dry-run-prompt 在不加载 Qwen 的情况下检查提示词。
已测量的本地模型运行记录在 docs/MODEL_RESULTS.md 中。
大多数保留的候选代码是使用 Unsloth 的 Qwen3.8 27B GGUF 以 BF16(Qwen3.8-27B-BF16,以 qwen3.8-27b-bf16 提供服务)格式生成的,通过 llama.cpp 运行,使用 32,768 token 的上下文和 qwen 模型预设。当前工作流程机械地使用 Ghidra 的反编译结果作为种子,仅要求 Qwen 提供有意义的函数契约和有界的源代码编辑,将有效编辑作为修复轨迹,并保留由 binary-comp 衡量的最佳结果。Gemma 4 31B IT BF16 也进行了基准测试,但其候选代码均未保留在源代码树中。
以下分数于 2026-08-16 使用 MSVC 4.1 和 binary-comp 从当前源代码树重新测量。记录时长包括受管服务器启动、生成或修复、构建以及对保留候选代码的比较。它不包括不成功的探索性运行,以及在已产生可恢复候选代码之后进行的修复轮次;这些仍可在运行日志中查阅。
| 地址 | 函数 | 当前相似度 | 记录时长 |
|---|---|---|---|
0x0040215C | IsLevelIndexInRange | 65.31% | 3m 06.4s |
0x00402205 | ShowLevelComplete | 93.96% | 5m 26.1s |
0x0040250C | SubmitHighScore | 97.37% | 1m 49.7s |
0x004026D0 | RenderScoreboard | 95.40% | 2m 30.9s |
0x00402BF3 | AddLevelToTable | 73.85% | 4m 04.6s |
0x00402DC6 | UpdateGameDisplay | 78.18% | 1m 36.4s |
0x00402EE7 | GetLevelDisplayInfo | 71.70% | 2m 15.9s |
0x00402FD5 | GetLevelIndex | 87.27% | 5m 48.3s |
0x00403430 | IsBombAtLevel | 80.62% | 27.3 s |
0x00403607 | PlaceLevel | 80.00% | 2m 32.6s |
0x00404764 | DrawLevelIndicator | 97.33% | 1m 35.6s |
0x0040499F | RenderCornerGlyph | 69.83% | 1m 50.9s |
0x00404D6E | DrawBitmapPair | 98.67% | 1m 04.6s |
0x00404E3B | RenderBitmapToWindow | 94.74% | 26.4 s |
0x00404ECE | DrawBitmapToWindow | 95.59% | 59.3 s |
0x00404F8B | DrawScore | 96.20% | 1m 32.4s |
0x0040507F | DrawScorePanel | 97.97% | 2m 45.0s |
0x0040525D | DrawScoreDigits | 94.20% | 2m 13.7s |
0x00405343 | RenderScoreOverlay | 77.78% | 1m 28.1s |
0x0040546B | DrawFrameBorder | 84.93% | 37.0 s |
0x0040552E | ExplodeBomb | 64.71% | 1m 50.9s |
0x0040560E | RenderExplosionWave | 85.07% | 5m 40.0s |
0x0040591A | DrawBombExplosion | 89.31% | 1m 45.8s |
0x00405AF5 | DrawPausedOverlay | 96.21% | 1m 05.1s |
0x00405C52 | HighScoreDialogProc | 79.82% | 41.5 s |
0x00405DB8 | ScorePanelDialogProc | 50.34% | 1m 53.1s |
0x00405F72 | DemoVersionDialogProc | 46.31% | 4m 18.5s |
0x004061D3 | OrderDialogProc | 53.16% | 10m 46.5s |
0x00408854 | DrawStartButton | 70.80% | 1m 35.6s |
0x00408A51 | UpdateMainMenuState | 97.56% | 28.9 s |
0x00408AD3 | InitializeGameLevel | 83.72% | 5m 35.7s |
0x00408E6A | LoadLevelData | 77.50% | 52.5 s |
0x00408F02 | LoadHighScores | 79.61% | 1m 15.0s |
0x00409092 | SaveHighScores | 94.12% | 1m 25.9s |
0x0040910C | LoadLevelBitmaps | 98.93% | 7m 08.4s |
0x00409DB6 | IsRatsHelpFile | 91.67% | 41.5 s |
以下地址的重建尝试已用尽,未保留任何源代码实现。花费时间为所有记录尝试的累计值。
| 延后地址 | 花费时间 | 结果 |
|---|---|---|
0x00401000 | 10m 29.7s | 函数过大,无法进行有界的首次遍历;保留了原始 1.13% 的骨架 |
0x00403840 | 13m 10.0s | 没有可编译的候选;过大,无法进行快速有界遍历 |
0x00406674 | — | 已跳过:过大,无法进行快速有界遍历 |
特别感谢: