Browse code

RVA broken.executable checks skip checks on virtual-only sections

git-svn: trunk@2484

aCaB authored on 2006/11/05 10:35:40
Showing 2 changed files
... ...
@@ -1,7 +1,15 @@
1
+Sun Nov  5 02:25:39 CET 2006 (acab)
2
+-----------------------------------
3
+  * libclamav/pe.c:	RVA broken.executable checks
4
+  			skip checks on virtual-only sections (reported by
5
+			Andrey J. Melnikoff (TEMHOTA) <temnota * kmv.ru> )
6
+
1 7
 Sun Nov  5 00:45:44 CET 2006 (acab)
8
+-----------------------------------
2 9
   * libclamav/pe.c:	add broken.executable checks on alignments
3 10
 
4 11
 Sun Nov  5 00:20:02 CET 2006 (acab)
12
+-----------------------------------
5 13
   * libclamav/pe.c:     lseek fix for last commit
6 14
 
7 15
 Sat Nov  4 23:57:14 CET 2006 (acab)
... ...
@@ -619,46 +619,70 @@ int cli_scanpe(int desc, cli_ctx *ctx)
619 619
 
620 620
 	cli_dbgmsg("------------------------------------\n");
621 621
 
622
-	if(!CLI_ISCONTAINED2(0, (uint32_t) fsize, EC32(section_hdr[i].PointerToRawData), EC32(section_hdr[i].SizeOfRawData)) || EC32(section_hdr[i].PointerToRawData) > fsize) {
623
-	    cli_dbgmsg("Possibly broken PE file - Section %d out of file (Offset@ %d, Rsize %d, Total filesize %d)\n", i, EC32(section_hdr[i].PointerToRawData), EC32(section_hdr[i].SizeOfRawData), fsize);
624
-	    if(DETECT_BROKEN) {
625
-		if(ctx->virname)
626
-		    *ctx->virname = "Broken.Executable";
627
-		free(section_hdr);
628
-		return CL_VIRUS;
629
-	    }
630
-	    broken = 1;
622
+	if (DETECT_BROKEN && EC32(section_hdr[i].VirtualAddress)%((pe_plus)?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment))) { /* Bad virtual alignment */
623
+	    cli_dbgmsg("VirtualAddress is misaligned\n");
624
+	    if(ctx->virname)
625
+	        *ctx->virname = "Broken.Executable";
626
+	    free(section_hdr);
627
+	    return CL_VIRUS;
628
+	}
631 629
 
632
-	} else {
633
-	    /* check MD5 section sigs */
634
-	    md5_sect = ctx->engine->md5_sect;
635
-	    while(md5_sect && md5_sect->size < EC32(section_hdr[i].SizeOfRawData))
636
-		md5_sect = md5_sect->next;
637
-
638
-	    if(md5_sect && md5_sect->size == EC32(section_hdr[i].SizeOfRawData)) {
639
-		md5_dig = cli_md5sect(desc, EC32(section_hdr[i].PointerToRawData), EC32(section_hdr[i].SizeOfRawData));
640
-		if(!md5_dig) {
641
-		    cli_errmsg("PE: Can't calculate MD5 for section %d\n", i);
642
-		} else {
643
-		    while(md5_sect && md5_sect->size == EC32(section_hdr[i].SizeOfRawData)) {
644
-			if(!strcmp(md5_dig, md5_sect->md5)) {
645
-			    if(ctx->virname)
646
-				*ctx->virname = md5_sect->virname;
647
-			    free(md5_dig);
648
-			    free(section_hdr);
649
-			    return CL_VIRUS;
630
+	if (EC32(section_hdr[i].SizeOfRawData)) { /* Don't bother with virtual only sections */
631
+	    if(!CLI_ISCONTAINED2(0, (uint32_t) fsize, EC32(section_hdr[i].PointerToRawData), EC32(section_hdr[i].SizeOfRawData)) || EC32(section_hdr[i].PointerToRawData) > fsize) {
632
+	        cli_dbgmsg("Possibly broken PE file - Section %d out of file (Offset@ %d, Rsize %d, Total filesize %d)\n", i, EC32(section_hdr[i].PointerToRawData), EC32(section_hdr[i].SizeOfRawData), fsize);
633
+		  if(DETECT_BROKEN) {
634
+		      if(ctx->virname)
635
+			  *ctx->virname = "Broken.Executable";
636
+		      free(section_hdr);
637
+		      return CL_VIRUS;
638
+		  }
639
+		  broken = 1;
640
+
641
+	    } else {
642
+	        /* check MD5 section sigs */
643
+	        md5_sect = ctx->engine->md5_sect;
644
+		while(md5_sect && md5_sect->size < EC32(section_hdr[i].SizeOfRawData))
645
+		    md5_sect = md5_sect->next;
646
+
647
+		if(md5_sect && md5_sect->size == EC32(section_hdr[i].SizeOfRawData)) {
648
+		    md5_dig = cli_md5sect(desc, EC32(section_hdr[i].PointerToRawData), EC32(section_hdr[i].SizeOfRawData));
649
+		    if(!md5_dig) {
650
+		        cli_errmsg("PE: Can't calculate MD5 for section %d\n", i);
651
+		    } else {
652
+		        while(md5_sect && md5_sect->size == EC32(section_hdr[i].SizeOfRawData)) {
653
+			    if(!strcmp(md5_dig, md5_sect->md5)) {
654
+			        if(ctx->virname)
655
+				    *ctx->virname = md5_sect->virname;
656
+				free(md5_dig);
657
+				free(section_hdr);
658
+				return CL_VIRUS;
659
+			    }
660
+			    md5_sect = md5_sect->next;
650 661
 			}
651
-			md5_sect = md5_sect->next;
662
+			free(md5_dig);
652 663
 		    }
653
-		    free(md5_dig);
654 664
 		}
655 665
 	    }
656 666
 	}
657 667
 
658 668
 	if(!i) {
669
+	    if (DETECT_BROKEN && EC32(section_hdr[i].VirtualAddress)!=((pe_plus)?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment))) { /* Bad first section RVA */
670
+	        cli_dbgmsg("First section is in the wrong place\n");
671
+	        if(ctx->virname)
672
+		    *ctx->virname = md5_sect->virname;
673
+		free(section_hdr);
674
+		return CL_VIRUS;
675
+	    }
659 676
 	    min = EC32(section_hdr[i].VirtualAddress);
660 677
 	    max = EC32(section_hdr[i].VirtualAddress) + EC32(section_hdr[i].SizeOfRawData);
661 678
 	} else {
679
+	    if (DETECT_BROKEN && EC32(section_hdr[i].VirtualAddress)-EC32(section_hdr[i-1].VirtualAddress)!=PESALIGN(EC32(section_hdr[i-1].VirtualSize), ((pe_plus)?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment)))) { /* No holes, no overlapping, no virtual disorder */
680
+	        cli_dbgmsg("Virtually misplaced section (wrong order, overlapping, non contiguous)\n");
681
+	        if(ctx->virname)
682
+		    *ctx->virname = md5_sect->virname;
683
+		free(section_hdr);
684
+		return CL_VIRUS;
685
+	    }
662 686
 	    if(EC32(section_hdr[i].VirtualAddress) < min)
663 687
 		min = EC32(section_hdr[i].VirtualAddress);
664 688