Implement mounted append AUTORUN boot
This commit is contained in:
@@ -83,7 +83,7 @@ noop_headless = false
|
||||
source = "investigation"
|
||||
confidence = "high"
|
||||
depends_on = []
|
||||
evidence = "native-RE (Ghidra): handler FUN_0041bc90 -> loader FUN_0040e980 -> resolver FUN_0044f390 indexes an 80-byte record table (base [ctx+0x414], count [ctx+0x40c]) at base+id*0x50 = the SYS4INI record layout {name[64],arc_id@0x40,file_number@0x44,offset@0x48,size@0x4c}. Confirmed statically: all 297 distinct corpus call-script ids resolve to a .BIN script with a semantically-exact name (0x1ab->ADDITEM, 0x2ae7->MES, 0x143->BUNKI, 0x329d->CALCREVISE), 0 out-of-range, 0 pack-branch. See docs/engine-re.md + name-resolution.md #1."
|
||||
evidence = "native-RE (Ghidra): handler FUN_0041bc90 -> loader script_frame_load_resource@0x40e980 -> resolver asset_open_indexed_entry@0x44f390 indexes an 80-byte record table (FileDB+0x414 base, FileDB+0x40c count) at base+id*0x50 = the SYS4INI record layout {name[64],arc_id@0x40,file_number@0x44,offset@0x48,size@0x4c}. The FileDB is embedded at EngineCtx+0x9c24c, making those EngineCtx+0x9c660/+0x9c658. Confirmed statically: all 297 distinct base-corpus call-script ids resolve to a .BIN script with a semantically-exact name (0x1ab->ADDITEM, 0x2ae7->MES, 0x143->BUNKI, 0x329d->CALCREVISE), 0 out-of-range. See docs/engine-re.md + name-resolution.md #1."
|
||||
confirm_by = ""
|
||||
details = """
|
||||
op 0x03 (call-script, argc 1): `call-script <id>`. RESOLVED — the id is a direct RAW index into
|
||||
@@ -95,11 +95,13 @@ Native mechanism (dispatch table `handler(op)=ctx[0x26c93+op]`, op 0x03 -> FUN_0
|
||||
2. FUN_0040e980 (loader): opens the resource by id, reads the 0x20-byte SYS4 header, checks magic,
|
||||
allocates per-frame code/local buffers from the header var-counts, reads the bytecode body,
|
||||
pushes a script frame (stride 0x1e = 30 dwords, indexed by ctx[0x14f45]).
|
||||
3. FUN_0044f390 (resolver): record = [ctx+0x414] + id*0x50. Tries a LOOSE OVERRIDE first
|
||||
(CreateFileA on record.name -> mod/patch hook point), else opens archive [record.arc_id*0x100 +
|
||||
ctx+0x410], SetFilePointer to record.offset, size = record.size.
|
||||
(High-byte-tagged ids `id & 0xff000000` select an alternate pack via [ctx+0x3028]; UNUSED by the
|
||||
corpus -- 0/297 ids have a high byte.)
|
||||
3. asset_open_indexed_entry@0x44f390 (resolver): its `this` is the embedded FileDB, not EngineCtx.
|
||||
Base record = [FileDB+0x414] + id*0x50. It tries a LOOSE OVERRIDE first (CreateFileA on
|
||||
record.name -> mod/patch hook point), else opens archive [record.arc_id*0x100 + FileDB+0x410],
|
||||
SetFilePointer to record.offset, size = record.size.
|
||||
High-byte-tagged ids select [FileDB+0x3028 + signed_selector*4] and index the chosen AAI by the
|
||||
low 24 bits. The base corpus has 0/297 explicit high-byte call-script operands; INIT2 op 0x143
|
||||
supplies mounted record-zero ids dynamically.
|
||||
Companion op 0x8f `call` is INTRA-script (a local JSR), not cross-script -- see its entry.
|
||||
This also names the whole call graph statically (build/callscript-names.json).
|
||||
"""
|
||||
@@ -2975,14 +2977,29 @@ argc = 0
|
||||
abi_source = "kelebek+decode-validated"
|
||||
|
||||
[opcode.semantics]
|
||||
name = "u00415FB0"
|
||||
category = "unknown"
|
||||
summary = ""
|
||||
name = "run-mounted-append-autoruns"
|
||||
category = "control"
|
||||
summary = "() - enqueue record zero from every mounted nonzero AAI selector in ascending selector order, then execute those packed scripts serially before resuming the caller."
|
||||
noop_headless = false
|
||||
source = "kelebek"
|
||||
confidence = "low"
|
||||
source = "investigation"
|
||||
confidence = "high"
|
||||
depends_on = []
|
||||
evidence = ""
|
||||
evidence = "Ghidra /v2: op_0x143_run_mounted_append_autoruns@0x4172f0 scans mounted_aai_catalogs[1..255] at EngineCtx+0x9f278, enqueues selector<<24 through script_launch_queue_enqueue@0x40f820 while dispatch is suppressed, advances the caller PC, then tail-dispatches through script_launch_queue_dispatch_next@0x40f6e0. Positive queue entries load in reserved frame 37 with return sentinel -10; op_0x2_exit_or_return_frame@0x417940 dispatches the next queued entry or restores the suspended caller. Corpus: the sole site is INIT2@0x17f, after its 23 base INIT children and global/array setup and immediately before TUNE.BIN."
|
||||
details = """
|
||||
The opcode does not look up an AUTORUN filename. For each non-null mounted catalog pointer in selector
|
||||
slots 1 through 255, it constructs the packed id `selector << 24`, whose low 24-bit record index is zero.
|
||||
At Himegari cold boot the native catalog loader has already mounted APPEND01 in selector 1 before SYSTEM4
|
||||
starts. SYSTEM4 calls INIT2; INIT2 runs EBINIT through SCINIT plus BTANINIT2, completes its base registry
|
||||
setup, executes this opcode, and resumes at its following TUNE call only after every queued record-zero
|
||||
script returns. Installed selector 1 record zero is `$1$AUTORUN.BIN`, which applies the append INIT deltas
|
||||
and registrations. This is a serial base-then-append patch boundary, not a filename overlay.
|
||||
|
||||
PORT = IMPLEMENTED. `IScriptProvider.MountedAppendSelectors` exposes mounted selector identity without
|
||||
coupling the VM to the SYS4 catalog type. The opcode snapshots, deduplicates, and sorts selectors, constructs
|
||||
each packed record-zero id, and runs the resolved script through the ordinary nested-frame machinery before
|
||||
resuming INIT2. Focused tests protect ordering, packed-id construction, caller suspension, and unresolved
|
||||
record-zero failure. Natural SYSTEM4 boot proves BTANINIT2 -> `$1$AUTORUN.BIN` -> `$1$EBINIT.BIN` -> TUNE.
|
||||
"""
|
||||
|
||||
[[opcode]]
|
||||
op = 0x144
|
||||
|
||||
Reference in New Issue
Block a user