paavohtl Claude Opus 4.6 (1M context) commited on
Commit
1bdc4f7
·
1 Parent(s): 8e36bc6

perf: batch MinHook enable calls for 10x faster test startup

Browse files

Replace per-hook MinHook::enable_hook() with queue_enable_hook(), then
call apply_queued() once after all hooks are installed. This batches
~90 VirtualProtect syscalls into a single pass per code page.

Results (17 tests):
j=4: ~35s → ~3s
j=16: ~25s → ~1.8s

The VirtualProtect calls were the entire startup bottleneck — each one
flushes the instruction cache and modifies page tables, and they were
serialized across all hooks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

crates/openwa-wormkit/src/hook.rs CHANGED
@@ -384,8 +384,8 @@ pub unsafe fn install(
384
  let trampoline = MinHook::create_hook(target, detour)
385
  .map_err(|e| format!("MinHook create_hook failed for {name}: {e}"))?;
386
 
387
- MinHook::enable_hook(target)
388
- .map_err(|e| format!("MinHook enable_hook failed for {name}: {e}"))?;
389
 
390
  let _ = log_line(&format!(
391
  " [REPLACE] {name}: target 0x{:08X}, trampoline 0x{:08X}",
 
384
  let trampoline = MinHook::create_hook(target, detour)
385
  .map_err(|e| format!("MinHook create_hook failed for {name}: {e}"))?;
386
 
387
+ MinHook::queue_enable_hook(target)
388
+ .map_err(|e| format!("MinHook queue_enable_hook failed for {name}: {e}"))?;
389
 
390
  let _ = log_line(&format!(
391
  " [REPLACE] {name}: target 0x{:08X}, trampoline 0x{:08X}",
crates/openwa-wormkit/src/lib.rs CHANGED
@@ -82,6 +82,13 @@ fn run() -> Result<(), String> {
82
 
83
  replacements::install_all()?;
84
 
 
 
 
 
 
 
 
85
  let _ = log_line("=== All replacements installed ===");
86
 
87
  // Signal the launcher that all hooks are installed and the main thread
 
82
 
83
  replacements::install_all()?;
84
 
85
+ // All hooks were queued during install_all() — now enable them in one
86
+ // batched VirtualProtect pass instead of one syscall per hook.
87
+ unsafe {
88
+ minhook::MinHook::apply_queued()
89
+ .map_err(|e| format!("MinHook apply_queued failed: {e}"))?;
90
+ }
91
+
92
  let _ = log_line("=== All replacements installed ===");
93
 
94
  // Signal the launcher that all hooks are installed and the main thread
crates/openwa-wormkit/src/replacements/file_isolation.rs CHANGED
@@ -163,8 +163,8 @@ pub fn install() -> Result<(), String> {
163
  let target = addr as *mut c_void;
164
  let trampoline = minhook::MinHook::create_hook(target, hook_create_file_a as *mut c_void)
165
  .map_err(|e| format!("MinHook create_hook failed for CreateFileA: {e}"))?;
166
- minhook::MinHook::enable_hook(target)
167
- .map_err(|e| format!("MinHook enable_hook failed for CreateFileA: {e}"))?;
168
 
169
  ORIG_CREATE_FILE_A.store(trampoline as u32, Ordering::Relaxed);
170
 
 
163
  let target = addr as *mut c_void;
164
  let trampoline = minhook::MinHook::create_hook(target, hook_create_file_a as *mut c_void)
165
  .map_err(|e| format!("MinHook create_hook failed for CreateFileA: {e}"))?;
166
+ minhook::MinHook::queue_enable_hook(target)
167
+ .map_err(|e| format!("MinHook queue_enable_hook failed for CreateFileA: {e}"))?;
168
 
169
  ORIG_CREATE_FILE_A.store(trampoline as u32, Ordering::Relaxed);
170
 
crates/openwa-wormkit/src/replacements/headless.rs CHANGED
@@ -99,7 +99,7 @@ pub fn install() -> Result<(), String> {
99
  if let Some(addr) = proc {
100
  let target = addr as *mut core::ffi::c_void;
101
  if let Ok(trampoline) = minhook::MinHook::create_hook(target, hook_fn) {
102
- let _ = minhook::MinHook::enable_hook(target);
103
  let fn_name = std::str::from_utf8(&name[..name.len() - 1]).unwrap_or("?");
104
  let _ = log_line(&format!(
105
  "[Headless] user32!{fn_name} hooked at 0x{:08X}, trampoline 0x{:08X}",
@@ -130,7 +130,7 @@ pub fn install() -> Result<(), String> {
130
  target,
131
  hook_create_semaphore_a as *mut core::ffi::c_void,
132
  ) {
133
- let _ = minhook::MinHook::enable_hook(target);
134
  ORIG_CREATE_SEMAPHORE_A
135
  .store(trampoline as u32, core::sync::atomic::Ordering::Relaxed);
136
  let _ = log_line(&format!(
 
99
  if let Some(addr) = proc {
100
  let target = addr as *mut core::ffi::c_void;
101
  if let Ok(trampoline) = minhook::MinHook::create_hook(target, hook_fn) {
102
+ let _ = minhook::MinHook::queue_enable_hook(target);
103
  let fn_name = std::str::from_utf8(&name[..name.len() - 1]).unwrap_or("?");
104
  let _ = log_line(&format!(
105
  "[Headless] user32!{fn_name} hooked at 0x{:08X}, trampoline 0x{:08X}",
 
130
  target,
131
  hook_create_semaphore_a as *mut core::ffi::c_void,
132
  ) {
133
+ let _ = minhook::MinHook::queue_enable_hook(target);
134
  ORIG_CREATE_SEMAPHORE_A
135
  .store(trampoline as u32, core::sync::atomic::Ordering::Relaxed);
136
  let _ = log_line(&format!(