pub mod header;
pub mod program_headers;
pub mod section_headers;
pub mod symbols;
use goblin::elf::Elf;
use std::path::Path;
use crate::display;
use crate::error::{BinparseError, Result};
pub struct ElfFile<'a> {
pub elf: Elf<'a>,
pub data: &'a [u8],
pub path: String,
}
impl<'a> ElfFile<'a> {
pub fn parse(data: &'a [u8], path: &Path) -> Result<Self> {
if data.len() < 4 {
return Err(BinparseError::FileTooSmall { size: data.len() });
}
if &data[0..4] != b"\x7FELF" {
return Err(BinparseError::NotElf(format!(
"Magic bytes: {:02X} {:02X} {:02X} {:02X}",
data[0], data[1], data[2], data[3]
)));
}
let elf = Elf::parse(data)?;
Ok(Self {
elf,
data,
path: path.display().to_string(),
})
}
pub fn format_description(&self) -> String {
let bits = if self.elf.is_64 { "64-bit" } else { "32-bit" };
let endian = if self.elf.little_endian {
"little endian"
} else {
"big endian"
};
let osabi = header::osabi_to_string(self.elf.header.e_ident[7]);
format!("{}, {}, {}", bits, endian, osabi)
}
pub fn print_file_info(&self) {
display::print_file_info(&self.path, self.data.len(), &self.format_description());
}
pub fn display_header(&self) {
header::display_header(&self.elf);
}
pub fn display_program_headers(&self) {
program_headers::display_program_headers(&self.elf);
}
pub fn display_section_headers(&self) {
section_headers::display_section_headers(&self.elf);
}
pub fn display_symbols(&self) {
symbols::display_symbols(&self.elf);
}
pub fn display_all(&self) {
self.display_header();
self.display_program_headers();
self.display_section_headers();
self.display_symbols();
}
}
pub trait BinaryFormat {
fn format_name(&self) -> &'static str;
fn display_header(&self);
fn display_segments(&self);
fn display_sections(&self);
fn display_symbols(&self);
fn display_all(&self);
}
impl<'a> BinaryFormat for ElfFile<'a> {
fn format_name(&self) -> &'static str {
"ELF"
}
fn display_header(&self) {
self.display_header();
}
fn display_segments(&self) {
self.display_program_headers();
}
fn display_sections(&self) {
self.display_section_headers();
}
fn display_symbols(&self) {
self.display_symbols();
}
fn display_all(&self) {
self.display_all();
}
}