use std::mem;
use std::str::FromStr;
use crate::image::*;
macro_rules! enum1 {
(
$(#[$meta:meta])*
$Item:ident($item:ident: $ty:ty),
$($name:ident => $desc:expr,)*
) => {
$(#[$meta])*
#[derive(Copy, Clone)]
pub struct $Item(pub $ty);
impl $Item {
pub fn to_str(self) -> Option<&'static str> {
match self.0 {
$($name => Some(stringify!($name)),)*
_ => None,
}
}
pub fn description(self) -> Option<&'static str> {
match self.0 {
$($name => Some($desc),)*
_ => None,
}
}
}
impl FromStr for $Item {
type Err = ();
fn from_str(s: &str) -> Result<$Item, ()> {
match s {
$(stringify!($name) => Ok($Item($name)),)*
_ => Err(()),
}
}
}
}
}
macro_rules! flags {
(
$(#[$meta:meta])*
$Item:ident($item:ident: $ty:ty),
$($index:expr, $name:expr => $desc:expr,)*
) => {
$(#[$meta])*
#[derive(Copy, Clone)]
pub struct $Item(pub $ty);
impl $Item {
pub fn flag_str(index: u32) -> Option<&'static str> {
match index {
$($index => Some(stringify!($name)),)*
_ => None,
}
}
pub fn flag_desc(index: u32) -> Option<&'static str> {
match index {
$($index => Some($desc),)*
_ => None,
}
}
pub fn parse_flag(s: &str) -> Option<$ty> {
match s {
$(stringify!($name) => Some($name),)*
_ => None,
}
}
pub fn to_strs(self) -> impl Clone + Iterator<Item = &'static str> {
(0..mem::size_of::<$ty>() as u32 * 8)
.filter_map(move |i| {
if self.0 & (1 << i) != 0 {
Self::flag_str(i)
}
else {
None
}
})
}
}
};
}
enum1! {
Machine(machine: u16),
IMAGE_FILE_MACHINE_I386 => "i386",
IMAGE_FILE_MACHINE_AMD64 => "AMD64",
IMAGE_FILE_MACHINE_IA64 => "IA64",
}
flags! {
FileChars(file_chars: u16),
0, IMAGE_FILE_RELOCS_STRIPPED => "RELOCS_STRIPPED",
1, IMAGE_FILE_EXECUTABLE_IMAGE => "EXECUTABLE_IMAGE",
2, IMAGE_FILE_LINE_NUMS_STRIPPED => "LINE_NUMS_STRIPPED",
3, IMAGE_FILE_LOCAL_SYMS_STRIPPED => "LOCAL_SYMS_STRIPPED",
4, IMAGE_FILE_AGGRESIVE_WS_TRIM => "AGGRESIVE_WS_TRIM",
5, IMAGE_FILE_LARGE_ADDRESS_AWARE => "LARGE_ADDRESS_AWARE",
6, IMAGE_FILE_6 => "Reserved",
7, IMAGE_FILE_BYTES_REVERSED_LO => "BYTES_REVERSED_LO",
8, IMAGE_FILE_32BIT_MACHINE => "32BIT_MACHINE",
9, IMAGE_FILE_DEBUG_STRIPPED => "DEBUG_STRIPPED",
10, IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP => "REMOVABLE_RUN_FROM_SWAP",
11, IMAGE_FILE_NET_RUN_FROM_SWAP => "NET_RUN_FROM_SWAP",
12, IMAGE_FILE_SYSTEM => "SYSTEM",
13, IMAGE_FILE_DLL => "DLL",
14, IMAGE_FILE_UP_SYSTEM_ONLY => "UP_SYSTEM_ONLY",
15, IMAGE_FILE_BYTES_REVERSED_HI => "BYTES_REVERSED_HI",
}
enum1! {
OptionalMagic(magic: u16),
IMAGE_NT_OPTIONAL_HDR32_MAGIC => "PE32",
IMAGE_NT_OPTIONAL_HDR64_MAGIC => "PE32+",
IMAGE_ROM_OPTIONAL_HDR_MAGIC => "ROM",
}
enum1! {
Subsystem(subsystem: u16),
IMAGE_SUBSYSTEM_UNKNOWN => "Unknown",
IMAGE_SUBSYSTEM_NATIVE => "Native",
IMAGE_SUBSYSTEM_WINDOWS_GUI => "Windows GUI",
IMAGE_SUBSYSTEM_WINDOWS_CUI => "Windows CUI",
IMAGE_SUBSYSTEM_OS2_CUI => "OS/2 CUI",
IMAGE_SUBSYSTEM_POSIX_CUI => "POSIX CUI",
IMAGE_SUBSYSTEM_NATIVE_WINDOWS => "Native Win9x driver",
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI => "Windows CE GUI",
IMAGE_SUBSYSTEM_EFI_APPLICATION => "Windows EFI Application",
IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER => "Windows EFI Boot Service Driver",
IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER => "Windows EFI Runtime Driver",
IMAGE_SUBSYSTEM_EFI_ROM => "Windows EFI ROM",
IMAGE_SUBSYSTEM_XBOX => "XBOX",
IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION => "Windows Boot Application",
}
flags! {
DllChars(dll_chars: u16),
0, IMAGE_DLLCHARACTERISTICS_0 => "Reserved",
1, IMAGE_DLLCHARACTERISTICS_1 => "Reserved",
2, IMAGE_DLLCHARACTERISTICS_2 => "Reserved",
3, IMAGE_DLLCHARACTERISTICS_3 => "Reserved",
4, IMAGE_DLLCHARACTERISTICS_4 => "Reserved",
5, IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA => "Image can handle a high entropy virtual address space",
6, IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE => "Can be relocated at load time",
7, IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY => "Code Integrity checks are enforced",
8, IMAGE_DLLCHARACTERISTICS_NX_COMPAT => "Image is NX compatible",
9, IMAGE_DLLCHARACTERISTICS_NO_ISOLATION => "Isolation aware, but do not isolate the image",
10, IMAGE_DLLCHARACTERISTICS_NO_SEH => "Does not use SEH",
11, IMAGE_DLLCHARACTERISTICS_NO_BIND => "Do not bind the image",
12, IMAGE_DLLCHARACTERISTICS_APPCONTAINER => "Image must execute in an AppContainer",
13, IMAGE_DLLCHARACTERISTICS_WDM_DRIVER => "A WDM driver",
14, IMAGE_DLLCHARACTERISTICS_GUARD_CF => "Image supports Control Flow Guard",
15, IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE => "Terminal Server aware",
}
enum1! {
DirectoryEntry(entry: usize),
IMAGE_DIRECTORY_ENTRY_EXPORT => "Export Directory",
IMAGE_DIRECTORY_ENTRY_IMPORT => "Import Directory",
IMAGE_DIRECTORY_ENTRY_RESOURCE => "Resource Directory",
IMAGE_DIRECTORY_ENTRY_EXCEPTION => "Exception Directory",
IMAGE_DIRECTORY_ENTRY_SECURITY => "Security Directory",
IMAGE_DIRECTORY_ENTRY_BASERELOC => "Base Relocation Table",
IMAGE_DIRECTORY_ENTRY_DEBUG => "Debug Directory",
IMAGE_DIRECTORY_ENTRY_ARCHITECTURE => "Architecture Specific Data",
IMAGE_DIRECTORY_ENTRY_GLOBALPTR => "RVA of GlobalPtr",
IMAGE_DIRECTORY_ENTRY_TLS => "TLS Directory",
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG => "Load Configuration Directory",
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT => "Bound Import Directory",
IMAGE_DIRECTORY_ENTRY_IAT => "Import Address Table",
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT => "Delay Load Import Descriptors",
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR => "COM Runtime Descriptor",
}
flags! {
SectionChars(section_chars: u32),
0, IMAGE_SCN_0 => "Reserved",
1, IMAGE_SCN_1 => "Reserved",
2, IMAGE_SCN_2 => "Reserved",
3, IMAGE_SCN_TYPE_NO_PAD => "TYPE_NO_PAD",
4, IMAGE_SCN_4 => "Reserved",
5, IMAGE_SCN_CNT_CODE => "Contains executable code",
6, IMAGE_SCN_CNT_INITIALIZED_DATA => "Contains initialized data",
7, IMAGE_SCN_CNT_UNINITIALIZED_DATA => "Contains uninitialized data",
8, IMAGE_SCN_LNK_OTHER => "LNK_OTHER",
9, IMAGE_SCN_LNK_INFO => "LNK_INFO",
10, IMAGE_SCN_10 => "Reserved",
11, IMAGE_SCN_LNK_REMOVE => "LNK_REMOVE",
12, IMAGE_SCN_LNK_COMDAT => "LNK_COMDAT",
13, IMAGE_SCN_13 => "Reserved",
14, IMAGE_SCN_NO_DEFER_SPEC_EXC => "NO_DEFER_SPEC_EXC",
15, IMAGE_SCN_GPREL => "GPREL",
16, IMAGE_SCN_16 => "Reserved",
17, IMAGE_SCN_MEM_PURGEABLE => "MEM_PURGEABLE",
18, IMAGE_SCN_MEM_LOCKED => "MEM_LOCKED",
19, IMAGE_SCN_MEM_PRELOAD => "MEM_PRELOAD",
20, IMAGE_SCN_ALIGN_1 => "",
21, IMAGE_SCN_ALIGN_2 => "",
22, IMAGE_SCN_ALIGN_4 => "",
23, IMAGE_SCN_ALIGN_8 => "",
24, IMAGE_SCN_LNK_NRELOC_OVFL => "LNK_NRELOC_OVFL",
25, IMAGE_SCN_MEM_DISCARDABLE => "MEM_DISCARDABLE",
26, IMAGE_SCN_MEM_NOT_CACHED => "MEM_NOT_CACHED",
27, IMAGE_SCN_MEM_NOT_PAGED => "MEM_NOT_PAGED",
28, IMAGE_SCN_MEM_SHARED => "MEM_SHARED",
29, IMAGE_SCN_MEM_EXECUTE => "MEM_EXECUTE",
30, IMAGE_SCN_MEM_READ => "MEM_READ",
31, IMAGE_SCN_MEM_WRITE => "MEM_WRITE",
}
enum1! {
ResourceName(name: u16),
RT_CURSOR => "RT_CURSOR",
RT_BITMAP => "RT_BITMAP",
RT_ICON => "RT_ICON",
RT_MENU => "RT_MENU",
RT_DIALOG => "RT_DIALOG",
RT_STRING => "RT_STRING",
RT_FONTDIR => "RT_FONTDIR",
RT_FONT => "RT_FONT",
RT_ACCELERATOR => "RT_ACCELERATOR",
RT_RCDATA => "RT_RCDATA",
RT_MESSAGETABLE => "RT_MESSAGETABLE",
RT_GROUP_CURSOR => "RT_GROUP_CURSOR",
RT_GROUP_ICON => "RT_GROUP_ICON",
RT_VERSION => "RT_VERSION",
RT_DLGINCLUDE => "RT_DLGINCLUDE",
RT_PLUGPLAY => "RT_PLUGPLAY",
RT_VXD => "RT_VXD",
RT_ANICURSOR => "RT_ANICURSOR",
RT_ANIICON => "RT_ANIICON",
RT_HTML => "RT_HTML",
RT_MANIFEST => "RT_MANIFEST",
}
enum1! {
RelocType(reloc_type: u8),
IMAGE_REL_BASED_ABSOLUTE => "ABSOLUTE",
IMAGE_REL_BASED_HIGH => "HIGH",
IMAGE_REL_BASED_LOW => "LOW",
IMAGE_REL_BASED_HIGHLOW => "HIGHLOW",
IMAGE_REL_BASED_HIGHADJ => "HIGHADJ",
IMAGE_REL_BASED_MACHINE_SPECIFIC_5 => "MACHINE_SPECIFIC_5",
IMAGE_REL_BASED_MACHINE_SPECIFIC_7 => "MACHINE_SPECIFIC_7",
IMAGE_REL_BASED_MACHINE_SPECIFIC_9 => "MACHINE_SPECIFIC_9",
IMAGE_REL_BASED_DIR64 => "DIR64",
}
enum1! {
UnwindOp(unwind_op: u8),
UWOP_PUSH_NONVOL => "push nonvol",
UWOP_ALLOC_LARGE => "alloc large",
UWOP_ALLOC_SMALL => "alloc small",
UWOP_SET_FPREG => "set fpreg",
UWOP_SAVE_NONVOL => "save nonvol",
UWOP_SAVE_NONVOL_FAR => "save nonvol large",
UWOP_SAVE_XMM128 => "save xmm128",
UWOP_SAVE_XMM128_FAR => "save xmm128 far",
UWOP_PUSH_MACHFRAME => "push machframe",
}
enum1! {
UnwindFlag(unwind_flag: u8),
UNW_FLAG_NHANDLER => "NHANDLER",
UNW_FLAG_EHANDLER => "EHANDLER",
UNW_FLAG_UHANDLER => "UHANDLER",
UNW_FLAG_FHANDLER => "FHANDLER",
UNW_FLAG_CHAININFO => "CHAININFO",
}
enum1! {
DebugType(debug_type: u32),
IMAGE_DEBUG_TYPE_UNKNOWN => "Unknown",
IMAGE_DEBUG_TYPE_COFF => "COFF",
IMAGE_DEBUG_TYPE_CODEVIEW => "CodeView",
IMAGE_DEBUG_TYPE_FPO => "FPO",
IMAGE_DEBUG_TYPE_MISC => "DBG",
IMAGE_DEBUG_TYPE_EXCEPTION => "Exception",
IMAGE_DEBUG_TYPE_FIXUP => "Fixup",
IMAGE_DEBUG_TYPE_OMAP_TO_SRC => "OMAP to src",
IMAGE_DEBUG_TYPE_OMAP_FROM_SRC => "OMAP from src",
IMAGE_DEBUG_TYPE_BORLAND => "Borland",
IMAGE_DEBUG_TYPE_RESERVED10 => "Reserved10",
IMAGE_DEBUG_TYPE_CLSID => "CLSID",
IMAGE_DEBUG_TYPE_VC_FEATURE => "VCFeature",
IMAGE_DEBUG_TYPE_POGO => "POGO",
IMAGE_DEBUG_TYPE_ILTCG => "ILTCG",
IMAGE_DEBUG_TYPE_MPX => "MPX",
IMAGE_DEBUG_TYPE_REPRO => "Repro",
}