Files
OpenFUT/docs/status-review.md
funman300 1fb664710a docs: add FLE bridge direction pivot and squad-injection test tooling
Adds the app-centric FLE bridge direction (direction.md) replacing the
Blaze-backend route as primary plan, plus a corrected foundational test
procedure and snapshot/diff/apply tooling for reverse-engineering FLE's
Freeze Lineup write mechanism. Also picks up prior untracked research docs
(status-review, fut-integration-options, fifa23-startup-flow, track-c) and
existing capture/export tooling that hadn't been committed yet.
2026-06-30 13:19:27 -07:00

18 KiB
Raw Permalink Blame History

OpenFUT Status Review

Generated 2026-06-30 — read-only stocktake, no code changed.


Executive Summary

OpenFUT has a mature offline FUT economy backend (Core, 25 phases, fully functional in isolation) and a sophisticated hook DLL that loads into FIFA 23, redirects EA hostnames to loopback, and bypasses TLS certificate verification. The Blaze/ProtoSSL layer is structurally ready: framing code exists, a TLS listener runs, cert-verify is patched. However the project is currently blocked before any Blaze traffic is ever seen. The fundamental problem is that FIFA 23 submits GoOnline to EbisuSDK and then waits for an asynchronous ONLINE_STATUS_EVENT push from the EA-app LSX server — a push that current code never sends. Every approach tried so far (flipping poll return values, forcing the state flags, read-only probes) confirms the gate is event-driven, not poll-driven. The Blaze captures directory contains six empty files. No Fire2 frame from FIFA 23 has ever been decoded. Until the ONLINE_STATUS_EVENT push is synthesized and delivered correctly, Milestones 27 are all waiting on the same single wall.


1. Proven vs Assumed

Claim Status Evidence
FIFA 23 uses DirtySDK / ProtoSSL Proven String scan hit ProtoSSLSend, ProtoSSLRecv, gosredirector in FIFA23.exe memory (Task 1)
version.dll loads and runs hook code Proven hook.log written at DLL_PROCESS_ATTACH
getaddrinfo IAT hook redirects EA domains to loopback Proven Hook log records every EA getaddrinfo call; connect_hook log confirms port redirects
ProtoSSL cert-verify prologue found and patched (FIFA23.exe) Proven ssl_patch.rs prologue confirmed at file offset 0xf0c850; hook log "ssl: main exe cert-verify patched"
ProtoSSL cert-verify patched in EAWebKit.dll Proven (if loaded) Lazy patch fires on first EA getaddrinfo call; hook log message confirms
Gate is upstream of DirtySDK — no DNS/connect fires on FUT entry Proven getaddrinfo, connect, WSASend/Recv hooks all show zero external traffic during "connecting to EA Servers"
GoOnline is called by the game Proven Read-only detour on anadius64.dll+0x2BB90 confirmed hit
anadius returns GoOnline success Proven Handler observed returning successfully; game still retries every ~7 s
Gate is downstream of GoOnline Proven GoOnline called + returns success; no Blaze connect follows
Connection-state function: GetInternetConnectedState @ anadius64.dll+0x27790 Proven Located via anadius LSX command-registration table; two-flag branch decoded (+0xCAB1A, +0xCAB1B)
Gate is event-driven (game waits for async push, not a poll return) Proven Forced both state flags AND GoOnline return to "1"; game kept retrying; worker-thread stack scan confirms handler runs on anadius IOCP thread, not FIFA's thread
GoOnline runs on anadius worker thread, not FIFA's call thread Proven Stack scan from inside detour found zero FIFA23.exe frames, sp ~2.4 KB from thread stack top
protossl-scan live toolkit is exhausted for finding GoOnline in FIFA23.exe Proven No "GoOnline" string in image; worker-thread call stack has no FIFA frames; jmpscan yields ~3875 hits (overwhelmingly data false positives)
FIFA 23 redirector config references Authorization: header (Nucleus token) Proven Found in FIFA23.exe .rdata pointer table @ +0x83FC858
openfut-core REST API complete and tested Proven 25 phases, 15 migrations, passing integration tests
Bridge LSX server starts and handles request-response Proven (code) openfut-bridge/src/lsx.rs + main.rs — server starts on 127.0.0.1:3216
Bridge LSX server ACTUALLY receives FIFA's LSX connections UNCONFIRMED anadius may intercept the same calls in-process before the TCP connection reaches the bridge
Bridge LSX server GetInternetConnectedState → connected="1" unblocks the gate UNCONFIRMED (known to fail in-process) Flipping the value via anadius in-process failed; bridge path not yet confirmed working
ONLINE_STATUS_EVENT push XML format UNKNOWN No capture; format not derived
Fire2 framing is correct for FIFA 23 UNCONFIRMED Implemented based on post-2012 EA convention; all blaze captures are empty (0 bytes)
Blaze component / command IDs for FIFA 23 UNKNOWN Zero captures; dispatch table entirely empty placeholders
ProtoSSL recv-injection convention (non-blocking return values etc.) UNCONFIRMED Never reached M4; recv_hook module removed from active install path
FUT REST endpoint paths in mapper.rs SPECULATIVE Based on community knowledge of older FIFA titles; the one actual capture in captures/ is an early GET from before the Blaze strategy
FLE Lua API exposes FUT DB tables in memory UNKNOWN export_squad.lua has never been run; FUT data may only exist server-side in online mode

