diff --git a/fifa17-recon/docs/plan-2026-08-06-card-subsystem.md b/fifa17-recon/docs/plan-2026-08-06-card-subsystem.md index deef77d..f6a5399 100644 --- a/fifa17-recon/docs/plan-2026-08-06-card-subsystem.md +++ b/fifa17-recon/docs/plan-2026-08-06-card-subsystem.md @@ -464,6 +464,33 @@ The lead worth following: find whether the owned cardtype-9 render path reaches this resolver, and if so which field feeds the league id. If it does, league logos need no `localizedName` at all and separate from the ball/misc gap. +#### Where to look next, and where NOT to (2026-08-21) + +The lead above was chased and stopped at a useful boundary. `FUN_180119bd0` — +the cardtype-7 caption resolver this whole section rests on — has **zero +references anywhere in CardsDLL**: no `call`, no `jmp`, and its address is never +taken in `.text`, `.rdata` or `.data`. It is nonetheless a genuine function +(clean `mov rax,rsp` entry after `int3` padding). + +A real, unreferenced function in a DLL is almost certainly an **export**, which +puts its caller in FIFA17.exe. That matches the shape of everything else here: +CardsDLL owns the card model and the database, and the EXE owns the UI that asks +for captions. `FUN_180098f20`'s only caller likewise iterates a small list +element, not a card record — a browse/catalog builder, not the owned-item path. + +So the practical guidance is: **stop looking for the owned cardtype-9 caption +path inside CardsDLL.** It is not there. Closing this by static reading means +parsing CardsDLL's export table and following the callers in FIFA17.exe's 79 MB, +which is a much larger job than the launch probe in "The one probe still +outstanding" — one item, one family, and the answer is visible on screen. + +Method note for whoever does dump memory here: CardsDLL's sections are +`.text` at image `0x180001000`, `.rdata` at `0x1801e5000`, `.data` at +`0x18028a000`. Confusing a LIVE mapping offset with an IMAGE offset silently +reads the wrong section and produces false negatives — every atom-name lookup +came back ABSENT until the region was corrected, including controls like +`resourceId`. Always validate a memory scan against a key known to be present. + --- ## 4. The card lifecycle @@ -1008,6 +1035,21 @@ be misrouted onto another field. **Freeze risk: none** -- removing a key the par skips strictly reduces executed code. Low value, zero cost, and it removes a field that three documents describe as if it did something. +**Fourth verification, 2026-08-21 (independent method).** Searched CardsDLL's +own `.rdata` in the running client for the literal key names. Every real atom is +present exactly once — `resourceId` `0x18022a3a8`, `cardsubtypeid` `0x180230520`, +`itemState` `0x180231490`, `assetId` `0x180230178`, `cardassetid` `0x180204200`, +`rareflag`, `untradeable`, `owners`, `contract`, `discardValue`, and notably +`localizedName` at `0x1802316d0` — while **`definitionId` is ABSENT entirely**. +The client has no string for it, so no arm can exist. That is a different method +from the three above (string table rather than key dictionary) and it agrees. + +NOT applied all the same. The player path that carries `definitionId` is +live-proven in production, the saving is payload only, and this project's house +rule is that a flag defaults to the live-proven value. "Provably inert" is a good +reason to stop documenting it as meaningful; it is not on its own a reason to +change a working wire. Bundle it with the next change that needs a launch. + --- ## 7. Proposed corrections to existing documents