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>
This commit is contained in:
funman300
2026-07-03 15:58:17 -07:00
parent ff4b5a87f5
commit 7dcf610b71
8 changed files with 1785 additions and 79 deletions
+17
View File
@@ -1,6 +1,7 @@
mod config;
mod connect_hook;
mod connectex_hook;
mod dial_notification;
mod hooks;
mod iat;
mod origin_spy;
@@ -10,6 +11,7 @@ mod probe;
mod recv_hook;
mod ssl_patch;
mod tls_bypass;
mod transport_watch;
use windows_sys::Win32::{
Foundation::{BOOL, HMODULE, TRUE},
@@ -25,6 +27,18 @@ pub(crate) fn write_log(msg: &str) {
{ let _ = f.write_all(msg.as_bytes()); }
}
/// Force the log to stable storage. `write_log` already opens+closes the file per line,
/// so nothing is buffered *inside our process* (a process crash can't lose a written
/// line). `sync_all` additionally flushes the OS cache to disk, for durability even
/// across a full system crash. We call this right before the dial trigger's call so the
/// pre-call log line is guaranteed on disk if the call faults.
#[allow(dead_code)]
pub(crate) fn flush_log() {
if let Ok(f) = std::fs::OpenOptions::new().append(true).open(r"C:\openfut_hook.log") {
let _ = f.sync_all();
}
}
#[no_mangle]
pub unsafe extern "system" fn DllMain(module: HMODULE, reason: u32, _: *mut ()) -> BOOL {
if reason == DLL_PROCESS_ATTACH { install_hooks(module); }
@@ -33,6 +47,9 @@ pub unsafe extern "system" fn DllMain(module: HMODULE, reason: u32, _: *mut ())
unsafe fn install_hooks(module: HMODULE) {
write_log("openfut_hook: DllMain fired\n");
// Milestone-0 transport watch: arm (or note disarmed) from env once, up front, so
// the getaddrinfo/connect/ConnectEx detours below can log Blaze-flavored activity.
transport_watch::arm_from_env();
let ip = config::read_redirect_ip(module);
hooks::set_redirect_ip(ip);