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 -- <GetAuthCode UserId ClientId Scope AppendAuthSource/>. 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 <noreply@anthropic.com>
This commit is contained in:
@@ -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):**
|
||||
|
||||
```
|
||||
<GetAuthCode UserId="<int>" ClientId="<str>" Scope="<str>" AppendAuthSource="true|false"/>
|
||||
```
|
||||
|
||||
- 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.
|
||||
|
||||
Reference in New Issue
Block a user