Wolfenstein Modloader Buy me a coffeeKaffee spendieren

In plain wordsIn einfachen Worten

Archive files of Wolfenstein II: The New Colossus carry an 8-byte value at header position +0x08. This report tested common hash functions over many parts of the file and over file names, and none reproduced it. A comparison of two custom archives shows the value stays the same even when the metadata changes. So it is probably an identity value tied to how the archive is mounted, not a checksum of the content.

  • No match for FarmHash64, CityHash64, XXH64, or MD5/SHA-1 slices over ten file regions.
  • No match either for hashes of the 24 retail archive file names in several spellings.
  • Two custom archives with different metadata share the same +0x08 value, so it is not a direct hash of that metadata.
  • Not ruled out: seeded or secret-keyed hashes, CRC64 variants, or a value supplied by the mount manifest.
  • Suggested next step: a loader test that changes only the archive's mount identity and records the expected value.

Archivdateien von Wolfenstein II: The New Colossus tragen an Header-Position +0x08 einen 8-Byte-Wert. Dieser Bericht testete gängige Hash-Funktionen über viele Dateibereiche und über Dateinamen, aber keine bildete den Wert nach. Ein Vergleich zweier eigener Archive zeigt, dass der Wert gleich bleibt, obwohl sich die Metadaten ändern. Er ist daher wahrscheinlich ein Identitätswert, der mit dem Einbinden des Archivs zusammenhängt, und keine Prüfsumme über den Inhalt.

  • Kein Treffer für FarmHash64, CityHash64, XXH64 oder MD5/SHA-1-Ausschnitte über zehn Dateibereiche.
  • Ebenfalls kein Treffer für Hashes der 24 Original-Archivnamen in mehreren Schreibweisen.
  • Zwei eigene Archive mit unterschiedlichen Metadaten haben denselben +0x08-Wert. Er ist also kein direkter Hash dieser Metadaten.
  • Nicht ausgeschlossen: Hashes mit Seed oder geheimem Schlüssel, CRC64-Varianten oder ein Wert aus dem Mount-Manifest.
  • Vorgeschlagener nächster Schritt: ein Ladetest, der nur die Mount-Identität des Archivs ändert und den erwarteten Wert protokolliert.

Technical detailsTechnische Details

Der technische Teil ist auf Englisch – so, wie er im Wiki steht. Unterstrichene Begriffe haben eine Erklärung auf Deutsch.

Outcome

No reproducible algorithmic hit was found. The strongest result is that the IDCL header at +0x08 is not a direct hash of the archive metadata: the custom chunk_26_hash1.resources and chunk_26_oracle.resources have identical values at +0x08 (3533df45c7f9b1d2) but differ at +0x20 and within the metadata byte range [0x698, 0x69c). This latter mutation also changes the value at +0x20 from 8447767104e04232 to fb64ec38103aa09d.

This suggests that a mount/package identity value (or a value retained from the package manifest) is more plausible than a content checksum. It also explains why modifying +0x08 alone in chunk_26_mountprobe.resources produces a different value without any corresponding changes to the file content.

Reproducible command and result

Run from the repository root:

python -u re_probes\hash08_scratch\inspect.py

The script utilizes three intentionally dissimilar retail metadata sets (chunk_8.resources, patch_4_chunkbase_6.resources, and gameresources.resources) and returns:

retail 3
direct_matches []
name_matches []

direct_matches [] covers FarmHash64, CityHash64, unseeded XXH64, and both endiannesses of MD5/SHA-1 first/last 64-bit slices across ten distinct regions: header, full metadata, header-normalized (+0x08 zeroed and +0x08/+0x20 zeroed), [0x10:], [0x28:], [0x78:], entry table, and string/pool/table regions. name_matches [] independently tests Farm/City/XXH unseeded variants over filename/stem, lower-case forms, and four base path spellings for all 24 retail archive filenames.

The same invocation prints these independently useful differential checks:

diff hash1 chunk_26_mountprobe.resources [('0x8', '0x10', 8)]
diff hash1 chunk_26_oracle.resources [('0x20', '0x28', 8), ('0x698', '0x69c', 4)]

The expected header value from the custom oracle is 3533df45c7f9b1d2; the alternative 6e9d625602ddbc9e is not derived by any of the tested candidates. Two custom artifacts with the old metadata marker are intentionally rejected by the parser; the probe reports that instead of treating their inferred regions as valid (IdclError: end of metadata magic is 00000000, expected IDCL). The parse-valid custom artifacts (hash2, mountprobe_v2, and oracle) also yield no direct Farm/City/XXH metadata hit.

Excluded / not excluded

Excluded: unseeded FarmHash64/CityHash64/XXH64 direct forms over the listed metadata and path spellings; the listed MD5/SHA truncations; and a direct metadata-content interpretation (via the differential counterexample).

Not excluded: seeded/secret-keyed variants, CRC64 variants or combinations, and a package-map/VFS-derived identifier. Static samples cannot distinguish a secret seed from a value supplied externally by the mount manifest.

Best next oracle

Perform one isolated loader oracle that holds the complete container bytes fixed while changing only the mount identity (filename or package-map chunk identity). If the requested wants value changes, capture the filename, chunk/basechunk IDs, and wanted u64 for at least three identities. This approach is far more discriminating than further raw-byte hash sweeps and can reveal the exact manifest/VFS input to reverse-engineer without altering game data.