rea-reverse

用 REA 检查 Godot PCK 资源,并核对解出的字节

基于 REA 6.8.0发布者 rea-reverse更新于 约 3 分钟读完
本页目录

rea inspect-artifact game.pck --json 会列出 Godot PCK 声明的文件,并用包里的 MD5 核对每个成员的字节;rea extract-artifact 把它们写出来,每个文件附 SHA-256,全程不启动游戏。REA 是第三方开源分析工具。它报告的三样东西要分开看:Godot 存储的路径、提取用的相对路径、实际读到的字节的哈希。想从真实游戏里还原场景和脚本,请用 GDRE Tools 这类专门工具;本文只讲核对字节。

测试环境:REA 6.8.0、Node 24.22.1、macOS arm64,样本是一个 197 字节、手工构造的格式 2 PCK,只有一个纯文本成员(头部的引擎版本 4.4.1 是写进去的,并非 Godot 导出)。另两个变体分别演示 MD5 不一致和全零 MD5。

样本 ZIP包含三个 PCK、生成器、清单和来源说明。ZIP 的 SHA-256 为 6f3fec1e029ff1802a2d3a90a20d4f5a54bf1d5143016349cd052e7b022ee76b。解压后在该目录运行命令。

1. 盘点包内目录

先检查未修改的样本:

rea inspect-artifact fixture.pck --json

命令退出码为 0,root_format 为 "godot-pck"。顶层 inspection 的 normalized_result.substeps 中包含 inventory Evidence;它自己的 evidence.normalized_result 下有 nodes、occurrences 和 coverage。

本例包含两个 node 和两个 occurrence,分别对应包本身和唯一的成员。根 occurrence 记录格式版本 2、声明文件数 1、directory_status: "available" 和 embedded: false。整个 PCK 的 SHA-256 为:

3a1301cdd0b50843204f1903e959d22d328c7885ac70ef000799041b7a1675f3

2. 区分原路径、输出路径和哈希

成员 occurrence 与其关联的内容 node 提供的是不同事实:

字段 实际值 含义
source_path res://notes/readme.txt 目录中的原始声明
logical_path notes/readme.txt 查找和提取使用的相对路径
source_location 偏移 164,长度 33 本包内成员字节的位置
declared_integrity.algorithm md5 容器声明的校验算法
hash_status verified 此成员的结果状态

声明的 MD5 是 68b695818cf1dc7b679c5d3eb6a7654d。内容 node 记录大小为 33 字节,SHA-256 为 0f55f0e01a41b89400c18da046c50cf4d91096c86b08ee779600f0114b5eb712。

两种哈希回答的问题不同。MD5 来自容器目录,REA 用读取到的成员字节核对该声明;SHA-256 标识实际观察到的内容。它们都不能证明包的作者是谁,也不能证明内容安全。关联 occurrence 和内容 node 时,使用 artifact_id,不要假设两个数组的顺序一一对应。

发布版 PCK 文档说明了原路径与逻辑路径的区别,以及完整性声明和观察到的内容身份之间的区别。

3. 提取并核对成员

执行:

rea extract-artifact fixture.pck --json

退出码为 0。normalized_result.output_root 指向新建的临时目录,每次运行名字都不同。

artifacts 数组只有一个条目:relative_path: "notes/readme.txt"、bytes_written: 33,SHA-256 与 inventory 中的内容 node 相同。containment_verified 为 true。另做的字节比较也确认,解出的文件与生成器的原始 33 字节 payload 一致。REA 按原样复制成员字节,不做 Godot 资源转换。把原始 PCK 和 JSON 结果与解出的文件放在一起,方便追溯。

4. 读取完整性失败

mismatch.pck 修改了一个 payload 字节,却保留原 MD5 声明。先使用默认策略检查:

rea inspect-artifact mismatch.pck --json

命令退出码为 1,错误码为 "artifact_integrity_mismatch"。details 指向 notes/readme.txt,给出了差异:

摘要 值
声明 MD5 68b695818cf1dc7b679c5d3eb6a7654d
计算 MD5 55e17d1b304dbfe1c7609bc693b99de3

针对这个故意修改的样本,我们又运行了:

rea inspect-artifact mismatch.pck --integrity-policy record-and-continue --json

这次退出码为 0,但没有修复包,也没有消除矛盾。成员仍是 hash_status: "mismatched",integrity_contradictions 中记录 trust: "observed-untrusted"。修改后内容的 SHA-256 被保留为 57d3d754f89615fcb2509d29ddb41e2b9ae1a844ee5dd5424098c487c7c0633f。这个模式用来记录已知矛盾,不代表校验通过。

5. 保留未知完整性事实

第三个样本保持原 payload,但把 MD5 声明设为全零:

rea inspect-artifact unknown-md5.pck --json

退出码为 0。成员仍有 hash_status: "verified",观察到的 SHA-256 也与原 payload 相同,但没有 declared_integrity 字段。相应地,format_metadata.md5_status 为 "all-zero",成员 limitation 明确说明来源完整性未知。

所以光看 verified 不够,还要看有没有 declared_integrity:这里字节的哈希是确定的,但包里没有可用的 MD5 声明。

REA 6.8.0 文档记录普通 PCK 格式 2–4 的支持范围,不支持格式 1;加密条目属于能力边界,REA 不负责解密。本次只测了独立的格式 2 样本及两个变体,没有测格式 3/4、嵌在可执行文件里的包、加密或真实导出。它也不反编译 GDScript、不恢复密钥。Electron 的资源封装格式见 ASAR 解包。