Probe mappin route event dispatch

This commit is contained in:
2026-06-20 00:59:35 -05:00
parent 3b0a66a87a
commit 2bbc6cbb46
3 changed files with 411 additions and 4 deletions
+11
View File
@@ -26,6 +26,12 @@ Current behavior:
`0x8d136c`, `0x431a34`, `0x55a4e4`, and `0x14de238`.
- For those listener callbacks, logs the listener object, event pointer, common
object fields, and vtable slots on candidate nested owner/service objects.
- Hooks the route handoff found from the journal listener bridge:
`0x598250`, `0x13763d8`, `0xaa62d0`, `0xaa6330`, `0x27abd7c`, and
`0x5625a4`.
- Logs mappin route-event fields, active/deactive route refs, the mappin
active-route map at `system + 0x1a0`, and the route observer list at
`system + 0x280`.
- Resolves the native mappin system when one of those paths fires, logs relevant
vtable slot addresses, and temporarily hooks the route-adjacent slots.
@@ -38,6 +44,11 @@ Current route-probe focus:
- mappin-system slots `0x1f0`, `0x280`, and `0x2f0`
- `JournalManager.TrackEntry` implementation: `0x5944fc`
- non-default `TrackEntry` listener callbacks listed above
- journal/mappin route bridge candidate: `0x598250`
- mappin route-event enqueue: `0x13763d8`
- mappin route-event handler: `0xaa62d0`
- mappin route activate/deactivate: `0xaa6330`, `0x27abd7c`
- route-build candidate called by the bridge: `0x5625a4`
Quest/objective pins did not fire the mappin tracking hooks in live tests. The
REDscript decompile shows that those pins call `JournalManager.TrackEntry`
+51 -3
View File
@@ -258,9 +258,57 @@ Static disassembly of these callbacks suggests the following split:
slots such as `0x218`, `0x230`, `0x240`, `0x340`, and `0x348`.
The installed probe now hooks those non-default callbacks directly and logs the
nested owner/service vtables. The next target is to identify which nested vtable
slot performs the route query or route cache update, then disassemble or patch
that function.
nested owner/service vtables. A later controlled run narrowed the quest route
handoff further:
```text
JournalManager.TrackEntry
-> JournalListener::Route callbacks at 0xe63f80 / 0xe63e6c
-> journal/mappin route bridge candidate at 0x598250
-> MappinSystem route-event enqueue at 0x13763d8
-> route-event handler at 0xaa62d0
-> activate route ref at 0xaa6330
-> or deactivate route ref at 0x27abd7c
```
The route listener object has two important nested service pointers in the live
logs:
```text
listener + 0x70: mappin system, vtable 0x14310e300
listener + 0x78: journal manager, vtable 0x1430f0890
```
The mappin system slot `0x240` points to RVA `0x13763d8`. Static disassembly
shows it is not the solver. It builds a small queued event with vtable
`0x14310e1c0`:
```text
event + 0x08: event type byte, value 5
event + 0x18: route/journal id
event + 0x20: mappin system pointer
event + 0x28: active/unactive bool
```
The event handler at `0xaa62d0` reads that bool and calls either `0xaa6330` or
`0x27abd7c` with the mappin system and a route reference taken from the event
payload. Both target functions look like active-route state toggles: they look
up a route ref in a map at `mappinSystem + 0x1a0`, set a byte at route object
offset `0x84`, then notify observers from the list at `mappinSystem + 0x280`
through virtual callbacks at offsets `0x48`/`0x50`.
Static xrefs also expose a shared route-change helper at `0x27aa2d8`, which
deactivates an old route ref and activates a new route ref. That is likely the
common mappin state transition path for both journal/objective routes and
custom/player pins.
The most route-building-looking static candidate currently in this chain is
`0x5625a4`, called once from the bridge at `0x5984ec`. The bridge resolves
journal route ids through virtual journal-manager calls, collects several route
descriptor/data pointers, and passes them to `0x5625a4`. The current RED4ext
probe hooks this function with a 12-argument inferred signature to determine
whether it builds GPS/path display data or merely updates UI-facing route
metadata.
## Native False Positives