wraith/structures/pe/
dos_header.rs

1//! DOS header (IMAGE_DOS_HEADER)
2
3pub const DOS_SIGNATURE: u16 = 0x5A4D; // "MZ"
4
5// reasonable bounds for e_lfanew - must be positive and within first 64MB
6const MIN_NT_HEADERS_OFFSET: i32 = 0x40; // at least past DOS header
7const MAX_NT_HEADERS_OFFSET: i32 = 0x4000000; // 64MB max
8
9#[repr(C, packed)]
10#[derive(Debug, Clone, Copy)]
11pub struct DosHeader {
12    pub e_magic: u16, // must be DOS_SIGNATURE
13    pub e_cblp: u16,
14    pub e_cp: u16,
15    pub e_crlc: u16,
16    pub e_cparhdr: u16,
17    pub e_minalloc: u16,
18    pub e_maxalloc: u16,
19    pub e_ss: u16,
20    pub e_sp: u16,
21    pub e_csum: u16,
22    pub e_ip: u16,
23    pub e_cs: u16,
24    pub e_lfarlc: u16,
25    pub e_ovno: u16,
26    pub e_res: [u16; 4],
27    pub e_oemid: u16,
28    pub e_oeminfo: u16,
29    pub e_res2: [u16; 10],
30    pub e_lfanew: i32, // offset to NT headers
31}
32
33impl DosHeader {
34    /// validate DOS signature
35    pub fn is_valid(&self) -> bool {
36        self.e_magic == DOS_SIGNATURE
37    }
38
39    /// check if e_lfanew offset is within reasonable bounds
40    pub fn is_nt_offset_valid(&self) -> bool {
41        self.e_lfanew >= MIN_NT_HEADERS_OFFSET && self.e_lfanew <= MAX_NT_HEADERS_OFFSET
42    }
43
44    /// get offset to NT headers (returns None if invalid)
45    pub fn nt_headers_offset_checked(&self) -> Option<usize> {
46        if self.is_nt_offset_valid() {
47            Some(self.e_lfanew as usize)
48        } else {
49            None
50        }
51    }
52
53    /// get offset to NT headers
54    ///
55    /// # Safety
56    /// caller must ensure offset is valid via `is_nt_offset_valid()` or bounds check
57    /// against module size. use `nt_headers_offset_checked()` for safe access.
58    pub fn nt_headers_offset(&self) -> usize {
59        self.e_lfanew as usize
60    }
61}