@@ -1221,8 +1221,16 @@ pub const TE_MAGIC: u16 = 0x5a56;
1221
1221
impl TeHeader {
1222
1222
/// Parse the TE header from the given bytes.
1223
1223
pub fn parse ( bytes : & [ u8 ] , offset : & mut usize ) -> error:: Result < Self > {
1224
+ const HEADER_SIZE : usize = core:: mem:: size_of :: < TeHeader > ( ) ;
1224
1225
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
+ } ) ?;
1226
1234
header. fixup_header ( adj_offset) ;
1227
1235
Ok ( header)
1228
1236
}
@@ -1364,7 +1372,10 @@ pub fn machine_to_str(machine: u16) -> &'static str {
1364
1372
1365
1373
#[ cfg( test) ]
1366
1374
mod tests {
1367
- use crate :: { error, pe:: header:: DosStub } ;
1375
+ use crate :: {
1376
+ error,
1377
+ pe:: header:: { DosStub , TeHeader } ,
1378
+ } ;
1368
1379
1369
1380
use super :: {
1370
1381
machine_to_str, DosHeader , Header , RichHeader , RichMetadata , COFF_MACHINE_X86 , DOS_MAGIC ,
@@ -1585,6 +1596,16 @@ mod tests {
1585
1596
0x00 ,
1586
1597
] ;
1587
1598
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
+
1588
1609
const WELL_FORMED_WITH_RICH_HEADER : & [ u8 ] =
1589
1610
include_bytes ! ( "../../tests/bins/pe/well_formed_import.exe.bin" ) ;
1590
1611
@@ -1713,6 +1734,20 @@ mod tests {
1713
1734
}
1714
1735
1715
1736
#[ 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
+
1716
1751
fn parse_with_omitted_dos_stub ( ) {
1717
1752
let header = Header :: parse ( & HEADER_WITH_OMITTED_DOS_STUB ) . unwrap ( ) ;
1718
1753
0 commit comments