Expand description
Indirect systemcalls on x64 windows with JOP/ROP support.
Provides functions and macros to find and call x64 Windows functions and system calls, and to obfuscate return addresses through the use of JOP/ROP chains found at runtime. It’s also written in no_alloc, no_std rust so it can be compiled to shellcode and offers support for user defined API hashing.
Modules§
Macros§
- functioncall
- This macro makes it extremely easy to call a windows function from your Rust code without importing it. Simply provide the hashed name of the dll, the hashed name of the function you want to call, and then whichever arguments it requires passed as if they are variadics. Please be very careful about your types, passing the wrong type is undefined behaviour and causes some extremely strange behaviour.
- get_
gadgets - This macro should make finding gadgets in dlls extremely simple. If you want more specific details, check out the functions get_image_memory_sections and search_gadget, but basically this takes in the (hashed) name of a dll, a slice representing the gadget to look for (IE &[0xc3] for ret), the maximum number of sections to bother iterating through, and the maximum number of gadgets to return. It returns a tuple of (number of gadgets found, array of gadget addresses) so that you can trim down the array it returns to a slice of only the “real” number of gadgets.
- get_
syscall - A macro that makes it easier to build the syscall struct. You pass it the hashed name of a dll (Almost certainly ntdll.dll) and the name of the specific syscall (NtWhatever or ZwWhatever) and it will construct the struct for you.
- hash
- A procedural macro that hashes a &str at compile time so that the RUNTIME_HASHER can find it. If you replace the RUNTIME_HASHER with a custom function, you’re likely going to want to replace this too.
- jopcall
- A macro which makes it much easier to make an indirect syscall via JOP. You first need to provide it a slice of gadgets where the first gadget is used to jump to rcx and the rest are placed on the stack as return values after the syscall. There is a maximum of 5 gadgets. It then takes a syscall struct of the syscall you want to call, and variadic arguments for the NtApi arguments that the syscall takes.
- syscall
- This is a macro to make a syscall without any return address obfuscation. Simply pass the syscall struct of the syscall you want to call and any arguments it takes.
Statics§
- RUNTIME_
HASHER - A static variable that you can overwrite with your own hashing function. This means that if you have your own hashing function that returns a u128, you can have the library use that whenever it’s searching for strings on the system. Combine this with your own compile time hashing macro to implement custom API hashing.