2. Milestone Status

Milestone Status Blocker Depends on unconfirmed assumption?
M1 — Locate connection-state decision point Done No
M2 — Flip gate, force "connected" Blocked Game waits for async ONLINE_STATUS_EVENT push; no current code sends it Yes — unknown event XML format
M3 — First ProtoSSL plaintext on Blaze connection 🔲 Not started Depends on M2 Yes — Fire2 framing unconfirmed
M4 — Answer redirector + decode first Fire2 frame 🔲 Not started Hard wall: Fire2 framing, recv-injection convention, component/command IDs all unconfirmed Yes — all three unknown
M5 — Blaze preauth / login / postauth 🔲 Not started Depends on M4 Yes — Blaze auth TDF body layout unknown
M6 — FUT entry + hub load 🔲 Not started Depends on M5; also requires FUT REST response shapes confirmed Yes — endpoint paths speculative
M7 — Squad Battles (AI FUT) 🔲 Not started Depends on M6 Yes

Note on roadmap.md wording: Under M2M4, roadmap.md uses **Done (observable):** bullets. These describe the success criterion for each milestone, not an achieved state. The authoritative status is in connection-gate-findings.md (M2 attempts failed; M3/M4 never started). The roadmap has not been updated to reflect M2 failure.

M4 is the first hard wall in detail

Even assuming M2 is solved, M4 requires three unconfirmed things simultaneously:

  1. Fire2 framing — the 12-byte header layout is assumed; if FIFA 23 uses an older Fire variant or a custom delta, the codec will misparse every packet.
  2. ProtoSSL recv-injection — delivering responses to the game via recv hook requires knowing what return values and buffer conventions ProtoSSL expects; recv_hook.rs exists but is not installed.
  3. Blaze component/command IDs — the dispatch table is entirely empty; we cannot answer any request until IDs are known from captures.

All three are resolved by getting one real captured frame. M4 is primarily a capture problem, not a decoding problem — once bytes exist, the framing and IDs are immediately readable.


3. Blockers, Risks, Unknowns

