binparse 0.1.0

A colorful, user-friendly alternative to readelf for analyzing ELF binaries
//! ELF binary format analysis module.
//!
//! This module provides functionality for parsing and displaying
//! ELF (Executable and Linkable Format) binary files, supporting
//! both 32-bit and 64-bit formats with little and big endian.

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};

/// Represents a parsed ELF file with associated data
pub struct ElfFile<'a> {
    /// The parsed ELF structure from goblin
    pub elf: Elf<'a>,
    /// Raw file data
    pub data: &'a [u8],
    /// File path for display
    pub path: String,
}

impl<'a> ElfFile<'a> {
    /// Parse an ELF file from raw bytes
    pub fn parse(data: &'a [u8], path: &Path) -> Result<Self> {
        if data.len() < 4 {
            return Err(BinparseError::FileTooSmall { size: data.len() });
        }

        // Check ELF magic bytes
        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(),
        })
    }

    /// Get the format description 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)
    }

    /// Print file information header
    pub fn print_file_info(&self) {
        display::print_file_info(&self.path, self.data.len(), &self.format_description());
    }

    /// Display the ELF header
    pub fn display_header(&self) {
        header::display_header(&self.elf);
    }

    /// Display program headers (segments)
    pub fn display_program_headers(&self) {
        program_headers::display_program_headers(&self.elf);
    }

    /// Display section headers
    pub fn display_section_headers(&self) {
        section_headers::display_section_headers(&self.elf);
    }

    /// Display symbol table
    pub fn display_symbols(&self) {
        symbols::display_symbols(&self.elf);
    }

    /// Display all information
    pub fn display_all(&self) {
        self.display_header();
        self.display_program_headers();
        self.display_section_headers();
        self.display_symbols();
    }
}

/// Trait for extensible binary format support
/// Can be implemented for PE, Mach-O, etc.
pub trait BinaryFormat {
    /// Get a human-readable format name
    fn format_name(&self) -> &'static str;

    /// Display the file header
    fn display_header(&self);

    /// Display segments/program headers
    fn display_segments(&self);

    /// Display sections
    fn display_sections(&self);

    /// Display symbols
    fn display_symbols(&self);

    /// Display all available information
    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();
    }
}