From 3c2c2e2304e204027f760d8bd5e0b20c64fb78c9 Mon Sep 17 00:00:00 2001 From: jan Date: Sat, 10 Oct 2020 18:03:18 +0200 Subject: [PATCH 1/4] pe: Add SIZEOF_IMAGE_SECTION_HEADER constant. --- src/pe/header.rs | 2 ++ 1 file changed, 2 insertions(+) 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 From 3131cc26ca659fa83e1fe896a50bc9b49c181cff Mon Sep 17 00:00:00 2001 From: jan Date: Sat, 10 Oct 2020 18:03:45 +0200 Subject: [PATCH 2/4] pe: Add validation for the section table and expose the raw section table to the user --- src/pe/mod.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/pe/mod.rs b/src/pe/mod.rs index 763378936..2a8482340 100644 --- a/src/pe/mod.rs +++ b/src/pe/mod.rs @@ -57,6 +57,7 @@ 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>, + pub section_table: &'a [u8] } impl<'a> PE<'a> { @@ -68,6 +69,20 @@ impl<'a> PE<'a> { + header::SIZEOF_PE_MAGIC + header::SIZEOF_COFF_HEADER + header.coff_header.size_of_optional_header as usize); + + let min_size = *offset + header.coff_header.number_of_sections as usize * header::SIZEOF_IMAGE_SECTION_HEADER; + + if bytes.len() < min_size { + // 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}", min_size, bytes.len()) + ) + ) + } + + let section_table = &bytes[*offset..min_size]; + let sections = header.coff_header.sections(bytes, offset)?; let is_lib = characteristic::is_dll(header.coff_header.characteristics); let mut entry = 0; @@ -174,6 +189,7 @@ impl<'a> PE<'a> { libraries, debug_data, exception_data, + section_table }) } } From aff5da4919f0f06a17145b2a08ddf25bcf76a350 Mon Sep 17 00:00:00 2001 From: jan Date: Sat, 10 Oct 2020 18:16:48 +0200 Subject: [PATCH 3/4] fmt: Fix formatting --- src/pe/mod.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/pe/mod.rs b/src/pe/mod.rs index 2a8482340..2d78b29af 100644 --- a/src/pe/mod.rs +++ b/src/pe/mod.rs @@ -57,7 +57,7 @@ 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>, - pub section_table: &'a [u8] + pub section_table: &'a [u8], } impl<'a> PE<'a> { @@ -70,15 +70,16 @@ impl<'a> PE<'a> { + header::SIZEOF_COFF_HEADER + header.coff_header.size_of_optional_header as usize); - let min_size = *offset + header.coff_header.number_of_sections as usize * header::SIZEOF_IMAGE_SECTION_HEADER; + let min_size = *offset + + header.coff_header.number_of_sections as usize * header::SIZEOF_IMAGE_SECTION_HEADER; if bytes.len() < min_size { // 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}", min_size, bytes.len()) - ) - ) + return Err(error::Error::Malformed(format!( + "Corrupted PE: Expected at least {:#X} bytes but got {:#X}", + min_size, + bytes.len() + ))); } let section_table = &bytes[*offset..min_size]; @@ -189,7 +190,7 @@ impl<'a> PE<'a> { libraries, debug_data, exception_data, - section_table + section_table, }) } } From 8dfcf29199e3f84ec1c174168c9cf37cb4b84a4e Mon Sep 17 00:00:00 2001 From: jan Date: Tue, 13 Oct 2020 12:27:25 +0200 Subject: [PATCH 4/4] pe: rename min_size to be more appropriate and add documentation for the section_table field --- src/pe/mod.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pe/mod.rs b/src/pe/mod.rs index 2d78b29af..b580fddaf 100644 --- a/src/pe/mod.rs +++ b/src/pe/mod.rs @@ -57,6 +57,7 @@ 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], } @@ -70,19 +71,19 @@ impl<'a> PE<'a> { + header::SIZEOF_COFF_HEADER + header.coff_header.size_of_optional_header as usize); - let min_size = *offset + let section_end_offset = *offset + header.coff_header.number_of_sections as usize * header::SIZEOF_IMAGE_SECTION_HEADER; - if bytes.len() < min_size { + 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}", - min_size, + section_end_offset, bytes.len() ))); } - let section_table = &bytes[*offset..min_size]; + 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);