Blockers (stop progress now)

  1. ONLINE_STATUS_EVENT push not synthesized (M2 wall)
    The game calls GoOnline, gets success, then waits indefinitely for a push event on the LSX socket that never arrives. This is the single gate blocking all Blaze work. Options: (a) trace the event format via Ghidra on FIFA23.exe (xref ONLINE_STATUS_EVENT string + the game's EbisuSDK listener), (b) RE anadius's LSX event-send path (find what it would push in an "online" scenario), (c) brute-force push candidate event XMLs and observe whether the game advances.

  2. Bridge LSX server delivery unconfirmed (architectural risk converted to blocker)
    The hook passes port 3216 connections through, assuming the bridge LSX server on the Linux host receives them. If anadius's in-process hooks intercept the winsock calls before they reach the TCP stack, the bridge server is never reached. This must be confirmed by checking openfut_hook.log for a getaddrinfo on the LSX host, or by observing the bridge server's accept logs.

Risks (could derail later)

  1. Fire2 framing wrong (M4 risk)
    If FIFA 23 uses Fire (pre-2012) or a modified frame layout, the codec misparses. Mitigation: the server has a Raw fallback mode for capturing raw bytes when framing fails.

  2. Secondary auth-token gate (M5 risk)
    connection-gate-findings.md noted the redirector request carries an Authorization: header. M1's final conclusion said GetAuthCode returns a fake token that appears accepted — but this was inferred, not confirmed by seeing the redirector request actually constructed with that token.

  3. EAAC not fully neutralized (persistent risk)
    FakeEAACLauncher bypasses the anticheat launcher. The hook DLL is unsigned. If EAAC is ever active (e.g., after a game update re-enables it), all hooks fail silently. Marked as "not active in offline/cracked builds" — assumed, not confirmed on every launch.

  4. FUT REST response shapes wrong (M6 risk)
    The 61 endpoint mappings in mapper.rs and the shaper stubs in shaper.rs are based on community guesses about older FIFA FUT APIs, not FIFA 23 captures. Response JSON shapes may differ enough to cause the client to fail silently or crash.

Unknowns (open questions)

  1. ONLINE_STATUS_EVENT XML format — exact tag names, field order, sender attribute, and any nonces/tokens required.
  2. GoOnline event sequence — whether ONLINE_STATUS_EVENT alone is sufficient or a sequence of events (e.g., PROFILE_EVENT, LOGIN_EVENT, COMMERCE_EVENT) is expected.
  3. Whether FLE exposes FUT DB tables — FUT card inventory and squad data likely live server-side in online mode; FLE may not surface them for in-process editing.
  4. Blaze component/command IDs for FIFA 23 — entirely unknown; no captures.
  5. openfut_hook.log current content — we have the code but no log output in any document. Whether the current hook (with connect, ssl_patch, tls_bypass, WSAIoctl, origin_spy all installed) fires correctly and what it observes is unverified in this review.

4. Track Comparison

Track A — Full EA-backend fake (M1M7, playable FUT vs AI)

What it delivers: The FIFA 23 FUT hub loads from OpenFUT Core; Squad Battles matches play and reward economy items.

Effort: Research-grade. Minimum path: synthesize ONLINE_STATUS_EVENT (unknown format, 12 weeks of RE), then capture Fire2 frames (days once M2 is solved), then implement Blaze auth handlers (weeks), then implement FUT entry (weeks), then Squad Battles (weeks). Realistic minimum: 36 months of expert RE work.

Proven support: Hook loads and redirects correctly. TLS bypass patched. Core economy backend complete. Blaze framing code and TLS listener exist.

Assumed: Fire2 framing correct; component/command IDs discoverable from captures; FUT REST shapes close enough to community guesses; no additional undiscovered gates.

Evidence for: Architecture is coherent. The M1 finding (gate precisely named and decoded) was achieved cleanly. The in-process hook approach is validated.

Evidence against: M2 was attempted and failed with the in-process approach. The event-driven architecture adds a full EbisuSDK emulation layer before even one Blaze byte is seen. The live toolkit is exhausted (Path A verdict); Ghidra-level work on a 505 MB binary is required. Six capture files with zero bytes.


Track B — Clean-room spec deliverable (M1M5 documented)

What it delivers: A documented map of the connection gate, LSX event sequence, Blaze auth surface (transport, framing, gate conditions, component IDs, TDF schemas). Valuable as an archival/community artifact even if Track A stalls.

Effort: Medium. M1 is done. M2M5 documentation emerges as a by-product of engineering work. The spec itself (writing) is lightweight; the engineering to produce the captures is the cost.

Proven support: M1 complete and documented. connection-gate-findings.md is already a high-quality spec artifact.

Assumed: Same as Track A for the unconfirmed values, but the spec can mark them TODO/CONFIRM rather than needing to implement them.

Evidence for: The clean-room constraint means a spec is the only artifact that can be safely published. connection-gate-findings.md shows this approach produces real value. B finishes even if A is never fully playable.

Evidence against: Track B alone doesn't produce a playable FUT; it is a foundation, not an end-user product.


Track C — FLE Lua bridge (local-match path, skip the backend gate)

What it delivers: FIFA 23 career mode or Kick-Off with an OpenFUT club's players and squad loaded via FLE's in-memory DB API. No online gate, no Blaze, no TLS. Fully offline from day one.

Effort: Low-to-medium. FLE is already loaded in the normal launch path. Tools exist (tools/squad-exporter/, tools/profile-exporter/). Primary unknown is whether FUT-relevant DB tables are accessible.

Proven support: FLE Lua API exposes GetDBTableRows / EditDBTableField for career mode. fifa23-startup-flow.md confirms FLE injects at load. fut-integration-options.md documents the integration path in detail and rates this as the recommended option.

Assumed: FUT card/club/squad data has in-memory DB table representations that FLE can write. If FUT data is purely server-side (loaded from EA servers, not from the Frostbite DB layer), Track C produces no FUT simulation at all — only career mode player stats.

Evidence for: Career mode already works with FLE edits (community precedent). Tools are present and designed for this path. No infrastructure work needed.

Evidence against: FUT in FIFA 23 uses server-side data. The cards in a player's FUT club, the coins, the squad — these are fetched from fut.ea.com REST APIs, not from the Frostbite embedded DB. FLE's GetDBTableRows likely exposes base player stats tables but not FUT item tables. The crucial test (run export_squad.lua while in FUT mode) has never been done.


Recommendation

Start Track C immediately as a parallel, low-cost validation.

Run export_squad.lua in FLE while inside the FUT hub (or attempting to enter it). If FUT tables appear in the export, Track C is viable and is the fastest path to something a user can interact with. This test takes one session and costs nothing.

Simultaneously, continue Track A/B with the next concrete RE step: synthesize the ONLINE_STATUS_EVENT push. The most actionable option is to run origin_spy logs from the current hook to see what LSX events fire during a session, then attempt to push candidate event XMLs via the bridge LSX server and watch whether the game advances. This is bounded, testable work that either unblocks M2 or produces the spec value for Track B.

Do not abandon Track A/B for Track C — they are complementary. Core is already built; the bridge is mostly built. The gap is purely the RE wall at M2.


5. Architecture and Provenance Sanity-Check

Hook + Brain coherence

The CLAUDE.md bridge architecture diagram (hook intercepts ProtoSSL → plain localhost TCP → blaze_brain → Core) remains coherent. The M1/M2 findings revealed one additional layer (EbisuSDK LSX event) that must precede the Blaze connection. The bridge has been updated to handle LSX directly. The overall design is sound; the M2 blocker is an implementation gap (event synthesis), not an architectural flaw.

One inconsistency to flag: The hook's lsx.rs contains a complete in-process LSX emulator (AES-128-ECB, CRandom, all response builders), but the recv/send hooks that activate it are explicitly removed (lib.rs: "recv/send hooks removed — LSX is now handled by the native openfut-bridge LSX server"). This is dead code. The bridge's LSX server is the current path. The in-process lsx.rs should either be deleted or documented as a fallback; its presence is confusing.

Clean-room status

No evidence of EA leaked source anywhere in the tree. All RE work is derived from:

  • Running the shipping binary and observing behavior (function return values, network traffic patterns)
  • Memory scanning of the live process (string search, xref, disasm of observed addresses)
  • Reading anadius's own compiled output (its exported symbols, its LSX XML format — which is anadius's own implementation, not EA's)
  • Community FUT API knowledge (mapper.rs endpoint paths — plausible but speculative)

The Blaze framing in fifa-blaze/crates/blaze-proto/src/frame.rs cites "Fire2 used by ME3, BF3, and most post-2012 titles" — this is sourced from public community documentation of those older titles, not from any leaked EA source. Clean-room intact.

The AES_KEY in the hook's lsx.rs ([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]) is a placeholder key used for the LSX session encryption. The real session key is derived from the challenge seed via CRandom — this algorithm was RE'd from anadius's own binary. No EA source required.


6. If You Read Only This

  • The project is blocked at M2. FIFA 23 submits GoOnline, gets success, then waits for an async ONLINE_STATUS_EVENT push on the LSX socket that no current code ever sends. All six Blaze capture files are empty (0 bytes). No Fire2 frame has ever been decoded.

  • M1 is the only completed milestone. The gate function (GetInternetConnectedState @ anadius64.dll+0x27790) is precisely named and its two-flag branch decoded. Everything after M1 is either blocked or not started.

  • The next concrete action is synthesizing the ONLINE_STATUS_EVENT push XML and testing whether the bridge's LSX server can deliver it to the game. This is the single thing that unblocks all Blaze work.

  • Track C (FLE Lua) is untested but cheap to validate. Run export_squad.lua while in FUT to find out if FUT DB tables are accessible. If yes, it is the fastest path to user-visible results. If no, it is ruled out with one session.

  • openfut-core is complete and ready — 25 phases, 15 migrations, full economy REST API, passing tests. It is not blocking anything; it is waiting for the bridge to connect to it.