Commit Graph

13 Commits

Author SHA1 Message Date
funman300 7edf682291 diag(fifa17): port the passive kit-selector trace onto main
Cherry-pick of 4b1d5aa from wip/kit-selector-re, which forked before the TLS
work and cannot be rebased: that branch predates fifa17_tls.rs/patch_mem.rs and
carries a large unrelated lineage (probe/lsx/recv_hook). Only the kit_trace
commit's own contents are taken.

Traces the client-side FUT pre-match kit path in CardsDLL: the GetMatchKits_DP
gate (KITS_AVAILABLE), setAvailableKits (home/away list count), the kit-item
clone driver (item type/subid/teamid at FUN_1801c3480), and the local teamkits
DB clone. Read-only passive detours reusing season_trace's installers, which
this widens to pub(crate).

The one open unknown it answers: the selector requires item+0x60 == 4, a pile
value the server has never been observed to produce (/club emits 1,
/purchased 6).

Verified in the cross-built artifact that the roster TLS gate patch is intact
alongside the new trace (fifa17_tls markers present, KIT_* markers present).
2026-08-21 04:15:58 +00:00
funman300 b098617573 feat(fifa17-hook): patch FIFA17 TLS gates in-process
Milestone B: move FIFA17 ProtoSSL certificate compatibility into version.dll so
the client-local contract is openfut.cfg + LSX + version.dll with no external
/proc-writing patcher. The proven external openfut-autopatch remains the oracle
and is NOT removed; this reaches behavioral parity for the fail-closed patches.

Patch set (ASLR-relocated at runtime; fail-closed byte-verified; one-shot):
- FIFA17.exe ProtoSSL cert gates (REQUIRED_FOR_TLS), preferred base 0x140000000:
    GATE1 rva 0x6132548  0f85 76010000 (JNZ) -> 90*6 (NOP)
    GATE2 rva 0x61361b0  48 89 5c (prologue) -> 31 c0 c3 (xor eax,eax; ret)
  Applied as a pair only when BOTH read their known original, exactly like the
  external patcher's cert_pass; polled until the STEAMPUNKS packer unpacks them.
- CardsDLL empty-My-Packs store crash-guard (REQUIRED_FOR_STORE_TLS, bug 6c),
  preferred base 0x180000000: rva 0x14858  75 0f (JNZ) -> 7f 0f (JG). Applied once
  CardsDLL maps (module-late).

Deliberately NOT ported: the external patcher's 8 unconditional STORE_PATCHES.
They carry no recovered original bytes (cannot be fail-closed) and are re-applied
every tick (would require the constant-rewrite loop this milestone forbids); the
external source records no rationale for them. Documented in the Vault ADR.

Architecture:
- patch_mem.rs: generic fail-closed primitive over a Mem trait — classify
  (ORIGINAL/ALREADY_PATCHED/MISMATCH), apply_checked (read->classify->write only on
  ORIGINAL->reread verify), VirtualQuery-guarded read + VirtualProtect/Flush write
  (WinMem). Trait abstraction makes every outcome host-testable without FIFA.
- fifa17_tls.rs: FIFA17-specific patch table + bounded poll worker (250ms, 15min
  cap, no busy-spin) started from fifa17::install() after the network redirect.
  Never patches an absolute address; never blind-writes on mismatch; a write/verify
  failure is reported, never pretended.

Phase 11: removed the season_trace CACHE_PACKNAMES_FAILED->SUCCESS force-success
bypass (a staging-only behavior-changer that was armed unconditionally in the
candidate); season_trace is now genuinely read-only passive tracing. sbc_dispatch
and store_entry remain the intended REPAIR_PROMOTED fixes.

Tests: 39 hook tests (26 baseline + 13 new: classify states, apply/idempotence,
no-blind-write on mismatch, unreadable-module wait, write-failure reporting, RVA/
live-addr relocation across bases, cert-gate pairing, patch-table integrity).
clippy --features fifa17 -D warnings clean; fmt clean; x86_64-pc-windows-gnu
cross-build. No network-config authority added (routing stays Milestone A).

Runtime validation (x64dbg site check + Windows/Linux retail) still outstanding.
2026-08-20 21:15:27 +00:00
funman300 00ad631034 refactor(launcher): retire FIFA 23; keep the hook game-generic by feature
FIFA 23 is not in development and was never a valid template for FIFA 17
(different game, different in-memory layout). Remove it as a build target and
as scaffolding, while preserving the per-game feature architecture so future
games plug in as new modules — never by copying retired reverse-engineering.

