Files
OpenFUT/fifa17-recon/tools/login_dump/BRIEF4.md
T
funman300 edab23f04a fifa17-recon: package the working offline FUT backend
Emulates FIFA 17's full online + Ultimate Team stack against an offline,
clean-room backend (no EA servers). Proven end-to-end 2026-08-01:
Origin login -> Blaze login -> device-trust -> the FUT hub.

Package:
- tools/openfut-fut.sh   one-command orchestrator (start/stop/status/restart)
- tools/root_arm.sh      idempotent host arm (sysctls, DNAT, /etc/hosts easw)
- tools/{lsx_responder_v2,blaze_responder_v3b,roster_server,utas_server,autopatch}.py
  the 5 servers (Origin LSX :4216, Blaze :42127/42130/42131, roster :8081,
  FUT/UTAS :8099) + heat2.py (Fire2/Heat2 TDF codec)
- FUT-RUNBOOK.md         runbook + gate-ladder troubleshooting
- docs/, tools/login_dump/*.md   the reverse-engineering write-ups

All findings are clean-room, from binaries we own; nothing from any leak.
The wire protocol maps 1:1 to FIFA 23.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PN5bmpDVQR1aXgefyWAt7o
2026-08-01 09:12:17 -07:00

54 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Agent brief — reverse the FIFA17 OSDK_UNDERAGE_ERROR (Origin error 0xa2000012) (clean-room)
## Clean-room rule (HARD)
Derive ONLY from decrypted dumps here + live /proc/PID/mem (`pgrep -x FIFA17.exe`, live 39211) +
our LSX/Blaze logs. NEVER leaked EA source.
## Where we are (this session's WIN)
The recipient-echo fix (lsx_responder_v2.py: response `sender` must byte-equal request `recipient`)
CASCADED the whole Origin login chain. Live-confirmed NATURAL (no forging): OriginSDK(*[0x144b7c7a0])
+0x3a0/+0x3a8 = 0x1f89493 (default user set), FIFA issued GetAuthCode ×3 on its own (FIFA17PC +
FIFA17PC-SERVER), SetPresence flowing ("In Menus"). The OSDK login state machine advanced
OSDK_INVALID_USER → **OSDK_UNDERAGE_ERROR**. On screen: "not eligible to use EA's online features due
to an age restriction". Blaze login (1/0x0A) still 0 — this age gate blocks before it.
## The exact gate
OSDK classifier **0x14717d5d0** (dump osdk_classifier_14717d5d0.bin.asm): reads the OSDK/Ebisu
manager's cached "last error" and maps it:
`cmp eax,0xa2000003 -> OSDK_INVALID_USER` (we cleared this — user now valid)
`cmp eax,0xa2000012 -> OSDK_UNDERAGE_ERROR` (the CURRENT error) <-- the target
The error code comes from the manager chain: manager `*[0x144b86bf8]` = live 0x43c46c70,
vptr **0x143959168**; classifier does `mov rcx,[0x144b86bf8]; mov rax,[rcx]; call [rax+0x60]` (=
**0x14719b1b0**, dump mgr_vt60_14719b1b0.bin.asm) -> rsi (a sub-object); then `rsi->vt[0x68]()` ->
the error code = 0xa2000012.
## What is ALREADY RULED OUT (do not re-chase)
- NOT from GetProfile: the IsUnderAge bool-parse (helper 0x14713ffa0: strconv result -> `setne al`,
so "false"->0 = not-underage) stores our IsUnderAge="false" correctly. GetProfile deserializer
0x147136140 reads only: UserId PersonaId Persona AvatarId Country IsUnderAge IsSubscriber
GeoCountry CommerceCountry CommerceCurrency — no DOB/age field.
- 0xa2000012 is NOT constructed by inline mov+lea/add arithmetic ANYWHERE in 0x146000000-0x1476f0000
(scanned, 0 sites). So it is a DATA-TABLE value (scan DATA regions for the raw dword `12 00 00 a2`
= an error-map table), or a value read from a Nucleus/HTTP/Blaze response, or a field.
- Nucleus :42131 was NOT hit this boot (no live conn) and Blaze login=0 — so the underage was cached
by an Origin/LSX operation during boot, before Blaze/Nucleus. (Confirm; don't assume.)
## The questions to answer
1. **Which sub-object does manager->vt[0x60] (0x14719b1b0) return, and where is its error field
(read by vt[0x68]) WRITTEN with 0xa2000012?** Find the writer = the operation that decided underage.
2. **What is 0xa2000012's source** — locate the raw dword in a data/error-map table (scan .rdata/.data
for `12 00 00 a2`), find the code that selects it, and what INPUT maps to it (an HTTP/Nucleus status?
a profile/account field? an entitlement? a hardcoded default when age is unverified?).
3. **What CONDITION makes FIFA underage** despite IsUnderAge="false"? Trace back from the writer to the
input we control (an LSX verb/field we answer wrong or omit, a Blaze reply, a missing DOB, an
entitlement/age-rating check). We own every server endpoint FIFA talks to.
4. **The fix**: concrete LSX/Blaze/Nucleus responder change (verb/field/value) that makes FIFA classify
the user as an adult, so OSDK advances past OSDK_UNDERAGE_ERROR toward Blaze login.
## Dumps / method
osdk_classifier_14717d5d0, mgr_vt60_14719b1b0, getprofile_deser_147136140, boolparse_ffa0,
authcode_impl_1470e67f0, sdk_connect_writer, + earlier auth/connect dumps. objdump Intel, VMA==runtime VA.
Dump more live: `f.seek(va); f.read(n)` + objdump --adjust-vma. Data-dword scan: read region, `d.find(b'\x12\x00\x00\xa2')`.
Every claim needs a VA/bytes/disasm/log line. We can WRITE /proc/mem too (A/B: poke a candidate field, watch
OSDK state 0x43d189d8+0x80 [re-find via vptr 0x14395c180] leave "OSDK_UNDERAGE_ERROR").