mirror of
https://github.com/Kudaes/DInvoke_rs
synced 2026-06-08 11:32:25 +00:00
dinvoke_rs published to crates.io
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
[build]
|
||||
rustflags = [
|
||||
"--remap-path-prefix", "dinvoke=",
|
||||
"--remap-path-prefix", "manualmap=",
|
||||
"--remap-path-prefix", "overload=",
|
||||
"--remap-path-prefix", "dmanager=",
|
||||
"--remap-path-prefix", "AAA=BBB" # AAA = string to remove (e.g. the same value as the %USERPROFILE% env variable);
|
||||
# BBB = new value, it can be left empty to remove strings from the final binary
|
||||
]
|
||||
@@ -3,7 +3,6 @@ name = "dinvoke_rs"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# From https://stackoverflow.com/questions/29008127/why-are-rust-executables-so-huge
|
||||
[profile.release]
|
||||
strip = true
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Kurosh Dabbagh Escalante
|
||||
Copyright (c) 2023 Kurosh Dabbagh Escalante
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -29,6 +29,15 @@ All the credits go to the creators of the original C# implementation of this too
|
||||
- [Use hardware breakpoints to spoof syscall parameters](#Syscall-parameters-spoofing)
|
||||
|
||||
# Usage
|
||||
|
||||
Import this crate into your project by adding the following line to your `cargo.toml`:
|
||||
|
||||
```rust
|
||||
[dependencies]
|
||||
dinvoke_rs = "0.1.2"
|
||||
```
|
||||
|
||||
# Examples
|
||||
## Resolving Exported APIs
|
||||
|
||||
The example below demonstrates how to use DInvoke_rs to dynamically find and call exports of a DLL (ntdll.dll in this case).
|
||||
|
||||
@@ -5,7 +5,6 @@ edition = "2021"
|
||||
|
||||
# From https://stackoverflow.com/questions/29008127/why-are-rust-executables-so-huge
|
||||
[profile.release]
|
||||
opt-level = 'z' # Optimize for size.
|
||||
strip = true
|
||||
|
||||
[dependencies]
|
||||
@@ -24,5 +23,6 @@ features = [
|
||||
"Win32_System_WindowsProgramming",
|
||||
"Wdk_Foundation",
|
||||
"Win32_Storage_FileSystem",
|
||||
"Win32_System_Memory"
|
||||
"Win32_System_Memory",
|
||||
"Win32_System_SystemInformation"
|
||||
]
|
||||
@@ -1,10 +1,9 @@
|
||||
use std::{collections::BTreeMap, ffi::c_void};
|
||||
use windows::Win32::{Foundation::{BOOL, HANDLE, HINSTANCE, UNICODE_STRING}, Security::SECURITY_ATTRIBUTES, System::{Diagnostics::Debug::{IMAGE_DATA_DIRECTORY, IMAGE_OPTIONAL_HEADER32, IMAGE_SECTION_HEADER, MINIDUMP_CALLBACK_INFORMATION, MINIDUMP_EXCEPTION_INFORMATION, MINIDUMP_USER_STREAM_INFORMATION, EXCEPTION_RECORD}, IO::{OVERLAPPED,IO_STATUS_BLOCK}}};
|
||||
use windows::Win32::{Foundation::{BOOL, HANDLE, HINSTANCE, UNICODE_STRING}, Security::SECURITY_ATTRIBUTES, System::{Diagnostics::Debug::{IMAGE_DATA_DIRECTORY, IMAGE_OPTIONAL_HEADER32, IMAGE_SECTION_HEADER, MINIDUMP_CALLBACK_INFORMATION, MINIDUMP_EXCEPTION_INFORMATION, MINIDUMP_USER_STREAM_INFORMATION, EXCEPTION_RECORD}, IO::{OVERLAPPED,IO_STATUS_BLOCK}, SystemInformation::SYSTEM_INFO, Memory::MEMORY_BASIC_INFORMATION}};
|
||||
use windows::core::PSTR;
|
||||
use windows::Wdk::Foundation::OBJECT_ATTRIBUTES;
|
||||
use winapi::shared::ntdef::LARGE_INTEGER;
|
||||
|
||||
|
||||
pub type PVOID = *mut c_void;
|
||||
pub type DWORD = u32;
|
||||
pub type EAT = BTreeMap<isize,String>;
|
||||
@@ -24,6 +23,12 @@ pub type CreateFileTransactedA = unsafe extern "system" fn (*mut u8, u32, u32, *
|
||||
pub type GetLastError = unsafe extern "system" fn () -> u32;
|
||||
pub type CloseHandle = unsafe extern "system" fn (HANDLE) -> i32;
|
||||
pub type VirtualFree = unsafe extern "system" fn (PVOID, usize, u32) -> bool;
|
||||
pub type LocalAlloc = unsafe extern "system" fn (u32, usize) -> PVOID;
|
||||
pub type TlsAlloc = unsafe extern "system" fn () -> u32;
|
||||
pub type TlsGetValue = unsafe extern "system" fn (u32) -> PVOID;
|
||||
pub type TlsSetValue = unsafe extern "system" fn (u32, PVOID) -> bool;
|
||||
pub type GetSystemInfo = unsafe extern "system" fn (*mut SYSTEM_INFO);
|
||||
pub type VirtualQueryEx = unsafe extern "system" fn (HANDLE, *const c_void, *mut MEMORY_BASIC_INFORMATION, usize) -> usize;
|
||||
pub type LptopLevelExceptionFilter = usize;
|
||||
pub type SetUnhandledExceptionFilter = unsafe extern "system" fn (filter: LptopLevelExceptionFilter) -> LptopLevelExceptionFilter;
|
||||
pub type LdrGetProcedureAddress = unsafe extern "system" fn (PVOID, *mut String, u32, *mut PVOID) -> i32;
|
||||
@@ -32,6 +37,7 @@ pub type NtProtectVirtualMemory = unsafe extern "system" fn (HANDLE, *mut PVOID,
|
||||
pub type NtAllocateVirtualMemory = unsafe extern "system" fn (HANDLE, *mut PVOID, usize, *mut usize, u32, u32) -> i32;
|
||||
pub type NtQueryInformationProcess = unsafe extern "system" fn (HANDLE, u32, PVOID, u32, *mut u32) -> i32;
|
||||
pub type NtQuerySystemInformation = unsafe extern "system" fn (u32, PVOID, u32, *mut u32) -> i32;
|
||||
pub type NtQueryInformationThread = unsafe extern "system" fn (HANDLE, u32, PVOID, u32, *mut u32) -> i32;
|
||||
pub type NtDuplicateObject = unsafe extern "system" fn (HANDLE, HANDLE, HANDLE, *mut HANDLE, u32, u32, u32) -> i32;
|
||||
pub type NtQueryObject = unsafe extern "system" fn (HANDLE, u32, PVOID, u32, *mut u32) -> i32;
|
||||
pub type NtOpenFile = unsafe extern "system" fn (*mut HANDLE, u32, *mut OBJECT_ATTRIBUTES, *mut IO_STATUS_BLOCK, u32, u32) -> i32;
|
||||
@@ -43,7 +49,16 @@ pub type RtlAdjustPrivilege = unsafe extern "system" fn (u32, u8, u8, *mut u8) -
|
||||
pub type RtlInitUnicodeString = unsafe extern "system" fn (*mut UNICODE_STRING, *const u16) -> () ;
|
||||
pub type RtlZeroMemory = unsafe extern "system" fn (PVOID, usize) -> ();
|
||||
pub type RtlQueueWorkItem = unsafe extern "system" fn (usize, PVOID, u32) -> i32;
|
||||
|
||||
|
||||
pub const JMP_RBX: u16 = 9215;
|
||||
pub const ADD_RSP: u32 = 1489273672;// add rsp,0x58 -> up to 11 parameters
|
||||
|
||||
pub const TLS_OUT_OF_INDEXES: u32 = 0xFFFFFFFF;
|
||||
|
||||
pub const UNW_FLAG_EHANDLER: u8 = 0x1;
|
||||
pub const UNW_FLAG_UHANDLER: u8 = 0x2;
|
||||
pub const UNW_FLAG_CHAININFO: u8 = 0x4;
|
||||
|
||||
pub const DLL_PROCESS_DETACH: u32 = 0;
|
||||
pub const DLL_PROCESS_ATTACH: u32 = 1;
|
||||
pub const DLL_THREAD_ATTACH: u32 = 2;
|
||||
@@ -5,7 +5,6 @@ edition = "2021"
|
||||
|
||||
# From https://stackoverflow.com/questions/29008127/why-are-rust-executables-so-huge
|
||||
[profile.release]
|
||||
opt-level = 'z' # Optimize for size.
|
||||
strip = true
|
||||
|
||||
[dependencies]
|
||||
@@ -8,13 +8,15 @@ use std::panic;
|
||||
use std::{collections::HashMap, ptr};
|
||||
use std::ffi::CString;
|
||||
use windows::Win32::System::Diagnostics::Debug::{GetThreadContext,SetThreadContext};
|
||||
use windows::Win32::System::Memory::MEMORY_BASIC_INFORMATION;
|
||||
use windows::Win32::System::SystemInformation::SYSTEM_INFO;
|
||||
use windows::Win32::System::Threading::PROCESS_BASIC_INFORMATION;
|
||||
use windows::Win32::System::IO::IO_STATUS_BLOCK;
|
||||
use windows::Wdk::Foundation::OBJECT_ATTRIBUTES;
|
||||
use windows::Win32::{Foundation::{HANDLE, HINSTANCE,UNICODE_STRING}, System::Threading::{GetCurrentProcess,GetCurrentThread}};
|
||||
use data::{ApiSetNamespace, ApiSetNamespaceEntry, ApiSetValueEntry, DLL_PROCESS_ATTACH, EAT, EntryPoint, MEM_COMMIT, MEM_RESERVE, PAGE_EXECUTE_READ, PAGE_READWRITE,
|
||||
PVOID, PeMetadata, CONTEXT, NtAllocateVirtualMemoryArgs, EXCEPTION_POINTERS, NtOpenProcessArgs, CLIENT_ID, PROCESS_QUERY_LIMITED_INFORMATION, NtProtectVirtualMemoryArgs,
|
||||
PAGE_READONLY, NtWriteVirtualMemoryArgs, ExceptionHandleFunction, PS_ATTRIBUTE_LIST, NtCreateThreadExArgs, LptopLevelExceptionFilter};
|
||||
PAGE_READONLY, NtWriteVirtualMemoryArgs, ExceptionHandleFunction, PS_ATTRIBUTE_LIST, NtCreateThreadExArgs, LptopLevelExceptionFilter, TLS_OUT_OF_INDEXES};
|
||||
use libc::c_void;
|
||||
use litcrypt2::lc;
|
||||
use winproc::Process;
|
||||
@@ -999,6 +1001,117 @@ pub fn close_handle(handle: HANDLE) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tls_alloc() -> u32
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
let ret: Option<u32>;
|
||||
let func_ptr: data::TlsAlloc;
|
||||
let module_base_address = get_module_base_address(&lc!("kernel32.dll"));
|
||||
dynamic_invoke!(module_base_address,&lc!("TlsAlloc"),func_ptr,ret,);
|
||||
|
||||
match ret {
|
||||
Some(x) => return x,
|
||||
None => return TLS_OUT_OF_INDEXES,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tls_get_value(index: u32) -> PVOID
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
let ret: Option<PVOID>;
|
||||
let func_ptr: data::TlsGetValue;
|
||||
let module_base_address = get_module_base_address(&lc!("kernel32.dll"));
|
||||
dynamic_invoke!(module_base_address,&lc!("TlsGetValue"),func_ptr,ret,index);
|
||||
|
||||
match ret {
|
||||
Some(x) => return x,
|
||||
None => return ptr::null_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tls_set_value(index: u32, data: PVOID) -> bool
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
let ret: Option<bool>;
|
||||
let func_ptr: data::TlsSetValue;
|
||||
let module_base_address = get_module_base_address(&lc!("kernel32.dll"));
|
||||
dynamic_invoke!(module_base_address,&lc!("TlsSetValue"),func_ptr,ret,index,data);
|
||||
|
||||
match ret {
|
||||
Some(x) => return x,
|
||||
None => return false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_last_error() -> u32
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
let ret: Option<u32>;
|
||||
let func_ptr: data::GetLastError;
|
||||
let module_base_address = get_module_base_address(&lc!("kernel32.dll"));
|
||||
dynamic_invoke!(module_base_address,&lc!("GetLastError"),func_ptr,ret,);
|
||||
|
||||
match ret {
|
||||
Some(x) => return x,
|
||||
None => return 0xf,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn local_alloc(flags: u32, size: usize) -> PVOID
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
let ret: Option<PVOID>;
|
||||
let func_ptr: data::LocalAlloc;
|
||||
let module_base_address = get_module_base_address(&lc!("kernel32.dll"));
|
||||
dynamic_invoke!(module_base_address,&lc!("localAlloc"),func_ptr,ret,flags,size);
|
||||
|
||||
match ret {
|
||||
Some(x) => return x,
|
||||
None => return ptr::null_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Dynamically calls GetSystemInfo.
|
||||
///
|
||||
pub fn get_system_info(sysinfo: *mut SYSTEM_INFO) {
|
||||
|
||||
unsafe
|
||||
{
|
||||
let _ret: Option<()>;
|
||||
let func_ptr: data::GetSystemInfo;
|
||||
let kernel32 = get_module_base_address(&lc!("kernel32.dll"));
|
||||
dynamic_invoke!(kernel32,&lc!("GetSystemInfo"),func_ptr,_ret,sysinfo);
|
||||
}
|
||||
}
|
||||
|
||||
/// Dynamically calls VirtualQueryEx.
|
||||
///
|
||||
pub fn virtual_query_ex(process_handle: HANDLE, page_address: *const c_void, buffer: *mut MEMORY_BASIC_INFORMATION, length: usize) -> usize{
|
||||
|
||||
unsafe
|
||||
{
|
||||
let ret: Option<usize>;
|
||||
let func_ptr: data::VirtualQueryEx;
|
||||
let kernel32 = get_module_base_address(&lc!("kernel32.dll"));
|
||||
dynamic_invoke!(kernel32,&lc!("VirtualQueryEx"),func_ptr,ret,process_handle,page_address,buffer,length);
|
||||
|
||||
match ret {
|
||||
Some(x) => return x,
|
||||
None => return 0 ,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Dynamically calls VirtualFree.
|
||||
pub fn virtual_free(address: PVOID, size: usize, free_type: u32) -> bool {
|
||||
unsafe
|
||||
@@ -1,8 +0,0 @@
|
||||
[build]
|
||||
rustflags = [
|
||||
"--remap-path-prefix", "dinvoke=",
|
||||
"--remap-path-prefix", "manualmap=",
|
||||
"--remap-path-prefix", "overload=",
|
||||
"--remap-path-prefix", "dmanager=",
|
||||
"--remap-path-prefix", "AAA=BBB" # AAA = prefix path to remove, probably the same value as the %USERPROFILE% env variable ; BBB = new value, it can be left empty
|
||||
]
|
||||
@@ -1,13 +0,0 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
|
||||
# Generated by vscode
|
||||
/.vscode/
|
||||
|
||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||
Cargo.lock
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
@@ -5,7 +5,6 @@ edition = "2021"
|
||||
|
||||
# From https://stackoverflow.com/questions/29008127/why-are-rust-executables-so-huge
|
||||
[profile.release]
|
||||
opt-level = 'z' # Optimize for size.
|
||||
strip = true
|
||||
|
||||
[dependencies]
|
||||
@@ -5,7 +5,6 @@ edition = "2021"
|
||||
|
||||
# From https://stackoverflow.com/questions/29008127/why-are-rust-executables-so-huge
|
||||
[profile.release]
|
||||
opt-level = 'z' # Optimize for size.
|
||||
strip = true
|
||||
|
||||
[dependencies]
|
||||
@@ -1,5 +1,4 @@
|
||||
fn main() {
|
||||
|
||||
println!("Hello world!");
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user