elf_utilities/file/
elf32.rs1use crate::{
2 header,
3 section::{self, Section32},
4 segment,
5};
6
7#[repr(C)]
8#[derive(Default, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
9pub struct ELF32 {
10 pub ehdr: header::Ehdr32,
11 pub sections: Vec<section::Section32>,
12 pub segments: Vec<segment::Segment32>,
13}
14
15impl ELF32 {
16 pub fn add_section(&mut self, mut sct: section::Section32) {
18 let is_section_name_table = sct.name == ".shstrtab";
20
21 let last_sct_idx = self.sections.len() - 1;
24 self.fill_elf_info(&mut sct, last_sct_idx, &self.sections[last_sct_idx]);
25
26 self.ehdr.e_shoff += sct.header.sh_size;
28 self.ehdr.e_shnum += 1;
29
30 self.sections.push(sct);
31
32 if is_section_name_table {
33 self.ehdr.e_shstrndx = self.sections.len() as u16 - 1;
34 }
35 }
36
37 pub fn add_segment(&mut self, sgt: segment::Segment32) {
38 self.ehdr.e_shoff += segment::Phdr32::SIZE as u32;
40 for sct in self.sections.iter_mut() {
41 sct.header.sh_offset += segment::Phdr32::SIZE as u32;
42 }
43 self.ehdr.e_phnum += 1;
44
45 self.segments.push(sgt);
46 }
47 pub fn to_le_bytes(&self) -> Vec<u8> {
48 let mut file_binary: Vec<u8> = Vec::new();
49
50 let mut header_binary = self.ehdr.to_le_bytes();
51 file_binary.append(&mut header_binary);
52
53 for seg in self.segments.iter() {
54 let mut phdr_binary = seg.header.to_le_bytes();
55 file_binary.append(&mut phdr_binary);
56 }
57
58 let mut sections = self.sections.clone();
59 sections.sort_by_key(|sct| sct.header.sh_offset);
60 for sct in self.sections.iter() {
61 let mut section_binary = sct.to_le_bytes();
62
63 if sct.header.sh_addralign > 1 && file_binary.len() != sct.header.sh_offset as usize {
64 file_binary.append(&mut vec![0x00; sct.header.sh_offset as usize - file_binary.len()]);
65 }
66
67 file_binary.append(&mut section_binary);
68 }
69
70 if file_binary.len() < self.ehdr.e_shoff as usize {
71 file_binary.append(&mut vec![0x00; self.ehdr.e_shoff as usize - file_binary.len()]);
72 }
73
74 for sct in self.sections.iter() {
75 let mut shdr_binary = sct.header.to_le_bytes();
76 file_binary.append(&mut shdr_binary);
77 }
78 file_binary
79 }
80
81 fn fill_elf_info(&self, new_sct: &mut Section32, prev_sct_idx: usize, prev_sct: &Section32) {
83 let prev_name_idx = prev_sct.header.sh_name;
84 let prev_name_len = prev_sct.name.as_bytes().len() as u32;
85 let prev_offset = prev_sct.header.sh_offset;
86 let prev_size = prev_sct.header.sh_size;
87
88 new_sct.header.sh_name = prev_name_idx + prev_name_len + 1;
90
91 if prev_sct_idx == 0 {
94 new_sct.header.sh_offset = header::Ehdr32::SIZE as u32
95 + segment::Phdr32::SIZE as u32 * self.segments.len() as u32;
96 } else {
97 new_sct.header.sh_offset = prev_offset + prev_size;
98 }
99
100 new_sct.header.sh_size = new_sct.contents.size() as u32;
101 }
102}