KamiKitsune420/bgt-decomp-tools

GitHub: KamiKitsune420/bgt-decomp-tools

一套用于从 BGT 引擎构建的音频游戏中恢复 AngelScript 伪源码、声音资源并支持重新打包的逆向工程工具包。

Stars: 1 | Forks: 0

# BGT 反编译工具包 从使用 **BGT** (BlastBay Gaming Toolkit),即 2010 年的音频游戏引擎构建的游戏中恢复源代码级结构和资源。 给它一个游戏可执行文件,它就会以可读的伪源码形式返回该游戏的代码、 其中包含的每一个字符串,以及它的声音。 ``` pip install -e . bgt unpack game.exe -o work/ bgt lift work/game_bytecode.bin game.exe -o game.as ``` ``` void ::main() { v1 = string("Psycho Strike"); ret = show_game_window(&v1); v1 = string("sounds.dat"); ret = v1.open(retreave); ret = reset_game(); ret = prepare_audio(); v2 = performance_debug; if (v2) { ret = start_profiling(); v1 = string("strikelog_errors.log"); ret = set_error_output(&v1); } ... ``` ## 安装 需要 Python 3.8+ 和 `pycryptodome`。 ``` pip install -e . ``` 这会为你提供一个 `bgt` 命令。你也可以不安装,直接在 `tools/` 目录中运行所有内容(`python tools/bgt_unpack.py ...`)。 ## 你可能想要的五个功能 ### 1. 从游戏中提取代码 ``` bgt unpack game.exe -o work/ ``` 生成 `work/game_bytecode.bin` —— 即解密并 解压后的游戏编译脚本。 ### 2. 阅读代码 ``` bgt lift work/game_bytecode.bin game.exe -o game.as ``` 伪源码:真实的函数名、类名、字符串字面量、`if`/`while`, 以及解析出的调用目标。这是大多数情况下你想要的。 如果你想要原始指令列表,请使用: ``` bgt disasm work/game_bytecode.bin game.exe -o game.asm ``` 仅查看单个函数: ``` bgt lift work/game_bytecode.bin game.exe -f main ``` ### 3. 查看声音包内部 ``` bgt pack list sounds.dat ``` ``` sounds.dat: v1, 975 entries, 974 encrypted, 1 distinct key ``` 如果显示 **1 distinct key**,说明一个密码就能打开整个声音包。如果显示成千上万个,说明游戏为每个文件使用了独立的密钥,这时你需要的是推导逻辑,而不是密码。 ### 4. 提取声音 你需要密钥。如果游戏的密码是其脚本中的纯字符串: ``` bgt crack sounds.dat --dict work/game_bytecode.bin --workers 0 ``` 然后执行: ``` bgt pack extract sounds.dat -o sounds/ --key ``` 如果 `crack` 什么也没找到,说明密码是经过计算而不是直接存储的——这很 常见。请阅读构建该密码的函数。`set_sound_decryption_key` 是 引擎的一部分,它没有自身的函数体,因此请查找**调用**它的代码: ``` bgt lift work/game_bytecode.bin game.exe --calls set_sound_decryption_key ``` ``` void ::prepare_audio() { ret = get_SCRIPT_COMPILED(); if (ret) { v2 = string("ZGtz9mdqa2F3ZWx0dXdGSkRLTFNKVklDMTA4MzIx..."); ret = get(&v2); // <- this transforms it ret = set_sound_decryption_key(v3, &v2); v2 = string("sounds.dat"); ret = set_sound_storage(v3); } } ``` 这就是种子以及将其转换为密钥的函数。`--calls` 也可以在 `bgt disasm` 中使用,当你拥有的名称属于 引擎而不是脚本时,这是通用的入口。 ### 5. 修改内容并重新构建游戏 ``` bgt asm work/game_bytecode.bin game.exe \ --replace sounds.dat=my_sounds.dat -o work/modified.bin bgt repack game.exe work/modified.bin -o patched.exe ``` 替换的内容长度可以不同。这两个步骤都会进行自我验证, 如果有任何异常都会拒绝写入。 ## 所有命令 | 命令 | 功能描述 | |---|---| | `bgt unpack game.exe -o work/` | 从可执行文件中恢复脚本 | | `bgt info game.exe` | 仅显示头部信息:overlay、密钥、大小 | | `bgt lift module.bin game.exe` | 输出伪源码 | | `... -f NAME` / `--calls NAME` | 输出单个函数,或调用该函数的内容 | | `bgt disasm module.bin game.exe` | 带有注释的指令列表 | | `bgt asm module.bin game.exe` | 重写模块,编辑其字面量 | | `bgt repack game.exe module.bin -o out.exe` | 将模块放回可执行文件中 | | `bgt pack list \| extract sounds.dat` | 检查或提取资源包 | | `bgt crack sounds.dat --dict module.bin` | 在脚本中搜索资源包密码 | | `bgt opcodes game.exe` | 转储引擎的操作码表 | | `bgt validate a.exe b.exe` | 对多个游戏运行整个流水线 | | `bgt ghidra status \| install \| decompile` | 设置并驱动 Ghidra | 运行 `bgt --help` 查看可用选项。 ## 你能得到什么,以及得不到什么 **你能得到**每一个函数、类、属性和枚举的**名称**,每一个字符串 字面量,完整的调用图,以及以 `if` / `while` / `break` 形式呈现的控制流。 **你得不到**局部变量名、参数名、行号或 注释。BGT 在编译时会将它们剥离,并且它们确实已经消失了——局部变量 会显示为 `v3`,参数显示为 `a0`。因此你可以忠实地重建游戏;但无法 完全恢复其原始文本。 ## 它适用于我的游戏吗? 运行: ``` bgt validate mygame.exe ``` 每个阶段都会输出 `ok` 或 `FAIL`。开发此工具所针对的三款游戏都能通过 所有阶段: | | Psycho Strike | Paladin of the Sky | Manamon 2 | |---|---|---|---| | 类 | 68 | 47 | 1,604 | | 函数 | 1,102 | 926 | 9,924 | | 已命名操作数 | 100% | 100% | 100% | | 逐字节重建 | yes | yes | yes | BGT 游戏共享同一个引擎,因此如果某个游戏失败,更有可能是遇到了此工具尚未见过的 BGT *版本*,而不是引擎被修改过。`bgt validate` 会显示是哪个阶段停止了运行。 ## 如果出现问题 **"no xproc10 trailer"** —— 不是 BGT 可执行文件,或者是打包方式不同的 BGT 版本。 **`bgt lift` 提示 "no function bodies were recovered"** —— 模块解析成功,但其函数记录未能解析。它会告诉你具体的方言以及停止的位置。 **`bgt crack` 什么也没找到** —— 这只能排除它尝试过的候选词,并且 它会打印出尝试的数量。密码很可能是计算得出的;请参阅上面的第 4 步。 **Ghidra 命令失败** —— 运行 `bgt ghidra status`。Ghidra 需要 JDK 21 或更高版本,而你 PATH 中的 `java` 往往是为其他用途保留的旧版本。 ## 文件 ``` tools/ the toolkit tests/ python -m pytest tests/ -q (124 tests, no game files needed) docs/ ghidra_workflow.md — how to read the engine's own loader CLAUDE.md the format itself, in detail, and why each part is believed ``` `CLAUDE.md` 是参考文档:加密链的工作原理、字节码 格式的布局、哪些部分是从二进制文件中读取的,哪些是推断出来的,以及 还有哪些问题尚未解决。在扩展任何功能之前,请先阅读此文档。 ## 许可证 [PolyForm Noncommercial License 1.0.0](LICENSE.md) — 版权所有 KamiKitsune420 (Adel Spence)。 简而言之:**使用它、修改它、分享它、为它做贡献** —— 仅限任何 非商业目的,包括个人使用、业余项目、研究和 教育。你必须在传递给他人的任何副本中保留许可证和 版权声明,因此你不能将其冒充为自己的作品。你**不得出售**它或 将其用于商业用途。 这是一个源码可见的许可证,而不是 OSI 批准的开源许可证;非商业 限制是其原因所在。 ## 免责声明 **本软件按“原样”提供,不提供任何形式的保证。作者不对 使用本软件产生的任何后果负责** —— 包括文件损坏、游戏安装 损坏,或你对所恢复内容进行操作而产生的任何法律后果。请参阅 [No Liability](LICENSE.md#no-liability)。 本工具旨在用于互操作性、保存和研究你拥有的游戏。它不附带 任何游戏文件或密钥 —— 它所做的一切都是基于你已经拥有的可执行文件 推导出来的。提取或重新分发特定游戏的代码或 资源在你所在地区是否合法,由你自己决定,本 工具不承担相关责任。
标签:Python, URL提取, 云资产清单, 反编译, 密码学, 手动系统调用, 无后门, 游戏引擎, 资源提取, 逆向工具, 逆向工程