docs(fifa17): record no-sentinel client resolver proof
Land the client-side empty-My-Packs resolver evidence and the session-stability invariant established by the F3/R1 experiments. - PART III (F3, CONFOUNDED CRASH): a mid-process sentinel -> no-sentinel flip left a stale POSITIVE My-Packs ordinal that still took the resolve branch and crashed at 0x180014882. Preserved verbatim (not a guard failure). - PART IV (R1, SUCCESS): backend set no-sentinel first, then a FRESH FIFA process; genuine purchasegroup response ids [1,5,6,7] is byte-identical to the F3 capture, so client process lifetime is the only changed variable. Store opens on Browse Packs, no crash, no dialog. Guard PROVEN on the tested build. - New INVARIANT: empty-My-Packs capability MUST be session-stable -- the server must not switch a running client between sentinel-present and sentinel-absent for the My Packs group within one FIFA process, because the client caches the group ordinal and a stale positive ordinal still crashes the resolver. - Both no-sentinel captures kept: client_guard (F3) and freshretest (R1). Backend P2 active-sentinel (65534) remains production default; no capability handshake is implemented yet.
This commit is contained in:
@@ -411,3 +411,33 @@ Scaleform/movie-driven). Recommend: adopt the active placeholder as an optional
|
||||
backend compatibility mode (safe, strictly better than baseline) AND pursue a
|
||||
client-side fix (hide the fake tile / stop the forced My-Packs resolution) for the
|
||||
fully clean result. **Not implemented.** Do NOT grant a real pack.
|
||||
|
||||
---
|
||||
|
||||
## Client resolver-guard experiment (2026-08-13) — RESULT F3 (crash, confounded)
|
||||
|
||||
A client-side `autopatch.py` memory guard (CardsDLL `0x180014858` `JNZ`→`JG`, routing
|
||||
category `<0` to list-all/Browse) was tested against the exact no-sentinel server condition
|
||||
(sentinel 65534 suppressed; `GET /store/purchasegroup` ids `[1,5,6,7]`, no mypacks group).
|
||||
The client **crashed at the identical resolver site `0x180014882`** (`[NULL+0x48]`), because
|
||||
it presented a **positive** My-Packs ordinal (crash is in the `>0` resolve branch), not the
|
||||
`-1` the guard diverts. **Confound:** FIFA was not relaunched after the backend flip, so it
|
||||
reused stale (sentinel-present) tab state. So the negative-only guard is **insufficient for a
|
||||
positive stale/invalid ordinal**, and the fresh-client case is **not yet decided** (needs a
|
||||
clean re-test: fresh launch with backend already no-sentinel). Backend P2 sentinel was
|
||||
restored immediately (mandatory rollback). Full record + candidate stronger guard:
|
||||
`docs/plans/FIFA17_EMPTY_MYPACKS_CLIENT_FIX.md` PART III.
|
||||
|
||||
## Fresh-process no-sentinel retest (2026-08-13) — RESULT R1 (SUCCESS)
|
||||
|
||||
Re-ran the above cleanly: backend entered no-sentinel mode **while FIFA was closed**, then a
|
||||
**fresh** FIFA (pid 553220, new autopatch 552999, guard `85 ff 7f 0f` enforced) launched and
|
||||
opened the Store. The genuine no-sentinel `/store/purchasegroup` (ids `[1,5,6,7]`, no 65534/
|
||||
mypacks) is **byte-identical** to the F3 capture, so the only changed variable is client
|
||||
process lifetime. Outcome: **no crash, no dialog, Store opens on Browse Packs, packs
|
||||
navigable** (cosmetics only: no tabs / no cover art / "0 items" — pre-existing). A fresh
|
||||
client publishes category `-1` for the absent group, which `JNZ→JG` routes to Browse/list-all
|
||||
with no NULL deref. **This confirms F3 was stale-positive-ordinal contamination, and proves
|
||||
Strategy A (resolver guard) on the tested build.** Backend P2 sentinel restored immediately
|
||||
(`f416e71e…`, `state=active`) and remains production default. Full record:
|
||||
`docs/plans/FIFA17_EMPTY_MYPACKS_CLIENT_FIX.md` PART IV.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{"purchase": [{"assetId": 1, "id": 1, "packType": "BRONZE", "description": "Bronze Pack", "state": "active", "saleType": "promo", "limitType": "NONE", "quantity": 0, "purchaseLimit": 0, "purchaseCount": 0, "isPremium": false, "sortPriority": 1, "currencies": [{"name": "coins", "funds": 400, "finalFunds": 400}], "extPrice": {"finalPrice": {"amount": 4, "currency": "mtx"}, "originalPrice": {"amount": 4, "currency": "mtx"}}, "packContentInfo": {"bronzeQuantity": 5, "silverQuantity": 0, "goldQuantity": 0, "rareQuantity": 0, "itemQuantity": 5}, "unopened": false, "displayGroup": {"value": "bronze"}}, {"assetId": 5, "id": 5, "packType": "GOLD", "description": "Gold Pack", "state": "active", "saleType": "promo", "limitType": "NONE", "quantity": 0, "purchaseLimit": 0, "purchaseCount": 0, "isPremium": false, "sortPriority": 2, "currencies": [{"name": "coins", "funds": 5000, "finalFunds": 5000}], "extPrice": {"finalPrice": {"amount": 50, "currency": "mtx"}, "originalPrice": {"amount": 50, "currency": "mtx"}}, "packContentInfo": {"bronzeQuantity": 0, "silverQuantity": 0, "goldQuantity": 7, "rareQuantity": 7, "itemQuantity": 7}, "unopened": false, "displayGroup": {"value": "gold"}}, {"assetId": 6, "id": 6, "packType": "GOLD", "description": "Premium Gold", "state": "active", "saleType": "promo", "limitType": "NONE", "quantity": 0, "purchaseLimit": 0, "purchaseCount": 0, "isPremium": false, "sortPriority": 3, "currencies": [{"name": "coins", "funds": 15000, "finalFunds": 15000}], "extPrice": {"finalPrice": {"amount": 150, "currency": "mtx"}, "originalPrice": {"amount": 150, "currency": "mtx"}}, "packContentInfo": {"bronzeQuantity": 0, "silverQuantity": 0, "goldQuantity": 11, "rareQuantity": 11, "itemQuantity": 11}, "unopened": false, "displayGroup": {"value": "gold"}}, {"assetId": 7, "id": 7, "packType": "GOLD", "description": "Special Players Pack", "state": "active", "saleType": "promo", "limitType": "NONE", "quantity": 0, "purchaseLimit": 0, "purchaseCount": 0, "isPremium": false, "sortPriority": 4, "currencies": [{"name": "coins", "funds": 25000, "finalFunds": 25000}], "extPrice": {"finalPrice": {"amount": 250, "currency": "mtx"}, "originalPrice": {"amount": 250, "currency": "mtx"}}, "packContentInfo": {"bronzeQuantity": 0, "silverQuantity": 0, "goldQuantity": 11, "rareQuantity": 11, "itemQuantity": 11}, "unopened": false, "displayGroup": {"value": "special"}}], "timestamp": 1596326400}
|
||||
@@ -0,0 +1 @@
|
||||
{"purchase": [{"assetId": 1, "id": 1, "packType": "BRONZE", "description": "Bronze Pack", "state": "active", "saleType": "promo", "limitType": "NONE", "quantity": 0, "purchaseLimit": 0, "purchaseCount": 0, "isPremium": false, "sortPriority": 1, "currencies": [{"name": "coins", "funds": 400, "finalFunds": 400}], "extPrice": {"finalPrice": {"amount": 4, "currency": "mtx"}, "originalPrice": {"amount": 4, "currency": "mtx"}}, "packContentInfo": {"bronzeQuantity": 5, "silverQuantity": 0, "goldQuantity": 0, "rareQuantity": 0, "itemQuantity": 5}, "unopened": false, "displayGroup": {"value": "bronze"}}, {"assetId": 5, "id": 5, "packType": "GOLD", "description": "Gold Pack", "state": "active", "saleType": "promo", "limitType": "NONE", "quantity": 0, "purchaseLimit": 0, "purchaseCount": 0, "isPremium": false, "sortPriority": 2, "currencies": [{"name": "coins", "funds": 5000, "finalFunds": 5000}], "extPrice": {"finalPrice": {"amount": 50, "currency": "mtx"}, "originalPrice": {"amount": 50, "currency": "mtx"}}, "packContentInfo": {"bronzeQuantity": 0, "silverQuantity": 0, "goldQuantity": 7, "rareQuantity": 7, "itemQuantity": 7}, "unopened": false, "displayGroup": {"value": "gold"}}, {"assetId": 6, "id": 6, "packType": "GOLD", "description": "Premium Gold", "state": "active", "saleType": "promo", "limitType": "NONE", "quantity": 0, "purchaseLimit": 0, "purchaseCount": 0, "isPremium": false, "sortPriority": 3, "currencies": [{"name": "coins", "funds": 15000, "finalFunds": 15000}], "extPrice": {"finalPrice": {"amount": 150, "currency": "mtx"}, "originalPrice": {"amount": 150, "currency": "mtx"}}, "packContentInfo": {"bronzeQuantity": 0, "silverQuantity": 0, "goldQuantity": 11, "rareQuantity": 11, "itemQuantity": 11}, "unopened": false, "displayGroup": {"value": "gold"}}, {"assetId": 7, "id": 7, "packType": "GOLD", "description": "Special Players Pack", "state": "active", "saleType": "promo", "limitType": "NONE", "quantity": 0, "purchaseLimit": 0, "purchaseCount": 0, "isPremium": false, "sortPriority": 4, "currencies": [{"name": "coins", "funds": 25000, "finalFunds": 25000}], "extPrice": {"finalPrice": {"amount": 250, "currency": "mtx"}, "originalPrice": {"amount": 250, "currency": "mtx"}}, "packContentInfo": {"bronzeQuantity": 0, "silverQuantity": 0, "goldQuantity": 11, "rareQuantity": 11, "itemQuantity": 11}, "unopened": false, "displayGroup": {"value": "special"}}], "timestamp": 1596326400}
|
||||
Reference in New Issue
Block a user