wraith/structures/pe/
section_header.rs

1//! Section header (IMAGE_SECTION_HEADER)
2
3pub const SECTION_NAME_SIZE: usize = 8;
4
5#[repr(C)]
6#[derive(Debug, Clone, Copy)]
7pub struct SectionHeader {
8    pub name: [u8; SECTION_NAME_SIZE],
9    pub virtual_size: u32,
10    pub virtual_address: u32,
11    pub size_of_raw_data: u32,
12    pub pointer_to_raw_data: u32,
13    pub pointer_to_relocations: u32,
14    pub pointer_to_linenumbers: u32,
15    pub number_of_relocations: u16,
16    pub number_of_linenumbers: u16,
17    pub characteristics: u32,
18}
19
20// section characteristics flags
21pub const IMAGE_SCN_CNT_CODE: u32 = 0x00000020;
22pub const IMAGE_SCN_CNT_INITIALIZED_DATA: u32 = 0x00000040;
23pub const IMAGE_SCN_CNT_UNINITIALIZED_DATA: u32 = 0x00000080;
24pub const IMAGE_SCN_MEM_EXECUTE: u32 = 0x20000000;
25pub const IMAGE_SCN_MEM_READ: u32 = 0x40000000;
26pub const IMAGE_SCN_MEM_WRITE: u32 = 0x80000000;
27pub const IMAGE_SCN_MEM_DISCARDABLE: u32 = 0x02000000;
28
29impl SectionHeader {
30    /// get section name as string (may not be null-terminated)
31    pub fn name_str(&self) -> &str {
32        let end = self
33            .name
34            .iter()
35            .position(|&b| b == 0)
36            .unwrap_or(SECTION_NAME_SIZE);
37        core::str::from_utf8(&self.name[..end]).unwrap_or("")
38    }
39
40    /// check if section is executable
41    pub fn is_executable(&self) -> bool {
42        self.characteristics & IMAGE_SCN_MEM_EXECUTE != 0
43    }
44
45    /// check if section is readable
46    pub fn is_readable(&self) -> bool {
47        self.characteristics & IMAGE_SCN_MEM_READ != 0
48    }
49
50    /// check if section is writable
51    pub fn is_writable(&self) -> bool {
52        self.characteristics & IMAGE_SCN_MEM_WRITE != 0
53    }
54
55    /// check if section contains code
56    pub fn contains_code(&self) -> bool {
57        self.characteristics & IMAGE_SCN_CNT_CODE != 0
58    }
59
60    /// convert section characteristics to memory protection flags
61    pub fn to_protection(&self) -> u32 {
62        let r = self.is_readable();
63        let w = self.is_writable();
64        let x = self.is_executable();
65
66        // PAGE_* constants
67        const PAGE_NOACCESS: u32 = 0x01;
68        const PAGE_READONLY: u32 = 0x02;
69        const PAGE_READWRITE: u32 = 0x04;
70        const PAGE_EXECUTE: u32 = 0x10;
71        const PAGE_EXECUTE_READ: u32 = 0x20;
72        const PAGE_EXECUTE_READWRITE: u32 = 0x40;
73
74        match (r, w, x) {
75            (false, false, false) => PAGE_NOACCESS,
76            (true, false, false) => PAGE_READONLY,
77            (true, true, false) => PAGE_READWRITE,
78            (false, false, true) => PAGE_EXECUTE,
79            (true, false, true) => PAGE_EXECUTE_READ,
80            (true, true, true) => PAGE_EXECUTE_READWRITE,
81            (false, true, false) => PAGE_READWRITE,          // fallback
82            (false, true, true) => PAGE_EXECUTE_READWRITE,   // fallback
83        }
84    }
85}