summary refs log tree commit diff
diff options
context:
space:
mode:
authortzlil <tzlils@protonmail.com>2023-03-21 15:44:11 +0200
committertzlil <tzlils@protonmail.com>2023-03-21 15:44:11 +0200
commit5d8493cf7e2d725fbd2aeca1644f56ebdafd4cf9 (patch)
treed4e8118514a117c55c5997d21128cf249d88d724
parentc8a66c643afe2d0a2da55eac537b13a466c242c2 (diff)
finished section headers printing
-rw-r--r--src/main.rs58
-rw-r--r--src/structs.rs54
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 = &sections[header.shstrndx as usize];
-        let strtab_section = unsafe { bytes.as_ptr().add(strtab.offset as usize) };
+        let strtab = unsafe {
+            bytes
+                .as_ptr()
+                .add((&sections[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(())
+    }
+}