| Crates.io | dinvk |
| lib.rs | dinvk |
| version | 0.4.2 |
| created_at | 2025-02-24 13:58:32.156142+00 |
| updated_at | 2025-12-01 01:24:09.165743+00 |
| description | Dynamically invoke arbitrary code in Rust (Dinvoke) |
| homepage | https://github.com/joaoviictorti/dinvk |
| repository | https://github.com/joaoviictorti/dinvk |
| max_upload_size | |
| id | 1567533 |
| size | 122,020 |
Dynamically invoke arbitrary code with Rust tricks, #[no_std] support, and compatibility for x64, x86, ARM64 and WoW64 (DInvoke)
This tool is a Rust version of DInvoke, originally written in C#, with additional features added.
#[no_std] environments (with alloc).get_module_address and get_proc_address: Jenkins3, Jenkins One-at-a-Time, DJB2, Murmur3, FNV-1a, SDBM, Lose, PJW, JS, and AP.Add dinvk to your project by updating your Cargo.toml:
cargo add dinvk
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.
Allows resolving and calling a function dynamically at runtime, avoiding static linking.
dinvoke!, resolving function addresses at runtime without direct linking. In this case, HeapAlloc is dynamically called to allocate memory.Import Address Table (IAT) of your PE file.use dinvk::module::get_module_address;
use dinvk::winapis::GetProcessHeap;
use dinvk::{types::HeapAllocFn, dinvoke};
const HEAP_ZERO_MEMORY: u32 = 8u32;
let kernel32 = get_module_address("KERNEL32.DLL", None);
let addr = dinvoke!(
kernel32,
"HeapAlloc",
HeapAllocFn,
GetProcessHeap(),
HEAP_ZERO_MEMORY,
0x200
);
println!("[+] Address: {:?}", addr);
Retrieves the base address of a module and resolves exported APIs using different methods: by string, ordinal, or hash.
KERNEL32 module is retrieved using both a string and a hash (Jenkins hash).LoadLibrary function address is resolved using the same methods, with an additional example using an ordinal number.use dinvk::module::{get_module_address, get_proc_address};
use dinvk::hash::jenkins;
// Retrieving module address via string and hash
let kernel32 = get_module_address("KERNEL32.DLL", None);
let kernel32 = get_module_address(3425263715u32, Some(jenkins));
// Retrieving exported API address via string, ordinal and hash
let addr = get_proc_address(kernel32, "LoadLibraryA", None);
let addr = get_proc_address(kernel32, 3962820501u32, Some(jenkins));
let addr = get_proc_address(kernel32, 997, None);
Executes syscalls indirectly, bypassing user-mode API hooks and security monitoring tools.
use std::{ffi::c_void, ptr::null_mut};
use dinvk::winapis::{NT_SUCCESS, NtCurrentProcess};
use dinvk::{Dll, syscall, types::HANDLE};
// Memory allocation using a syscall
let mut addr = null_mut::<c_void>();
let mut size = (1 << 12) as usize;
let status = syscall!("NtAllocateVirtualMemory", NtCurrentProcess(), &mut addr, 0, &mut size, 0x3000, 0x04)
.ok_or("syscall resolution failed")?;
if !NT_SUCCESS(status) {
eprintln!("[-] NtAllocateVirtualMemory Failed With Status: {}", status);
return Ok(());
}
Supports various hashing algorithms for API resolution, improving stealth and flexibility.
use dinvk::hash::*;
println!("{}", jenkins("dinvk"));
println!("{}", jenkins3("dinvk"));
println!("{}", ap("dinvk"));
println!("{}", js("dinvk"));
println!("{}", murmur3("dinvk"));
println!("{}", fnv1a("dinvk"));
println!("{}", djb2("dinvk"));
println!("{}", crc32ba("dinvk"));
println!("{}", loselose("dinvk"));
println!("{}", pjw("dinvk"));
println!("{}", sdbm("dinvk"));
Utilizes hardware breakpoints to manipulate syscall parameters before execution, bypassing security hooks.
use dinvk::{
types::HANDLE,
breakpoint::{
set_use_breakpoint,
veh_handler
},
};
use dinvk::winapis::{
NT_SUCCESS,
NtAllocateVirtualMemory,
AddVectoredExceptionHandler,
RemoveVectoredExceptionHandler,
};
// Enabling breakpoint hardware
set_use_breakpoint(true);
let handle = AddVectoredExceptionHandler(0, Some(veh_handler));
// Allocating memory and using breakpoint hardware
let mut addr = std::ptr::null_mut();
let mut size = 1 << 12;
let status = NtAllocateVirtualMemory(-1isize as HANDLE, &mut addr, 0, &mut size, 0x3000, 0x04);
if !NT_SUCCESS(status) {
eprintln!("[-] NtAllocateVirtualMemory Failed With Status: {}", status);
return Ok(());
}
// Disabling breakpoint hardware
set_use_breakpoint(false);
RemoveVectoredExceptionHandler(handle);
Enables #[no_std] compatibility for environments without the Rust standard library.
#[no_std] support, define the required features in your Cargo.toml.[dependencies]
dinvk = { version = "<version>", features = ["alloc", "panic"] }
#[no_std] Mode.#![no_std]
#![no_main]
use dinvk::allocator::WinHeap;
use dinvk::module::{get_ntdll_address, get_proc_address};
use dinvk::println;
#[unsafe(no_mangle)]
fn main() -> u8 {
let addr = get_proc_address(get_ntdll_address(), "NtOpenProcess", None);
println!("[+] NtOpenProcess: {:?}", addr);
0
}
#[global_allocator]
static ALLOCATOR: WinHeap = WinHeap;
#[cfg(not(test))]
#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
dinvk::panic::panic_handler(info)
}
dinvk is licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in dinvk by you, as defined in the Apache-2.0 license, shall be dually licensed as above, without any additional terms or conditions.