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
4.7 KiB
Agent brief — FUT loading-screen QUIET STALL (what is FIFA waiting for?) (clean-room)
Clean-room rule (HARD)
Derive ONLY from decrypted FIFA17.exe dumps + live /proc/PID/mem (pgrep -x FIFA17.exe, live 66672)
- /tmp/blaze_responder.log + /tmp/blaze_rx/ + blaze_responder_v3b.py. NEVER leaked EA source/headers.
Where we are — the WIN, and this stall
This session cracked the ENTIRE FIFA17 login+connection+FUT-service-init chain (8 gates, each a one-attribute/value/type/RPC responder fix). FIFA now: logs in, holds a live Blaze session, and after selecting FUT reached the Ultimate Team LOADING screen (stadium + "17", NO error). The last fix (CensusData subscribe) stopped a 71k-retry storm and let FIFA run its FUT-init RPC burst. NOW FIFA IS QUIET-STALLED on the loading screen: idle-pinging Blaze every 20s, NOT storming, NOT reaching any new endpoint (no SYN-SENT to UTAS/fut.ea.com), both LSX:4216 + Blaze:42130 conns STABLE. It ran its init burst, took our (mostly EMPTY) replies, and is WAITING for something to complete the load.
KEY ADVANTAGE: FIFA is LIVE-FROZEN at the wait point right now (pid 66672). The FUT/OSDK loading-state object is inspectable in memory as-is — find the flag/counter it is polling.
The FUT-init RPC burst FIFA sent (decoded from /tmp/blaze_rx/), and how we replied
| # | RPC | request (decoded) | our reply |
|---|---|---|---|
| listEntitlements | Auth 1/0x20 | GNLS=['FIFA17PCBoxContent','FIFA16PC'], FLAG=3 | entitlements_response NLST=[1 entitlement, GNAM="FIFA17PC", TAG=ONLINE_ACCESS] — GROUP MISMATCH? |
| getInvitations | Clubs 0x000b/0x0640 | CLID=0 INVT=0 NSOT=0 | EMPTY |
| fetchMessages | Messaging 0x000f/0x0002 | FLAG=4, TYPE=... | EMPTY |
| userSettingsLoad | Util 0x0009/0x000a | KEY='FirstTimeFlag' UID=0 | EMPTY (?) |
| userSettingsLoadAll | Util 0x0009/0x000c | (empty) | EMPTY |
| fetchSettings/Groups | OSDKSettings 0x08c9/0x01,0x02 | (empty) | EMPTY |
| getStatGroupList/getKeyScopesMap/getPeriodIds | Stats 0x0007/0x03,0x0f,0x14 | (empty) | EMPTY |
| getEventsURL | SponsoredEvents 0x081c/0x0003 | (empty) | EMPTY |
| getClubsComponentSettings | Clubs 0x000b/0x0a28 | (empty) | EMPTY |
| getInvitations, listEntitlements were the LAST real RPCs (RX #32/#33) before it went quiet. |
Our entitlement reply (blaze_responder_v3b.py entitlement_fields ~:907): GNAM="FIFA17PC", TAG="ONLINE_ACCESS", PJID/PRID="1027460", STAT=1, TYPE=1. The request asked for group "FIFA17PCBoxContent" — investigate whether FUT requires an entitlement in THAT group.
Questions to answer
- What is the FUT loading screen waiting for to complete? FIFA is live-frozen at the wait — find the loading/OSDK state object and the flag/counter/condition it polls or blocks on. What SETS it: a specific RPC reply's data, a server-pushed NOTIFICATION, or a count of completed async loads? (FUT init typically fans out N async "downloaders"/loaders and waits for all to complete.)
- Is it the entitlements? Reverse the listEntitlements (1/0x20) client handler: does FUT gate on an entitlement in group 'FIFA17PCBoxContent' (the box-content / FUT-access grant)? What must our NLST contain (GNAM value, TAG, TYPE, count) so FUT considers the user entitled? Our GNAM="FIFA17PC" may be wrong.
- Is FIFA waiting on a server NOTIFICATION (UserSessions / a FUT-ready / a Messaging / a downloader-complete push) that a real server would send but we don't? Find which notification the loading state consumes.
- Which specific empty-replied RPC (if any) is the block — Stats getStatGroupList, OSDKSettings fetchSettings, Messaging fetchMessages, userSettingsLoad 'FirstTimeFlag', Clubs getInvitations — does any of them feed a required loading input? Reverse the client response handler for the load-bearing one.
- The fix: the minimal blaze_responder_v3b.py change (a non-empty reply TDF for the load-bearing RPC, a corrected entitlement group, and/or a pushed notification) that advances the loading screen. Give exact TDF (tags/types/values) + the observable success signal (FIFA leaves the loading screen / issues the next new RPC / connects to a FUT service).
Method / dumps
Our responder: blaze_responder_v3b.py (dispatch, entitlement_fields, notification()). Heat2: heat2.py. Saved requests: /tmp/blaze_rx/rx_.bin (16B hdr + payload; decode with heat2.decode_tdf). Log: /tmp/blaze_responder.log. FIFA live pid 66672 (frozen at the wait — inspect the loading state NOW). FifaOnline:: reflection ~0x143900000 (SeasonalPlayDownloader, ClubsDivCountDownloader, TournamentHandler, etc. seen there — the FUT loaders live here). Blaze SDK ~0x146d00000-0x147000000. Every claim needs a VA/bytes/disasm/log line. CLEAN-ROOM only.