Skip to main content

Crate spoof

Crate spoof 

Source
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, dyncvoke feature spoof). Builds RtlUserThreadStart -> BaseThreadInitThunk -> gadget frames -> target. Works from any thread, including pool threads.
  • Desync (dyncvoke feature spoof-desync, crate feature desync). Splices spoofed frames onto a live BaseThreadInitThunk return 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 addr with 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§

SpoofError
Spoofing errors. Variants carry SpoofTag rather than literal strings.
SpoofKind
Selects which mode the public entry uses.
SpoofTag
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.