Skip to content

Add opt-in encrypted pack key recovery (--recover-key) - #470

Closed
figurophobia wants to merge 1 commit into
GDRETools:masterfrom
figurophobia:recover-key
Closed

figurophobia wants to merge 1 commit into
GDRETools:masterfrom
figurophobia:recover-key

Conversation

@figurophobia

@figurophobia figurophobia commented Oct 21, 2026 •

Copy link
Copy Markdown

This adds an opt-in way to open packs whose directory table is encrypted when the key is not known: --recover-key scans the pack (or the self-contained executable that contains it) for the 32-byte key and verifies each candidate against the index MD5.

I know key extraction was declined in #7, so this is deliberately narrow and does nothing unless the user explicitly passes the flag:

  • Off by default. No GUI changes, no automatic scanning.
  • No behaviour change for existing recovery/extract flows.
  • Only runs when a pack with PACK_DIR_ENCRYPTED is opened and no key was supplied.
  • Custom decryptors are left alone (the scan is skipped when one is configured).

Implementation:

  • utility/key_recovery.cpp: parses the pack header (v2/v3/v4), locates the encrypted directory, and scans the containing file in parallel chunks with WorkerThreadPool. Candidates are cheaply filtered by decrypting the first 16 bytes and checking for a plausible path prefix (res:// or a printable relative path), then fully verified by decrypting the table and comparing its MD5.
  • GDREPackedSource::try_open_pack calls it when GDRESettings::is_key_recovery_enabled() is set and no key is available. On success the key is stored like a user-provided key; set_encryption_key now also syncs the engine's script encryption key so encrypted resources keep working.
  • standalone/gdre_main.gd: --recover-key flag and help text; README updated.
  • tests/test_key_recovery.cpp: builds v2 and v4 packs with an encrypted index and checks the key is found, plus a negative case that must return nothing.

Known limitations:

  • Opening a bare .pck whose key only exists in a separate executable cannot recover it from that file alone; point the tool at the executable (or the game directory) instead.
  • Sparse bundles (v4 + PACK_SPARSE_BUNDLE) use the salt-based scheme and are skipped.

Locally I built the module against the gdre-wb-f964fa714f5 branch with tests=yes and the full [GDSDecomp] suite passes (100 cases, including the 3 new ones). CI here is waiting for workflow approval, so it hasn't run on GitHub yet.

If the project's stance on this hasn't changed, feel free to close this; I mainly wanted to see whether an opt-in, CLI-only version would be acceptable.

Scan the pack or self-contained executable for a 32 byte key that
decrypts the directory table, verifying candidates against the index
MD5. The scan only runs when --recover-key is passed, so the existing
behaviour is unchanged unless the option is explicitly requested.

Adds a small test that builds v2/v4 packs with an encrypted index and
checks that the key is found (and that no key is reported when absent).
@nikitalita

Copy link
Copy Markdown
Collaborator

Sorry, but I am going to have to decline. I do not wish to escalate the obfuscation arms race. GDRE Tools is the most popular reverse-engineering tool for Godot games, and if this functionality is added, I fear that developers will start to add custom encryption and/or other obfuscation methods to prevent reverse-engineering their games. That would be a net-loss for everyone. I appreciate the effort put into this nonetheless, and I would suggest you make this a separate tool.

@nikitalita nikitalita closed this Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants