From 90a07ccd51e1f984e6b5385c3ad8876704e7ea31 Mon Sep 17 00:00:00 2001 From: tzlil Date: Tue, 21 Feb 2023 23:53:21 +0200 Subject: add ugly fmt displaying like readelf --- src/main.rs | 12 ++++++-- src/structs.rs | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 98 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index 7a189bf..3033ece 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,10 +16,18 @@ impl Elf { header } } -} +} + +// readelf behavior here +impl std::fmt::Display for Elf { + fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("ELF Header:\n"); + formatter.write_fmt(format_args!("{}", self.header)) + } +} fn main() { let data = include_bytes!("../elf"); let elf = Elf::new(&data[..]); - println!("{:?}", elf); + println!("{}", elf); } diff --git a/src/structs.rs b/src/structs.rs index c055350..f5eb7ea 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -23,10 +23,30 @@ pub struct ElfIdent { pub _unused: [u8; 7], } +impl std::fmt::Display for ElfIdent { + fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("Magic:\t"); + + for b in unsafe {*(std::ptr::addr_of!(self) as *const [u8; 16])} { + formatter.pad(&format!("{:02x?} ", b)); + } + + formatter.write_fmt(format_args!("\nClass:\t{:?}", self.class)); + formatter.write_fmt(format_args!("\nData:\t{}", self.data)); + formatter.write_fmt(format_args!("\nVersion:\t{} ({})", self.version, match self.version { + 0 => "invalid", + 1 => "current", + 2_u8..=u8::MAX => todo!(), // need to cover all cases + })); + formatter.write_fmt(format_args!("\nOS/ABI:\t{}", self.OSABI)); + formatter.write_fmt(format_args!("\nABI Verscion:\t{}", self.ABIVersion)) + } +} + // https://man7.org/linux/man-pages/man5/elf.5.html // https://wiki.osdev.org/ELF // https://en.wikipedia.org/wiki/Executable_and_Linkable_Format -#[repr(C, packed)] +#[repr(C)] #[derive(Debug)] pub struct ElfHeader { pub ident: ElfIdent, @@ -72,6 +92,25 @@ pub struct ElfHeader { pub shstrndx: u16, } +impl std::fmt::Display for ElfHeader { + fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_fmt(format_args!("{}", self.ident)); + formatter.write_fmt(format_args!("\nType:\t{}", self.r#type)); + formatter.write_fmt(format_args!("\nMachine:\t{}", self.machine)); + formatter.write_fmt(format_args!("\nVersion:\t{:#02x?}", self.version)); + formatter.write_fmt(format_args!("\nEntry point address:\t{:#x?}", self.entry)); + formatter.write_fmt(format_args!("\nStart of program headers:\t{} (bytes into file)", self.phoff)); + formatter.write_fmt(format_args!("\nStart of section headers:\t{} (bytes into file)", self.shoff)); + formatter.write_fmt(format_args!("\nFlags:\t{:#x?}", self.flags)); + formatter.write_fmt(format_args!("\nSize of this header:\t{} (bytes)", self.ehsize)); + formatter.write_fmt(format_args!("\nSize of program headers:\t{} (bytes)", self.phentsize)); + formatter.write_fmt(format_args!("\nNumber of program headers:\t{}", self.phnum)); + formatter.write_fmt(format_args!("\nSize of section headers:\t{} (bytes)", self.shentsize)); + formatter.write_fmt(format_args!("\nNumber of section headers:\t{}", self.shnum)); + formatter.write_fmt(format_args!("\nSection header string table index:\t{}", self.shstrndx)) + } +} + #[derive(Debug, Copy, Clone)] #[repr(u16)] pub enum Type { @@ -82,13 +121,36 @@ pub enum Type { Core = 4, } +impl std::fmt::Display for Type { + fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Type::None => formatter.write_str("NONE (None)"), + Type::Rel => formatter.write_str("REL (Relocatable file)"), + Type::Exec => formatter.write_str("EXEC (Executable file)"), + Type::Dyn => formatter.write_str("DYN (Shared object file)"), + Type::Core => formatter.write_str("CORE (Core file)"), + } + } +} + #[derive(Debug, Copy, Clone)] #[repr(u16)] pub enum Machine { + // there are many many many more, im just gonna do x86 + // https://github.com/bminor/binutils-gdb/blob/master/binutils/readelf.c#L2746 None = 1, X86_64 = 62, } +impl std::fmt::Display for Machine { + fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Machine::None => formatter.write_str("None"), + Machine::X86_64 => formatter.write_str("Advanced Micro Devices X86-64"), + } + } +} + #[derive(Debug, Copy, Clone)] #[repr(u8)] @@ -102,18 +164,37 @@ pub enum Class { pub enum OSABI { None = 0x00, SystemV = 0x01, - HPUX = 0x02, - Solaris = 0x03, - IRIX = 0x04, - FreeBSD = 0x05, - TRU64 = 0x06, - ARM = 0x07, + // HPUX = 0x02, + // Solaris = 0x03, + // IRIX = 0x04, + // FreeBSD = 0x05, + // TRU64 = 0x06, + // ARM = 0x07, Standalone = 0x08, } +impl std::fmt::Display for OSABI { + fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + OSABI::None => formatter.write_str("UNIX - System V"), + OSABI::SystemV => formatter.write_str("UNIX - System V"), + OSABI::Standalone => formatter.write_str("Standalone"), + } + } +} + #[derive(Debug, Copy, Clone)] #[repr(u8)] pub enum Endian { Little = 1, Big = 2, +} + +impl std::fmt::Display for Endian { + fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Endian::Little => formatter.write_str("2's complement, little endian"), + Endian::Big => formatter.write_str("1's complement, big endian"), + } + } } \ No newline at end of file -- cgit 1.4.1