git-svn: trunk@2484
aCaB authored on 2006/11/05 10:35:40... | ... |
@@ -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 |
|