Single stub direct and indirect syscalling with runtime SSN resolving for windows.
RUST_SYSCALLS
Single stub direct and indirect syscalling with runtime SSN resolving for windows.Features:
- One single line for all your syscalls
- Function name hashing at compilation time
- Direct or indirect sycalls
- x86_64, WOW64 and x86 native support
- Designed to allow the implementation of custom SSN fetching methods (check the end of this readme for more info)
How to use:
- Add the git repository / local path to the library to your dependencies:
rustsyscalls = {git = "https://github.com/janoglezcampos/rustsyscalls"}
or
> rust_syscalls = {path = <path to library folder>}
- Choose direct or indirect method by setting
DIRECTorINDIRECTas a feature:
rustsyscalls = {path = <path to library folder>}, features = ["INDIRECT_"]}
- Import
use rust_syscalls::syscall;
- Syscall:
NTSTATUS status = syscall!("NtClose", handle);
Example:
#![allow(nonsnakecase)]
use ntapi::ntapibase::CLIENTID;
use rust_syscalls::syscall;
use winapi::shared::ntdef::{OBJECT_ATTRIBUTES, HANDLE, NULL, NTSTATUS, PVOID}; use winapi::um::winnt::{PROCESSVMWRITE, PROCESSVMREAD, MEMORYBASICINFORMATION}; use std::mem::size_of; fn main(){ let pid : u64 = 3268; //Process PID let currentProcess : HANDLE = -1isize as _; let meminfolen : usize = sizeof::<MEMORYBASICINFORMATION>() as ;
let mut handle : HANDLE = NULL; let mut status : NTSTATUS; let meminfo: MEMORYBASICINFORMATION = MEMORYBASIC_INFORMATION { BaseAddress: NULL, AllocationBase: NULL, AllocationProtect: 0, RegionSize: 0, State: 0, Protect: 0, Type: 0, };
let oa : OBJECTATTRIBUTES = OBJECTATTRIBUTES { Length: sizeof::<OBJECTATTRIBUTES>() as _, RootDirectory: NULL, ObjectName: NULL as _, Attributes: 0, SecurityDescriptor: NULL, SecurityQualityOfService: NULL };
let cid : CLIENTID = CLIENTID { UniqueProcess: pid as _, UniqueThread: 0 as _ };
unsafe { status = syscall!("NtOpenProcess", &mut handle, PROCESSVMWRITE | PROCESSVMREAD, &oa, &cid); } println!("\n\t[-] NtOpenProcess status: {:#02X}", status);
if status != 0 { return; }
unsafe { status = syscall!("NtQueryVirtualMemory", currentProcess, &pid, 0, &meminfo, meminfo_len, NULL as PVOID); } println!("\n\t[-] NtQueryVirtualMemory status: {:#02X}", status); if status != 0 { return; }
println!("\n\t[-] Protect value: {:#02X}\n\t", mem_info.Protect);
unsafe { status = syscall!("NtClose", handle); } println!("\t[-] NtClose status: {:#02X}", status); }
Implementing new SSN and syscall addresses runtime resolving methods:
All the code required to do the SSN and address fetching is included in the file src\syscall_resolve.rs.
There is one core function used to retrieve the values called get_ssn, with 4 implementations, where the received argument is the result of calling crate::obf!(\<your function name\>), and the return values are the ssn (u16), and, in case of indirect syscalling, the address of the syscall/sysenter instruction that you want to use.
- x86_64 direct:
- x86_64 indirect:
- x86 direct:
- x86 indirect:
Just reimplement this functions with your desired fetching method.
Thanks to SysWhispers3 for being a strong pilar on the development of this library