1use std::fmt;
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17pub enum Architecture {
18 X86,
19 X64,
20 Arm,
21 Arm64,
22 Unknown(u16),
23}
24
25impl Architecture {
26 pub const fn from_machine_type(machine: u16) -> Self {
37 match machine {
38 0x014c => Self::X86, 0x8664 => Self::X64, 0x01c0 => Self::Arm, 0xaa64 => Self::Arm64, other => Self::Unknown(other),
43 }
44 }
45
46 pub const fn as_image_file_machine(self) -> Option<u16> {
55 match self {
56 Self::X86 => Some(0x014c),
57 Self::X64 => Some(0x8664),
58 Self::Arm => Some(0x01c0),
59 Self::Arm64 => Some(0xaa64),
60 Self::Unknown(_) => None,
61 }
62 }
63
64 pub const fn is_x86(self) -> bool {
65 matches!(self, Self::X86)
66 }
67 pub const fn is_x64(self) -> bool {
68 matches!(self, Self::X64)
69 }
70 pub const fn is_arm(self) -> bool {
71 matches!(self, Self::Arm | Self::Arm64)
72 }
73}
74
75impl fmt::Display for Architecture {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 match self {
78 Self::X86 => write!(f, "x86"),
79 Self::X64 => write!(f, "x64"),
80 Self::Arm => write!(f, "ARM"),
81 Self::Arm64 => write!(f, "ARM64"),
82 Self::Unknown(v) => write!(f, "Unknown(0x{v:04x})"),
83 }
84 }
85}
86
87#[derive(Clone, Debug, PartialEq, Eq)]
89#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
90pub struct ExportInfo {
91 pub name: Option<String>,
93 pub ordinal: u32,
95 pub is_forwarded: bool,
97 pub forward_to: Option<String>,
99 pub relative_address: Option<u32>,
101}
102
103#[derive(Clone, Debug)]
107#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
108pub struct ExportDirectory {
109 pub characteristics: u32,
110 pub timestamp: u32,
111 pub major_version: u16,
112 pub minor_version: u16,
113 pub name_rva: u32,
114 pub ordinal_base: u32,
115 pub address_table_entries: u32,
116 pub number_of_name_pointers: u32,
117 pub address_table_rva: u32,
118 pub name_pointer_rva: u32,
119 pub ordinal_table_rva: u32,
120}
121
122#[derive(Clone, Debug)]
124#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
125pub struct VerificationReport {
126 pub dll_path: std::path::PathBuf,
128 pub total_exports: usize,
130 pub found: Vec<String>,
132 pub missing: Vec<String>,
134 pub complete: bool,
136 pub unexpected: Vec<String>,
138 pub mismatches: Vec<NameMismatch>,
140 pub architecture: Architecture,
142}
143
144#[derive(Clone, Debug, PartialEq, Eq)]
146#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
147pub struct NameMismatch {
148 pub expected: String,
150 pub actual: String,
152 pub ordinal: u32,
154}
155
156#[derive(Clone, Debug, Default)]
158#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
159pub struct ExportDiff {
160 pub missing: Vec<String>,
162 pub extra: Vec<String>,
164 pub common: Vec<String>,
166}
167
168#[derive(Clone, Debug)]
170#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
171pub struct PeFile {
172 pub path: std::path::PathBuf,
174 pub architecture: Architecture,
176 pub is_dll: bool,
178 pub image_base: u64,
180 pub entry_point_rva: u32,
182 pub export_directory: Option<ExportDirectory>,
184 pub exports: Vec<ExportInfo>,
186}