ctf_pwn/unix/
elf_file.rs

1use crate::unix::error::ElfError;
2use crate::unix::symbol::Symbol;
3use elf::endian::AnyEndian;
4use elf::file::FileHeader;
5use elf::ElfBytes;
6use std::collections::HashMap;
7use std::ffi::OsStr;
8use std::path::PathBuf;
9use tokio::fs;
10use crate::unix::{parse_got_from_elf, parse_plt_from_elf};
11
12pub struct Elf {
13    data: Vec<u8>,
14    header: FileHeader<AnyEndian>,
15    symbols: HashMap<String, Symbol>,
16    dynamic_symbols: HashMap<String, Symbol>,
17    got: HashMap<String, u64>,
18    plt: HashMap<String, u64>,
19}
20
21impl Elf {
22    pub async fn parse<T: ?Sized + AsRef<OsStr>>(path: &T) -> Result<Elf, ElfError> {
23        let path = PathBuf::from(path);
24        let file_data = fs::read(path).await?;
25        let file = ElfBytes::<AnyEndian>::minimal_parse(file_data.as_slice())?;
26        let symbols = Symbol::parse_symbol_table(&file)?;
27        let dynamic_symbols = Symbol::parse_dynamic_symbol_table(&file)?;
28        let got = parse_got_from_elf(&file, &dynamic_symbols)?;
29        let plt = parse_plt_from_elf(&file, &dynamic_symbols)?;
30        let symbols = symbols.into_iter()
31            .map(|s| (s.name.clone(), s))
32            .collect();
33        let dynamic_symbols = dynamic_symbols.into_iter()
34            .map(|s| (s.name.clone(), s))
35            .collect();
36        let header = file.ehdr;
37        Ok(Elf {
38            data: file_data,
39            header,
40            symbols,
41            dynamic_symbols,
42            got,
43            plt,
44        })
45    }
46
47    pub fn plt(&self) -> &HashMap<String, u64>
48    {
49        &self.plt
50    }
51
52    pub fn got(&self) -> &HashMap<String, u64>
53    {
54        &self.got
55    }
56
57    pub fn symbols(&self) -> &HashMap<String, Symbol>
58    {
59        &self.symbols
60    }
61
62    pub fn dynamic_symbols(&self) -> &HashMap<String, Symbol>
63    {
64        &self.dynamic_symbols
65    }
66
67    pub fn header(&self) -> &FileHeader<AnyEndian>
68    {
69        &self.header
70    }
71
72    pub fn data(&self) -> &[u8]
73    {
74        &self.data
75    }
76}