binkit 0.1.0

A modular toolbox for analyzing, disassembling, and patching binary formats
Documentation
use crate::traits::binary_printer::BinaryPrinter;
use crate::traits::header_field::HeaderField;

use super::types::{elf64_header::Elf64Header, elf64_program_header::Elf64ProgramHeader, elf64_section_header::Elf64SectionHeader};
use tabled::{Table, Tabled};
use tabled::settings::{Settings, Style};

pub struct Elf64Printer;

impl BinaryPrinter for Elf64Printer {
    type Header = Elf64Header;
    type ProgramHeader = Elf64ProgramHeader;
    type SectionHeader = Elf64SectionHeader;

    fn print_header(&self, header: &Self::Header){
        #[derive(Tabled)]
        struct HeaderField<'a> {
            name: &'a str,
            describe: String,
        }

        let fields = vec![
            HeaderField { name: "e_ident",  describe: header.e_ident.describe() },
            HeaderField { name: "e_type",  describe: header.e_type.describe() },
            HeaderField { name: "e_machine",  describe: header.e_machine.describe() },
            HeaderField { name: "e_version",  describe: header.e_version.describe() },
            HeaderField { name: "e_entry",  describe: header.e_entry.describe() },
            HeaderField { name: "e_phoff",  describe: header.e_phoff.describe() },
            HeaderField { name: "e_shoff",  describe: header.e_shoff.describe() },
            HeaderField { name: "e_flags",  describe: header.e_flags.describe() },
            HeaderField { name: "e_ehsize",  describe: header.e_ehsize.describe() },
            HeaderField { name: "e_phentsize",  describe: header.e_phentsize.describe() },
            HeaderField { name: "e_phnum",  describe: header.e_phnum.describe() },
            HeaderField { name: "e_shentsize",  describe: header.e_shentsize.describe() },
            HeaderField { name: "e_shnum",  describe: header.e_shnum.describe() },
            HeaderField { name: "e_shstrndx",  describe: header.e_shstrndx.describe() },
        ];

        let table_config = Settings::default()
            .with(Style::modern());
        let table = Table::new(fields).with(table_config).to_string();
        println!("Elf header:");
        println!("{}", table);
    }

    fn print_program_headers(&self, phs: &[Self::ProgramHeader]) {
        #[derive(Tabled)]
        struct ProgramHeaderFields {
            p_type: String,
            p_offset: String,
            p_vaddr: String,
            p_paddr: String,
            p_filesz: String,
            p_memsz: String,
            p_flags: String,
            p_align: String,
        }

        let table_config = Settings::default()
            .with(Style::modern());

        let mut fields: Vec<ProgramHeaderFields> = Vec::with_capacity(phs.len());

        for ph in phs {
            fields.push(
                ProgramHeaderFields { 
                    p_type: ph.p_type.describe(),
                    p_offset: ph.p_offset.describe(),
                    p_vaddr: ph.p_vaddr.describe(),
                    p_paddr: ph.p_paddr.describe(),
                    p_filesz: ph.p_filesz.describe(),
                    p_memsz: ph.p_memsz.describe(),
                    p_flags: ph.p_flags.describe(),
                    p_align: ph.p_align.describe()
                }
            );
        }

        let table = Table::new(fields).with(table_config).to_string();

        println!("\nProgram headers:");
        println!("{}", table);
    }

    fn print_section_headers(&self, shs: &[Self::SectionHeader]) {
        #[derive(Tabled)]
        struct SectionHeaderFields {
            sh_name: String,
            sh_type: String,
            sh_flags: String,
            sh_addr: String,
            sh_offset: String,
            sh_size: String,
            sh_link: String,
            sh_info: String,
            sh_addralign: String,
            sh_entsize: String,
        }

        let table_config = Settings::default()
            .with(Style::modern());

        let mut fields: Vec<SectionHeaderFields> = Vec::with_capacity(shs.len());

        for sh in shs {
            fields.push(
                SectionHeaderFields { 
                    sh_name: sh.sh_name.describe(),
                    sh_type: sh.sh_type.describe(),
                    sh_flags: sh.sh_flags.describe(),
                    sh_addr: sh.sh_addr.describe(),
                    sh_offset: sh.sh_offset.describe(),
                    sh_size: sh.sh_size.describe(),
                    sh_link: sh.sh_link.describe(),
                    sh_info: sh.sh_info.describe(),
                    sh_addralign: sh.sh_addralign.describe(),
                    sh_entsize: sh.sh_entsize.describe()
                }
            );
        }

        let table = Table::new(fields).with(table_config).to_string();

        println!("\nSection headers:");
        println!("{}", table);
    }
}