use crate::{BinaryInfo, Result};
use goblin::Object;
#[derive(Debug)]
pub struct ElfApiResolver {
is_buffer: bool,
api_map: std::collections::HashMap<String, std::collections::HashMap<u64, (String, String)>>,
}
impl ElfApiResolver {
pub fn new() -> Result<ElfApiResolver> {
let mut war = ElfApiResolver {
is_buffer: false,
api_map: std::collections::HashMap::new(),
};
war.api_map
.insert("lief".to_string(), std::collections::HashMap::new());
Ok(war)
}
pub fn update(&mut self, binary_info: &BinaryInfo) -> Result<()> {
self.is_buffer = binary_info.is_buffer;
if !self.is_buffer {
let mut address = 0x401700;
if let Object::Elf(elf) = Object::parse(binary_info.raw_data)? {
for reloc in elf.pltrelocs.iter() {
if reloc.r_sym != 0
&& let Some(sym) = elf.dynsyms.get(reloc.r_sym)
&& sym.is_import()
&& sym.is_function()
{
self.api_map.get_mut("lief").unwrap().insert(
address,
(
"".to_string(),
elf.dynstrtab.get_at(sym.st_name).unwrap_or("").to_string(),
),
);
address += 0x10;
}
}
}
}
Ok(())
}
pub fn get_api(
&self,
to_addr: u64,
_absolute_addr: u64,
) -> Result<(Option<String>, Option<String>)> {
if let Some(s) = self.api_map.get("lief")
&& let Some((dll, api)) = s.get(&to_addr)
{
return Ok((Some(dll.to_string()), Some(api.to_string())));
}
Ok((None, None))
}
}