Skip to main content

syscall

Macro syscall 

Source
macro_rules! syscall {
    ($name:expr $(, $arg:expr)* $(,)?) => { ... };
}
Available on x86-64 only.
Expand description

Resolve a Zw/Nt syscall by name (Tartarus Gate) and dispatch via the variadic Hell’s Hall gateway.

Every argument is cast as usize and then transmuted to *mut c_void before the call, so the kernel sees uniform 64-bit slots no matter what mix of integer and pointer types you pass at the call site. This matches the flow used by spoof_syscall! and spoof! so all three macros take the same shape of arguments and return the same shape of result.

Returns Result<*mut c_void, SyscallError>. Err means name or SSN resolution failed and the kernel transition never happened. Ok(ptr) returns the raw NTSTATUS the kernel gave us, in pointer-width form. Convert it with .unwrap() as i32 or (... as usize) as i32.

§Examples

use dyncvoke_core::syscall;
use core::ffi::c_void;
use core::ptr::null_mut;

let mut p_tmp_address: *mut c_void = null_mut();
let mut s_chunk: usize = 0x1000;
let mut old_prot: u32 = 0;

let status = syscall!(
    "NtProtectVirtualMemory",
    -1isize as *mut c_void,                                          // NtCurrentProcess
    &mut p_tmp_address as *mut *mut c_void as *mut c_void,
    &mut s_chunk as *mut usize as *mut c_void,
    0x20u32 as *mut c_void,                                          // PAGE_EXECUTE_READ
    &mut old_prot as *mut u32 as *mut c_void,
    null_mut::<c_void>(),
    null_mut::<c_void>(),
    null_mut::<c_void>(),
    null_mut::<c_void>(),
    null_mut::<c_void>(),
    null_mut::<c_void>(),
)
.ok()
.unwrap() as i32;

Trailing null_mut::<c_void>() slots are optional. The macro counts what you actually pass and tells the gateway the right argument count. Supports arbitrary arity, zero-arg syscalls (e.g. NtYieldExecution), and trailing commas.