M2: flips fire but gate is async event (not a poll)
- Hook: force GetInternetConnectedState->connected (flags +0xCAB1A/+0xCAB1B) and flip GoOnline to report "1" (+0xAF530) instead of "0" (+0xADE64). - protossl-scan: add `read` mode (hex/ascii dump at addr|module+off). - Finding: neither flip unblocks the game; it keeps retrying GoOnline every ~7s. The FUT-online flow is event-driven -- the game waits for an async "online established" event anadius (offline-only) never pushes. Documented in connection-gate-findings.md. Next: trace FIFA-side flow (Ghidra) / anadius event-send to inject the online event. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -136,6 +136,50 @@ fn main() {
|
||||
let _ = CloseHandle(process);
|
||||
}
|
||||
}
|
||||
// read <hex-addr | module+0xoffset> [len] [pid|name]
|
||||
// Dump raw bytes (hex + ASCII) at an address — to read short strings /
|
||||
// data the disassembler doesn't resolve.
|
||||
Some("read") => {
|
||||
let arg = match args.get(1) {
|
||||
Some(a) => a.clone(),
|
||||
None => {
|
||||
eprintln!("Usage: protossl-scan read <hex-addr | module+0xoffset> [len] [pid]");
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
let len = args
|
||||
.get(2)
|
||||
.and_then(|s| s.parse::<usize>().ok().or_else(|| parse_hex(s)))
|
||||
.unwrap_or(64);
|
||||
let pid = resolve_pid(args.get(3).map(|s| s.as_str()));
|
||||
let process = open_for_read(pid);
|
||||
let modules = enumerate_modules(pid);
|
||||
let target = match resolve_target(&arg, &modules) {
|
||||
Some(t) => t,
|
||||
None => {
|
||||
eprintln!("Could not resolve '{arg}'");
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
println!("== read {} len {len} ==", describe(target, &modules));
|
||||
match read_bytes(process, target, len) {
|
||||
Some(b) => {
|
||||
for off in (0..b.len()).step_by(16) {
|
||||
let row = &b[off..(off + 16).min(b.len())];
|
||||
let hexp: String = row.iter().map(|x| format!("{x:02X} ")).collect();
|
||||
let asc: String = row
|
||||
.iter()
|
||||
.map(|&x| if (0x20..=0x7e).contains(&x) { x as char } else { '.' })
|
||||
.collect();
|
||||
println!(" 0x{:016X} {:<48} {}", target + off, hexp, asc);
|
||||
}
|
||||
}
|
||||
None => println!(" (could not read memory at that address)"),
|
||||
}
|
||||
unsafe {
|
||||
let _ = CloseHandle(process);
|
||||
}
|
||||
}
|
||||
// callers <hex-addr | module+0xoffset> [pid|name]
|
||||
// Find direct call/jmp sites that target an address — walks up the call
|
||||
// graph (e.g. from a connect helper to the code that gates it).
|
||||
|
||||
Reference in New Issue
Block a user