1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use crate::memory::{FLAG_EXECUTABLE, FLAG_FREEZED};
use crate::Error;
pub use goblin_v023::elf::program_header::{PF_R, PF_W, PF_X, PT_LOAD};
pub use goblin_v023::elf::section_header::SHF_EXECINSTR;
pub fn convert_flags(p_flags: u32, allow_freeze_writable: bool) -> Result<u8, Error> {
let readable = p_flags & PF_R != 0;
let writable = p_flags & PF_W != 0;
let executable = p_flags & PF_X != 0;
if !readable {
return Err(Error::ElfSegmentUnreadable);
}
if writable && executable {
return Err(Error::ElfSegmentWritableAndExecutable);
}
if executable {
Ok(FLAG_EXECUTABLE | FLAG_FREEZED)
} else if writable && !allow_freeze_writable {
Ok(0)
} else {
Ok(FLAG_FREEZED)
}
}
pub struct ProgramHeader {
pub p_type: u32,
pub p_flags: u32,
pub p_offset: u64,
pub p_vaddr: u64,
pub p_paddr: u64,
pub p_filesz: u64,
pub p_memsz: u64,
pub p_align: u64,
}
impl ProgramHeader {
pub fn from_v0(header: &goblin_v023::elf::ProgramHeader) -> Self {
Self {
p_type: header.p_type,
p_flags: header.p_flags,
p_offset: header.p_offset,
p_vaddr: header.p_vaddr,
p_paddr: header.p_paddr,
p_filesz: header.p_filesz,
p_memsz: header.p_memsz,
p_align: header.p_align,
}
}
pub fn from_v1(header: &goblin_v040::elf::ProgramHeader) -> Self {
Self {
p_type: header.p_type,
p_flags: header.p_flags,
p_offset: header.p_offset,
p_vaddr: header.p_vaddr,
p_paddr: header.p_paddr,
p_filesz: header.p_filesz,
p_memsz: header.p_memsz,
p_align: header.p_align,
}
}
}
pub struct SectionHeader {
pub sh_name: usize,
pub sh_type: u32,
pub sh_flags: u64,
pub sh_addr: u64,
pub sh_offset: u64,
pub sh_size: u64,
pub sh_link: u32,
pub sh_info: u32,
pub sh_addralign: u64,
pub sh_entsize: u64,
}
impl SectionHeader {
pub fn from_v0(header: &goblin_v023::elf::SectionHeader) -> Self {
Self {
sh_name: header.sh_name,
sh_type: header.sh_type,
sh_flags: header.sh_flags,
sh_addr: header.sh_addr,
sh_offset: header.sh_offset,
sh_size: header.sh_size,
sh_link: header.sh_link,
sh_info: header.sh_info,
sh_addralign: header.sh_addralign,
sh_entsize: header.sh_entsize,
}
}
pub fn from_v1(header: &goblin_v040::elf::SectionHeader) -> Self {
Self {
sh_name: header.sh_name,
sh_type: header.sh_type,
sh_flags: header.sh_flags,
sh_addr: header.sh_addr,
sh_offset: header.sh_offset,
sh_size: header.sh_size,
sh_link: header.sh_link,
sh_info: header.sh_info,
sh_addralign: header.sh_addralign,
sh_entsize: header.sh_entsize,
}
}
}