rea-reverse

Inspect Godot PCK Assets and Verify Extracted Bytes with REA

Written for REA 6.8.0Published by rea-reverseUpdated 3 min read
On this page

rea inspect-artifact game.pck --json lists the files a Godot PCK declares and checks each member’s bytes against the pack’s MD5; rea extract-artifact writes them out with a SHA-256 per file, without launching the game. REA is a third-party open-source analysis tool. Keep apart three things it reports: the path Godot stored, the relative path used for extraction, and the hash of the bytes actually read. To recover scenes and scripts from a real game, use a dedicated tool such as GDRE Tools; this page is about verifying the bytes.

Test setup: REA 6.8.0, Node 24.22.1, macOS arm64, and a 197-byte hand-built format-2 PCK with one plain-text member (the header’s engine version 4.4.1 is a written value; this is not a Godot export). Two variants show a checksum mismatch and an all-zero MD5.

The sample ZIP includes all three PCKs, the generator, a manifest and provenance notes. Its SHA-256 is 6f3fec1e029ff1802a2d3a90a20d4f5a54bf1d5143016349cd052e7b022ee76b. Run the commands from the extracted directory.

Inventory PCK assets and check integrity evidenceSilent walkthrough with English captions.

1. Inventory the pack

Start with the unchanged sample:

rea inspect-artifact fixture.pck --json

The command exited with code 0 and reported root_format: "godot-pck". The top-level inspection contains an inventory Evidence record under normalized_result.substeps; its own evidence.normalized_result holds nodes, occurrences and coverage.

For this sample, the inventory contained two nodes and two occurrences: the pack itself and its single member. The root occurrence recorded format version 2, one declared file, directory_status: "available" and embedded: false. The pack’s SHA-256 was:

3a1301cdd0b50843204f1903e959d22d328c7885ac70ef000799041b7a1675f3

2. Separate source paths, output paths and hashes

The member occurrence and linked content node supplied different kinds of facts:

Field Observed value What it identifies
source_path res://notes/readme.txt Original directory declaration
logical_path notes/readme.txt Relative lookup/extraction path
source_location Offset 164, length 33 Member bytes in this pack
declared_integrity.algorithm md5 Container checksum algorithm
hash_status verified Result for this member

The declared MD5 was 68b695818cf1dc7b679c5d3eb6a7654d. The content node recorded 33 bytes and SHA-256 0f55f0e01a41b89400c18da046c50cf4d91096c86b08ee779600f0114b5eb712.

These hashes answer different questions. The MD5 originates in the container’s directory; REA checks that claim against the member bytes. The SHA-256 identifies the observed content. Neither establishes who created the pack or whether its contents are safe. Keep the occurrence’s artifact_id when joining it to a content node instead of assuming that two arrays share the same order.

The released PCK documentation explains the source/logical-path distinction and the separation of declared integrity from observed content identity.

3. Extract and compare the member

Run:

rea extract-artifact fixture.pck --json

It exited with code 0. normalized_result.output_root points to a new temporary directory whose name changes per run.

The artifacts array contained one entry: relative_path: "notes/readme.txt", bytes_written: 33 and the same SHA-256 as the inventory’s content node. containment_verified was true. A separate byte comparison confirmed the extracted file matched the generator’s original 33-byte payload. REA copies member bytes as stored; it does not convert Godot resources. Keep the original pack and the JSON next to the extracted files so each output can be traced back.

4. Read an integrity failure

mismatch.pck changes one payload byte while keeping the original MD5 declaration. Inspect it with the default policy:

rea inspect-artifact mismatch.pck --json

The command exited with code 1 and code: "artifact_integrity_mismatch". Its details identified notes/readme.txt and the disagreement:

Digest Value
Declared MD5 68b695818cf1dc7b679c5d3eb6a7654d
Calculated MD5 55e17d1b304dbfe1c7609bc693b99de3

For this deliberately modified fixture, we also ran:

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

That run exited with code 0, but did not repair the pack or make the discrepancy disappear. The member remained hash_status: "mismatched"; integrity_contradictions recorded trust: "observed-untrusted". It retained the modified content’s SHA-256 as 57d3d754f89615fcb2509d29ddb41e2b9ae1a844ee5dd5424098c487c7c0633f. Use this mode to record a known contradiction, not as a pass.

5. Keep unknown integrity explicit

The third sample preserves the original payload but declares an all-zero MD5:

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

It exited with code 0. The member still had hash_status: "verified" and the same observed SHA-256 as the original payload, but there was no declared_integrity field. Instead, format_metadata.md5_status was "all-zero" and a member limitation explicitly marked source integrity as unknown.

So verified alone is not enough: check whether declared_integrity exists. Here the bytes have a known hash but the pack made no usable MD5 claim.

REA’s 6.8.0 guide documents ordinary PCK formats 2–4, with format 1 unsupported, and describes encrypted entries as a boundary rather than something it decrypts. We tested only the standalone format-2 fixture and its two variants, not formats 3/4, packs embedded in an executable, encryption or a real export. It does not decompile GDScript or recover keys. For Electron’s packaged-asset format, see ASAR extraction.