probe: ungate the forcing experiment (manual-only)
install_force_connect() is no longer auto-called from install_probes_deferred, so normal probe builds don't poke the online flow. Kept for reference; re-enable the call to reproduce the 2026-07-02 forcing experiment. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -161,6 +161,47 @@ pub unsafe fn install_listener_probe() {
|
||||
crate::write_log(&format!("PROBE listener: dispatch site patched @ {:#x}\n", target as usize));
|
||||
}
|
||||
|
||||
/// FORCING EXPERIMENT: directly invoke `nucleusConnectREST` (FIFA23.exe+0x2861910)
|
||||
/// from a background thread once FIFA is at "connecting". That function is nearly
|
||||
/// self-contained — it fetches X=[0x14acd02c0], M=[X+0x360], ctx=[M+0x778] from the
|
||||
/// global singleton and, if ctx is non-null, sends a GetAuthCode LSX request. The
|
||||
/// dormant subsystem never calls it; we call it ourselves to test whether triggering
|
||||
/// the connect makes FIFA fire GetAuthCode (which the bridge answers) and advance.
|
||||
/// Guarded: we only call once the ctx chain is valid, to avoid a null-deref crash.
|
||||
pub fn install_force_connect() {
|
||||
std::thread::spawn(|| unsafe {
|
||||
let base = GetModuleHandleA(core::ptr::null());
|
||||
if base.is_null() { return; }
|
||||
let base = base as usize;
|
||||
let x_slot = base + 0xacd02c0;
|
||||
let rest: extern "system" fn() -> usize =
|
||||
core::mem::transmute(base + 0x2861910);
|
||||
// Wait for the ctx chain to be valid (FIFA past bootstrap), up to ~60s.
|
||||
let mut fired = 0;
|
||||
for i in 0..120u32 {
|
||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||
let ctx = read_ptr(x_slot)
|
||||
.filter(|&x| x != 0)
|
||||
.and_then(|x| read_ptr(x + 0x360))
|
||||
.filter(|&m| m != 0)
|
||||
.and_then(|m| read_ptr(m + 0x778))
|
||||
.filter(|&c| c != 0);
|
||||
let Some(ctx) = ctx else { continue; };
|
||||
// Give the game a few seconds settled at "connecting" before poking.
|
||||
if i < 60 { continue; }
|
||||
crate::write_log(&format!(
|
||||
"FORCE: calling nucleusConnectREST() (ctx={ctx:#x}) attempt {fired}\n"
|
||||
));
|
||||
let r = rest();
|
||||
crate::write_log(&format!("FORCE: nucleusConnectREST returned {r:#x}\n"));
|
||||
fired += 1;
|
||||
if fired >= 3 { break; }
|
||||
std::thread::sleep(std::time::Duration::from_millis(3000));
|
||||
}
|
||||
crate::write_log("FORCE: done\n");
|
||||
});
|
||||
}
|
||||
|
||||
struct Target {
|
||||
/// DLL name (nul-terminated) or ignored when `main_exe` is true.
|
||||
module: &'static [u8],
|
||||
@@ -279,6 +320,9 @@ pub fn install_probes_deferred() {
|
||||
install_probes();
|
||||
install_listener_probe();
|
||||
install_state_sampler();
|
||||
// install_force_connect(); // manual-only: forcing experiment (2026-07-02);
|
||||
// re-enable to auto-invoke nucleusConnectREST(). Off by default so normal
|
||||
// probe builds don't poke the online flow.
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user