From 80406ce3e44bae0eefe545407ba95ef1c370091f Mon Sep 17 00:00:00 2001 From: Sylpheed RE agent Date: Fri, 28 Aug 2026 11:41:52 +0000 Subject: [PATCH] re: the RTTI route is dead - BASE_INFO enumerates 95 screens instead Item (a): can the vtable scan name the corpus's anonymous classes? The route I proposed last turn - "the RTTI behind those two anon classes" - does not exist. Of all 1150 catalogued vtables, 1150 carry an ANON_ class name, 0 have rtti_present set, and 0 have a non-empty base_classes_json. Not one named class, not one RTTI flag, not one base-class edge in the whole table. Withdrawn as unrunnable; the ANON_Class_XXXXXXXX labels are synthesised, not recovered. The sibling methods cannot name a class either: slots 0, 2, 3 and 4 of both EX_ classes reference zero strings. Every naming datum sits in slot 1, the method the corpus already had. Re-verified at the true addresses (0x820A9760 and 0x820A9350) that sub_822814D8 and sub_8227A3A0 are each slot 1 uniquely, and sub_82286BC8 is in no vtable. What the shape DID give: both classes are 5-slot with an exactly-88-byte slot 0. 83 vtables have 5 slots, 16 also have the 88-byte slot 0, 13 of those have a catalogued slot 1, and 10 build a key list. Ranked by key count the two known screens sit at the top and the rest name themselves - a medals screen (MEDALS/ACHIEVED_MEDALS/NEW_MEDAL), an evaluation list (EVALUATION_LIST plus eval_%02d_eval / eval_%02d_points), the gamma screen (GAMMA_RGB/GAMMA_WB), POINT_RANKING, CLEAR_TIME_RANKING, and three bare ones. POINT_RANKING and CLEAR_TIME_RANKING being two separate screens is a direct lead for the open item "which challenge stage is which leaderboard mode": the leaderboard is ranked two ways and each way has its own class. But the obvious follow-on claim - that BASE_INFO marks this family - is false, and the control says so. BASE_INFO is a single string at 0x820A20EC referenced by 95 functions: 10 inside the family, 85 outside, including sub_82286BC8 (the save screen, in no vtable at all) and sub_822AE628 (the hangar loader). So the direction inverts: BASE_INFO is the universal first key of every screen key list, a 95-function population, while the 5-slot/88-byte shape is only a weak filter that catches 10 of them plus 6 non-screens. Enumerate screens by BASE_INFO, not by vtable shape. All seventeen artefacts byte-identical. --- docs/re/BACKLOG.md | 32 ++++++++++++++ docs/re/structures/result-screens.md | 63 ++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/docs/re/BACKLOG.md b/docs/re/BACKLOG.md index 54172a0..5f25837 100644 --- a/docs/re/BACKLOG.md +++ b/docs/re/BACKLOG.md @@ -6966,3 +6966,35 @@ unfiltered count would inflate by ~633. Elsewhere the populations are disjoint. **Rule**: always filter `kind='call'`; and a function with no `call` edges is a **virtual method**, not a gap to fill from `ind_call`. + +--- + +## ✅❌ 2026-08-28 — the RTTI route is dead; `BASE_INFO` enumerates 95 screens + +Item (a): can the vtable scan name the anonymous classes? + +❌ **The RTTI route I proposed last turn does not exist.** Of all **1 150** +catalogued vtables: **1 150** have an `ANON_` class name, **0** have +`rtti_present`, **0** have a non-empty `base_classes_json`. Withdrawn as +unrunnable. + +❌ **Sibling methods cannot name a class either** — slots 0/2/3/4 of both `EX_` +classes reference **zero** strings; all naming content is in slot 1, which the +corpus already had. + +✅ **Re-verified at the true addresses** (`0x820A9760` / `0x820A9350`): +`sub_822814D8` and `sub_8227A3A0` are each slot 1, uniquely. + +✅ **The shape did find eight more screens.** 83 vtables have 5 slots; **16** +also have an exactly-88-byte slot 0; 13 have a catalogued slot 1; **10 build a +key list** — naming the medals screen, an evaluation list (`eval_%02d_points`), +the gamma screen, **`POINT_RANKING`**, **`CLEAR_TIME_RANKING`**, and 3 bare ones. + +🔑 **Two separate ranking screens** — a lead for "which challenge stage is which +leaderboard mode". + +❌ **But `BASE_INFO` is not the family signature.** One string, **95** referring +functions: **10 inside the family, 85 outside** (`95 = 10 + 85`), including +`sub_82286BC8` and `sub_822AE628`. **`BASE_INFO` is the universal screen-key-list +marker; the vtable shape is only a weak filter.** Enumerate screens by +`BASE_INFO`, not by vtable shape. diff --git a/docs/re/structures/result-screens.md b/docs/re/structures/result-screens.md index 25d3197..42014ca 100644 --- a/docs/re/structures/result-screens.md +++ b/docs/re/structures/result-screens.md @@ -227,3 +227,66 @@ is safe and an `ind_call`-based one is meaningless. **Rule for future work:** always filter `kind='call'`; and when a function has no `call` edges, that is a *fact about it* — it is a virtual method — not a gap to be filled from `ind_call`. + +### ❌ The RTTI route is dead — and ✅ what the vtable scan gave instead + +Last iteration proposed "the RTTI behind those two anonymous classes" as the next +route with power. **Measured, it does not exist.** + +| over all 1 150 catalogued vtables | | +|---|---| +| `class_name` starting `ANON_` | **1 150 of 1 150** | +| `rtti_present` true | **0** | +| non-empty `base_classes_json` | **0** | + +There is not one named class, not one RTTI flag, and not one base-class edge in +the whole table. ⚠️ **Withdrawn: my own "next route" from last turn was +unrunnable.** The `ANON_Class_XXXXXXXX` labels are synthesised, not recovered +names. + +✅ **Re-verified, though**: reading the two vtables at their true addresses +(`0x820A9760`, `0x820A9350`) confirms `sub_822814D8` and `sub_8227A3A0` are each +**slot 1, uniquely**, and `sub_82286BC8` is in no vtable. + +❌ **The sibling methods cannot name the class either.** Slots 0, 2, 3 and 4 of +both classes reference **zero** strings. Every naming datum in both classes sits +in slot 1 — the method the corpus already had. + +#### ✅ But the shape found eight more screens + +Both classes are 5-slot with an exactly-88-byte slot 0. Filtering the whole +table on that shape: 83 vtables have 5 slots, **16** also have the 88-byte slot +0, 13 of those have a catalogued slot 1, and **10 of the 13 build a key list**. +Ranked by key count, the two known screens are at the top and the rest name +themselves: + +| class | slot 1 | its key vocabulary | +|---|---|---| +| `ANON_Class_271D5F25` | `sub_822814D8` | `EX_STAGE_RESULT` / `STAGE_RESULT` — **the debriefing** | +| `ANON_Class_CAA8AD62` | `sub_8227A3A0` | `EX_OVERVIEW` / `OVERVIEW` / `LAST_RESULT` — **the career screen** | +| `ANON_Class_5FFD2641` | `sub_82278960` | `MEDALS`, `ACHIEVED_MEDALS`, `NEW_MEDAL`, `DETAIL_NEW` | +| `ANON_Class_8501FBF7` | `sub_82275F80` | `EVALUATION_LIST`, `eval_%02d_eval`, `eval_%02d_points` | +| `ANON_Class_B09C08C7` | `sub_822B4838` | `GAMMA_RGB`, `GAMMA_WB` | +| `ANON_Class_9795AB66` | `sub_8227F6E0` | **`POINT_RANKING`** | +| `ANON_Class_A7CB2C37` | `sub_82282C28` | **`CLEAR_TIME_RANKING`** | +| `ANON_Class_7EE7DC6F` / `431702E3` / `22F09B71` | `sub_822B6F60` / `sub_822B84A8` / `sub_822B9B78` | `BASE_INFO` only | + +🔑 **`POINT_RANKING` and `CLEAR_TIME_RANKING` are two separate screens** — a +direct lead for the open item "which challenge stage is which leaderboard mode": +the leaderboard is ranked two ways, and each way has its own class. + +⚠️ Note `eval_%02d_eval` — a **printf numeric wildcard**, the code-side analogue +of the datasheet schema's `???` suffix wildcard. + +#### ❌ …but `BASE_INFO` is NOT this family's signature + +The obvious next claim — "`BASE_INFO` marks the family" — is false, and the +control says so plainly. `BASE_INFO` is a single string (`0x820A20EC`) and +**95 functions reference it: 10 inside the family, 85 outside** (`95 = 10 + 85`). +Among the outsiders are `sub_82286BC8` (the save screen, in no vtable at all) and +`sub_822AE628` (the hangar loader). + +So the direction inverts: **`BASE_INFO` is the universal first key of every +screen key list — a 95-function population** — while the 5-slot/88-byte shape is +only a **weak** filter that happens to catch 10 of them (and 6 non-screens). Use +`BASE_INFO` to enumerate screens; do not use the vtable shape.