1use serde::{Deserialize, Serialize};
2use std::fmt;
3
4#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
8pub enum ElfType {
9 None,
11 Relocatable,
13 Executable,
15 SharedObject,
17 Core,
19}
20
21impl fmt::Display for ElfType {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 match self {
24 ElfType::None => write!(f, "无类型文件"),
25 ElfType::Relocatable => write!(f, "可重定位文件"),
26 ElfType::Executable => write!(f, "可执行文件"),
27 ElfType::SharedObject => write!(f, "共享目标文件"),
28 ElfType::Core => write!(f, "核心转储文件"),
29 }
30 }
31}
32
33impl From<u16> for ElfType {
34 fn from(value: u16) -> Self {
35 match value {
36 0 => ElfType::None,
37 1 => ElfType::Relocatable,
38 2 => ElfType::Executable,
39 3 => ElfType::SharedObject,
40 4 => ElfType::Core,
41 _ => ElfType::None,
42 }
43 }
44}
45
46#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
50pub enum ElfMachine {
51 None,
53 I386,
55 X86_64,
57 Arm,
59 AArch64,
61 RiscV,
63}
64
65impl From<u16> for ElfMachine {
66 fn from(value: u16) -> Self {
67 match value {
68 0 => ElfMachine::None,
69 3 => ElfMachine::I386,
70 62 => ElfMachine::X86_64,
71 40 => ElfMachine::Arm,
72 183 => ElfMachine::AArch64,
73 243 => ElfMachine::RiscV,
74 _ => ElfMachine::None,
75 }
76 }
77}
78
79#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
84pub struct ElfHeader64 {
85 pub e_ident: [u8; 16],
87 pub e_type: u16,
89 pub e_machine: u16,
91 pub e_version: u32,
93 pub e_entry: u64,
95 pub e_phoff: u64,
97 pub e_shoff: u64,
99 pub e_flags: u32,
101 pub e_ehsize: u16,
103 pub e_phentsize: u16,
105 pub e_phnum: u16,
107 pub e_shentsize: u16,
109 pub e_shnum: u16,
111 pub e_shstrndx: u16,
113}
114
115#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
119pub struct ProgramHeader64 {
120 pub p_type: u32,
122 pub p_flags: u32,
124 pub p_offset: u64,
126 pub p_vaddr: u64,
128 pub p_paddr: u64,
130 pub p_filesz: u64,
132 pub p_memsz: u64,
134 pub p_align: u64,
136}
137
138#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
142pub struct SectionHeader64 {
143 pub sh_name: u32,
145 pub sh_type: u32,
147 pub sh_flags: u64,
149 pub sh_addr: u64,
151 pub sh_offset: u64,
153 pub sh_size: u64,
155 pub sh_link: u32,
157 pub sh_info: u32,
159 pub sh_addralign: u64,
161 pub sh_entsize: u64,
163}
164
165pub mod segment_type {
167 pub const PT_NULL: u32 = 0;
169 pub const PT_LOAD: u32 = 1;
171 pub const PT_DYNAMIC: u32 = 2;
173 pub const PT_INTERP: u32 = 3;
175 pub const PT_NOTE: u32 = 4;
177 pub const PT_SHLIB: u32 = 5;
179 pub const PT_PHDR: u32 = 6;
181 pub const PT_TLS: u32 = 7;
183}
184
185pub mod section_type {
187 pub const SHT_NULL: u32 = 0;
189 pub const SHT_PROGBITS: u32 = 1;
191 pub const SHT_SYMTAB: u32 = 2;
193 pub const SHT_STRTAB: u32 = 3;
195 pub const SHT_RELA: u32 = 4;
197 pub const SHT_HASH: u32 = 5;
199 pub const SHT_DYNAMIC: u32 = 6;
201 pub const SHT_NOTE: u32 = 7;
203 pub const SHT_NOBITS: u32 = 8;
205 pub const SHT_REL: u32 = 9;
207 pub const SHT_SHLIB: u32 = 10;
209 pub const SHT_DYNSYM: u32 = 11;
211}
212
213pub mod segment_flags {
215 pub const PF_X: u32 = 1;
217 pub const PF_W: u32 = 2;
219 pub const PF_R: u32 = 4;
221}
222
223pub mod section_flags {
225 pub const SHF_WRITE: u64 = 1;
227 pub const SHF_ALLOC: u64 = 2;
229 pub const SHF_EXECINSTR: u64 = 4;
231}
232
233impl ElfHeader64 {
234 pub fn new() -> Self {
236 let mut e_ident = [0u8; 16];
237 e_ident[0] = 0x7f;
239 e_ident[1] = b'E';
240 e_ident[2] = b'L';
241 e_ident[3] = b'F';
242 e_ident[4] = 2;
244 e_ident[5] = 1;
246 e_ident[6] = 1;
248 e_ident[7] = 0;
250
251 Self {
252 e_ident,
253 e_type: 2, e_machine: 62, e_version: 1,
256 e_entry: 0x401000, e_phoff: 64, e_shoff: 0, e_flags: 0,
260 e_ehsize: 64, e_phentsize: 56, e_phnum: 1, e_shentsize: 64, e_shnum: 0, e_shstrndx: 0, }
267 }
268}
269
270impl Default for ElfHeader64 {
271 fn default() -> Self {
272 Self::new()
273 }
274}
275
276impl ProgramHeader64 {
277 pub fn new_load_segment(offset: u64, vaddr: u64, size: u64) -> Self {
279 Self {
280 p_type: segment_type::PT_LOAD,
281 p_flags: segment_flags::PF_R | segment_flags::PF_X, p_offset: offset,
283 p_vaddr: vaddr,
284 p_paddr: vaddr,
285 p_filesz: size,
286 p_memsz: size,
287 p_align: 0x1000, }
289 }
290}
291
292#[derive(Debug, Clone)]
296pub struct ElfFile {
297 pub header: ElfHeader64,
299 pub program_headers: Vec<ProgramHeader64>,
301 pub section_headers: Vec<SectionHeader64>,
303 pub data: Vec<u8>,
305}
306
307impl ElfFile {
308 pub fn new() -> Self {
310 Self { header: ElfHeader64::new(), program_headers: Vec::new(), section_headers: Vec::new(), data: Vec::new() }
311 }
312
313 pub fn add_program_header(&mut self, header: ProgramHeader64) {
315 self.program_headers.push(header);
316 self.header.e_phnum = self.program_headers.len() as u16;
317 }
318
319 pub fn set_entry_point(&mut self, entry: u64) {
321 self.header.e_entry = entry;
322 }
323
324 pub fn to_bytes(&self) -> Vec<u8> {
326 let mut bytes = Vec::new();
327
328 bytes.extend_from_slice(&self.header_to_bytes());
330
331 for ph in &self.program_headers {
333 bytes.extend_from_slice(&self.program_header_to_bytes(ph));
334 }
335
336 while bytes.len() % 0x1000 != 0 {
338 bytes.push(0);
339 }
340
341 bytes.extend_from_slice(&self.data);
343
344 bytes
345 }
346
347 fn header_to_bytes(&self) -> [u8; 64] {
349 let mut bytes = [0u8; 64];
350 let h = &self.header;
351
352 bytes[0..16].copy_from_slice(&h.e_ident);
353 bytes[16..18].copy_from_slice(&h.e_type.to_le_bytes());
354 bytes[18..20].copy_from_slice(&h.e_machine.to_le_bytes());
355 bytes[20..24].copy_from_slice(&h.e_version.to_le_bytes());
356 bytes[24..32].copy_from_slice(&h.e_entry.to_le_bytes());
357 bytes[32..40].copy_from_slice(&h.e_phoff.to_le_bytes());
358 bytes[40..48].copy_from_slice(&h.e_shoff.to_le_bytes());
359 bytes[48..52].copy_from_slice(&h.e_flags.to_le_bytes());
360 bytes[52..54].copy_from_slice(&h.e_ehsize.to_le_bytes());
361 bytes[54..56].copy_from_slice(&h.e_phentsize.to_le_bytes());
362 bytes[56..58].copy_from_slice(&h.e_phnum.to_le_bytes());
363 bytes[58..60].copy_from_slice(&h.e_shentsize.to_le_bytes());
364 bytes[60..62].copy_from_slice(&h.e_shnum.to_le_bytes());
365 bytes[62..64].copy_from_slice(&h.e_shstrndx.to_le_bytes());
366
367 bytes
368 }
369
370 fn program_header_to_bytes(&self, ph: &ProgramHeader64) -> [u8; 56] {
372 let mut bytes = [0u8; 56];
373
374 bytes[0..4].copy_from_slice(&ph.p_type.to_le_bytes());
375 bytes[4..8].copy_from_slice(&ph.p_flags.to_le_bytes());
376 bytes[8..16].copy_from_slice(&ph.p_offset.to_le_bytes());
377 bytes[16..24].copy_from_slice(&ph.p_vaddr.to_le_bytes());
378 bytes[24..32].copy_from_slice(&ph.p_paddr.to_le_bytes());
379 bytes[32..40].copy_from_slice(&ph.p_filesz.to_le_bytes());
380 bytes[40..48].copy_from_slice(&ph.p_memsz.to_le_bytes());
381 bytes[48..56].copy_from_slice(&ph.p_align.to_le_bytes());
382
383 bytes
384 }
385}
386
387impl Default for ElfFile {
388 fn default() -> Self {
389 Self::new()
390 }
391}