Expand description
Call-stack spoofing for Dyncvoke.
Public API is spoof! (direct call) and spoof_syscall! (indirect
syscall). Mode is a compile-time choice:
- Synthetic (default,
dyncvokefeaturespoof). BuildsRtlUserThreadStart -> BaseThreadInitThunk -> gadget frames -> target. Works from any thread, including pool threads. - Desync (
dyncvokefeaturespoof-desync, crate featuredesync). Splices spoofed frames onto a liveBaseThreadInitThunkreturn on the current thread. Looks closer to a normal user thread. Fails on pool threads that never went through that path.
ⓘ
use spoof::{spoof_syscall, AsPointer};
use core::ffi::c_void;
use core::ptr::null_mut;
let mut addr: *mut c_void = null_mut();
let mut size: usize = 0x1000;
let status = spoof_syscall!(
"NtAllocateVirtualMemory",
-1isize,
addr.as_ptr_mut(),
0usize,
size.as_ptr_mut(),
0x3000u32,
0x04u32,
).unwrap() as i32;The trampoline lives in src/asm/{msvc,gnu}/*.asm and reads
types::Config by field order. Do not reorder those fields.
Syscall SSNs come from dyncvoke_core::resolve_syscall.
Modules§
- pe
- Minimal PE walker — just enough to locate the .pdata RUNTIME_FUNCTION table for a loaded module. We deliberately don’t reuse dyncvoke_core’s PE parser because that one was built for manual mapping (full optional-header deserialization, etc.). For spoofing we only need the data-directory at IMAGE_DIRECTORY_ENTRY_EXCEPTION.
- types
- unwind
- Walk UNWIND_INFO records to derive stack sizes and RBP offsets. Three walkers (rbp_offset, stack_frame, ignoring_set_fpreg) verified against live ntdll, kernelbase, and kernel32 prologues.
- util
Macros§
- spoof
- Spoof a direct function call. Resolves the spoofing scaffolding once
and then jumps to
addrwith the supplied args under a fake stack. - spoof_
syscall - Spoof an indirect syscall. SSN is resolved via dyncvoke_core’s Tartarus Gate, then the syscall instruction inside ntdll is dispatched under a fake stack.
Enums§
- Spoof
Error - Spoofing errors. Variants carry
SpoofTagrather than literal strings. - Spoof
Kind - Selects which mode the public entry uses.
- Spoof
Tag - Where a failure happened. Carried by SpoofError variants as a non-string
tag so the error path doesn’t leak plaintext module/function names into
.rdata. Display impl decrypts via obfstr at format time only.
Traits§
- AsPointer
- Ergonomic trait that lets call sites write
addr.as_ptr_mut()in macro args instead of&mut addr as *mut _ as *mut c_void.