From b3d146b75838861cfcd7684a6051543c591b13d9 Mon Sep 17 00:00:00 2001 From: Sylpheed RE agent Date: Thu, 27 Aug 2026 04:15:33 +0000 Subject: [PATCH] re: the script lookup is a tag_hash directory search; pak route dead under both hashes 0x82448AA0 and 0x82448C50 are not strcmp. Both pass the name to 0x82447DF0 and use the result as a key: the first binary-searches a table of 16-byte records (x16 for the end, /16 for the count, >>1 for the midpoint), the second packs the hash into a three-word key and calls 0x8244E338. Decoded 0x82447DF0 from the disassembly as ((sum of extsb bytes) & 0xFF) << 24 | (rolling mod 0x00FFFFDF) -- i.e. tag_hash. tools/re-capture/unitgroup.py::tag_hash already documents itself as "a transcription of sub_82447DF0", so this was in the corpus; the useful part is that it identifies which hash the ARCHIVE uses. That exposed a defect in my previous sweep: it probed name_hash (0x00FFF9D7, lowercased) only, while the archive keys by tag_hash (0x00FFFFDF, case-sensitive). Re-ran with BOTH: 1380 names -> 2148 distinct hashes, 41 paks, 26443 records. STILL ZERO. The pak-record hypothesis is now refuted with the right hash rather than merely unsupported. Left open: the XEX's compressed/encrypted region (default.xex never decrypted here), plus two untried static threads -- the second pair of SCRIPTS/GP_SCRIPT references at 0x82262374 / 0x822622bc, in a different function, and tracing [r31+80] back to whoever opened the archive being name-tested. --- docs/re/mission-phase-advance.md | 39 ++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/docs/re/mission-phase-advance.md b/docs/re/mission-phase-advance.md index 1e9f962f..985f7b34 100644 --- a/docs/re/mission-phase-advance.md +++ b/docs/re/mission-phase-advance.md @@ -201,11 +201,40 @@ construction of `dat\GP_SCRIPT.pak`. That is consistent with `GP_SCRIPT` being the name the engine expects an archive to *report*, which is why no file of that name exists to be found. -❔ Still open, with the next concrete steps: identify `0x82448AA0` (strcmp vs -strstr vs a hash-compare) and `0x82448C50`/`0x8216F218` around it, and follow -`[r31+80]` — the object whose name is being tested — back to whoever opened it. -That names the container. The XEX's compressed/encrypted region remains the other -candidate; the retail `default.xex` has never been decrypted here. +### The lookup is a HASHED directory search, and the pak route is now dead under both hashes + +`0x82448AA0` and `0x82448C50` are not `strcmp`. Both pass the name to +**`0x82447DF0`** and use the result as a key: + +* `0x82448AA0` hashes, then binary-searches a table of **16-byte records** — + `rlwinm r11,r11,4` (×16) to find the end, `srawi r11,r11,4` (÷16) for the + count, `srawi r9,r11,1` for the midpoint. +* `0x82448C50` hashes, packs the result into a three-word key at `sp+80`, and + calls `0x8244E338` to find it. + +**`0x82447DF0` is `tag_hash`** — decoded from the disassembly as +`((Σ extsb(byte)) & 0xFF) << 24 | (rolling mod 0x00FFFFDF)`, and +`tools/re-capture/unitgroup.py::tag_hash` already documents itself as "a +transcription of `sub_82447DF0`". So the archive keys records by the same +case-sensitive `0x00FFFFDF` hash the IDXD tables use, **not** by `name_hash` +(`0x00FFF9D7`, lowercased). + +❌ **That was a real defect in the previous sweep** — it probed `name_hash` only. +Re-run with **both** hashes: 1 380 candidate names → **2 148 distinct hashes**, +against all **41** paks and **26 443** records. **Still zero.** + +So the pak-record hypothesis is now refuted properly: right hash, right archive +set, right record count. The scripts are not in a pak under any of +`MISSION1..33` / `MISSION_*_PRT` / `SCRIPTS` / `GP_SCRIPT`, with or without the +`SCRIPTS\`, `GP_SCRIPT\`, `script\`, `SCRIPT\`, `scripts\` prefixes and the +`.prt/.PRT/.scr/.bin/.dat` suffixes. + +❔ **What is left.** The XEX's compressed/encrypted region is now the leading +candidate — the retail `default.xex` has never been decrypted here. The untried +static thread is the *second* pair of references, `0x82262374` (SCRIPTS) and +`0x822622bc` (GP_SCRIPT), which live in a different function from +`sub_8225EE20`; and tracing `[r31+80]` back to whoever opened that archive would +name the container directly. ## ✅ Tooling correction: the `.pe` is NOT stale