wip(hook): preserve local FIFA17 configurable-server redirect + hook refactors
Preserved uncommitted openfut-hook WIP from the feat/launcher-arming checkout so the
canonical launcher can move to the reconciled merge ca7ce26 without losing it. This is
WORK-IN-PROGRESS (not production-polished): a configurable OpenFUT-server redirect for the
injected hook — new src/server.rs (server::set / sin_addr / dest_port_nbo_from_source_nbo,
referenced by lib.rs + connect_hook + connectex_hook) plus supporting changes to config.rs,
connect_hook.rs, connectex_hook.rs, hooks.rs, iat.rs, lib.rs, origin_spy.rs, ssl_patch.rs,
tls_bypass.rs, Cargo.{toml,lock}.
NOTE: this overlaps (same files, different approach) the SBC-tracing lineage's openfut-hook
changes now merged in ca7ce26; reconciling the two hook variants is a separate, deliberate
task. This commit only PRESERVES the local WIP on a dedicated branch.
This commit is contained in:
+35
-20
@@ -1,22 +1,23 @@
|
||||
use std::{
|
||||
ffi::CStr,
|
||||
sync::{
|
||||
OnceLock,
|
||||
atomic::{AtomicBool, Ordering},
|
||||
OnceLock,
|
||||
},
|
||||
};
|
||||
|
||||
use windows_sys::Win32::Networking::WinSock::{ADDRINFOA, getaddrinfo as sys_getaddrinfo};
|
||||
use windows_sys::Win32::Networking::WinSock::{getaddrinfo as sys_getaddrinfo, ADDRINFOA};
|
||||
|
||||
type GetaddrinfoFn = unsafe extern "system" fn(
|
||||
*const u8,
|
||||
*const u8,
|
||||
*const ADDRINFOA,
|
||||
*mut *mut ADDRINFOA,
|
||||
) -> i32;
|
||||
type GetaddrinfoFn =
|
||||
unsafe extern "system" fn(*const u8, *const u8, *const ADDRINFOA, *mut *mut ADDRINFOA) -> i32;
|
||||
|
||||
static REAL: OnceLock<GetaddrinfoFn> = OnceLock::new();
|
||||
static REDIRECT_IP: OnceLock<Vec<u8>> = OnceLock::new();
|
||||
// NUL-terminated dotted-quad of the resolved OpenFUT server, built once at init
|
||||
// from the SAME shared config the socket hooks use. getaddrinfo redirects EA
|
||||
// hostnames here so DNS resolves to the configured server. If configuration was
|
||||
// missing/invalid this stays empty and EA hostnames are NOT redirected (no
|
||||
// loopback fallback).
|
||||
static REDIRECT_HOST: OnceLock<Vec<u8>> = OnceLock::new();
|
||||
|
||||
// Flipped to true the first time we successfully apply the runtime cert patch.
|
||||
// The patch is deferred to here (rather than DllMain) because EAWebKit.dll may
|
||||
@@ -27,10 +28,12 @@ pub fn set_real(f: GetaddrinfoFn) {
|
||||
let _ = REAL.set(f);
|
||||
}
|
||||
|
||||
pub fn set_redirect_ip(ip: String) {
|
||||
let mut bytes = ip.into_bytes();
|
||||
/// Install the resolved redirect IPv4 (dotted-quad) getaddrinfo will hand back
|
||||
/// for EA hostnames. Called once at init from the shared resolved server.
|
||||
pub fn set_redirect_ip(ip: std::net::Ipv4Addr) {
|
||||
let mut bytes = ip.to_string().into_bytes();
|
||||
bytes.push(0);
|
||||
let _ = REDIRECT_IP.set(bytes);
|
||||
let _ = REDIRECT_HOST.set(bytes);
|
||||
}
|
||||
|
||||
/// Returns true if `host` is an EA / EA-Sports domain that should be redirected
|
||||
@@ -60,18 +63,30 @@ pub unsafe extern "system" fn hooked_getaddrinfo(
|
||||
if !CERT_PATCHED.load(Ordering::Relaxed) {
|
||||
if crate::ssl_patch::patch_eawebkit_cert_verify() {
|
||||
CERT_PATCHED.store(true, Ordering::Relaxed);
|
||||
crate::write_log("openfut_hook: ProtoSSL cert-verify patched (lazy, from getaddrinfo)\n");
|
||||
crate::write_log(
|
||||
"openfut_hook: ProtoSSL cert-verify patched (lazy, from getaddrinfo)\n",
|
||||
);
|
||||
} else {
|
||||
crate::write_log("openfut_hook: ProtoSSL cert-verify patch FAILED in getaddrinfo\n");
|
||||
crate::write_log(
|
||||
"openfut_hook: ProtoSSL cert-verify patch FAILED in getaddrinfo\n",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let redirect = REDIRECT_IP
|
||||
.get()
|
||||
.map(|v| v.as_ptr())
|
||||
.unwrap_or(b"127.0.0.1\0".as_ptr());
|
||||
let real = REAL.get().copied().unwrap_or(sys_getaddrinfo);
|
||||
return real(redirect, service_name, hints, result);
|
||||
// Only redirect when a server was configured & resolved. If not,
|
||||
// fall through to the real resolver — we never invent a loopback
|
||||
// destination here.
|
||||
match REDIRECT_HOST.get() {
|
||||
Some(redirect) => {
|
||||
let real = REAL.get().copied().unwrap_or(sys_getaddrinfo);
|
||||
return real(redirect.as_ptr(), service_name, hints, result);
|
||||
}
|
||||
None => {
|
||||
crate::write_log(
|
||||
"openfut_hook: EA host seen but no OpenFUT server configured — NOT redirecting\n",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user