dinvk/macros.rs
1/// Macro to dynamically invoke a function from a specified module.
2///
3/// # Example
4///
5/// ```
6/// let ntdll = get_ntdll_address();
7/// let result = dinvoke!(ntdll, "NtQueryInformationProcess", extern "system" fn(...) -> u32, ...);
8/// ```
9#[macro_export]
10macro_rules! dinvoke {
11 ($module:expr, $function:expr, $ty:ty, $($arg:expr),*) => {{
12 // Get the address of the function in the specified module
13 let address = $crate::module::get_proc_address($module, $function, None);
14 if address.is_null() {
15 None
16 } else {
17 // Transmute the function pointer to the desired type and invoke it with the provided arguments
18 let func = unsafe { core::mem::transmute::<*mut core::ffi::c_void, $ty>(address) };
19 Some(unsafe { func($($arg),*) })
20 }
21 }};
22}
23
24/// Macro to perform a system call (syscall) by dynamically resolving its function name.
25///
26/// # Example
27///
28/// ```
29/// let mut addr = null_mut::<c_void>();
30/// let mut size = (1 << 12) as usize;
31/// let status = syscall!("NtAllocateVirtualMemory", -1isize as HANDLE, &mut addr, 0, &mut size, 0x3000, 0x04)
32/// .ok_or("syscall resolution failed")?;
33///
34/// if !NT_SUCCESS(status) {
35/// eprintln!("[-] NtAllocateVirtualMemory Failed With Status: {}", status);
36/// }
37/// ```
38#[macro_export]
39#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
40macro_rules! syscall {
41 ($function_name:expr, $($y:expr), +) => {{
42 // Retrieve the address of ntdll.dll
43 let ntdll = $crate::module::get_ntdll_address();
44
45 // Get the address of the specified function in ntdll.dll
46 let addr = $crate::module::get_proc_address(ntdll, $function_name, None);
47 if addr.is_null() {
48 None
49 } else {
50 // Retrieve the SSN for the target function
51 match $crate::ssn($function_name, ntdll) {
52 None => None,
53 Some(ssn) => {
54 // Calculate the syscall address
55 match $crate::get_syscall_address(addr) {
56 None => None,
57 Some(syscall_addr) => {
58 // Count number of args
59 let cnt = 0u32 $(+ { let _ = &$y; 1u32 })+;
60
61 // Execute syscall
62 Some(unsafe { $crate::asm::do_syscall(ssn, syscall_addr, cnt, $($y),+) })
63 }
64 }
65 }
66 }
67 }
68 }};
69}
70
71/// Prints output to the Windows console.
72#[macro_export]
73macro_rules! println {
74 ($($arg:tt)*) => {{
75 use core::fmt::Write;
76
77 let mut console = $crate::console::ConsoleWriter;
78 let _ = writeln!(console, $($arg)*);
79 }};
80}