@@ -1209,8 +1209,16 @@ pub const TE_MAGIC: u16 = 0x5a56;
12091209impl TeHeader {
12101210 /// Parse the TE header from the given bytes.
12111211 pub fn parse ( bytes : & [ u8 ] , offset : & mut usize ) -> error:: Result < Self > {
1212+ const HEADER_SIZE : usize = core:: mem:: size_of :: < TeHeader > ( ) ;
12121213 let mut header: TeHeader = bytes. gread_with ( offset, scroll:: LE ) ?;
1213- let adj_offset = header. stripped_size as u32 - core:: mem:: size_of :: < TeHeader > ( ) as u32 ;
1214+ let stripped_size = header. stripped_size as u32 ;
1215+ let adj_offset = stripped_size
1216+ . checked_sub ( HEADER_SIZE as u32 )
1217+ . ok_or_else ( || {
1218+ error:: Error :: Malformed ( format ! (
1219+ "Stripped size ({stripped_size:#x}) is smaller than TE header size ({HEADER_SIZE:#x})" ,
1220+ ) )
1221+ } ) ?;
12141222 header. fixup_header ( adj_offset) ;
12151223 Ok ( header)
12161224 }
@@ -1352,7 +1360,10 @@ pub fn machine_to_str(machine: u16) -> &'static str {
13521360
13531361#[ cfg( test) ]
13541362mod tests {
1355- use crate :: { error, pe:: header:: DosStub } ;
1363+ use crate :: {
1364+ error,
1365+ pe:: header:: { DosStub , TeHeader } ,
1366+ } ;
13561367
13571368 use super :: {
13581369 machine_to_str, Header , RichHeader , RichMetadata , COFF_MACHINE_X86 , DOS_MAGIC , PE_MAGIC ,
@@ -1534,6 +1545,16 @@ mod tests {
15341545 0x00 ,
15351546 ] ;
15361547
1548+ /// Malformed very small TE with valid TE magic.
1549+ ///
1550+ /// https://github.com/m4b/goblin/issues/450
1551+ const MALFORMED_SMALL_TE : [ u8 ; 58 ] = [
1552+ 0x56 , 0x5A , 0x52 , 0x5A , 0x50 , 0x00 , 0x17 , 0x00 , 0x00 , 0x00 , 0x36 , 0x00 , 0x00 , 0x00 , 0x00 ,
1553+ 0x10 , 0x86 , 0x02 , 0x0C , 0x00 , 0x00 , 0x01 , 0x01 , 0x01 , 0x01 , 0x1B , 0x01 , 0x01 , 0x00 , 0x00 ,
1554+ 0xFF , 0xB5 , 0x00 , 0x00 , 0x00 , 0x04 , 0x34 , 0x00 , 0x00 , 0xFF , 0xB5 , 0x00 , 0x00 , 0x00 , 0x04 ,
1555+ 0x34 , 0x15 , 0x40 , 0x13 , 0x41 , 0x0E , 0x10 , 0x15 , 0x40 , 0x13 , 0x41 , 0x0E , 0x10 ,
1556+ ] ;
1557+
15371558 #[ test]
15381559 fn crss_header ( ) {
15391560 let header = Header :: parse ( & & CRSS_HEADER [ ..] ) . unwrap ( ) ;
@@ -1656,4 +1677,19 @@ mod tests {
16561677 let header_result = RichHeader :: parse ( & CORRUPTED_RICH_HEADER ) ;
16571678 assert_eq ! ( header_result. is_err( ) , true ) ;
16581679 }
1680+
1681+ #[ test]
1682+ fn parse_malformed_small_te ( ) {
1683+ let mut offset = 0 ;
1684+ let header = TeHeader :: parse ( & MALFORMED_SMALL_TE , & mut offset) ;
1685+ assert_eq ! ( header. is_err( ) , true ) ;
1686+ if let Err ( error:: Error :: Malformed ( msg) ) = header {
1687+ assert_eq ! (
1688+ msg,
1689+ "Stripped size (0x17) is smaller than TE header size (0x28)"
1690+ ) ;
1691+ } else {
1692+ panic ! ( "Expected a Malformed error but got {:?}" , header) ;
1693+ }
1694+ }
16591695}
0 commit comments