diff --git a/src/read/coff/section.rs b/src/read/coff/section.rs index 8762e249..60b2a204 100644 --- a/src/read/coff/section.rs +++ b/src/read/coff/section.rs @@ -77,6 +77,21 @@ impl<'data> SectionTable<'data> { .find(|(_, section)| section.name(strings) == Ok(name)) .map(|(index, section)| (index + 1, section)) } + + /// Compute the maximum file offset used by sections. + /// This will usually match the end of file, unless the PE file has a [data overlay] + /// (https://security.stackexchange.com/questions/77336/how-is-the-file-overlay-read-by-an-exe-virus) + pub fn max_section_file_offset(&self) -> u64 { + let mut max = 0; + for section in self.iter() { + let end_of_section = section.pointer_to_raw_data.get(LE) as u64 + + section.size_of_raw_data.get(LE) as u64; + if end_of_section > max { + max = end_of_section; + } + } + max + } } /// An iterator over the loadable sections of a `CoffFile`. diff --git a/src/read/pe/file.rs b/src/read/pe/file.rs index 78648f39..a154d656 100644 --- a/src/read/pe/file.rs +++ b/src/read/pe/file.rs @@ -31,7 +31,6 @@ where pub(super) nt_headers: &'data Pe, pub(super) data_directories: &'data [pe::ImageDataDirectory], pub(super) common: CoffCommon<'data, R>, - pub(super) overlay_offset: Option, pub(super) data: R, } @@ -49,16 +48,6 @@ where let symbols = nt_headers.symbols(data)?; let image_base = nt_headers.optional_header().image_base(); - let file_size = data - .len() - .map_err(|()| read::Error("Unable to get file length"))?; - let final_offset = Self::compute_final_offset(offset, file_size, §ions); - let overlay_offset = if final_offset < file_size { - Some(final_offset + 1) - } else { - None - }; - Ok(PeFile { dos_header, nt_headers, @@ -68,7 +57,6 @@ where symbols, image_base, }, - overlay_offset, data, }) } @@ -107,32 +95,6 @@ where pub fn data(&self) -> R { self.data } - - /// Returns the offset where the overlay (if any) starts. - /// - /// A [data overlay](https://security.stackexchange.com/questions/77336/how-is-the-file-overlay-read-by-an-exe-virus) - /// is the part of the PE file after all headers and sections. Some malware use it to conceal data - pub fn overlay_offset(&self) -> Option { - self.overlay_offset - } - - /// Compute the end of file, according to the offset and sizes declared in the headers - fn compute_final_offset(end_of_headers: u64, file_size: u64, sections: &SectionTable) -> u64 { - let mut final_offset: u64 = end_of_headers; - for section in sections.iter() { - let new_offset = section.pointer_to_raw_data.get(LE); - let new_size = section.size_of_raw_data.get(LE); - let new_final = new_offset as u64 + new_size as u64; - if new_final <= file_size && new_final > final_offset { - final_offset = new_final - } - } - - // We'll assume the PE "data directories" are all contained within the sections - // Note that some other parsing libraries (e.g. the `pefile` Python library) does not make such an assumption - - final_offset - } } impl<'data, Pe, R> read::private::Sealed for PeFile<'data, Pe, R>