From 54420bbb8de6b85b1f811a81d8690cdad5f15707 Mon Sep 17 00:00:00 2001 From: "Hui, Chunyang" Date: Thu, 7 Jan 2021 10:35:08 +0000 Subject: [PATCH] elf.parse: added lazy_parse function --- src/elf/mod.rs | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/elf/mod.rs b/src/elf/mod.rs index b8775b23..a4c40bd0 100644 --- a/src/elf/mod.rs +++ b/src/elf/mod.rs @@ -202,9 +202,56 @@ if_sylvan! { pub fn is_object_file(&self) -> bool { self.header.e_type == header::ET_REL } + + pub fn parse_elf_hdr(bytes: &'a [u8]) -> error::Result
{ + bytes.pread::
(0) + } + + // Lazy parse the ELF contents after parsing headers, program headers and interpreter. This function mainly just assembles + // an Elf struct. Once we have the struct, we can choose to parse whatever we want. + pub fn lazy_parse(header: Header, program_headers: ProgramHeaders, interpreter: Option<&'a str>) -> error::Result { + let entry = header.e_entry as usize; + let is_lib = header.e_type == header::ET_DYN; + let is_lsb = header.e_ident[header::EI_DATA] == header::ELFDATA2LSB; + let endianness = scroll::Endian::from(is_lsb); + let class = header.e_ident[header::EI_CLASS]; + if class != header::ELFCLASS64 && class != header::ELFCLASS32 { + return Err(error::Error::Malformed(format!("Unknown values in ELF ident header: class: {} endianness: {}", + class, + header.e_ident[header::EI_DATA]))); + } + let is_64 = class == header::ELFCLASS64; + let container = if is_64 { Container::Big } else { Container::Little }; + let ctx = Ctx::new(container, endianness); + + Ok(Elf { + header, + program_headers, + section_headers: Default::default(), + shdr_strtab: Default::default(), + dynamic: None, + dynsyms: Default::default(), + dynstrtab: Strtab::default(), + syms: Default::default(), + strtab: Default::default(), + dynrelas: Default::default(), + dynrels: Default::default(), + pltrelocs: Default::default(), + shdr_relocs: Default::default(), + soname: None, + interpreter, + libraries: vec![], + is_64, + is_lib, + entry: entry as u64, + little_endian: is_lsb, + ctx, + }) + } + /// Parses the contents of the byte stream in `bytes`, and maybe returns a unified binary pub fn parse(bytes: &'a [u8]) -> error::Result { - let header = bytes.pread::
(0)?; + let header = Self::parse_elf_hdr(bytes)?; let entry = header.e_entry as usize; let is_lib = header.e_type == header::ET_DYN; let is_lsb = header.e_ident[header::EI_DATA] == header::ELFDATA2LSB;