4evy/thaw-content-repair
GitHub: 4evy/thaw-content-repair
修复《托尼霍克:美国荒园》Xbox 360 版 mod 因文件大小不匹配而触发脏光盘错误的专用补丁工具。
Stars: 1 | Forks: 0
# THAW 内容修复 🛹
为 **[@TiZmSpectrum](https://github.com/TiZmSpectrum)** 制作。
有时 mod 会用一个比原版稍大或稍小的文件替换游戏文件。
THAW 仍然记着旧的大小,这会导致它产生混淆,并可能
向你显示可怕的 **脏光盘 (dirty-disc)** 屏幕。
`thaw-content-repair` 解决了这种不匹配问题。将其指向你 mod 的 `Compressed`
文件夹,它将:
- 告知游戏替换文件的正确大小;
- 创建修补后的副本,同时保留你的原始文件;
- 仔细检查每个输入是否为预期的 THAW 版本;以及
- 跳过否则会阻止游戏运行的脏光盘弹窗。
简而言之:**原始游戏文件 + mod 文件夹 -> 准备好可以使用的修复后文件。**
## 快速开始
### 1. 下载或构建
你可以从
[滚动发布 (rolling release)](../../releases/tag/rolling) 下载预构建版本。如果你希望自己构建,
你需要 Meson、Ninja、C23 编译器、GLib 和 zlib。
使用 Nix,直接从此仓库构建包:
```
nix build
```
可执行文件将位于 `./result/bin/thaw-content-repair`。
对于常规的 Meson 构建:
```
meson setup build
meson compile -C build
```
想先确保一切正常?
```
meson test -C build --print-errorlogs
```
### 2. 收集你的文件
将原始的 `default.xex` 和 `compress.toc.xen` 放在当前目录中。
你还需要从解压后的 mod 中获取 `Compressed` 文件夹:
```
your-working-folder/
|-- default.xex
|-- compress.toc.xen
|-- build/
|-- thaw-content-repair
your-mod/
|-- Compressed/
```
### 3. 开始运行
```
./build/thaw-content-repair \
--content-root /path/to/your-mod/Compressed
```
如果一切检查正常,你将得到:
- `default_patched.xex`
- `compress_patched.toc.xen`
你的原始文件不会被覆盖。将修复后的文件复制到
你设置中的相应位置,然后去滑板吧。✨
## 正在修复什么?
受支持的 mod 更改了这两个文件:
| 替换文件 | 旧大小 | 新大小 |
| ------------------------------------------------- | ---------: | ---------: |
| `Pak\qb.pab.xen` | `0x1784F9` | `0x1784E0` |
| `Worlds\worldZones\z_mainmenu\z_mainmenu.pak.xen` | `0x36BF3D` | `0x36BF3F` |
THAW 将这些大小保存在 `compress.toc.xen` 中。该工具会更新它们,并更改
`default.xex` 中的一条指令,以便游戏继续运行,而不是打开
脏光盘屏幕。
第二个更改范围很广:它抑制了六种不同文件错误路径的弹窗,
而不仅仅是针对此 mod。因此,如果真正缺少或损坏的文件出现,可能也会继续运行而不会显示通常的警告。
## 自定义文件位置
你不必将所有内容都保存在同一个目录中:
```
./build/thaw-content-repair \
--binary /path/to/default.xex \
--binary-output /path/to/default_patched.xex \
--toc /path/to/compress.toc.xen \
--toc-output /path/to/compress_patched.toc.xen \
--content-root /path/to/your-mod/Compressed
```
运行 `thaw-content-repair --help` 获取完整的选项列表。
## 安全检查 🛟
方便的 `--content-root` 模式特意设计得很严格。在写入
任何内容之前,它会验证:
- 两个原始游戏文件的完整 SHA-256 哈希值;
- XEX 补丁位置、调用目标以及 XAM 导入记录;
- 两个原始 TOC 记录;以及
- 每个请求的替换文件和输出路径。
所有更改都在内存中准备就绪,然后才会打开任何一个输出。写入操作使用
GLib 一致且持久的文件替换模式,因此糟糕的第二个输入不会
让你得到一个只完成了一半的第一个输出。
修复后文件的预期哈希值为:
```
a9e1f052175538ebc0b98a43f7ff7347ce879d769e953c35075a9f9ef9bf726c default_patched.xex
921d2fe57b90694829d1332bbdefd7e69550225d705928c376ca212f622cb060 compress_patched.toc.xen
```
## 极客角落 🤓
即使不阅读本部分,你也可以愉快地使用该工具。如果地址、
PowerPC 和逆向工程文件格式是你的菜,欢迎登船。
## 高级模式
较低级别的接口可以应用受保护的字节补丁并更新其他 TOC1
记录:
```
./build/thaw-content-repair \
--binary input.bin \
--binary-output output.bin \
--patch OFFSET:EXPECTED_HEX:REPLACEMENT_HEX \
--toc input.toc \
--toc-output output.toc \
--content 'TOC\path.xen=/path/to/replacement.xen'
```
`--patch` 和 `--content` 都可以重复使用。与 `--content-root` 不同,此
模式是通用的,不需要已知的 THAW 文件哈希值。在写入任何内容之前,每个提供的
保护和 TOC 映射仍会进行验证。
## 构建和安装
### 要求
- Meson 1.3 或更新版本
- 支持 ISO C23 的编译器
- GLib 2.68 或更新版本
- zlib 1.2.9 或更新版本
- Ninja 或其他 Meson 后端
对于严格的开发构建:
```
meson setup build -Dwerror=true
meson compile -C build
meson test -C build --print-errorlogs
```
`werror` 是可选的,因此较新的编译器警告不会破坏发行版或
子项目构建。
安装可执行文件、共享库、头文件、README 和 `pkg-config`
元数据,请使用:
```
meson install -C build
```
## `libneversoft`
该仓库还构建了一个小型的、无 GLib 依赖的 C 库,用于 Neversoft QB 键
和 TOC1 缓冲区。其头文件适用于 C、C++ 和 FFI 调用者。
```
#include
uint32_t key = neversoft_qb_key("Pak\\qb.pab.xen");
size_t record_offset;
uint32_t previous_size;
NeversoftToc1Status status = neversoft_toc1_set_logical_size(
toc_bytes,
toc_byte_count,
key,
replacement_byte_count,
&record_offset,
&previous_size);
```
安装后:
```
cc example.c $(pkg-config --cflags --libs neversoft)
```
## Windows
最友好的 Windows 路线是 MSYS2 中的 UCRT64 环境:
```
pacman -S mingw-w64-ucrt-x86_64-gcc \
mingw-w64-ucrt-x86_64-glib2 \
mingw-w64-ucrt-x86_64-zlib \
mingw-w64-ucrt-x86_64-meson
meson setup build
meson compile -C build
meson test -C build --print-errorlogs
```
通过 GLib 的 Windows 命令行处理支持 Unicode 路径。
对于交叉编译,为具有
匹配的 `x86_64-w64-mingw32-*` 编译器、`pkg-config`、GLib 和 zlib 的主机包含了 `cross/windows-x86_64.ini`:
```
meson setup build-windows --cross-file cross/windows-x86_64.ini
meson compile -C build-windows
```
## 研究与参考
- [Xenia XAM 导出表](https://github.com/xenia-project/xenia/blob/master/src/xenia/kernel/xam/xam_table.inc)
- [Xenia XEX 加载器](https://github.com/xenia-project/xenia/blob/master/src/xenia/cpu/xex_module.cc)
- [Queen Bee QB 键实现](https://github.com/Nanook/Queen-Bee/blob/master/QueenBeeParser/Qb/QbKey.cs)
- [Meson 内置选项](https://mesonbuild.com/Builtin-options.html)
- [GLib 一致的文件写入](https://docs.gtk.org/glib/func.file_set_contents_full.html)
XEX 补丁
对于受支持的 `default.xex`,有一条 PowerPC 指令发生了改变: ``` VA 0x821B6514, raw XEX offset 0x1B0514 4812442C b 0x822DA940 4E800020 blr ``` 前面的指令是 `li r3,0`,因此修补后的存根返回零, 而不会进入脏光盘处理程序。Ghidra 找到了六个对该存根的条件调用,位于: ``` 0x822D3ED8 0x822D3F18 0x822D40B0 0x822D4190 0x822D4240 0x822D4498 ``` 它们涵盖了打开/大小、异步读取、查找/定位和完成错误 路径。只有 `0x822D4498` 是明确的 `0x571` 情况。 处理程序调用 XAM 序号 `0x2D9`,Xenia 将其标识为 `XamShowDirtyDiscErrorUI`。TOC1 布局
TOC1 头将其大端序记录数存储在 `+0x04` 处,将记录 表偏移量存储在 `+0x08` 处(在此文件中为 `0x20`)。记录按 QB 键排序, 每条记录 16 字节: | 记录偏移量 | 含义 | | ------------: | ------------------------------------ | | `+0x00` | 路径 QB 键 | | `+0x04` | 存储/分配范围 | | `+0x08` | 逻辑/解压后的字节数 | | `+0x0C` | 未知;在受保护的记录中为零 | 可执行文件将 `+0x04` 向上取整到 `0x800` 字节边界以进行存储工作。其 解码器和输出缓存循环会消耗 `+0x08`,这就是为什么修复仅更改 该字段的原因。 两条受保护记录的完整详细信息: | TOC 路径 | QB 键 | 记录 | 逻辑大小字段 | 原版 | 替换 | | ------------------------------------------------- | ---------: | --------: | -----------------: | ---------: | ----------: | | `Pak\qb.pab.xen` | `DF759C02` | `0xF580` | `0xF588` | `0x1784F9` | `0x1784E0` | | `Worlds\worldZones\z_mainmenu\z_mainmenu.pak.xen` | `EDC0A32A` | `0x10410` | `0x10418` | `0x36BF3D` | `0x36BF3F` |标签:Meson, Xbox 360, 客户端加密, 文件修复, 游戏模组, 补丁工具, 预握手