7edf682291
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).
79 lines
2.5 KiB
Rust
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();
|
|
}
|