@@ -737,14 +737,14 @@ int cli_scanpe(cli_ctx *ctx)
737737 char sname [9 ], epbuff [4096 ], * tempfile ;
738738 uint32_t epsize ;
739739 ssize_t bytes , at ;
740- unsigned int i , found , upx_success = 0 , min = 0 , max = 0 , err , overlays = 0 ;
740+ unsigned int i , j , found , upx_success = 0 , min = 0 , max = 0 , err , overlays = 0 , rescan = 1 ;
741741 unsigned int ssize = 0 , dsize = 0 , dll = 0 , pe_plus = 0 , corrupted_cur ;
742742 int (* upxfn )(const char * , uint32_t , char * , uint32_t * , uint32_t , uint32_t , uint32_t ) = NULL ;
743743 const char * src = NULL ;
744744 char * dest = NULL ;
745745 int ndesc , ret = CL_CLEAN , upack = 0 , native = 0 ;
746746 size_t fsize ;
747- uint32_t valign , falign , hdr_size , j ;
747+ uint32_t valign , falign , hdr_size ;
748748 struct cli_exe_section * exe_sections ;
749749 char timestr [32 ];
750750 struct pe_image_data_dir * dirs ;
@@ -1238,18 +1238,52 @@ int cli_scanpe(cli_ctx *ctx)
12381238 cli_jsonint (pe_json , "NumberOfSections" , nsections );
12391239#endif
12401240
1241+ while (rescan == 1 ) {
1242+ rescan = 0 ;
1243+ for (i = 0 ; i < nsections ; i ++ ) {
1244+ exe_sections [i ].rva = PEALIGN (EC32 (section_hdr [i ].VirtualAddress ), valign );
1245+ exe_sections [i ].vsz = PESALIGN (EC32 (section_hdr [i ].VirtualSize ), valign );
1246+ exe_sections [i ].raw = PEALIGN (EC32 (section_hdr [i ].PointerToRawData ), falign );
1247+ exe_sections [i ].rsz = PESALIGN (EC32 (section_hdr [i ].SizeOfRawData ), falign );
1248+ exe_sections [i ].chr = EC32 (section_hdr [i ].Characteristics );
1249+ exe_sections [i ].urva = EC32 (section_hdr [i ].VirtualAddress ); /* Just in case */
1250+ exe_sections [i ].uvsz = EC32 (section_hdr [i ].VirtualSize );
1251+ exe_sections [i ].uraw = EC32 (section_hdr [i ].PointerToRawData );
1252+ exe_sections [i ].ursz = EC32 (section_hdr [i ].SizeOfRawData );
1253+
1254+ if (exe_sections [i ].rsz ) { /* Don't bother with virtual only sections */
1255+ if (!CLI_ISCONTAINED (0 , fsize , exe_sections [i ].uraw , exe_sections [i ].ursz )
1256+ || exe_sections [i ].raw >= fsize ) {
1257+ cli_dbgmsg ("Broken PE file - Section %d starts or exists beyond the end of file (Offset@ %lu, Total filesize %lu)\n" , i , (unsigned long )exe_sections [i ].raw , (unsigned long )fsize );
1258+ if (nsections == 1 ) {
1259+ free (section_hdr );
1260+ free (exe_sections );
1261+
1262+ if (DETECT_BROKEN_PE ) {
1263+ cli_append_virus (ctx , "Heuristics.Broken.Executable" );
1264+ return CL_VIRUS ;
1265+ }
1266+
1267+ return CL_CLEAN ; /* no ninjas to see here! move along! */
1268+ }
1269+
1270+ for (j = i ; j < nsections - 1 ; j ++ )
1271+ memcpy (& exe_sections [j ], & exe_sections [j + 1 ], sizeof (struct cli_exe_section ));
1272+
1273+ for (j = i ; j < nsections - 1 ; j ++ )
1274+ memcpy (& section_hdr [j ], & section_hdr [j + 1 ], sizeof (struct pe_image_section_hdr ));
1275+
1276+ nsections -- ;
1277+ rescan = 1 ;
1278+ break ;
1279+ }
1280+ }
1281+ }
1282+ }
1283+
12411284 for (i = 0 ; i < nsections ; i ++ ) {
1242- strncpy (sname , (char * ) section_hdr [i ].Name , 8 );
1243- sname [8 ] = 0 ;
1244- exe_sections [i ].rva = PEALIGN (EC32 (section_hdr [i ].VirtualAddress ), valign );
1245- exe_sections [i ].vsz = PESALIGN (EC32 (section_hdr [i ].VirtualSize ), valign );
1246- exe_sections [i ].raw = PEALIGN (EC32 (section_hdr [i ].PointerToRawData ), falign );
1247- exe_sections [i ].rsz = PESALIGN (EC32 (section_hdr [i ].SizeOfRawData ), falign );
1248- exe_sections [i ].chr = EC32 (section_hdr [i ].Characteristics );
1249- exe_sections [i ].urva = EC32 (section_hdr [i ].VirtualAddress ); /* Just in case */
1250- exe_sections [i ].uvsz = EC32 (section_hdr [i ].VirtualSize );
1251- exe_sections [i ].uraw = EC32 (section_hdr [i ].PointerToRawData );
1252- exe_sections [i ].ursz = EC32 (section_hdr [i ].SizeOfRawData );
1285+ strncpy (sname , (char * ) section_hdr [i ].Name , 8 );
1286+ sname [8 ] = 0 ;
12531287
12541288#if HAVE_JSON
12551289 add_section_info (ctx , & exe_sections [i ]);
@@ -1304,18 +1338,6 @@ int cli_scanpe(cli_ctx *ctx)
13041338 }
13051339
13061340 if (exe_sections [i ].rsz ) { /* Don't bother with virtual only sections */
1307- if (exe_sections [i ].raw >= fsize ) { /* really broken */
1308- cli_dbgmsg ("Broken PE file - Section %d starts beyond the end of file (Offset@ %lu, Total filesize %lu)\n" , i , (unsigned long )exe_sections [i ].raw , (unsigned long )fsize );
1309- cli_dbgmsg ("------------------------------------\n" );
1310- free (section_hdr );
1311- free (exe_sections );
1312- if (DETECT_BROKEN_PE ) {
1313- cli_append_virus (ctx , "Heuristics.Broken.Executable" );
1314- return CL_VIRUS ;
1315- }
1316- return CL_CLEAN ; /* no ninjas to see here! move along! */
1317- }
1318-
13191341 if (SCAN_ALGO && (DCONF & PE_CONF_POLIPOS ) && !* sname && exe_sections [i ].vsz > 40000 && exe_sections [i ].vsz < 70000 && exe_sections [i ].chr == 0xe0000060 ) polipos = i ;
13201342
13211343 /* check hash section sigs */
0 commit comments