diff --git a/src/pe/header.rs b/src/pe/header.rs index e4d8bc177..e4b257fff 100644 --- a/src/pe/header.rs +++ b/src/pe/header.rs @@ -56,6 +56,8 @@ pub const SIZEOF_COFF_HEADER: usize = 20; /// PE\0\0, little endian pub const PE_MAGIC: u32 = 0x0000_4550; pub const SIZEOF_PE_MAGIC: usize = 4; +// sizeof(IMAGE_SECTION_HEADER), used for header calculations +pub const SIZEOF_IMAGE_SECTION_HEADER: usize = 40; /// The contents of this field are assumed to be applicable to any machine type pub const COFF_MACHINE_UNKNOWN: u16 = 0x0; /// Matsushita AM33 diff --git a/src/pe/mod.rs b/src/pe/mod.rs index 763378936..b580fddaf 100644 --- a/src/pe/mod.rs +++ b/src/pe/mod.rs @@ -57,6 +57,8 @@ pub struct PE<'a> { pub debug_data: Option>, /// Exception handling and stack unwind information, if any, contained in the PE header pub exception_data: Option>, + /// The raw, unparsed section table. + pub section_table: &'a [u8], } impl<'a> PE<'a> { @@ -68,6 +70,21 @@ impl<'a> PE<'a> { + header::SIZEOF_PE_MAGIC + header::SIZEOF_COFF_HEADER + header.coff_header.size_of_optional_header as usize); + + let section_end_offset = *offset + + header.coff_header.number_of_sections as usize * header::SIZEOF_IMAGE_SECTION_HEADER; + + if bytes.len() < section_end_offset { + // The section table contains more entries than the binary can provide given the size + return Err(error::Error::Malformed(format!( + "Corrupted PE: Expected at least {:#X} bytes but got {:#X}", + section_end_offset, + bytes.len() + ))); + } + + let section_table = &bytes[*offset..section_end_offset]; + let sections = header.coff_header.sections(bytes, offset)?; let is_lib = characteristic::is_dll(header.coff_header.characteristics); let mut entry = 0; @@ -174,6 +191,7 @@ impl<'a> PE<'a> { libraries, debug_data, exception_data, + section_table, }) } }