use dyncvoke_core::{
get_function_address, get_module_base_address, get_syscall_address, resolve_syscall,
};
#[test]
fn resolve_known_syscalls() {
for (name, expected_ssn) in &[
("NtClose", 15u16),
("NtAllocateVirtualMemory", 24),
("NtOpenProcess", 38),
("NtCreateFile", 85),
("NtProtectVirtualMemory", 80),
("NtCreateThreadEx", 201),
] {
let (ssn, addr) = resolve_syscall(name).unwrap_or_else(|e| panic!("{}: {}", name, e));
assert_eq!(ssn, *expected_ssn, "{}: ssn mismatch", name);
assert!(addr != 0, "{}: syscall addr is 0", name);
let stub = get_function_address(get_module_base_address("ntdll.dll"), name);
assert_eq!(addr - stub, 18, "{}: syscall addr is at offset {}, expected 18", name, addr - stub);
}
}
#[test]
fn resolve_unknown_returns_error() {
let result = resolve_syscall("NtThisFunctionDoesNotExistAnywhere");
assert!(result.is_err());
}
#[test]
fn get_syscall_address_skips_ssdt_check_branch() {
let ntdll = get_module_base_address("ntdll.dll");
let nt_close = get_function_address(ntdll, "NtClose");
let addr = get_syscall_address(nt_close as *mut _).unwrap();
let byte_after = unsafe { *((addr + 2) as *const u8) };
assert_eq!(byte_after, 0xC3, "byte after syscall must be 0xC3 (ret)");
}