dinvk 🦀
Dynamically invoke arbitrary code with Rust tricks, #[no_std] support, and compatibility for x64, x86, and WoW64 (DInvoke)
This tool is a Rust version of DInvoke, originally written in C#, with additional features added.
Table of Contents
Features
- ✅ Dynamically invoke arbitrary code
- ✅ Indirect Syscall (x64, x86, Wow64)
- ✅ Tampered Syscalls Via Hardware BreakPoints (x64, x86, Wow64)
- ✅ PE headers parsing
- ✅ Library Proxy Loading
- ✅ Support
#[no_std]projects - ✅ Retrieve exported API addresses via string, ordinal, and hashing
- ✅ Retrieve module addresses via string and hashing
- ✅ Supports multiple 32-bit hash algorithms for API Hashing using
GetModuleHandleandGetProcAddress: Jenkins3, Jenkins One-at-a-Time, DJB2, Murmur3, FNV-1a, SDBM, Lose, PJW, JS, and AP
Installation
Add dinvk to your project by updating your Cargo.toml:
Or manually add the dependency:
[]
= "<version>"
Usage
dinvk provides several features for invoking code dynamically, performing indirect syscalls and manipulating exported modules and APIs. Below are detailed examples of how to use each feature.
Dynamically Invoke Arbitrary Code
Allows resolving and calling a function dynamically at runtime, avoiding static linking.
- This example demonstrates the dynamic invocation of arbitrary code using
dinvoke!, resolving function addresses at runtime without direct linking. In this case,HeapAllocis dynamically called to allocate memory. - Using this macro is beneficial if you want to avoid having APIs directly listed in the
Import Address Table (IAT)of your PE file.
use ;
const HEAP_ZERO_MEMORY: u32 = 8u32;
Retrieving Module Addresses and Exported APIs
Retrieves the base address of a module and resolves exported APIs using different methods: by string, ordinal, or hash.
- In this example, the address of the
KERNEL32module is retrieved using both a string and a hash (Jenkins hash). - Then, the
LoadLibraryfunction address is resolved using the same methods, with an additional example using an ordinal number.
use ;
Indirect syscall
Executes syscalls indirectly, bypassing user-mode API hooks and security monitoring tools.
- This macro has no argument limit and is designed only for x64 architecture.
- It uses techniques such as Hells Gate, Halos Gate, and Tartarus Gate to dynamically locate the System Service Number (SSN) and invoke the syscall indirectly.
- Currently supporting x64, x86 and WoW64.
use ;
use ;
Different Hash Methods for API Hashing
Supports various hashing algorithms for API resolution, improving stealth and flexibility.
- Currently, the library only supports 32-bit hashes for API lookup.
use *;
Library Proxy Loading
Allows DLLs to be loaded indirectly using an API call as an intermediary to clean the call stack and act as a proxy.
use LdrProxy;
Tampered Syscalls Via Hardware BreakPoints
Utilizes hardware breakpoints to manipulate syscall parameters before execution, bypassing security hooks.
- The library includes several API wrappers that leverage DInvoke and support hardware breakpoints to spoof syscall arguments dynamically.
- These breakpoints modify syscall parameters after security monitoring tools inspect them but before the syscall executes, effectively bypassing detection.
- Currently supporting x64, x86 and WoW64.
- You can find the full list of wrapped functions in the wrappers module.
use ;
Support for #[no_std] Environments
Enables #[no_std] compatibility for environments without the Rust standard library.
- To enable
#[no_std]support, define the required features in yourCargo.toml.
[]
= { = "<version>", = ["alloc", "dinvk_panic"] }
- Running in
#[no_std]Mode.
use WinHeap;
use ;
static ALLOCATOR: WinHeap = new;
!
Contributing to dinvk
To contribute to dinvk, follow these steps:
- Fork this repository.
- Create a branch:
git checkout -b <branch_name>. - Make your changes and commit them:
git commit -m '<commit_message>'. - Push your changes to your branch:
git push origin <branch_name>. - Create a pull request.
Alternatively, consult the GitHub documentation on how to create a pull request.
References
I want to express my gratitude to these projects that inspired me to create dinvk:
License
This project is licensed under the MIT License. See the LICENSE file for details.