From 651c189659a082eaca2a945232c934dd822735c9 Mon Sep 17 00:00:00 2001 From: tzlil Date: Tue, 21 Mar 2023 17:00:25 +0200 Subject: add fenix to flake, change to nightly --- src/main.rs | 49 +++++++++++--- src/structs.rs | 208 +++++++++++++++++++++++++++++++++++---------------------- 2 files changed, 169 insertions(+), 88 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index b517cd8..c900d2a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ // #![allow(incomplete_features)] // #![feature(unsized_locals)] mod structs; -use crate::structs::{ElfHeader, ElfSectionHeader}; +use crate::structs::{ElfHeader, ElfSectionHeader, ElfSectionType, ElfSymbol}; use std::io::Read; #[repr(C)] @@ -9,6 +9,7 @@ use std::io::Read; struct Elf { header: &'static ElfHeader, sections: &'static [ElfSectionHeader], + // symbols: &'static Vec, strtab: *const u8, } @@ -30,11 +31,37 @@ impl Elf { .add((§ions[header.shstrndx as usize]).offset as usize) }; - // for sec in sections { - // println!("{:?}", unsafe { std::ffi::CStr::from_ptr( - // strtab.add(sec.name as usize) as *const i8 - // )}); + let symtab = sections + .iter() + .find(|&&sec| sec.r#type == ElfSectionType::SymTab) + .expect("No symbol table!"); + let symstrtab = unsafe { bytes.as_ptr().add(symtab.link as usize) }; + let symbols: Vec<&str> = unsafe { + std::slice::from_raw_parts( + bytes.as_ptr().add(symtab.offset as usize) as *const ElfSymbol, + (symtab.size / symtab.entsize) as usize, + ) + } + .iter() + .filter(|sym| sym.shndx != 0) + .map(|sym| unsafe { + std::ffi::CStr::from_ptr(symstrtab.add(sym.name as usize) as *const i8) + .to_str() + .unwrap_or("") + }) + .filter(|name| name.len() > 1) + .collect(); + dbg!(symbols); + // for sym in symbols { + // dbg!(sym); + // let name = unsafe { + // std::ffi::CStr::from_ptr(symstrtab.add(sym.name as usize) as *const i8) + // .to_str() + // .unwrap_or("") + // }; + // dbg!(name); // } + Elf { header, sections, @@ -65,8 +92,12 @@ impl std::fmt::Display for Elf { } 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( + " 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(()) @@ -84,5 +115,7 @@ fn main() { buffer }; let elf = Elf::new(&buffer[..]); - println!("{}", elf); + // println!("{}", elf); + + // dbg!(symtab); } diff --git a/src/structs.rs b/src/structs.rs index 099e5ee..f5c8140 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -261,61 +261,62 @@ impl std::fmt::Display for Endian { #[derive(Debug, Copy, Clone)] #[repr(C)] pub struct ElfSectionHeader { - /* This member specifies the name of the section. Its value - is an index into the section header string table section, - giving the location of a null-terminated string. */ + /// This member specifies the name of the section. Its value + /// is an index into the section header string table section, + /// giving the location of a null-terminated string. pub name: u32, - /* This member categorizes the section's contents and - semantics. */ + + /// This member categorizes the section's contents and + /// semantics. pub r#type: ElfSectionType, - /* Sections support one-bit flags that describe miscellaneous - attributes. If a flag bit is set in sh_flags, the - attribute is "on" for the section. Otherwise, the - attribute is "off" or does not apply. Undefined - attributes are set to zero. */ + /// Sections support one-bit flags that describe miscellaneous + /// attributes. If a flag bit is set in sh_flags, the + /// attribute is "on" for the section. Otherwise, the + /// attribute is "off" or does not apply. Undefined + /// attributes are set to zero. pub flags: ElfSectionFlags, - /* If this section appears in the memory image of a process, - this member holds the address at which the section's first - byte should reside. Otherwise, the member contains zero. */ + /// If this section appears in the memory image of a process, + /// this member holds the address at which the section's first + /// byte should reside. Otherwise, the member contains zero. pub addr: u64, - /* This member's value holds the byte offset from the - beginning of the file to the first byte in the section. - One section type, SHT_NOBITS, occupies no space in the - file, and its sh_offset member locates the conceptual - placement in the file. */ + /// This member's value holds the byte offset from the + /// beginning of the file to the first byte in the section. + /// One section type, SHT_NOBITS, occupies no space in the + /// file, and its sh_offset member locates the conceptual + /// placement in the file. pub offset: u64, - /* This member holds the section's size in bytes. Unless the - section type is SHT_NOBITS, the section occupies sh_size - bytes in the file. A section of type SHT_NOBITS may have - a nonzero size, but it occupies no space in the file. */ + /// This member holds the section's size in bytes. Unless the + /// section type is SHT_NOBITS, the section occupies sh_size + /// bytes in the file. A section of type SHT_NOBITS may have + /// a nonzero size, but it occupies no space in the file. pub size: u64, - /* This member holds a section header table index link, whose - interpretation depends on the section type. */ + /// This member holds a section header table index link, whose + /// interpretation depends on the section type. pub link: u32, - /* This member holds extra information, whose interpretation - depends on the section type. */ + /// This member holds extra information, whose interpretation + /// depends on the section type. pub info: u32, - /* Some sections have address alignment constraints. If a - section holds a doubleword, the system must ensure - doubleword alignment for the entire section. That is, the - value of sh_addr must be congruent to zero, modulo the - value of sh_addralign. Only zero and positive integral - powers of two are allowed. The value 0 or 1 means that - the section has no alignment constraints. */ + /// Some sections have address alignment constraints. If a + /// section holds a doubleword, the system must ensure + /// doubleword alignment for the entire section. That is, the + /// value of sh_addr must be congruent to zero, modulo the + /// value of sh_addralign. Only zero and positive integral + /// powers of two are allowed. The value 0 or 1 means that + /// the section has no alignment constraints. pub addralign: u64, - /* Some sections hold a table of fixed-sized entries, such as - a symbol table. For such a section, this member gives the - size in bytes for each entry. This member contains zero - if the section does not hold a table of fixed-size - entries. */ + /// Some sections hold a table of fixed-sized entries, such as + /// a symbol table. For such a section, this member gives the + /// size in bytes for each entry. This member contains zero + /// if the section does not hold a table of fixed-size + /// entries. pub entsize: u64, } @@ -337,71 +338,71 @@ impl std::fmt::Display for ElfSectionHeader { } } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq)] #[repr(u32)] pub enum ElfSectionType { - /* This value marks the section header as inactive. - It does not have an associated section. Other - members of the section header have undefined - values. */ + /// This value marks the section header as inactive. + /// It does not have an associated section. Other + /// members of the section header have undefined + /// values. Null = 0, - /* This section holds information defined by the - program, whose format and meaning are determined - solely by the program. */ + /// This section holds information defined by the + /// program, whose format and meaning are determined + /// solely by the program. ProgBits = 1, - /* This section holds a symbol table. Typically, - SHT_SYMTAB provides symbols for link editing, - though it may also be used for dynamic linking. As - a complete symbol table, it may contain many - symbols unnecessary for dynamic linking. An object - file can also contain a SHT_DYNSYM section. */ + /// This section holds a symbol table. Typically, + /// SHT_SYMTAB provides symbols for link editing, + /// though it may also be used for dynamic linking. As + /// a complete symbol table, it may contain many + /// symbols unnecessary for dynamic linking. An object + /// file can also contain a SHT_DYNSYM section. SymTab = 2, - /* This section holds a string table. An object file - may have multiple string table sections. */ + /// This section holds a string table. An object file + /// may have multiple string table sections. StrTab = 3, - /* This section holds relocation entries with explicit - addends, such as type Elf32_Rela for the 32-bit - class of object files. An object may have multiple - relocation sections. */ + /// This section holds relocation entries with explicit + /// addends, such as type Elf32_Rela for the 32-bit + /// class of object files. An object may have multiple + /// relocation sections. Rela = 4, - /* This section holds a symbol hash table. An object - participating in dynamic linking must contain a - symbol hash table. An object file may have only - one hash table. */ + /// This section holds a symbol hash table. An object + /// participating in dynamic linking must contain a + /// symbol hash table. An object file may have only + /// one hash table. Hash = 5, - /* This section holds information for dynamic linking. - An object file may have only one dynamic section. */ + /// This section holds information for dynamic linking. + /// An object file may have only one dynamic section. Dynamic = 6, - /* This section holds notes (ElfN_Nhdr). */ + /// This section holds notes (ElfN_Nhdr). Note = 7, - /* A section of this type occupies no space in the - file but otherwise resembles SHT_PROGBITS. - Although this section contains no bytes, the - sh_offset member contains the conceptual file - offset. */ + /// A section of this type occupies no space in the + /// file but otherwise resembles SHT_PROGBITS. + /// Although this section contains no bytes, the + /// sh_offset member contains the conceptual file + /// offset. NoBits = 8, - /* This section holds relocation offsets without - explicit addends, such as type Elf32_Rel for the - 32-bit class of object files. An object file may - have multiple relocation sections. */ + /// This section holds relocation offsets without + /// explicit addends, such as type Elf32_Rel for the + /// 32-bit class of object files. An object file may + /// have multiple relocation sections. Rel = 9, - /* This section is reserved but has unspecified - semantics. */ + /// This section is reserved but has unspecified + /// semantics. ShLib = 10, - /* This section holds a minimal set of dynamic linking - symbols. An object file can also contain a - SHT_SYMTAB section. */ + /// This section holds a minimal set of dynamic linking + /// symbols. An object file can also contain a + /// SHT_SYMTAB section. DynSym = 11, InitArray = 14, @@ -421,7 +422,7 @@ impl std::fmt::Display for ElfSectionType { ElfSectionType::StrTab => "STRTAB".fmt(formatter), ElfSectionType::Rela => "RELA".fmt(formatter), ElfSectionType::Hash => "HASH".fmt(formatter), - ElfSectionType::Dynamic => "Dynamic".fmt(formatter), + ElfSectionType::Dynamic => "DYNAMIC".fmt(formatter), ElfSectionType::Note => "NOTE".fmt(formatter), ElfSectionType::NoBits => "NOBITS".fmt(formatter), ElfSectionType::Rel => "REL".fmt(formatter), @@ -454,3 +455,50 @@ impl std::fmt::Display for ElfSectionFlags { Ok(()) } } + +#[derive(Debug, Clone, PartialEq, Eq)] +#[repr(C)] +pub struct ElfSymbol { + /// This member holds an index into the symbol table's string table, + /// which holds the character representations of the symbol names. If the + /// value is non-zero, it represents a string table index that gives the + /// symbol name. Otherwise, the symbol table entry has no name. + pub name: u32, + + /// This member specifies the symbol's type and binding attributes. + pub info: u8, + + /// This member currently specifies a symbol's visibility. + pub other: u8, + + /// Every symbol table entry is defined in relation to some section. This + /// member holds the relevant section header table index. As the sh_link and + /// sh_info interpretation table and the related text describe, some section + /// indexes indicate special meanings. + /// + /// If this member contains SHN_XINDEX, then the actual section header index + /// is too large to fit in this field. The actual value is contained in the + /// associated section of type SHT_SYMTAB_SHNDX. + pub shndx: u16, + + /// This member gives the value of the associated symbol. Depending on the + /// context, this may be an absolute value, an address, and so on. + /// + /// * In relocatable files, st_value holds alignment constraints for a + /// symbol whose section index is SHN_COMMON. + /// * In relocatable files, st_value holds a section offset for a defined + /// symbol. st_value is an offset from the beginning of the section that + /// st_shndx identifies. + /// * In executable and shared object files, st_value holds a virtual + /// address. To make these files' symbols more useful for the dynamic + /// linker, the section offset (file interpretation) gives way to a + /// virtual address (memory interpretation) for which the section number + /// is irrelevant. + pub value: u64, + + /// This member gives the symbol's size. + /// For example, a data object's size is the number of bytes contained in + /// the object. This member holds 0 if the symbol has no size or an unknown + /// size. + pub size: u64, +} -- cgit 1.4.1