#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]
extern crate alloc;
#[cfg(not(windows))]
compile_error!("dyncvoke-data is Windows-only");
use alloc::{collections::BTreeMap, string::String, vec::Vec};
use core::ffi::c_void;
pub use obfstr;
#[macro_export]
macro_rules! lc {
($s:literal) => {
$crate::obfstr::obfstring!($s)
};
}
use windows_sys::Win32::Foundation::BOOL;
use windows_sys::Win32::Graphics::Printing::{DOC_INFO_1A, PRINTER_DEFAULTSA};
use windows_sys::Win32::Security::SECURITY_ATTRIBUTES;
use windows_sys::Win32::System::Diagnostics::Debug::{EXCEPTION_RECORD, IMAGE_DATA_DIRECTORY, IMAGE_OPTIONAL_HEADER32, IMAGE_SECTION_HEADER, MINIDUMP_CALLBACK_INFORMATION, MINIDUMP_EXCEPTION_INFORMATION, MINIDUMP_USER_STREAM_INFORMATION};
use windows_sys::Win32::System::Diagnostics::ToolHelp::THREADENTRY32;
use windows_sys::Win32::System::Memory::MEMORY_BASIC_INFORMATION;
use windows_sys::Win32::System::SystemInformation::SYSTEM_INFO;
use windows_sys::Win32::System::Threading::{PROCESS_INFORMATION, STARTUPINFOW};
use windows_sys::Win32::System::WindowsProgramming::CLIENT_ID;
use windows_sys::Win32::System::IO::{IO_STATUS_BLOCK, OVERLAPPED};
pub type HANDLE = *mut c_void;
pub type HINSTANCE = *mut c_void;
pub fn section_ascii_name(name: &[u8; 8]) -> &[u8] {
match name.iter().position(|&b| b == 0) {
Some(i) => &name[..i],
None => name,
}
}
#[repr(C)]
#[allow(non_snake_case)]
#[derive(Default)]
pub struct UNICODE_STRING {
pub Length: u16,
pub MaximumLength: u16,
pub Buffer: *mut u16,
}
#[repr(C)]
#[allow(non_snake_case)]
#[derive(Clone, Copy)]
pub struct OBJECT_ATTRIBUTES {
pub Length: u32,
pub RootDirectory: HANDLE,
pub ObjectName: *mut UNICODE_STRING,
pub Attributes: u32,
pub SecurityDescriptor: *mut c_void,
pub SecurityQualityOfService: *mut c_void,
}
impl Default for OBJECT_ATTRIBUTES {
fn default() -> Self {
unsafe { core::mem::zeroed() }
}
}
#[repr(C)]
#[allow(non_snake_case)]
#[derive(Clone, Copy, Default)]
pub struct LARGE_INTEGER {
pub QuadPart: i64,
}
pub type PVOID = *mut c_void;
pub type DWORD = u32;
pub type EAT = BTreeMap<usize,String>;
pub type EntryPoint = extern "system" fn (HINSTANCE, u32, *mut c_void) -> BOOL;
pub type QueryInterface = unsafe extern "system" fn (*mut c_void, *const GUID, *mut *mut c_void) -> u32;
pub type AddRef = unsafe extern "system" fn(*mut c_void) -> u32;
pub type Release = unsafe extern "system" fn(*mut c_void) -> u32;
pub type ImpersonateLoggedOnUser = unsafe extern "system" fn (HANDLE) -> bool;
pub type RevertToSelf = unsafe extern "system" fn () -> bool;
pub type LoadLibraryA = unsafe extern "system" fn (*mut u8) -> usize;
pub type FreeLibrary = unsafe extern "system" fn (HINSTANCE) -> BOOL;
pub type CreateToolhelp32Snapshot = unsafe extern "system" fn (u32, u32) -> HANDLE;
pub type Thread32First = unsafe extern "system" fn (HANDLE, *mut THREADENTRY32) -> bool;
pub type Thread32Next = unsafe extern "system" fn (HANDLE, *mut THREADENTRY32) -> bool;
pub type PostThreadMessageA = unsafe extern "system" fn (u32, u32, usize, isize) -> bool;
pub type OpenProcess = unsafe extern "system" fn (u32, i32, u32) -> HANDLE;
pub type OpenThread = unsafe extern "system" fn (u32, i32, u32) -> HANDLE;
pub type OpenPrintA = unsafe extern "system" fn (*mut u8, *mut HANDLE, *mut PRINTER_DEFAULTSA) -> BOOL;
pub type StartDocPrinterA = unsafe extern "system" fn (HANDLE, u32, *mut DOC_INFO_1A) -> u32;
pub type GetDefaultPrinterA = unsafe extern "system" fn (*mut u8, *mut u32) -> BOOL;
pub type EnumProcesses = unsafe extern "system" fn (*mut u32, u32, *mut u32) -> bool;
pub type EnumProcessModules = unsafe extern "system" fn (HANDLE, *mut usize, u32, *mut u32) -> bool;
pub type SetPriorityClass = unsafe extern "system" fn (HANDLE, u32) -> bool;
pub type SetThreadPriority = unsafe extern "system" fn (HANDLE, u32) -> bool;
pub type QueueUserWorkItem = unsafe extern "system" fn (*mut c_void, *mut c_void, u32) -> bool;
pub type InitializeProcThreadAttributeList = unsafe extern "system" fn (PVOID, u32, u32, *mut usize) -> BOOL;
pub type UpdateProcThreadAttribute = unsafe extern "system" fn (PVOID, u32, usize, *const c_void, usize, PVOID, *const usize) -> BOOL;
pub type QueryFullProcessImageNameW = unsafe extern "system" fn (HANDLE, u32, *mut u16, *mut u32) -> i32;
pub type MiniDumpWriteDump = unsafe extern "system" fn (HANDLE, u32, HANDLE, u32, *mut MINIDUMP_EXCEPTION_INFORMATION,
*mut MINIDUMP_USER_STREAM_INFORMATION, *mut MINIDUMP_CALLBACK_INFORMATION) -> i32;
pub type GetOverlappedResult = unsafe extern "system" fn (HANDLE, *mut OVERLAPPED, *mut u32, bool) -> BOOL;
pub type CreateFileA = unsafe extern "system" fn (*mut u8, u32, u32, *const SECURITY_ATTRIBUTES, u32, u32, HANDLE) -> HANDLE;
pub type CreateFileW = unsafe extern "system" fn (*const u16, u32, u32, *const SECURITY_ATTRIBUTES, u32, u32, HANDLE) -> HANDLE;
pub type ReadFile = unsafe extern "system" fn (HANDLE, PVOID, u32, *mut u32, *mut OVERLAPPED) -> i32;
pub type CreateTransaction = unsafe extern "system" fn (*mut SECURITY_ATTRIBUTES, *mut GUID, u32, u32, u32, u32, *mut u16) -> HANDLE;
pub type CreateFileTransactedA = unsafe extern "system" fn (*mut u8, u32, u32, *const SECURITY_ATTRIBUTES, u32, u32, HANDLE,
HANDLE, *const u32, PVOID) -> HANDLE;
pub type CreateProcessWithLogon = unsafe extern "system" fn (*const u16, *const u16, *const u16, u32, *const u16, *mut u16, u32, *const c_void, *const u16, *const STARTUPINFOW, *mut PROCESS_INFORMATION) -> BOOL;
pub type RollbackTransaction = unsafe extern "system" fn (HANDLE) -> BOOL;
pub type GetFileSize = unsafe extern "system" fn (HANDLE, *mut u32) -> u32;
pub type CreateFileMapping = unsafe extern "system" fn (HANDLE, *const SECURITY_ATTRIBUTES, u32, u32, u32, *mut u8) -> HANDLE;
pub type MapViewOfFile = unsafe extern "system" fn (HANDLE, u32, u32, u32, usize) -> PVOID;
pub type UnmapViewOfFile = unsafe extern "system" fn (PVOID) -> BOOL;
pub type ConvertThreadToFiber = unsafe extern "system" fn (PVOID) -> PVOID;
pub type CreateFiber = unsafe extern "system" fn (usize, PVOID, PVOID) -> PVOID;
pub type SwitchToFiber = unsafe extern "system" fn (PVOID);
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 GetModuleHandleExA = unsafe extern "system" fn (i32,*const u8,*mut usize) -> bool;
pub type GetModuleBaseNameW = unsafe extern "system" fn (HANDLE, usize, *mut u16, u32) -> u32;
pub type GetModuleFileNameExW = unsafe extern "system" fn (HANDLE, usize, *mut u16, u32) -> u32;
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 AddVectoredExceptionHandler = unsafe extern "system" fn (first: u32, handle: usize) -> PVOID;
pub type SetUnhandledExceptionFilter = unsafe extern "system" fn (filter: LptopLevelExceptionFilter) -> LptopLevelExceptionFilter;
pub type BCryptOpenAlgorithmProvider = unsafe extern "system" fn (*mut HANDLE, *const u16, *const u16, u32) -> i32;
pub type BCryptGetProperty = unsafe extern "system" fn (HANDLE, *const u16, *mut u8, u32, *mut u32, u32) -> i32;
pub type BCryptSetProperty = unsafe extern "system" fn (HANDLE, *const u16, *mut u8, u32, u32) -> i32;
pub type BCryptGenerateSymmetricKey = unsafe extern "system" fn (HANDLE,*mut HANDLE, *mut u8, u32, *mut u8, u32, u32) -> i32;
pub type BCryptEncrypt = unsafe extern "system" fn (HANDLE, *mut u8, u32, PVOID, *mut u8, u32, *mut u8, u32, *mut u32, u32) -> i32;
pub type BCryptDestroyKey = unsafe extern "system" fn (HANDLE) -> i32;
pub type BCryptDecrypt = unsafe extern "system" fn (HANDLE, *mut u8, u32, PVOID, *mut u8, u32, *mut u8, u32, *mut u32, u32) -> i32;
pub type BCryptCloseAlgorithmProvider = unsafe extern "system" fn (HANDLE, u32) -> i32;
pub type CryptSignHashW = unsafe extern "system" fn (usize, u32, *mut u16, u32, *mut u8, *mut u32) -> bool;
pub type CreateEventW = unsafe extern "system" fn (*const SECURITY_ATTRIBUTES, i32, i32, *const u16) -> HANDLE;
#[repr(C)]
#[allow(non_camel_case_types, non_snake_case)]
pub struct ANSI_STRING {
pub Length: u16,
pub MaximumLength: u16,
pub Buffer: *const u8,
}
pub type LdrGetProcedureAddress = unsafe extern "system" fn (PVOID, *const ANSI_STRING, u32, *mut PVOID) -> i32;
pub type NtCreateTransaction = unsafe extern "system" fn (*mut HANDLE, u32, *mut OBJECT_ATTRIBUTES, *mut GUID, HANDLE, u32, u32, u32, *mut LARGE_INTEGER, *mut UNICODE_STRING) -> i32;
pub type NtWriteVirtualMemory = unsafe extern "system" fn (HANDLE, PVOID, PVOID, usize, *mut usize) -> i32;
pub type NtProtectVirtualMemory = unsafe extern "system" fn (HANDLE, *mut PVOID, *mut usize, u32, *mut u32) -> i32;
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 NtQueryInformationFile = unsafe extern "system" fn (HANDLE, *mut IO_STATUS_BLOCK, PVOID, u32, 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 NtCreateUserProcess = unsafe extern "system" fn (*mut HANDLE, *mut HANDLE,u32, u32, *mut OBJECT_ATTRIBUTES,*mut OBJECT_ATTRIBUTES, u32, u32, PVOID, *mut PsCreateInfo, *mut PsAttributeList) -> i32;
pub type NtOpenFile = unsafe extern "system" fn (*mut HANDLE, u32, *mut OBJECT_ATTRIBUTES, *mut IO_STATUS_BLOCK, u32, u32) -> i32;
pub type NtCreateSection = unsafe extern "system" fn (*mut HANDLE, u32, *mut OBJECT_ATTRIBUTES, *mut LARGE_INTEGER, u32, u32, HANDLE) -> i32;
pub type NtMapViewOfSection = unsafe extern "system" fn (HANDLE, HANDLE, *mut PVOID, usize, usize, *mut LARGE_INTEGER, *mut usize, u32, u32, u32) -> i32;
pub type NtOpenProcess = unsafe extern "system" fn (*mut HANDLE, u32, *mut OBJECT_ATTRIBUTES, *mut ClientId) -> i32;
pub type NtCreateThreadEx = unsafe extern "system" fn (*mut HANDLE, u32, *mut OBJECT_ATTRIBUTES, HANDLE, PVOID, PVOID, u32, usize, usize, usize, *mut PsAttributeList) -> i32;
pub type NtReadVirtualMemory = unsafe extern "system" fn (HANDLE, PVOID, PVOID, usize, *mut usize) -> i32;
pub type NtRemoveProcessDebug = unsafe extern "system" fn (HANDLE, HANDLE) -> i32;
pub type NtWaitForDebugEvent = unsafe extern "system" fn (HANDLE, u8, *mut LARGE_INTEGER, PVOID) -> i32;
pub type NtTerminateProcess = unsafe extern "system" fn (HANDLE, i32) -> i32;
pub type NtOpenKey = unsafe extern "system" fn (*mut HANDLE, u32, *mut OBJECT_ATTRIBUTES) -> i32;
pub type NtSaveKey = unsafe extern "system" fn (HANDLE, HANDLE) -> i32;
pub type NtOpenProcessToken = unsafe extern "system" fn (HANDLE, u32, *mut HANDLE) -> i32;
pub type NtDuplicateToken = unsafe extern "system" fn (HANDLE, u32, *mut OBJECT_ATTRIBUTES, bool, u32, *mut HANDLE) -> i32;
pub type NtCreateKey = unsafe extern "system" fn (*mut HANDLE, u32, *mut OBJECT_ATTRIBUTES, u32, *mut UNICODE_STRING, u32, *mut u32) -> i32;
pub type NtSetValueKey = unsafe extern "system" fn (HANDLE, *const UNICODE_STRING, u32, u32, *const c_void, u32) -> i32;
pub type RtlAdjustPrivilege = unsafe extern "system" fn (u32, u8, u8, *mut u8) -> i32;
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 type RtlAddFunctionTable = unsafe extern "system" fn (usize, i32, usize) -> bool;
pub type NtCommitTransaction = unsafe extern "system" fn (HANDLE, bool) -> i32;
pub const JMP_RBX: u16 = 9215;
pub const ADD_RSP: u32 = 1489273672;
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 IMAGE_REL_AMD64_ABSOLUTE: u16 = 0x0000;
pub const IMAGE_REL_AMD64_ADDR64: u16 = 0x0001;
pub const IMAGE_REL_AMD64_ADDR32: u16 = 0x0002;
pub const IMAGE_REL_AMD64_ADDR32NB: u16 = 0x0003;
pub const IMAGE_REL_AMD64_REL32: u16 = 0x0004;
pub const DLL_PROCESS_DETACH: u32 = 0;
pub const DLL_PROCESS_ATTACH: u32 = 1;
pub const DLL_THREAD_ATTACH: u32 = 2;
pub const DLL_THREAD_DETACH: u32 = 3;
pub const PAGE_NOACCESS: u32 = 0x1;
pub const PAGE_READONLY: u32 = 0x2;
pub const PAGE_READWRITE: u32 = 0x4;
pub const PAGE_WRITECOPY: u32 = 0x8;
pub const PAGE_EXECUTE: u32 = 0x10;
pub const PAGE_EXECUTE_READ: u32 = 0x20;
pub const PAGE_EXECUTE_READWRITE: u32 = 0x40;
pub const PAGE_EXECUTE_WRITECOPY: u32 = 0x80;
pub const MEM_COMMIT: u32 = 0x1000;
pub const MEM_RESERVE: u32 = 0x2000;
pub const SECTION_MEM_READ: u32 = 0x40000000;
pub const SECTION_MEM_WRITE: u32 = 0x80000000;
pub const SECTION_MEM_EXECUTE: u32 = 0x20000000;
pub const GENERIC_READ: u32 = 0x80000000;
pub const GENERIC_WRITE: u32 = 0x40000000;
pub const GENERIC_EXECUTE: u32 = 0x20000000;
pub const GENERIC_ALL: u32 = 0x10000000;
pub const SECTION_ALL_ACCESS: u32 = 0x10000000;
pub const PROCESS_QUERY_LIMITED_INFORMATION: u32 = 0x1000;
pub const THREAD_ALL_ACCESS: u32 = 0x000F0000 | 0x00100000 | 0xFFFF;
pub const FILE_SHARE_NONE: u32 = 0x0;
pub const FILE_SHARE_READ: u32 = 0x1;
pub const FILE_SHARE_WRITE: u32 = 0x2;
pub const FILE_SHARE_DELETE: u32 = 0x4;
pub const DELETE: u32 = 0x10000;
pub const FILE_READ_DATA: u32 = 0x1;
pub const FILE_READ_ATTRIBUTES: u32 = 0x80;
pub const FILE_READ_EA: u32 = 0x8;
pub const READ_CONTROL: u32 = 0x20000;
pub const FILE_WRITE_DATA: u32 = 0x2;
pub const FILE_WRITE_ATTRIBUTES: u32 = 0x100;
pub const FILE_WRITE_EA: u32 = 0x10;
pub const FILE_APPEND_DATA: u32 = 0x4;
pub const WRITE_DAC: u32 = 0x40000;
pub const WRITE_OWNER: u32 = 0x80000;
pub const SYNCHRONIZE: u32 = 0x100000;
pub const FILE_EXECUTE: u32 = 0x20;
pub const FILE_SYNCHRONOUS_IO_NONALERT: u32 = 0x20;
pub const FILE_NON_DIRECTORY_FILE: u32 = 0x40;
pub const SEC_IMAGE: u32 = 0x1000000;
pub const MAX_PATH: u32 = 260;
#[derive(Clone)]
#[repr(C)]
pub struct PeMetadata {
pub pe: u32,
pub is_32_bit: bool,
pub image_file_header: ImageFileHeader,
pub opt_header_32: IMAGE_OPTIONAL_HEADER32,
pub opt_header_64: ImageOptionalHeader64,
pub sections: Vec<IMAGE_SECTION_HEADER>
}
impl Default for PeMetadata {
fn default() -> PeMetadata {
unsafe {
PeMetadata {
pe: u32::default(),
is_32_bit: false,
image_file_header: ImageFileHeader::default(),
opt_header_32: core::mem::zeroed(),
opt_header_64: core::mem::zeroed(),
sections: Vec::default(),
}
}
}
}
#[derive(Clone)]
#[repr(C)]
pub struct CoffMetadata {
pub image_file_header: ImageFileHeader,
pub sections: Vec<IMAGE_SECTION_HEADER>,
pub sections_order: BTreeMap<u32,Vec<u16>>,
pub sections_mapped_addresses: BTreeMap<u16,usize>,
pub symbols: Vec<CoffSymbol>,
pub imports: BTreeMap<String,usize>
}
impl Default for CoffMetadata {
fn default() -> CoffMetadata {
CoffMetadata {
image_file_header: ImageFileHeader::default(),
sections: Vec::default(),
sections_order: BTreeMap::default(),
sections_mapped_addresses: BTreeMap::default(),
symbols: Vec::default(),
imports: BTreeMap::default()
}
}
}
#[derive(Clone, Copy)]
#[repr(C)]
pub struct AuxSymbolEntry {
pub aux_symbol_entry: [u8;18]
}
impl Default for AuxSymbolEntry {
fn default() -> AuxSymbolEntry {
AuxSymbolEntry {
aux_symbol_entry: [0u8;18]
}
}
}
#[derive(Clone)]
#[repr(C)]
pub struct CoffSymbol {
pub name_str: String,
pub symbol_offset: u32, pub value: u32,
pub section_number: u16,
pub symbol_type: u16,
pub storage_class: u8,
pub aux_symbols: u8,
pub aux_symbol_entries: Vec<AuxSymbolEntry>
}
impl Default for CoffSymbol {
fn default() -> CoffSymbol {
CoffSymbol {
name_str: String::default(),
symbol_offset: u32::default(),
value: u32::default(),
section_number: u16::default(),
symbol_type: u16::default(),
storage_class: u8::default(),
aux_symbols: u8::default(),
aux_symbol_entries: Vec::default()
}
}
}
#[repr(C)]
pub struct PeManualMap {
pub decoy_module: String,
pub base_address: usize,
pub pe_info: PeMetadata,
}
#[repr(C)]
#[derive(Copy, Clone, Default, PartialEq, Debug, Eq)]
pub struct ApiSetNamespace {
pub unused: [u8;12],
pub count: i32, pub entry_offset: i32, }
#[repr(C)]
#[derive(Copy, Clone, Default, PartialEq, Debug, Eq)]
pub struct ApiSetNamespaceEntry {
pub unused1: [u8;4],
pub name_offset: i32, pub name_length: i32, pub unused2: [u8;4],
pub value_offset: i32, pub value_length: i32, }
#[repr(C)]
#[derive(Copy, Clone, Default, PartialEq, Debug, Eq)]
pub struct ApiSetValueEntry {
pub flags: i32, pub name_offset: i32, pub name_count: i32, pub value_offset: i32, pub value_count: i32, }
#[derive(Copy, Clone, Default, PartialEq, Debug, Eq)]
#[repr(C)]
pub struct ImageFileHeader {
pub machine: u16,
pub number_of_sections: u16,
pub time_data_stamp: u32,
pub pointer_to_symbol_table: u32,
pub number_of_symbols: u32,
pub size_of_optional_header: u16,
pub characteristics: u16,
}
#[derive(Copy, Clone)]
#[repr(C)] pub struct ImageOptionalHeader64 {
pub magic: u16,
pub major_linker_version: u8,
pub minor_linker_version: u8,
pub size_of_code: u32,
pub size_of_initialized_data: u32,
pub size_of_unitialized_data: u32,
pub address_of_entry_point: u32,
pub base_of_code: u32,
pub image_base: u64,
pub section_alignment: u32,
pub file_alignment: u32,
pub major_operating_system_version: u16,
pub minor_operating_system_version: u16,
pub major_image_version: u16,
pub minor_image_version: u16,
pub major_subsystem_version: u16,
pub minor_subsystem_version: u16,
pub win32_version_value: u32,
pub size_of_image: u32,
pub size_of_headers: u32,
pub checksum: u32,
pub subsystem: u16,
pub dll_characteristics: u16,
pub size_of_stack_reserve: u64,
pub size_of_stack_commit: u64,
pub size_of_heap_reserve: u64,
pub size_of_heap_commit: u64,
pub loader_flags: u32,
pub number_of_rva_and_sizes: u32,
pub datas_directory: [IMAGE_DATA_DIRECTORY; 16],
}
#[derive(Copy, Clone, Default, PartialEq, Debug, Eq)]
#[repr(C)]
pub struct GUID
{
pub data1: u32,
pub data2: u16,
pub data3: u16,
pub data4: [u8; 8],
}
#[repr(C)]
pub struct SystemHandleInformation {
pub number_of_handles: u32,
pub handles: Vec<SystemHandleTableEntryInfo>,
}
#[repr(C)]
pub struct SystemHandleTableEntryInfo {
pub process_id: u16,
pub creator_back_trace_index: u16,
pub object_type_index: u8,
pub handle_attributes: u8,
pub handle_value: u16,
pub object: PVOID,
pub granted_access: u32,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct ClientId {
pub unique_process: HANDLE,
pub unique_thread: HANDLE,
}
impl Default for ClientId {
fn default() -> Self {
unsafe { core::mem::zeroed() }
}
}
pub struct NtAllocateVirtualMemoryArgs
{
pub handle: HANDLE,
pub base_address: *mut PVOID
}
pub struct NtOpenProcessArgs
{
pub handle: *mut HANDLE,
pub access: u32,
pub attributes: *mut OBJECT_ATTRIBUTES,
pub client_id: *mut ClientId
}
pub struct NtProtectVirtualMemoryArgs
{
pub handle: HANDLE,
pub base_address: *mut PVOID,
pub size: *mut usize,
pub protection: u32
}
pub struct NtWriteVirtualMemoryArgs
{
pub handle: HANDLE,
pub base_address: PVOID,
pub buffer: PVOID,
pub size: usize
}
pub struct NtCreateThreadExArgs
{
pub thread: *mut HANDLE,
pub access: u32,
pub attributes: *mut OBJECT_ATTRIBUTES,
pub process: HANDLE
}
#[repr(C)]
#[allow(non_snake_case)]
pub struct CONTEXT {
pub P1Home: u64,
pub P2Home: u64,
pub P3Home: u64,
pub P4Home: u64,
pub P5Home: u64,
pub P6Home: u64,
pub ContextFlags: u32,
pub MxCsr: u32,
pub SegCs: u16,
pub SegDs: u16,
pub SegEs: u16,
pub SegFs: u16,
pub SegGs: u16,
pub SegSs: u16,
pub EFlags: u32,
pub Dr0: u64,
pub Dr1: u64,
pub Dr2: u64,
pub Dr3: u64,
pub Dr6: u64,
pub Dr7: u64,
pub Rax: u64,
pub Rcx: u64,
pub Rdx: u64,
pub Rbx: u64,
pub Rsp: u64,
pub Rbp: u64,
pub Rsi: u64,
pub Rdi: u64,
pub R8: u64,
pub R9: u64,
pub R10: u64,
pub R11: u64,
pub R12: u64,
pub R13: u64,
pub R14: u64,
pub R15: u64,
pub Rip: u64,
pub Anonymous: [u8; 512],
pub VectorRegister: [u8; 16 * 26],
pub VectorControl: u64,
pub DebugControl: u64,
pub LastBranchToRip: u64,
pub LastBranchFromRip: u64,
pub LastExceptionToRip: u64,
pub LastExceptionFromRip: u64,
}
impl Default for CONTEXT
{
fn default() -> CONTEXT {
CONTEXT {
P1Home: 0,
P2Home: 0,
P3Home: 0,
P4Home: 0,
P5Home: 0,
P6Home: 0,
ContextFlags: 0,
MxCsr: 0,
SegCs: 0,
SegDs: 0,
SegEs: 0,
SegFs: 0,
SegGs: 0,
SegSs: 0,
EFlags: 0,
Dr0: 0,
Dr1: 0,
Dr2: 0,
Dr3: 0,
Dr6: 0,
Dr7: 0,
Rax: 0,
Rcx: 0,
Rdx: 0,
Rbx: 0,
Rsp: 0,
Rbp: 0,
Rsi: 0,
Rdi: 0,
R8: 0,
R9: 0,
R10: 0,
R11: 0,
R12: 0,
R13: 0,
R14: 0,
R15: 0,
Rip: 0,
Anonymous: [0; 512],
VectorRegister: [0; 16 * 26],
VectorControl: 0,
DebugControl: 0,
LastBranchToRip: 0,
LastBranchFromRip: 0,
LastExceptionToRip: 0,
LastExceptionFromRip: 0
}
}
}
#[repr(C)]
pub struct ExceptionPointers {
pub exception_record: *mut EXCEPTION_RECORD,
pub context_record: *mut CONTEXT,
}
#[repr(C)]
pub struct PsAttributeList {
pub size: u32,
pub unk1: u32,
pub unk2: u32,
pub unk3: *mut u32,
pub unk4: u32,
pub unk5: u32,
pub unk6: u32,
pub unk7: *mut u32,
pub unk8: u32,
}
pub enum ExceptionHandleFunction
{
NtOpenProcess,
NtAllocateVirtualMemory,
NtWriteVirtualMemory,
NtProtectVirtualMemory,
NtCreateThreadEx
}
#[repr(C)]
#[derive(Copy, Clone, Default)]
pub struct RuntimeFunction {
pub begin_addr: u32,
pub end_addr: u32,
pub unwind_addr: u32
}
#[repr(C)]
pub struct PsCreateInfo {
pub size: usize,
pub unused: [u8;80],
}
#[repr(C)]
pub struct PsAttribute {
pub attribute: usize,
pub size: usize,
pub union: PsAttributeU,
pub return_length: *mut usize,
}
#[repr(C)]
pub union PsAttributeU {
pub value: usize,
pub value_ptr: PVOID,
}
#[derive(Clone,Copy,Default)]
#[repr(C)]
pub struct PsCreateInfoInitState{
pub init_flags: u32,
pub additional_file_access: u32,
}
#[derive(Clone,Copy)]
#[repr(C)]
pub struct PsCreateInfoUSuccessSate {
pub output_flags: u32,
pub file_handle: HANDLE,
pub section_handle: HANDLE,
pub user_process_parameters_native: u64,
pub user_process_parameters_wow64: u32,
pub current_parameter_flags: u32,
pub peb_address_native: u64,
pub peb_address_wow64: u32,
pub manifest_address: u64,
pub manifest_size: u32,
}
#[derive(Clone,Copy)]
#[repr(C)]
pub union PsCreateInfoU {
pub init_state: PsCreateInfoInitState,
pub file_handle: HANDLE,
pub dll_characteristics: u16,
pub ifeokey: HANDLE,
pub success_state: PsCreateInfoUSuccessSate,
}
#[repr(C)]
pub struct FileProcessIdsUsingFileInformation {
pub number_of_process_ids_in_list: u32,
pub process_id_list: [usize;1],
}
#[repr(C)]
pub struct ThreadBasicInformation {
pub exit_status: i32,
pub teb_base_address: PVOID,
pub client_id: CLIENT_ID,
pub affinity_mask: usize,
pub priority: i32,
pub base_priority: i32,
}
#[cfg(test)]
extern crate std;
#[cfg(test)]
mod tests {
use super::*;
use core::ptr;
#[test]
fn test_unicode_string_default() {
let us = UNICODE_STRING::default();
assert_eq!(us.Length, 0);
assert_eq!(us.MaximumLength, 0);
assert!(us.Buffer.is_null());
}
#[test]
fn test_unicode_string_creation() {
let us = UNICODE_STRING {
Length: 10,
MaximumLength: 12,
Buffer: ptr::null_mut(),
};
assert_eq!(us.Length, 10);
assert_eq!(us.MaximumLength, 12);
}
#[test]
fn test_object_attributes_default() {
let oa = OBJECT_ATTRIBUTES::default();
assert_eq!(oa.Length, 0);
assert!(oa.RootDirectory.is_null());
assert!(oa.ObjectName.is_null());
assert_eq!(oa.Attributes, 0);
}
#[test]
fn test_large_integer_default() {
let li = LARGE_INTEGER::default();
assert_eq!(li.QuadPart, 0);
}
#[test]
fn test_large_integer_creation() {
let li = LARGE_INTEGER { QuadPart: 12345 };
assert_eq!(li.QuadPart, 12345);
}
#[test]
fn test_dll_constants() {
assert_eq!(DLL_PROCESS_DETACH, 0);
assert_eq!(DLL_PROCESS_ATTACH, 1);
assert_eq!(DLL_THREAD_ATTACH, 2);
assert_eq!(DLL_THREAD_DETACH, 3);
}
#[test]
fn test_page_constants() {
assert_eq!(PAGE_NOACCESS, 0x1);
assert_eq!(PAGE_READONLY, 0x2);
assert_eq!(PAGE_READWRITE, 0x4);
assert_eq!(PAGE_WRITECOPY, 0x8);
assert_eq!(PAGE_EXECUTE, 0x10);
assert_eq!(PAGE_EXECUTE_READ, 0x20);
assert_eq!(PAGE_EXECUTE_READWRITE, 0x40);
assert_eq!(PAGE_EXECUTE_WRITECOPY, 0x80);
}
#[test]
fn test_memory_constants() {
assert_eq!(MEM_COMMIT, 0x1000);
assert_eq!(MEM_RESERVE, 0x2000);
}
#[test]
fn test_section_constants() {
assert_eq!(SECTION_MEM_READ, 0x40000000);
assert_eq!(SECTION_MEM_WRITE, 0x80000000);
assert_eq!(SECTION_MEM_EXECUTE, 0x20000000);
}
#[test]
fn test_access_constants() {
assert_eq!(GENERIC_READ, 0x80000000);
assert_eq!(GENERIC_WRITE, 0x40000000);
assert_eq!(GENERIC_EXECUTE, 0x20000000);
assert_eq!(GENERIC_ALL, 0x10000000);
}
#[test]
fn test_file_share_constants() {
assert_eq!(FILE_SHARE_NONE, 0x0);
assert_eq!(FILE_SHARE_READ, 0x1);
assert_eq!(FILE_SHARE_WRITE, 0x2);
assert_eq!(FILE_SHARE_DELETE, 0x4);
}
#[test]
fn test_file_access_constants() {
assert_eq!(DELETE, 0x10000);
assert_eq!(FILE_READ_DATA, 0x1);
assert_eq!(FILE_READ_ATTRIBUTES, 0x80);
assert_eq!(FILE_READ_EA, 0x8);
assert_eq!(READ_CONTROL, 0x20000);
assert_eq!(FILE_WRITE_DATA, 0x2);
assert_eq!(FILE_WRITE_ATTRIBUTES, 0x100);
assert_eq!(FILE_WRITE_EA, 0x10);
assert_eq!(FILE_APPEND_DATA, 0x4);
}
#[test]
fn test_file_open_constants() {
assert_eq!(FILE_SYNCHRONOUS_IO_NONALERT, 0x20);
assert_eq!(FILE_NON_DIRECTORY_FILE, 0x40);
}
#[test]
fn test_other_constants() {
assert_eq!(SEC_IMAGE, 0x1000000);
assert_eq!(MAX_PATH, 260);
assert_eq!(TLS_OUT_OF_INDEXES, 0xFFFFFFFF);
}
#[test]
fn test_unw_flags() {
assert_eq!(UNW_FLAG_EHANDLER, 0x1);
assert_eq!(UNW_FLAG_UHANDLER, 0x2);
assert_eq!(UNW_FLAG_CHAININFO, 0x4);
}
#[test]
fn test_coff_relocation_constants() {
assert_eq!(IMAGE_REL_AMD64_ABSOLUTE, 0x0000);
assert_eq!(IMAGE_REL_AMD64_ADDR64, 0x0001);
assert_eq!(IMAGE_REL_AMD64_ADDR32, 0x0002);
assert_eq!(IMAGE_REL_AMD64_ADDR32NB, 0x0003);
assert_eq!(IMAGE_REL_AMD64_REL32, 0x0004);
}
#[test]
fn test_pe_metadata_default() {
let pe = PeMetadata::default();
assert_eq!(pe.pe, 0);
assert!(!pe.is_32_bit);
}
#[test]
fn test_coff_metadata_default() {
let coff = CoffMetadata::default();
assert_eq!(coff.image_file_header.machine, 0);
assert!(coff.sections.is_empty());
assert!(coff.imports.is_empty());
}
#[test]
fn test_image_file_header_default() {
let header = ImageFileHeader::default();
assert_eq!(header.machine, 0);
assert_eq!(header.number_of_sections, 0);
assert_eq!(header.time_data_stamp, 0);
}
#[test]
fn test_client_id_default() {
let cid = ClientId::default();
assert!(cid.unique_process.is_null());
assert!(cid.unique_thread.is_null());
}
#[test]
fn test_api_set_namespace_default() {
let ns = ApiSetNamespace::default();
assert_eq!(ns.count, 0);
assert_eq!(ns.entry_offset, 0);
}
#[test]
fn test_api_set_namespace_entry_default() {
let entry = ApiSetNamespaceEntry::default();
assert_eq!(entry.name_offset, 0);
assert_eq!(entry.name_length, 0);
assert_eq!(entry.value_offset, 0);
assert_eq!(entry.value_length, 0);
}
#[test]
fn test_api_set_value_entry_default() {
let entry = ApiSetValueEntry::default();
assert_eq!(entry.flags, 0);
assert_eq!(entry.name_offset, 0);
assert_eq!(entry.name_count, 0);
assert_eq!(entry.value_offset, 0);
assert_eq!(entry.value_count, 0);
}
#[test]
fn test_context_default() {
let ctx = CONTEXT::default();
assert_eq!(ctx.P1Home, 0);
assert_eq!(ctx.Rax, 0);
assert_eq!(ctx.Rsp, 0);
assert_eq!(ctx.Rip, 0);
}
#[test]
fn test_guid_default() {
let guid = GUID::default();
assert_eq!(guid.data1, 0);
assert_eq!(guid.data2, 0);
assert_eq!(guid.data3, 0);
}
#[test]
fn test_runtime_function_default() {
let rf = RuntimeFunction::default();
assert_eq!(rf.begin_addr, 0);
assert_eq!(rf.end_addr, 0);
assert_eq!(rf.unwind_addr, 0);
}
#[test]
fn test_handle_type() {
let null_handle: HANDLE = ptr::null_mut();
assert!(null_handle.is_null());
}
#[test]
fn test_hinstance_type() {
let null_hinstance: HINSTANCE = ptr::null_mut();
assert!(null_hinstance.is_null());
}
}