Files
openfut-launcher/openfut-hook/src/lib.rs
T
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

79 lines
2.5 KiB
Rust

// openfut-hook: the version.dll proxy that injects OpenFUT's client-side
// compatibility hooks into an EA FUT client.
//
// GAME-GENERIC BY FEATURE: each supported game is its own module, selected by a
// per-game Cargo feature (currently only `fifa17`). `install_hooks` dispatches to
// the selected game's `install()`. Generic infrastructure — the version proxy,
// the connect/WSAConnect/ConnectEx redirect, IAT primitives, and the shared
// `openfut-common` config — stays game-neutral. Add a future game with its own
// `mod <game>;` behind a feature plus a dispatch arm; never by copying a retired
// game's reverse-engineering.
#[cfg(not(any(feature = "fifa17")))]
compile_error!("select a game, e.g. --features fifa17");
mod connect_hook;
mod connectex_hook;
#[cfg(feature = "fifa17")]
mod fifa17;
#[cfg(feature = "fifa17")]
mod fifa17_tls;
mod iat;
#[cfg(feature = "fifa17")]
mod kit_trace;
mod patch_mem;
#[cfg(feature = "fifa17")]
mod sbc_dispatch;
#[cfg(feature = "fifa17")]
mod sbc_hook;
#[cfg(feature = "fifa17")]
mod sbc_request_trace;
#[cfg(feature = "fifa17")]
mod sbc_trace;
#[cfg(feature = "fifa17")]
mod season_trace;
#[cfg(feature = "fifa17")]
mod store_entry;
mod version_proxy;
use windows_sys::Win32::{
Foundation::{BOOL, HMODULE, TRUE},
System::SystemServices::DLL_PROCESS_ATTACH,
};
pub(crate) fn write_log(msg: &str) {
use std::io::Write;
if let Ok(mut f) = std::fs::OpenOptions::new()
.create(true)
.append(true)
.open(r"C:\openfut_hook.log")
{
let _ = f.write_all(msg.as_bytes());
}
}
/// # Safety
///
/// This is the DLL entry point invoked by the Windows loader; it MUST NOT be
/// called manually. `module` must be the valid `HMODULE` the loader passes for
/// this DLL. On `DLL_PROCESS_ATTACH` it installs process-wide inline detours
/// (raw memory patching), so it must run exactly once, on the loader thread,
/// before any hooked API is used.
#[no_mangle]
pub unsafe extern "system" fn DllMain(module: HMODULE, reason: u32, _: *mut ()) -> BOOL {
if reason == DLL_PROCESS_ATTACH {
// VERSION forwarding must be ready before DllMain returns. Hook setup
// may be deferred, but a caller can use any proxy export immediately.
if version_proxy::resolve() {
install_hooks(module);
}
}
TRUE
}
/// Dispatch to the selected game's install path. Exactly one game feature must be
/// enabled (enforced by the crate-level `compile_error!` above).
unsafe fn install_hooks(_module: HMODULE) {
#[cfg(feature = "fifa17")]
fifa17::install();
}