Skip to content

Commit

Permalink
[review] Moved the overlay detection logic
Browse files Browse the repository at this point in the history
  • Loading branch information
daladim committed Aug 9, 2021
1 parent 81fdc3b commit 22c14f4
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 38 deletions.
15 changes: 15 additions & 0 deletions src/read/coff/section.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
38 changes: 0 additions & 38 deletions src/read/pe/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u64>,
pub(super) data: R,
}

Expand All @@ -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, &sections);
let overlay_offset = if final_offset < file_size {
Some(final_offset + 1)
} else {
None
};

Ok(PeFile {
dos_header,
nt_headers,
Expand All @@ -68,7 +57,6 @@ where
symbols,
image_base,
},
overlay_offset,
data,
})
}
Expand Down Expand Up @@ -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<u64> {
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>
Expand Down

0 comments on commit 22c14f4

Please sign in to comment.