Skip to content

Commit

Permalink
pe.header: add parsing without dos, and fix parsing PE with zero raw_…
Browse files Browse the repository at this point in the history
…data_size of section (#396)

* pe.utils: handle case when section raw_data is zero
* pe.header: added ability to parse part of pe header without dos

---------

Co-authored-by: Radmir Rezbaev <rrezbaev@ptsecurity.com>
  • Loading branch information
ideeockus and Radmir Rezbaev authored Oct 27, 2024
1 parent 5b0382c commit f401d18
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 8 deletions.
29 changes: 21 additions & 8 deletions src/pe/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -791,14 +791,7 @@ pub struct Header {
}

impl Header {
pub fn parse(bytes: &[u8]) -> error::Result<Self> {
let dos_header = DosHeader::parse(&bytes)?;
let dos_stub = bytes.pread(DOS_STUB_OFFSET as usize).map_err(|_| {
error::Error::Malformed(format!(
"cannot parse DOS stub (offset {:#x})",
DOS_STUB_OFFSET
))
})?;
fn parse_impl(bytes: &[u8], dos_header: DosHeader, dos_stub: DosStub) -> error::Result<Self> {
let mut offset = dos_header.pe_pointer as usize;
let signature = bytes.gread_with(&mut offset, scroll::LE).map_err(|_| {
error::Error::Malformed(format!("cannot parse PE signature (offset {:#x})", offset))
Expand All @@ -809,6 +802,7 @@ impl Header {
} else {
None
};

Ok(Header {
dos_header,
dos_stub,
Expand All @@ -817,6 +811,25 @@ impl Header {
optional_header,
})
}

/// Parses PE header from the given bytes; this will fail if the DosHeader or DosStub is malformed or missing in some way
pub fn parse(bytes: &[u8]) -> error::Result<Self> {
let dos_header = DosHeader::parse(&bytes)?;
let dos_stub = bytes.pread(DOS_STUB_OFFSET as usize).map_err(|_| {
error::Error::Malformed(format!(
"cannot parse DOS stub (offset {:#x})",
DOS_STUB_OFFSET
))
})?;

Header::parse_impl(bytes, dos_header, dos_stub)
}

/// Parses PE header from the given bytes, a default DosHeader and DosStub are generated, and any malformed header or stub is ignored
pub fn parse_without_dos(bytes: &[u8]) -> error::Result<Self> {
let dos_header = DosHeader::default();
Header::parse_impl(bytes, dos_header, DosStub::default())
}
}

impl ctx::TryIntoCtx<scroll::Endian> for Header {
Expand Down
2 changes: 2 additions & 0 deletions src/pe/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ fn section_read_size(section: &section_table::SectionTable, file_alignment: u32)

if virtual_size == 0 {
read_size
} else if read_size == 0 {
virtual_size
} else {
cmp::min(read_size, round_size(virtual_size))
}
Expand Down

0 comments on commit f401d18

Please sign in to comment.