M1 probe: GoOnline passes, gate is downstream (token/status)

Add a read-only detour on anadius's GoOnline handler (anadius64.dll+0x2BB90).
Result: the game calls GoOnline during the "connecting" attempt and anadius
returns success, yet no Blaze connection follows. The gate is therefore
downstream of GoOnline -- the auth-token (GetAuthCode) and/or the "online
established" status callback. Recorded in connection-gate-findings.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
funman300
2026-06-29 18:46:27 -07:00
parent 55c9757e74
commit 4c57cf571c
2 changed files with 86 additions and 8 deletions
+63 -4
View File
@@ -191,15 +191,31 @@ unsafe extern "system" fn init_thread(_: *mut c_void) -> u32 {
hook_winsock_data();
hook_connect();
// Then the plaintext-capture detour on _ProtoSSLSendPacket.
// Then the plaintext-capture detour on _ProtoSSLSendPacket, plus the
// read-only anadius GoOnline probe (M1). Retry until both are installed.
let mut send_done = false;
let mut anadius_done = false;
for _ in 0..60 {
if let Some(addr) = find_send_packet() {
install_hook(addr);
if !send_done {
if let Some(addr) = find_send_packet() {
install_hook(addr);
send_done = true;
}
}
if !anadius_done && hook_anadius_probes() {
anadius_done = true;
}
if send_done && anadius_done {
return 0;
}
Sleep(1000);
}
log("ERROR: _ProtoSSLSendPacket pattern not found after 60s");
if !send_done {
log("ERROR: _ProtoSSLSendPacket pattern not found after 60s");
}
if !anadius_done {
log("ERROR: anadius64.dll not loaded after 60s; GoOnline probe not installed");
}
0
}
@@ -377,6 +393,12 @@ unsafe fn install_detour(
return;
}
};
install_detour_at(addr, detour, slot, label);
}
/// Install an inline detour at a raw address (for non-exported targets such as
/// internal anadius handlers located by module+offset).
unsafe fn install_detour_at(addr: usize, detour: *const (), slot: &AtomicUsize, label: &str) {
let d = match RawDetour::new(addr as *const (), detour) {
Ok(d) => d,
Err(e) => {
@@ -393,6 +415,43 @@ unsafe fn install_detour(
log(&format!("{label} hook installed"));
}
// --- M1 read-only probe: anadius GoOnline handler -------------------------
static ORIG_GOONLINE: AtomicUsize = AtomicUsize::new(0);
/// Read-only detour on anadius's GoOnline handler (anadius64.dll+0x2BB90): log
/// that it was reached, then call the original unchanged. Tells us whether the
/// game even asks to go online during the "connecting" attempt.
unsafe extern "system" fn hooked_goonline(a: usize, b: usize, c: usize, d: usize) -> usize {
log(&format!("PROBE anadius GoOnline CALLED (rcx=0x{a:X} rdx=0x{b:X})"));
let orig = ORIG_GOONLINE.load(Ordering::SeqCst);
if orig != 0 {
let f: unsafe extern "system" fn(usize, usize, usize, usize) -> usize =
core::mem::transmute(orig);
f(a, b, c, d)
} else {
0
}
}
/// Resolve anadius64.dll's runtime base and detour the GoOnline handler.
/// Returns true once installed (or if anadius isn't present and we should stop
/// retrying is decided by the caller). Returns false if anadius isn't loaded yet.
unsafe fn hook_anadius_probes() -> bool {
let base = match GetModuleHandleW(PCWSTR(wide("anadius64.dll").as_ptr())) {
Ok(m) => m.0 as usize,
Err(_) => return false, // not loaded yet
};
log(&format!("anadius64.dll base = 0x{base:X}"));
install_detour_at(
base + 0x2BB90,
hooked_goonline as *const (),
&ORIG_GOONLINE,
"PROBE anadius GoOnline @ +0x2BB90",
);
true
}
/// Detour the DNS resolvers so we see every hostname lookup.
unsafe fn hook_dns() {
let ws2 = match LoadLibraryW(PCWSTR(wide("ws2_32.dll").as_ptr())) {