mirror of
https://github.com/EddieIvan01/memexec
synced 2024-06-25 00:10:33 +00:00
369 lines
12 KiB
Rust
369 lines
12 KiB
Rust
use std::os::raw::c_void;
|
|
|
|
pub(crate) type WORD = u16;
|
|
pub(crate) type LONG = i32;
|
|
pub(crate) type DWORD = u32;
|
|
pub(crate) type BYTE = u8;
|
|
pub(crate) type ULONGLONG = u64;
|
|
pub(crate) type CHAR = i8;
|
|
pub(crate) type PVOID = *const c_void;
|
|
|
|
pub(crate) const IMAGE_DOS_SIGNATURE: WORD = 0x5a4d;
|
|
pub(crate) const IMAGE_NT_SIGNATURE: DWORD = 0x00004550;
|
|
|
|
pub(crate) const IMAGE_FILE_EXECUTABLE_IMAGE: WORD = 0x0002; // File is executable (i.e. no unresolved external references).
|
|
#[allow(dead_code)]
|
|
pub(crate) const IMAGE_FILE_LARGE_ADDRESS_AWARE: WORD = 0x0020; // App can handle >2gb addresses
|
|
#[allow(dead_code)]
|
|
pub(crate) const IMAGE_FILE_32BIT_MACHINE: WORD = 0x0100; // 32 bit word machine.
|
|
pub(crate) const IMAGE_FILE_DLL: WORD = 0x2000; // File is a DLL.
|
|
|
|
pub(crate) const IMAGE_FILE_MACHINE_I386: WORD = 0x014c;
|
|
pub(crate) const IMAGE_FILE_MACHINE_AMD64: WORD = 0x8664;
|
|
|
|
pub(crate) const IMAGE_NT_OPTIONAL_HDR32_MAGIC: WORD = 0x10b;
|
|
pub(crate) const IMAGE_NT_OPTIONAL_HDR64_MAGIC: WORD = 0x20b;
|
|
|
|
pub const PAGE_NOACCESS: DWORD = 0x01;
|
|
pub const PAGE_READONLY: DWORD = 0x02;
|
|
pub const PAGE_READWRITE: DWORD = 0x04;
|
|
pub const PAGE_EXECUTE: DWORD = 0x10;
|
|
pub const PAGE_EXECUTE_READ: DWORD = 0x20;
|
|
pub const PAGE_EXECUTE_READWRITE: DWORD = 0x40;
|
|
|
|
pub const IMAGE_SCN_MEM_EXECUTE: DWORD = 0x20000000;
|
|
pub const IMAGE_SCN_MEM_READ: DWORD = 0x40000000;
|
|
pub const IMAGE_SCN_MEM_WRITE: DWORD = 0x80000000;
|
|
|
|
pub(crate) const IMAGE_SIZEOF_SHORT_NAME: usize = 8;
|
|
|
|
pub(crate) const IMAGE_NUMBEROF_DIRECTORY_ENTRIES: usize = 16;
|
|
|
|
pub const IMAGE_DIRECTORY_ENTRY_EXPORT: usize = 0; // Export Directory
|
|
pub const IMAGE_DIRECTORY_ENTRY_IMPORT: usize = 1; // Import Directory
|
|
pub const IMAGE_DIRECTORY_ENTRY_RESOURCE: usize = 2; // Resource Directory
|
|
pub const IMAGE_DIRECTORY_ENTRY_EXCEPTION: usize = 3; // Exception Directory
|
|
pub const IMAGE_DIRECTORY_ENTRY_SECURITY: usize = 4; // Security Directory
|
|
pub const IMAGE_DIRECTORY_ENTRY_BASERELOC: usize = 5; // Base Relocation Table
|
|
pub const IMAGE_DIRECTORY_ENTRY_DEBUG: usize = 6; // Debug Directory
|
|
pub const IMAGE_DIRECTORY_ENTRY_ARCHITECTURE: usize = 7; // Architecture Specific Data
|
|
pub const IMAGE_DIRECTORY_ENTRY_GLOBALPTR: usize = 8; // RVA of GP
|
|
pub const IMAGE_DIRECTORY_ENTRY_TLS: usize = 9; // TLS Directory
|
|
pub const IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG: usize = 10; // Load Configuration Directory
|
|
pub const IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT: usize = 11; // Bound Import Directory in headers
|
|
pub const IMAGE_DIRECTORY_ENTRY_IAT: usize = 12; // Import Address Table
|
|
pub const IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT: usize = 13; // Delay Load Import Descriptors
|
|
pub const IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR: usize = 14; // COM Runtime descriptor
|
|
|
|
#[cfg(all(target_arch = "x86_64", target_os = "windows"))]
|
|
pub(crate) const IMAGE_REL_BASED_DIR64: WORD = 10;
|
|
#[cfg(all(target_arch = "x86", target_os = "windows"))]
|
|
pub(crate) const IMAGE_REL_BASED_HIGHLOW: WORD = 3;
|
|
|
|
#[cfg(all(target_arch = "x86_64", target_os = "windows"))]
|
|
pub(crate) const IMAGE_REL_BASED: WORD = IMAGE_REL_BASED_DIR64;
|
|
#[cfg(all(target_arch = "x86", target_os = "windows"))]
|
|
pub(crate) const IMAGE_REL_BASED: WORD = IMAGE_REL_BASED_HIGHLOW;
|
|
|
|
#[cfg(all(target_arch = "x86_64", target_os = "windows"))]
|
|
pub(crate) const IMAGE_ORDINAL_FLAG64: isize = 0x8000000000000000;
|
|
#[cfg(all(target_arch = "x86", target_os = "windows"))]
|
|
pub(crate) const IMAGE_ORDINAL_FLAG32: isize = 0x80000000;
|
|
|
|
#[cfg(all(target_arch = "x86_64", target_os = "windows"))]
|
|
pub(crate) const IMAGE_ORDINAL_FLAG: isize = IMAGE_ORDINAL_FLAG64;
|
|
#[cfg(all(target_arch = "x86", target_os = "windows"))]
|
|
pub(crate) const IMAGE_ORDINAL_FLAG: isize = IMAGE_ORDINAL_FLAG32;
|
|
|
|
macro_rules! struct_wrapper {
|
|
(struct $name:ident {
|
|
$($field:ident: $t:ty,)*
|
|
}) => {
|
|
#[repr(C)]
|
|
#[derive(Debug)]
|
|
pub struct $name {
|
|
$(pub $field: $t),*
|
|
}
|
|
}
|
|
}
|
|
|
|
struct_wrapper!(
|
|
struct IMAGE_DOS_HEADER {
|
|
// DOS .EXE header
|
|
e_magic: WORD, // Magic number
|
|
e_cblp: WORD, // Bytes on last page of file
|
|
e_cp: WORD, // Pages in file
|
|
e_crlc: WORD, // Relocations
|
|
e_cparhdr: WORD, // Size of header in paragraphs
|
|
e_minalloc: WORD, // Minimum extra paragraphs needed
|
|
e_maxalloc: WORD, // Maximum extra paragraphs needed
|
|
e_ss: WORD, // Initial (relative) SS value
|
|
e_sp: WORD, // Initial SP value
|
|
e_csum: WORD, // Checksum
|
|
e_ip: WORD, // Initial IP value
|
|
e_cs: WORD, // Initial (relative) CS value
|
|
e_lfarlc: WORD, // File address of relocation table
|
|
e_ovno: WORD, // Overlay number
|
|
e_res: [WORD; 4], // Reserved words
|
|
e_oemid: WORD, // OEM identifier (for e_oeminfo)
|
|
e_oeminfo: WORD, // OEM information; e_oemid specific
|
|
e_res2: [WORD; 10], // Reserved words
|
|
e_lfanew: LONG, // File address of new exe header
|
|
}
|
|
);
|
|
|
|
struct_wrapper!(
|
|
struct IMAGE_FILE_HEADER {
|
|
Machine: WORD,
|
|
NumberOfSections: WORD,
|
|
TimeDateStamp: DWORD,
|
|
PointerToSymbolTable: DWORD,
|
|
NumberOfSymbols: DWORD,
|
|
SizeOfOptionalHeader: WORD,
|
|
Characteristics: WORD,
|
|
}
|
|
);
|
|
|
|
/*
|
|
ImageBase
|
|
|
|
EXE
|
|
32-bit 0x400000
|
|
64-bit 0x140000000
|
|
|
|
DLL
|
|
32-bit 0x10000000
|
|
64-bit 0x180000000
|
|
*/
|
|
|
|
struct_wrapper!(
|
|
struct IMAGE_OPTIONAL_HEADER32 {
|
|
Magic: WORD,
|
|
MajorLinkerVersion: BYTE,
|
|
MinorLinkerVersion: BYTE,
|
|
SizeOfCode: DWORD,
|
|
SizeOfInitializedData: DWORD,
|
|
SizeOfUninitializedData: DWORD,
|
|
AddressOfEntryPoint: DWORD,
|
|
BaseOfCode: DWORD,
|
|
BaseOfData: DWORD,
|
|
ImageBase: DWORD,
|
|
SectionAlignment: DWORD,
|
|
FileAlignment: DWORD,
|
|
MajorOperatingSystemVersion: WORD,
|
|
MinorOperatingSystemVersion: WORD,
|
|
MajorImageVersion: WORD,
|
|
MinorImageVersion: WORD,
|
|
MajorSubsystemVersion: WORD,
|
|
MinorSubsystemVersion: WORD,
|
|
Win32VersionValue: DWORD,
|
|
SizeOfImage: DWORD,
|
|
SizeOfHeaders: DWORD,
|
|
CheckSum: DWORD,
|
|
Subsystem: WORD,
|
|
DllCharacteristics: WORD,
|
|
SizeOfStackReserve: DWORD,
|
|
SizeOfStackCommit: DWORD,
|
|
SizeOfHeapReserve: DWORD,
|
|
SizeOfHeapCommit: DWORD,
|
|
LoaderFlags: DWORD,
|
|
NumberOfRvaAndSizes: DWORD,
|
|
DataDirectory: [IMAGE_DATA_DIRECTORY; IMAGE_NUMBEROF_DIRECTORY_ENTRIES],
|
|
}
|
|
);
|
|
|
|
struct_wrapper!(
|
|
struct IMAGE_NT_HEADERS32 {
|
|
Signature: DWORD,
|
|
FileHeader: IMAGE_FILE_HEADER,
|
|
OptionalHeader: IMAGE_OPTIONAL_HEADER32,
|
|
}
|
|
);
|
|
|
|
struct_wrapper!(
|
|
struct IMAGE_OPTIONAL_HEADER64 {
|
|
Magic: WORD,
|
|
MajorLinkerVersion: BYTE,
|
|
MinorLinkerVersion: BYTE,
|
|
SizeOfCode: DWORD,
|
|
SizeOfInitializedData: DWORD,
|
|
SizeOfUninitializedData: DWORD,
|
|
AddressOfEntryPoint: DWORD,
|
|
BaseOfCode: DWORD,
|
|
ImageBase: ULONGLONG,
|
|
SectionAlignment: DWORD,
|
|
FileAlignment: DWORD,
|
|
MajorOperatingSystemVersion: WORD,
|
|
MinorOperatingSystemVersion: WORD,
|
|
MajorImageVersion: WORD,
|
|
MinorImageVersion: WORD,
|
|
MajorSubsystemVersion: WORD,
|
|
MinorSubsystemVersion: WORD,
|
|
Win32VersionValue: DWORD,
|
|
SizeOfImage: DWORD,
|
|
SizeOfHeaders: DWORD,
|
|
CheckSum: DWORD,
|
|
Subsystem: WORD,
|
|
DllCharacteristics: WORD,
|
|
SizeOfStackReserve: ULONGLONG,
|
|
SizeOfStackCommit: ULONGLONG,
|
|
SizeOfHeapReserve: ULONGLONG,
|
|
SizeOfHeapCommit: ULONGLONG,
|
|
LoaderFlags: DWORD,
|
|
NumberOfRvaAndSizes: DWORD,
|
|
DataDirectory: [IMAGE_DATA_DIRECTORY; IMAGE_NUMBEROF_DIRECTORY_ENTRIES],
|
|
}
|
|
);
|
|
|
|
struct_wrapper!(
|
|
struct IMAGE_NT_HEADERS64 {
|
|
Signature: DWORD,
|
|
FileHeader: IMAGE_FILE_HEADER,
|
|
OptionalHeader: IMAGE_OPTIONAL_HEADER64,
|
|
}
|
|
);
|
|
|
|
struct_wrapper!(
|
|
struct IMAGE_DATA_DIRECTORY {
|
|
VirtualAddress: DWORD,
|
|
Size: DWORD,
|
|
}
|
|
);
|
|
|
|
struct_wrapper!(
|
|
struct IMAGE_SECTION_HEADER {
|
|
Name: [u8; IMAGE_SIZEOF_SHORT_NAME],
|
|
/*
|
|
union {
|
|
DWORD PhysicalAddress;
|
|
DWORD VirtualSize;
|
|
} Misc;
|
|
*/
|
|
Misc: DWORD,
|
|
VirtualAddress: DWORD,
|
|
SizeOfRawData: DWORD,
|
|
PointerToRawData: DWORD,
|
|
PointerToRelocations: DWORD,
|
|
PointerToLinenumbers: DWORD,
|
|
NumberOfRelocations: WORD,
|
|
NumberOfLinenumbers: WORD,
|
|
Characteristics: DWORD,
|
|
}
|
|
);
|
|
|
|
struct_wrapper!(
|
|
struct IMAGE_BASE_RELOCATION {
|
|
VirtualAddress: DWORD,
|
|
SizeOfBlock: DWORD,
|
|
}
|
|
);
|
|
|
|
struct_wrapper!(
|
|
struct IMAGE_IMPORT_DESCRIPTOR {
|
|
/*
|
|
union {
|
|
DWORD Characteristics; // 0 for terminating null import descriptor
|
|
DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
|
|
}
|
|
*/
|
|
OriginalFirstThunk: DWORD,
|
|
// 0 if not bound,
|
|
// -1 if bound, and real date\time stamp
|
|
// in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
|
|
// O.W. date/time stamp of DLL bound to (Old BIND)
|
|
TimeDateStamp: DWORD,
|
|
ForwarderChain: DWORD, // -1 if no forwarders
|
|
Name: DWORD,
|
|
FirstThunk: DWORD, // RVA to IAT (if bound this IAT has actual addresses)
|
|
}
|
|
);
|
|
|
|
/*
|
|
union {
|
|
ULONGLONG ForwarderString; // PBYTE
|
|
ULONGLONG Function; // PDWORD
|
|
ULONGLONG Ordinal;
|
|
ULONGLONG AddressOfData; // PIMAGE_IMPORT_BY_NAME
|
|
}
|
|
*/
|
|
#[cfg(all(target_arch = "x86_64", target_os = "windows"))]
|
|
pub(crate) type IMAGE_THUNK_DATA64 = ULONGLONG;
|
|
|
|
/*
|
|
union {
|
|
DWORD ForwarderString; // PBYTE
|
|
DWORD Function; // PDWORD
|
|
DWORD Ordinal;
|
|
DWORD AddressOfData; // PIMAGE_IMPORT_BY_NAME
|
|
}
|
|
*/
|
|
#[cfg(all(target_arch = "x86", target_os = "windows"))]
|
|
pub(crate) type IMAGE_THUNK_DATA32 = DWORD;
|
|
|
|
#[cfg(all(target_arch = "x86_64", target_os = "windows"))]
|
|
pub(crate) type IMAGE_THUNK_DATA = IMAGE_THUNK_DATA64;
|
|
#[cfg(all(target_arch = "x86", target_os = "windows"))]
|
|
pub(crate) type IMAGE_THUNK_DATA = IMAGE_THUNK_DATA32;
|
|
|
|
struct_wrapper!(
|
|
struct IMAGE_IMPORT_BY_NAME {
|
|
Hint: WORD,
|
|
Name: CHAR,
|
|
}
|
|
);
|
|
|
|
pub type PIMAGE_TLS_CALLBACK = extern "system" fn(PVOID, DWORD, PVOID);
|
|
|
|
struct_wrapper!(
|
|
struct IMAGE_TLS_DIRECTORY64 {
|
|
StartAddressOfRawData: ULONGLONG,
|
|
EndAddressOfRawData: ULONGLONG,
|
|
AddressOfIndex: ULONGLONG, // PDWORD
|
|
AddressOfCallBacks: ULONGLONG, // PIMAGE_TLS_CALLBACK *;
|
|
SizeOfZeroFill: DWORD,
|
|
|
|
/*
|
|
union {
|
|
DWORD Characteristics;
|
|
struct {
|
|
DWORD Reserved0 : 20;
|
|
DWORD Alignment : 4;
|
|
DWORD Reserved1 : 8;
|
|
} DUMMYSTRUCTNAME;
|
|
} DUMMYUNIONNAME;
|
|
*/
|
|
Reserved0: DWORD,
|
|
Alignment: DWORD,
|
|
Reserved1: DWORD,
|
|
}
|
|
);
|
|
|
|
struct_wrapper!(
|
|
struct IMAGE_TLS_DIRECTORY32 {
|
|
StartAddressOfRawData: DWORD,
|
|
EndAddressOfRawData: DWORD,
|
|
AddressOfIndex: DWORD, // PDWORD
|
|
AddressOfCallBacks: DWORD, // PIMAGE_TLS_CALLBACK *;
|
|
SizeOfZeroFill: DWORD,
|
|
|
|
/*
|
|
union {
|
|
DWORD Characteristics;
|
|
struct {
|
|
DWORD Reserved0 : 20;
|
|
DWORD Alignment : 4;
|
|
DWORD Reserved1 : 8;
|
|
} DUMMYSTRUCTNAME;
|
|
} DUMMYUNIONNAME;
|
|
*/
|
|
Reserved0: DWORD,
|
|
Alignment: DWORD,
|
|
Reserved1: DWORD,
|
|
}
|
|
);
|
|
|
|
#[cfg(all(target_arch = "x86_64", target_os = "windows"))]
|
|
pub(crate) type IMAGE_TLS_DIRECTORY = IMAGE_TLS_DIRECTORY64;
|
|
#[cfg(all(target_arch = "x86", target_os = "windows"))]
|
|
pub(crate) type IMAGE_TLS_DIRECTORY = IMAGE_TLS_DIRECTORY32;
|