@@ -1221,8 +1221,16 @@ pub const TE_MAGIC: u16 = 0x5a56;
12211221impl TeHeader {
12221222 /// Parse the TE header from the given bytes.
12231223 pub fn parse ( bytes : & [ u8 ] , offset : & mut usize ) -> error:: Result < Self > {
1224+ const HEADER_SIZE : usize = core:: mem:: size_of :: < TeHeader > ( ) ;
12241225 let mut header: TeHeader = bytes. gread_with ( offset, scroll:: LE ) ?;
1225- let adj_offset = header. stripped_size as u32 - core:: mem:: size_of :: < TeHeader > ( ) as u32 ;
1226+ let stripped_size = header. stripped_size as u32 ;
1227+ let adj_offset = stripped_size
1228+ . checked_sub ( HEADER_SIZE as u32 )
1229+ . ok_or_else ( || {
1230+ error:: Error :: Malformed ( format ! (
1231+ "Stripped size ({stripped_size:#x}) is smaller than TE header size ({HEADER_SIZE:#x})" ,
1232+ ) )
1233+ } ) ?;
12261234 header. fixup_header ( adj_offset) ;
12271235 Ok ( header)
12281236 }
@@ -1364,7 +1372,10 @@ pub fn machine_to_str(machine: u16) -> &'static str {
13641372
13651373#[ cfg( test) ]
13661374mod tests {
1367- use crate :: { error, pe:: header:: DosStub } ;
1375+ use crate :: {
1376+ error,
1377+ pe:: header:: { DosStub , TeHeader } ,
1378+ } ;
13681379
13691380 use super :: {
13701381 machine_to_str, DosHeader , Header , RichHeader , RichMetadata , COFF_MACHINE_X86 , DOS_MAGIC ,
@@ -1585,6 +1596,16 @@ mod tests {
15851596 0x00 ,
15861597 ] ;
15871598
1599+ /// Malformed very small TE with valid TE magic.
1600+ ///
1601+ /// https://github.com/m4b/goblin/issues/450
1602+ const MALFORMED_SMALL_TE : [ u8 ; 58 ] = [
1603+ 0x56 , 0x5A , 0x52 , 0x5A , 0x50 , 0x00 , 0x17 , 0x00 , 0x00 , 0x00 , 0x36 , 0x00 , 0x00 , 0x00 , 0x00 ,
1604+ 0x10 , 0x86 , 0x02 , 0x0C , 0x00 , 0x00 , 0x01 , 0x01 , 0x01 , 0x01 , 0x1B , 0x01 , 0x01 , 0x00 , 0x00 ,
1605+ 0xFF , 0xB5 , 0x00 , 0x00 , 0x00 , 0x04 , 0x34 , 0x00 , 0x00 , 0xFF , 0xB5 , 0x00 , 0x00 , 0x00 , 0x04 ,
1606+ 0x34 , 0x15 , 0x40 , 0x13 , 0x41 , 0x0E , 0x10 , 0x15 , 0x40 , 0x13 , 0x41 , 0x0E , 0x10 ,
1607+ ] ;
1608+
15881609 const WELL_FORMED_WITH_RICH_HEADER : & [ u8 ] =
15891610 include_bytes ! ( "../../tests/bins/pe/well_formed_import.exe.bin" ) ;
15901611
@@ -1713,6 +1734,20 @@ mod tests {
17131734 }
17141735
17151736 #[ test]
1737+ fn parse_malformed_small_te ( ) {
1738+ let mut offset = 0 ;
1739+ let header = TeHeader :: parse ( & MALFORMED_SMALL_TE , & mut offset) ;
1740+ assert_eq ! ( header. is_err( ) , true ) ;
1741+ if let Err ( error:: Error :: Malformed ( msg) ) = header {
1742+ assert_eq ! (
1743+ msg,
1744+ "Stripped size (0x17) is smaller than TE header size (0x28)"
1745+ ) ;
1746+ } else {
1747+ panic ! ( "Expected a Malformed error but got {:?}" , header) ;
1748+ }
1749+ }
1750+
17161751 fn parse_with_omitted_dos_stub ( ) {
17171752 let header = Header :: parse ( & HEADER_WITH_OMITTED_DOS_STUB ) . unwrap ( ) ;
17181753
0 commit comments