[GH-ISSUE #3633] [Feature] Godot PCK inspection and extraction as an artifact reader #1357

Closed
opened 2026-10-16 21:04:37 +00:00 by bsakaguchi · 6 comments
Owner

Originally created by @0xthearchitect on GitHub (Oct 14, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/3633

Area: Evidence, artifacts, or reconstruction
Expected interaction with targets: Read existing files or captured data
Verification available so far: I have a prototype or observed results

Current limitation

REA has no support for Godot Engine games. A Godot export is usually a native executable with an embedded PCK archive (trailer magic GDPC), or a standalone .pck. The game's scenes (.tscn/.scn), scripts (GDScript, often compiled to bytecode), resources and data all live inside that archive.

Today the only path is native analysis of the executable. That analysis only sees the Godot engine, not the game. On large exports it is also impractical. In my case a 1.6 GB Godot 4.6.1 export was killed by the kernel OOM killer when Ghidra's JVM reached about 3.9 GB of resident memory during import, before any findings were produced.

Desired outcome and success criteria

  • inspect-artifact recognizes a standalone .pck, or a PCK embedded in an ELF/PE/Mach-O executable. It reports the following as observed facts with Evidence:
    • format version and engine version (major, minor, patch);
    • pack flags, including whether the directory or files are encrypted;
    • file base offset and file count;
    • the entry inventory: res:// path, offset, size and MD5.
  • extract-artifact extracts unencrypted entries through the existing safe output tree, verifying the per-entry MD5 when present.
  • Encrypted packs and entries are reported as encrypted and their contents stay unknown. There is no decryption and no key handling.
  • Bounded parsing: fail-closed on truncated or overflowing tables, with entry counts and string lengths validated against the file size before allocation.

Alternatives considered

  • Native analysis (Ghidra/IDA): sees only the engine, and the cost is dominated by the embedded data (see above).
  • External tools such as GDRE Tools (gdsdecomp): they recover full projects. However, they bundle the Godot runtime, perform lossy resource conversions and produce no Evidence provenance. They are a useful manual oracle, not a REA workflow.

Possible direction

Add a PckArtifactReader next to AsarArtifactReader/ZipArtifactReader, so that inventory, inspection and extraction reuse the existing ownership, resource-scope and safe-output code.

The PCK format is open source, so it can be checked against the reference implementation (Godot core/io/file_access_pack.cpp, format versions 1–3). Embedded packs are located via the trailer (GDPC magic plus a 64-bit offset at the end of the file), or via the pck section for ELF/PE exports.

Out of scope for this first step, as possible separate proposals:

  • decoding binary resources (.scn/.res) to text;
  • decompiling GDScript bytecode;
  • any PCK decryption.

Verification

  • Synthetic fixtures built in-test following the exporter layout (no committed binaries).
  • Manual check against packs produced by a real writer (GDRE Tools --pck-create). A pack exported by the official Godot editor is still to do.
  • No commercial game samples are needed or would be shared.

Prototype results

A draft prototype (GodotPckArtifactReader, plus godot-pck in the format enums, classification, inventory and extraction) is on a branch. This is not a request to integrate; it exists to inform the scope decision.

  • inspect-artifact and extract-artifact work end to end on standalone .pck files produced by GDRE Tools (--pck-create, formats 2 and 3, engine 4.6.1).
  • Running the reader directly on a real 1.6 GB Godot 4.6.1 Linux export (embedded format 3 pack, 3937 members):
    • every member was listed and read with its declared MD5 verified;
    • 1,603,593,586 member bytes in 3.4 s, peak RSS 173 MiB (warm page cache, single run).
    • Ghidra was OOM-killed on the same file at about 3.9 GB.
  • 14 synthetic unit cases: formats 2 and 3, standalone and embedded, MD5 contradiction, encrypted member, encrypted directory, sparse bundle, patch removal entry, member-count overflow, out-of-range data, format 1, and a missing or bad trailer.
  • check:fast and docs:check pass; the artifact/domain/contract/application suites pass (4334 tests).

Known prototype limits:

  • An executable with an embedded pack still classifies as ELF/PE. Exposing the embedded pack as a child container of the executable is an open design question.
  • The MD5 is verified on read and fails closed. It is not surfaced as declared integrity, because ArtifactEntry only carries SHA-256, so record-and-continue does not apply to it yet.
  • Format 1 (Godot 3) is refused as unsupported rather than guessed.

Questions for maintainers

  1. Is a Godot PCK reader in scope as format inspection plus ordinary archive extraction?
  2. Should it surface through inspect-artifact/extract-artifact, or through a dedicated inspect-godot-pack operation?
  3. Is reporting encrypted entries as unknown (no decryption) the right boundary?
  4. Should an executable with an embedded pack expose it as a child container in its inventory, and should ArtifactEntry gain a declared-digest algorithm so the MD5 participates in integrity policy?
Originally created by @0xthearchitect on GitHub (Oct 14, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/3633 **Area:** Evidence, artifacts, or reconstruction **Expected interaction with targets:** Read existing files or captured data **Verification available so far:** I have a prototype or observed results ### Current limitation REA has no support for Godot Engine games. A Godot export is usually a native executable with an embedded PCK archive (trailer magic `GDPC`), or a standalone `.pck`. The game's scenes (`.tscn`/`.scn`), scripts (GDScript, often compiled to bytecode), resources and data all live inside that archive. Today the only path is native analysis of the executable. That analysis only sees the Godot engine, not the game. On large exports it is also impractical. In my case a 1.6 GB Godot 4.6.1 export was killed by the kernel OOM killer when Ghidra's JVM reached about 3.9 GB of resident memory during import, before any findings were produced. ### Desired outcome and success criteria - `inspect-artifact` recognizes a standalone `.pck`, or a PCK embedded in an ELF/PE/Mach-O executable. It reports the following as observed facts with Evidence: - format version and engine version (major, minor, patch); - pack flags, including whether the directory or files are encrypted; - file base offset and file count; - the entry inventory: `res://` path, offset, size and MD5. - `extract-artifact` extracts unencrypted entries through the existing safe output tree, verifying the per-entry MD5 when present. - Encrypted packs and entries are reported as encrypted and their contents stay unknown. There is no decryption and no key handling. - Bounded parsing: fail-closed on truncated or overflowing tables, with entry counts and string lengths validated against the file size before allocation. ### Alternatives considered - **Native analysis (Ghidra/IDA):** sees only the engine, and the cost is dominated by the embedded data (see above). - **External tools such as GDRE Tools (gdsdecomp):** they recover full projects. However, they bundle the Godot runtime, perform lossy resource conversions and produce no Evidence provenance. They are a useful manual oracle, not a REA workflow. ### Possible direction Add a `PckArtifactReader` next to `AsarArtifactReader`/`ZipArtifactReader`, so that inventory, inspection and extraction reuse the existing ownership, resource-scope and safe-output code. The PCK format is open source, so it can be checked against the reference implementation (Godot `core/io/file_access_pack.cpp`, format versions 1–3). Embedded packs are located via the trailer (`GDPC` magic plus a 64-bit offset at the end of the file), or via the `pck` section for ELF/PE exports. Out of scope for this first step, as possible separate proposals: - decoding binary resources (`.scn`/`.res`) to text; - decompiling GDScript bytecode; - any PCK decryption. ### Verification - Synthetic fixtures built in-test following the exporter layout (no committed binaries). - Manual check against packs produced by a real writer (GDRE Tools `--pck-create`). A pack exported by the official Godot editor is still to do. - No commercial game samples are needed or would be shared. ### Prototype results A draft prototype (`GodotPckArtifactReader`, plus `godot-pck` in the format enums, classification, inventory and extraction) is on a branch. This is not a request to integrate; it exists to inform the scope decision. - `inspect-artifact` and `extract-artifact` work end to end on standalone `.pck` files produced by GDRE Tools (`--pck-create`, formats 2 and 3, engine 4.6.1). - Running the reader directly on a real 1.6 GB Godot 4.6.1 Linux export (embedded format 3 pack, 3937 members): - every member was listed and read with its declared MD5 verified; - 1,603,593,586 member bytes in 3.4 s, peak RSS 173 MiB (warm page cache, single run). - Ghidra was OOM-killed on the same file at about 3.9 GB. - 14 synthetic unit cases: formats 2 and 3, standalone and embedded, MD5 contradiction, encrypted member, encrypted directory, sparse bundle, patch removal entry, member-count overflow, out-of-range data, format 1, and a missing or bad trailer. - `check:fast` and `docs:check` pass; the artifact/domain/contract/application suites pass (4334 tests). Known prototype limits: - An executable with an embedded pack still classifies as ELF/PE. Exposing the embedded pack as a child container of the executable is an open design question. - The MD5 is verified on read and fails closed. It is not surfaced as declared integrity, because `ArtifactEntry` only carries SHA-256, so `record-and-continue` does not apply to it yet. - Format 1 (Godot 3) is refused as unsupported rather than guessed. ### Questions for maintainers 1. Is a Godot PCK reader in scope as format inspection plus ordinary archive extraction? 2. Should it surface through `inspect-artifact`/`extract-artifact`, or through a dedicated `inspect-godot-pack` operation? 3. Is reporting encrypted entries as unknown (no decryption) the right boundary? 4. Should an executable with an embedded pack expose it as a child container in its inventory, and should `ArtifactEntry` gain a declared-digest algorithm so the MD5 participates in integrity policy?
Author
Owner

@matbrgz commented on GitHub (Oct 14, 2026):

Seams related or dup https://github.com/morluto/rea/issues/3631

<!-- gh-comment-id:6176785477 --> @matbrgz commented on GitHub (Oct 14, 2026): Seams related or dup https://github.com/morluto/rea/issues/3631
Author
Owner

@0xthearchitect commented on GitHub (Oct 14, 2026):

Thanks, I missed #3631 (it didn't show up in search when I filed this). They overlap, but this one is intentionally narrower: just reading and extracting PCK containers, with no decryption, resource decoding or GDScript decompilation, so it stays within the documented format-inspection/extraction scope. It also already has a working draft in #3634.

I'm happy to treat this as the first slice of #3631, and to close this issue and retarget #3634 there if maintainers prefer one thread. The open questions above (CLI surface, embedded packs, MD5 as declared integrity) would apply either way.

<!-- gh-comment-id:6176873662 --> @0xthearchitect commented on GitHub (Oct 14, 2026): Thanks, I missed #3631 (it didn't show up in search when I filed this). They overlap, but this one is intentionally narrower: just reading and extracting PCK containers, with no decryption, resource decoding or GDScript decompilation, so it stays within the documented format-inspection/extraction scope. It also already has a working draft in #3634. I'm happy to treat this as the first slice of #3631, and to close this issue and retarget #3634 there if maintainers prefer one thread. The open questions above (CLI surface, embedded packs, MD5 as declared integrity) would apply either way.
Author
Owner

@matbrgz commented on GitHub (Oct 14, 2026):

Go ahead all yours. Wating your PR.

<!-- gh-comment-id:6176900760 --> @matbrgz commented on GitHub (Oct 14, 2026): Go ahead all yours. Wating your PR.
Author
Owner

@matbrgz commented on GitHub (Oct 16, 2026):

Duplicate of #3631.

This feature request covers Godot PCK inspection and entry extraction (GDPC magic, standalone .pck archives, and embedded executable trailers), which was already proposed earlier in #3631 ([Feature] Godot reverse engineering: PCK unpacking, scene/resource deserialization, GDScript bytecode decompilation, and signal graph reconstruction).

@morluto: could you please review and consider closing this issue in favor of the earlier canonical issue #3631 (or consolidating the specific artifact reader criteria into #3631) to maintain unified tracking for Godot engine support?

<!-- gh-comment-id:6205873584 --> @matbrgz commented on GitHub (Oct 16, 2026): Duplicate of #3631. This feature request covers Godot PCK inspection and entry extraction (`GDPC` magic, standalone `.pck` archives, and embedded executable trailers), which was already proposed earlier in #3631 (`[Feature] Godot reverse engineering: PCK unpacking, scene/resource deserialization, GDScript bytecode decompilation, and signal graph reconstruction`). @morluto: could you please review and consider closing this issue in favor of the earlier canonical issue #3631 (or consolidating the specific artifact reader criteria into #3631) to maintain unified tracking for Godot engine support?
Author
Owner

@morluto commented on GitHub (Oct 26, 2026):

Thank you for the focused PCK proposal, prototype and fixture evidence. #3634 landed standalone and EOF-embedded PCK inspection/extraction for formats 2–4, with retained header/member facts, MD5 integrity handling and explicit unknowns for encrypted content. I’m closing this first-slice request as completed. Godot 3 format 1 remains under #7063, and the merged embedded path covers EOF trailers; please feel free to reopen if a distinct executable-section lookup case needs tracking. Broader Godot resource and GDScript work remains in #3631. I did not rerun the artifact workflow in this pass.

<!-- gh-comment-id:6428090751 --> @morluto commented on GitHub (Oct 26, 2026): Thank you for the focused PCK proposal, prototype and fixture evidence. #3634 landed standalone and EOF-embedded PCK inspection/extraction for formats 2–4, with retained header/member facts, MD5 integrity handling and explicit unknowns for encrypted content. I’m closing this first-slice request as completed. Godot 3 format 1 remains under #7063, and the merged embedded path covers EOF trailers; please feel free to reopen if a distinct executable-section lookup case needs tracking. Broader Godot resource and GDScript work remains in #3631. I did not rerun the artifact workflow in this pass.
Author
Owner

@0xthearchitect commented on GitHub (Oct 27, 2026):

Thank you

<!-- gh-comment-id:6438256554 --> @0xthearchitect commented on GitHub (Oct 27, 2026): Thank you
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#1357
No description provided.