use std::fmt;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Architecture {
X86,
X64,
Arm,
Arm64,
Unknown(u16),
}
impl Architecture {
pub const fn from_machine_type(machine: u16) -> Self {
match machine {
0x014c => Self::X86, 0x8664 => Self::X64, 0x01c0 => Self::Arm, 0xaa64 => Self::Arm64, other => Self::Unknown(other),
}
}
pub const fn as_image_file_machine(self) -> Option<u16> {
match self {
Self::X86 => Some(0x014c),
Self::X64 => Some(0x8664),
Self::Arm => Some(0x01c0),
Self::Arm64 => Some(0xaa64),
Self::Unknown(_) => None,
}
}
pub const fn is_x86(self) -> bool {
matches!(self, Self::X86)
}
pub const fn is_x64(self) -> bool {
matches!(self, Self::X64)
}
pub const fn is_arm(self) -> bool {
matches!(self, Self::Arm | Self::Arm64)
}
}
impl fmt::Display for Architecture {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::X86 => write!(f, "x86"),
Self::X64 => write!(f, "x64"),
Self::Arm => write!(f, "ARM"),
Self::Arm64 => write!(f, "ARM64"),
Self::Unknown(v) => write!(f, "Unknown(0x{v:04x})"),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ExportInfo {
pub name: Option<String>,
pub ordinal: u32,
pub is_forwarded: bool,
pub forward_to: Option<String>,
pub relative_address: Option<u32>,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ExportDirectory {
pub characteristics: u32,
pub timestamp: u32,
pub major_version: u16,
pub minor_version: u16,
pub name_rva: u32,
pub ordinal_base: u32,
pub address_table_entries: u32,
pub number_of_name_pointers: u32,
pub address_table_rva: u32,
pub name_pointer_rva: u32,
pub ordinal_table_rva: u32,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct VerificationReport {
pub dll_path: std::path::PathBuf,
pub total_exports: usize,
pub found: Vec<String>,
pub missing: Vec<String>,
pub complete: bool,
pub unexpected: Vec<String>,
pub mismatches: Vec<NameMismatch>,
pub architecture: Architecture,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct NameMismatch {
pub expected: String,
pub actual: String,
pub ordinal: u32,
}
#[derive(Clone, Debug, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ExportDiff {
pub missing: Vec<String>,
pub extra: Vec<String>,
pub common: Vec<String>,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PeFile {
pub path: std::path::PathBuf,
pub architecture: Architecture,
pub is_dll: bool,
pub image_base: u64,
pub entry_point_rva: u32,
pub export_directory: Option<ExportDirectory>,
pub exports: Vec<ExportInfo>,
}