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.5 KiB
Agent brief — reverse the FIFA17 Origin-SDK CONNECT handshake + Blaze login trigger (clean-room)
Clean-room rule (HARD)
Derive ONLY from the decrypted .bin/.asm dumps here + live /proc/PID/mem (pid via
pgrep -x FIFA17.exe, currently 13643) + our own LSX/Blaze logs. NEVER leaked EA source.
Story so far (established this session, all live-verified)
The online-login is a coordinated chain: Origin SDK connect → default user → auth code → Blaze login → account info. We forced individual pieces; each got us one layer deeper and revealed the next:
m_isLoggedIn(OriginMgr+0x13) is NOT the gate (forcing it from boot changed nothing).DoTick @0x146f199c0(FirstPartyAuthTokenRetriever) polls a 2-slot queue atretriever+0x8(retriever = *[0x1448a3b20]+0x4e98); empty → never requests auth.- We FORGED a
FirstPartyAuthCodeFutureImplnode (0xF0 bytes, see docs/ENQUEUE_PLAN.md) + setOriginSDK(*[0x144b7c7a0])+0x3a0default-user, andDoTickprocessed it and calledOriginRequestAuthCodeSync(impl0x1470e67f0). It DID send<GetAuthCode ClientId="FIFA17PC">over LSX and we answered with an AuthCode — BUT the node also logged Origin Error0xa2080000, and crucially BlazeAuthentication::login (1/0x0A)STILL never fired (count 0); FIFA only ever sendsAuthentication::logout (1/0x46). - The
0xa2080000originates inside0x1470e67f0: after the arg-guards pass, it looks up Origin service/interface id0x1e8via thunk0x1470dbfa0→[0x144b7c778](dispatcher0x1470d9380), which returns NULL → the Origin SDK is not truly CONNECTED.
The two questions to crack
- What makes the Origin SDK "connected" — i.e. what writes
OriginSDK+0x3a0(default user) and registers service0x1e8? The writer is0x1470e5ad5(dumpsdk_connect_writer_1470e5980.asm), guarded by a ~15s connect-wait loop at0x147118d80(dumpconnect_wait_guard_147118c00.asm, literal "EbisuSDK" nearby). What LSX exchange / event does that wait poll for, that our responder is not providing? If we answer it, the SDK connects and +0x3a0 + service 0x1e8 populate naturally. - Why does FIFA send Blaze
logoutnotlogineven when an auth code is available? Reverse the Blaze LoginManager's decision to callAuthentication::login (1/0x0A)— what precondition it checks (likely a connected Origin session + a valid client-config[cfg+0x750], which our emptyfetchClientConfignever populates — the Blaze-SDK auth fetchers0x147237350/0x147237450, dumpsblaze_authfetch1/2, bail on exactly that).
Dumps here (decrypted; objdump Intel, VMA==runtime VA)
sdk_connect_writer_1470e5980.bin.asm— the +0x3a0/+0x3a8 writer (0x1470e5ad5) + surrounding connect fnconnect_wait_guard_147118c00.bin.asm— the ~15s connect-wait guard (0x147118d80)svc_dispatch_1470d9380.bin.asm— the service-lookup dispatcher (thunk target; id 0x1e8)blaze_authfetch1_147237350.bin.asm,blaze_authfetch2_147237450.bin.asm— Blaze-SDK auth fetchers ([cfg+0x750] bail)authcode_impl_1470e67f0.bin.asm— OriginRequestAuthCodeSync impl (guards + service lookup + send 0x1470e1ed0)dotick_full_146f199c0.bin.asm, plus earlier: origin_getdefaultuser, vt00-31, dispatch/matcher/parser, ENQUEUE_PLAN.md You MAY dump more live decrypted code (ptrace_scope=0):f.seek(va); f.read(n)+ objdump --adjust-vma. Follow callers/callees as needed (e.g. what calls 0x1470e5ad5; what registers service 0x1e8; the Blaze login-state fn).
Our current LSX answers (what FIFA sends → we reply) — for correlation
FIFA boot verbs on :4216: GetConfig, GetProfile(index=0), GetSetting(IS_IGO_ENABLED/ENVIRONMENT/ IS_IGO_AVAILABLE/LANGUAGE), GetGameInfo(FREETRIAL/LANGUAGES/UPTODATE), GetInternetConnectedState, IsProgressiveInstallationAvailable, SetDownloaderUtilization. We answer all (see tools/lsx_responder_v2.py build_reply). Our Blaze fetchClientConfig currently returns near-empty (SV_* keys only). A verb or response we're getting WRONG/EMPTY is the likely reason the SDK never connects — find it.
Deliverable
Concrete, ranked, SERVER-SIDE changes (LSX responder verbs/responses + Blaze fetchClientConfig content)
that make: (1) the Origin SDK connect (populate +0x3a0 + service 0x1e8), and (2) FIFA send Blaze
login (1/0x0A). For each: the exact LSX/Blaze message + expected observable (service 0x1e8 non-null;
Authentication::login on /tmp/blaze_responder.log). Note anything still needing a live experiment.