From 5d8493cf7e2d725fbd2aeca1644f56ebdafd4cf9 Mon Sep 17 00:00:00 2001 From: tzlil Date: Tue, 21 Mar 2023 15:44:11 +0200 Subject: finished section headers printing --- src/main.rs | 58 ++++++++++++++++++++++++++++++++++++++++------------------ src/structs.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 92 insertions(+), 20 deletions(-) diff --git a/src/main.rs b/src/main.rs index 9be3a25..b517cd8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,13 +9,14 @@ use std::io::Read; struct Elf { header: &'static ElfHeader, sections: &'static [ElfSectionHeader], + strtab: *const u8, } impl Elf { pub fn new(bytes: &[u8]) -> Elf { let header = unsafe { &*(bytes.as_ptr() as *const ElfHeader) }; assert_eq!(&header.ident.magic, b"\x7fELF"); - + let sections = unsafe { std::slice::from_raw_parts( bytes.as_ptr().add(header.shoff as usize) as *const ElfSectionHeader, @@ -23,23 +24,22 @@ impl Elf { ) }; - let strtab = §ions[header.shstrndx as usize]; - let strtab_section = unsafe { bytes.as_ptr().add(strtab.offset as usize) }; + let strtab = unsafe { + bytes + .as_ptr() + .add((§ions[header.shstrndx as usize]).offset as usize) + }; - // let names = unsafe { - // std::slice::from_raw_parts( - // strtab_section as *const u8, - // strtab.size as usize, - // ) - // }; - // dbg!(std::str::from_utf8(&names).unwrap()); - for sec in sections { - println!("{:?}", unsafe { std::ffi::CStr::from_ptr( - strtab_section.add(sec.name as usize) as *const i8 - )}); + // for sec in sections { + // println!("{:?}", unsafe { std::ffi::CStr::from_ptr( + // strtab.add(sec.name as usize) as *const i8 + // )}); + // } + Elf { + header, + sections, + strtab, } - // dbg!(sections[5].r#type as u32); - Elf { header, sections } } } @@ -47,7 +47,29 @@ impl Elf { 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)) + formatter.write_fmt(format_args!("{}\n", self.header))?; + + formatter.write_str("Section Headers:\n")?; + formatter + .write_str(" [Nr] Name Type Address Offset\n")?; + formatter + .write_str(" Size EntSize Flags Link Info Align\n")?; + + for (i, section) in self.sections.iter().enumerate() { + let name = unsafe { + std::ffi::CStr::from_ptr(self.strtab.add(section.name as usize) as *const i8) + .to_str() + .expect("Bad section name") + }; + formatter.write_fmt(format_args!(" [{: >2}] {: <17.17} {}\n", i, name, section))?; + } + + formatter.write_str("Key to Flags:\n")?; + formatter.write_str(" W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n")?; + formatter.write_str(" L (link order), O (extra OS processing required), G (group), T (TLS),\n")?; + formatter.write_str(" C (compressed), x (unknown), o (OS specific), E (exclude),\n")?; + formatter.write_str(" D (mbind), l (large), p (processor specific)\n")?; + Ok(()) } } @@ -62,5 +84,5 @@ fn main() { buffer }; let elf = Elf::new(&buffer[..]); - // println!("{}", elf); + println!("{}", elf); } diff --git a/src/structs.rs b/src/structs.rs index 69ec14e..4757f2a 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -319,6 +319,24 @@ pub struct ElfSectionHeader { pub entsize: u64, } +impl std::fmt::Display for ElfSectionHeader { + fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_fmt(format_args!( + "{: <16} {:0>16x} {:0>8x}\n {:0>16x} {:0>16x} {: ^10} {: <5} {: <5} {}", + self.r#type, + self.addr, + self.offset, + self.size, + self.entsize, + self.flags, + self.link, + self.info, + self.addralign + ))?; + Ok(()) + } +} + #[derive(Debug, Copy, Clone)] #[repr(u32)] pub enum ElfSectionType { @@ -389,11 +407,43 @@ pub enum ElfSectionType { GnuHash = 0x6FFFFFF6, } +impl std::fmt::Display for ElfSectionType { + fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + ElfSectionType::Null => "NULL".fmt(formatter), + ElfSectionType::ProgBits => "PROGBITS".fmt(formatter), + ElfSectionType::SymTab => "SYMTAB".fmt(formatter), + ElfSectionType::StrTab => "STRTAB".fmt(formatter), + ElfSectionType::Rela => "RELA".fmt(formatter), + ElfSectionType::Hash => "HASH".fmt(formatter), + ElfSectionType::Dynamic => "Dynamic".fmt(formatter), + ElfSectionType::Note => "NOTE".fmt(formatter), + ElfSectionType::NoBits => "NOBITS".fmt(formatter), + ElfSectionType::Rel => "REL".fmt(formatter), + ElfSectionType::ShLib => "SHLIB".fmt(formatter), + ElfSectionType::DynSym => "DYNSYM".fmt(formatter), + ElfSectionType::GnuHash => "GNU_HASH".fmt(formatter), + } + } +} + bitflags! { - #[derive(Debug, Copy, Clone)] - pub struct ElfSectionFlags: u64 { + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub struct ElfSectionFlags: u64 { const WRITE = 0x1; const ALLOC = 0x2; const EXEC = 0x4; } } + +// PAIN IN THE ASS!!!!!!! +// https://github.com/aixoss/binutils/blob/master/binutils/readelf.c#L4966 +// https://github.com/llvm-mirror/llvm/blob/2c4ca6832fa6b306ee6a7010bfb80a3f2596f824/tools/llvm-readobj/ELFDumper.cpp#L1176 +impl std::fmt::Display for ElfSectionFlags { + fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + // if *self == ElfSectionFlags::WRITE { + " A".fmt(formatter); + // } + Ok(()) + } +} -- cgit 1.4.1