From 24c1925b5f9567b4da827a3d9122dbdcbcf153c4 Mon Sep 17 00:00:00 2001 From: funman300 Date: Thu, 2 Jul 2026 17:25:41 -0700 Subject: [PATCH] docs: recover GetAuthCode request format; localize gate to EASFC job-enqueue poll Traced the far end of the online gate: FIFA's GetAuthCodeT::Serialize (+0x278d2c0) yields the exact LSX request it would send to start the Nucleus->Blaze chain -- . It is wrapped by a GetAuthCodeJob in the EASFC online-job module. The wall is not the LSX wire or event delivery (events parse fine) but that FIFA's EASFC controller never enqueues the job -- it polls cached online state and our single isOnline flag doesn't satisfy the combined condition. Closes the is-it-the-events question (no); next artifact is the controller poll guard. Co-Authored-By: Claude Fable 5 --- docs/connection-gate-findings.md | 81 ++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/docs/connection-gate-findings.md b/docs/connection-gate-findings.md index 774c2ec..2a77dbe 100644 --- a/docs/connection-gate-findings.md +++ b/docs/connection-gate-findings.md @@ -761,9 +761,90 @@ path alone flips the game-side online state machine — the real gate is in FIFA online orchestrator, reachable only by probing the runtime virtual listener or a deeper RE of that state machine. +### Live listener captured — the event callback is a NO-OP (2026-07-02) + +Added a behavior-preserving mid-function detour (probe.rs `openfut_listener_stub`, +patch at FIFA23.exe+0x274d4d7) to capture the runtime target of the OnlineStatusEvent +dispatch (`call [rax+0x28]`). Result: + +``` +PROBE OnlineStatus.listener: vtable=0x1480b9ac0 (rva 0x80b9ac0) fn=0x142751060 (rva 0x2751060) +``` + +`FIFA23.exe+0x2751060` is `ret 0x0` — a **no-op**, one of a table of identical `ret 0` +stubs (i.e. the default/empty virtual slot; this object does not override the +online-status notification). So the immediate event callback does nothing. + +**Reframes the approach.** `OnlineStatusEventT::HandleMessage` does two things: it +stores the parsed bool into a map (state), then calls this (no-op) notify. So our push +updates FIFA's *stored* online state but triggers no active reaction — there is no +callback to kick off the auth/Blaze chain. The transition must be driven by FIFA +**polling** that stored state (consistent with the observed GetProfile / +GetInternetConnectedState polling), gated on some combined condition our single +online flag doesn't satisfy. Event-pushing alone cannot trigger it; the next dig is +the state reader / poll gate (who reads the map HandleMessage writes, and what else it +requires), which is deeper FIFA-internal RE. + +The probe tooling now cleanly captures live virtual-dispatch targets (alignment-safe +mid-function detour) — reusable for the next layer. + ### Next gate: Blaze/online (M2) "connecting to EA servers" is the Blaze layer. The hook log shows FIFA has made **no** Blaze connect yet (nothing on 443/10041/42127) while spinning, so it is stalled at pre-auth. Per the architecture, Blaze rides ProtoSSL in-process (a different transport than LSX), so serving it is separate, larger work — the M2 effort, now actually reached. + +--- + +## GetAuthCode request format recovered — the gate is job-enqueue, not event-push (2026-07-02) + +Continuing past the "live listener is a NO-OP" finding, I traced the *other end* of +the gate: the LSX request FIFA must send to start the Nucleus→Blaze chain, and what +gates it. Static RE of FIFA23.exe (clean-room; the client's own serializers are the +oracle). + +**The request FIFA would send (exact, from its serializer at FIFA23.exe+0x278d2c0):** + +``` + +``` + +- Serializer `GetAuthCodeT::Serialize` @ **FIFA23.exe+0x278d2c0**. Element string + `GetAuthCode` @ .rdata 0x1480c27d0 (its *only* xref — this is the sole builder). +- Field layout in the request struct: `UserId=[rbx+0x00]`, `ClientId=[rbx+0x08]` + (string), `Scope=[rbx+0x28]` (string), `AppendAuthSource=[rbx+0x48]` (bool). +- Attribute-name strings: `UserId` 0x147ea7bc8, `ClientId` 0x1480c2c98, + `Scope` 0x147c79514, `AppendAuthSource` 0x1480c2ca8. +- This is rung 1 of M2's auth chain: FIFA asks the SDK (== us, over LSX) for a Nucleus + auth code; it then exchanges that code at accounts.ea.com → token → gosredirector → + Blaze. We now know the exact request to answer once we can make FIFA send it. + +**Who sends it — and the actual gate.** The request is wrapped by a **`GetAuthCodeJob`** +inside FIFA's EASFC online-job module (a large block ~FIFA23.exe+0x51b0000..0x528xxxx; +job/response telemetry tags `GetAuthCodeJob` @ 0x1484630d0, `GetAuthCodeJobResponse` @ +0x148455b98). The job's completion/response handler is at **FIFA23.exe+0x51b66c0** (sets +its done-flag `[r15+8]=1`, logs via those tags). The serializer is invoked polymorphically +from the LSX client when the job runs — it is **not** called directly, so there is no +static call-xref from the trigger; the job is *enqueued* by the EASFC online controller's +state machine. + +**Conclusion (the gate, precisely stated).** The wall is **not** on the LSX wire and +**not** in event delivery (our OnlineStatus/Login events parse fine; cf. the no-op-listener +finding above). The wall is that FIFA's **EASFC online controller never enqueues +`GetAuthCodeJob`**. That controller decides "am I online enough to authenticate?" by +*polling* its cached online state (the map `OnlineStatusEventT::HandleMessage` writes), +and our single `isOnline=true` flag does not satisfy its combined condition. So: + +- Event-push alone cannot cross it (confirmed twice now, from both ends). +- The true next artifact is the **EASFC controller's online-readiness poll** — the guard, + in that 0x51b0000..0x528xxxx module, that must pass before `GetAuthCodeJob` is enqueued. + That is a large state-machine RE (hundreds of KB of EASFC job code), i.e. the genuine + multi-week M2 frontier the status review priced. + +**Net for this session:** recovered the exact `GetAuthCode` request format (so the round +trip is ready when we cross the gate) and localized the gate to a specific FIFA module and +mechanism (EASFC job-enqueue poll, not LSX/events). This closes the "is it the events?" +question — it is not. The remaining work is FIFA-internal EASFC state-machine RE, which +sits directly against the [[project_direction_pivot]] (FLE career mode is the stated +primary plan) as a cost/priority decision, not a technical unknown on the LSX side.