fix(hooks): correct vtable hook parameter counts from RET analysis
Browse filesProcessFrame: RET 0x4 = 1 stack param (flags), was 0 — stack corruption
HandleMessage: RET 0x10 = 4 stack params (sender, msg_type, size, data), was 2
These wrong parameter counts caused stack corruption on every virtual
call, crashing when returning from a match to the main menu.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
crates/openwa-validator/src/hooks/vtable.rs
CHANGED
|
@@ -76,23 +76,26 @@ impl VtableHook {
|
|
| 76 |
static ORIG_CTASK_PROCESS_FRAME: AtomicU32 = AtomicU32::new(0);
|
| 77 |
|
| 78 |
/// Hook for CTask::ProcessFrame (vtable slot 7).
|
| 79 |
-
/// thiscall
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
let orig: unsafe extern "fastcall" fn(u32, u32) -> u32 =
|
| 83 |
core::mem::transmute(ORIG_CTASK_PROCESS_FRAME.load(Ordering::Relaxed));
|
| 84 |
-
orig(this, 0)
|
| 85 |
}
|
| 86 |
|
| 87 |
/// Original CTask::HandleMessage function pointer
|
| 88 |
static ORIG_CTASK_HANDLE_MESSAGE: AtomicU32 = AtomicU32::new(0);
|
| 89 |
|
| 90 |
/// Hook for CTask::HandleMessage (vtable slot 2).
|
| 91 |
-
/// thiscall(this,
|
| 92 |
-
|
| 93 |
-
|
|
|
|
|
|
|
|
|
|
| 94 |
core::mem::transmute(ORIG_CTASK_HANDLE_MESSAGE.load(Ordering::Relaxed));
|
| 95 |
-
orig(this, 0,
|
| 96 |
}
|
| 97 |
|
| 98 |
// ---------------------------------------------------------------------------
|
|
|
|
| 76 |
static ORIG_CTASK_PROCESS_FRAME: AtomicU32 = AtomicU32::new(0);
|
| 77 |
|
| 78 |
/// Hook for CTask::ProcessFrame (vtable slot 7).
|
| 79 |
+
/// thiscall(this, flags) — RET 0x4 confirms 1 stack param.
|
| 80 |
+
/// flags bit 0: if set, frees `this` (scalar deleting destructor pattern).
|
| 81 |
+
unsafe extern "fastcall" fn hook_ctask_process_frame(this: u32, _edx: u32, flags: u32) -> u32 {
|
| 82 |
+
let orig: unsafe extern "fastcall" fn(u32, u32, u32) -> u32 =
|
| 83 |
core::mem::transmute(ORIG_CTASK_PROCESS_FRAME.load(Ordering::Relaxed));
|
| 84 |
+
orig(this, 0, flags)
|
| 85 |
}
|
| 86 |
|
| 87 |
/// Original CTask::HandleMessage function pointer
|
| 88 |
static ORIG_CTASK_HANDLE_MESSAGE: AtomicU32 = AtomicU32::new(0);
|
| 89 |
|
| 90 |
/// Hook for CTask::HandleMessage (vtable slot 2).
|
| 91 |
+
/// thiscall(this, sender, msg_type, size, data) — RET 0x10 confirms 4 stack params.
|
| 92 |
+
/// Iterates children list and forwards message to each child's HandleMessage.
|
| 93 |
+
unsafe extern "fastcall" fn hook_ctask_handle_message(
|
| 94 |
+
this: u32, _edx: u32, sender: u32, msg_type: u32, size: u32, data: u32,
|
| 95 |
+
) -> u32 {
|
| 96 |
+
let orig: unsafe extern "fastcall" fn(u32, u32, u32, u32, u32, u32) -> u32 =
|
| 97 |
core::mem::transmute(ORIG_CTASK_HANDLE_MESSAGE.load(Ordering::Relaxed));
|
| 98 |
+
orig(this, 0, sender, msg_type, size, data)
|
| 99 |
}
|
| 100 |
|
| 101 |
// ---------------------------------------------------------------------------
|