Hook (openfut-hook):
- Delete install_hooks_fifa23 and every FIFA23-only module: config, hooks,
  transport_watch, ssl_patch, origin_spy, tls_bypass, dial_notification, probe
  (+ probe feature), recv_hook (+ capture_baseline feature), plus the orphan
  FIFA23 LSX/Origin files lsx.rs and ea_stub.rs. ~3.6k lines; git + Vault retain
  the research.
- lib.rs is now game-generic: a per-game feature selects that game's module and
  install_hooks dispatches to it. No game feature => compile_error!("select a
  game, e.g. --features fifa17"). --features fifa17 remains the build invariant.
- Drop the crate-wide  blanket (it existed only
  to hide the compiled-but-unused FIFA23 modules). Replace with narrow, justified
  #[allow(dead_code)] on the three FIFA17 SBC RE-scaffolding items it was masking,
  so the candidate stays behavior-identical.
- connect_hook: the redirect is now always the config-driven path (openfut-common
  target from openfut.cfg); the hardcoded-loopback rewrite and its dead consts are
  gone. Removed the FIFA23-era transport_watch diagnostics from the shared
  connect/WSAConnect/ConnectEx detours. Deleted unused iat::patch_iat_in.

Launcher:
- fifa_game_dir no longer defaults to a hardcoded '.../FIFA 23' Steam path; it is
  empty by default, matching the launcher's own rule that it never invents a path
  to somebody's game install (like openfut_server_host and game_profile).
- Generalise the remaining 'FIFA 23' doc literals in config.rs / setup.rs.

Proof: fifa17 clippy -D warnings clean; no-game build fails with the documented
compile_error; launcher 75 tests pass unchanged; launcher + hook cross-build
x86_64-pc-windows-gnu; cargo fmt --check clean; zero FIFA23 symbols/literals
remain. FIFA17 armed-module set unchanged (redirect + SBC/store/season).
2026-08-20 20:56:52 +00:00
openfut 164100fc40 diag(fifa17): passive season-native call tracer for offline-Seasons entry
Adds openfut-hook/src/season_trace.rs: read-only CardsDLL detours that log the
FIFA17 FUT offline-season entry native call sequence (no behavior change; each
wrapper logs then calls the original via a trampoline). Traces the FUT_Season
natives proven by the registration table FUN_18004e3f0:
  GetUsersOfflineDivision 0x4eb50 (NOT LoadOfflineSeasons),
  LoadOfflineSeasons 0x4ee10 + async impl 0x57560,
  LoadCurrentOfflineSeason 0x4eb70 + impl 0x57230 + completion 0x578e0,
  StartSeason 0x4f340, GetOfflineSeasonInfo 0x4e850.
Includes a near-trampoline installer (install_detour_reloc) that relocates a
single rip-relative disp32 so functions with rip-relative prologues can be
detoured (trampoline allocated within +/-1.5GiB of CardsDLL).
2026-08-19 23:37:26 +00:00
funman300 9aecc658ad hook(fifa17): guarded store-entry category clamp (promoted)
The FUT store flashes a Browse-Packs overview on first open: the store
screen ctor leaves screen+0x290 (CATEGORY_ID) at 0, and the resolver
FUN_1800147f0 treats 0 as list-all, so the first render draws the group
overview before the movie posts a tab ordinal.

Detour the store render FUN_18007dab0 (RVA 0x7dab0): when the incoming
category is 0, substitute the first present group ordinal (1) so the
first frame lands on a real tab. Provably crash-safe: it writes 1 only
after FUN_180014420(_, 1) (the resolver's own ordinal->group lookup,
whose first arg is dead) returns non-NULL, which is exactly the
resolver's non-crash precondition; the positive-invalid NULL deref at
0x14882 is thus unreachable. No group yet -> category left 0 -> Browse,
still safe.

Promoted like the SBC dispatch: build-armed (CLAMP_PROMOTED), no env.
Signature-gated on both the detoured render and the called lookup,
image-validated, installed under thread suspension, fail-closed. Only
the overview flash is addressed; the empty-My-Packs entry dialog is
movie-side (packed .apt) and out of CardsDLL reach (see Vault
Store Resolver Guard 2026-08-19). fmt/clippy -D warnings clean both
feature sets, 26 hook tests pass, x86_64-pc-windows-gnu release builds.
2026-08-19 15:20:47 +00:00
funman300 6cdb45e482 Instrument FIFA17 SBC completion dispatch 2026-08-18 20:20:00 +00:00
funman300 d1a71bd5a1 style(hook): clippy -D warnings clean on default + fifa17 features
Modernize manual nul-terminated byte strings to C-string literals (c"...")
at all Win32 GetModuleHandleA/GetProcAddress/getaddrinfo call sites (byte-identical),
drop two redundant SOL_SOCKET-as-i32 casts, remove a needless return in the fifa17
install path, and add a # Safety section to DllMain. Scope the FIFA-23-path
dead-code/unused-import lints (unused only under the fifa17 feature, stripped by the
linker) with a documented crate-level cfg_attr allow. Cross-verified: both the
default and fifa17 builds now pass clippy -D warnings and compile; probe and
capture_baseline still build.
2026-08-15 19:31:21 +00:00
funman300 3d895fb7ac feat: add guarded FIFA 17 SBC diagnostics 2026-08-07 11:43:08 -07:00
funman300 7dcf610b71 openfut-hook: RE instrumentation for the Blaze dial-gate investigation
In-process, read-only probes and transport observation built while closing
the online/FUT route from both the memory and network sides.

- probe.rs / dial_notification.rs: menu-time ctx dump, connMgr enumerator,
  synthetic dial-notification + direct-call dial trigger, and the
  [element+0x40] container write-watchpoint. All env-gated, one-shot,
  VirtualQuery-guarded; none alter game state by default.
- transport_watch.rs + connect/connectex/hooks/lib: M0 transport observation
  (grep-friendly TRANSPORT_WATCH logging on the existing getaddrinfo/connect/
  WSAConnect/ConnectEx detours) and an IPv6 (v4-mapped) EA-redirect so the
  game's IPv6 :443 dials land on the bridge instead of the dead servers.

Findings: the game never initiates a Blaze connection offline; the dial
handler is registered by a self-registering, message-driven state machine
whose container stays empty with no Blaze exchange. See openfut-bridge
docs/closure-and-preservation.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 15:58:17 -07:00
funman300 feaff0443f hook: in-process RE instrumentation + LSX redirect + capture tooling
Hook-side tooling for the LSX/Blaze reverse-engineering effort:

- probe.rs (new, `probe` feature): passive logging detours on FIFA's online-flow
  functions via the unhook/rehook pattern (no trampoline/relocation, works on
  RIP-relative prologues). Deferred install waits for anadius64.dll to load, then
  logs enter/return for GoOnline + GetInternetConnectedState (anadius) and the
  OnlineStatusEvent/Login deserializers (FIFA23.exe). Revealed that our pushed LSX
  events reach FIFA and parse OK, while GoOnline never fires — localizing the online
  gate to FIFA's game-side event consumer.
- connect_hook.rs: redirect FIFA's LSX connect :3216 → :3217 so it lands on the
  native openfut-bridge LSX server (slips past anadius's in-process :3216 intercept);
  gated off under the `capture_baseline` feature.
- recv_hook.rs: boundary-safe trampolines + LSX peer filtering for the
  capture_baseline path (log anadius's real LSX frames when the redirect is off).

Build the instrumented DLL with `--features probe` (or `--features capture_baseline`
for the anadius-baseline capture). Both features are off by default.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:59:27 -07:00
funman300 87241acc1a feat(hook): expand IAT hook coverage with TLS bypass, connect/recv hooks, and logging
Adds connect_hook, connectex_hook, recv_hook, ssl_patch, tls_bypass, lsx, ea_stub,
and origin_spy modules to intercept EA's TLS and socket layers in addition to
getaddrinfo. Adds DLL-level logging to C:\openfut_hook.log for debugging. Also
patches windows-sys feature flags to include Cryptography and Threading APIs needed
by the new hooks.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 10:36:17 -07:00
funman300 dfa2c9afc7 feat: make hook redirect IP configurable from launcher
The DLL now reads openfut.cfg from its own directory on DLL_PROCESS_ATTACH
and uses the IP it contains as the redirect target instead of hardcoding
127.0.0.1. Falls back to 127.0.0.1 if the file is absent.

The launcher writes openfut.cfg alongside version.dll when deploying, and
the Setup tab exposes a "Redirect IP" field with an "Update" button that
rewrites openfut.cfg in-place without redeploying the DLL. Useful when
running the emulator on a different machine on the LAN.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 21:08:44 -07:00
funman300 9b5da57f12 feat: replace hosts file with DLL injection hook
Adds openfut-hook/, a Windows DLL (cdylib, x86_64-pc-windows-gnu) that
patches the IAT of FIFA 23 at load time to redirect getaddrinfo calls
for fut.ea.com / utas.*.fut.ea.com to 127.0.0.1, sending all FUT
traffic to the local bridge — no /etc/hosts changes needed.

Deployment: the launcher copies openfut_hook.dll into the FIFA 23 game
folder as version.dll (a DLL FIFA loads but delegates to system).
Proton picks up the local copy automatically when you set:
  WINEDLLOVERRIDES="version=n,b" %command%
in Steam launch options.

Also updates cert install to try the Wine/Proton cert store (wine
certutil) before falling back to the Linux system CA store, and removes
all hosts file code from setup.rs / app.rs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 21:05:35 -07:00