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.
This commit is contained in:
Sylpheed RE agent
2026-08-27 04:15:33 +00:00
parent 6d6766db18
commit b3d146b758

View File

@@ -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