git-svn: trunk@2967
aCaB authored on 2007/03/24 11:47:35... | ... |
@@ -1,4 +1,9 @@ |
1 |
-Fri Mar 23 21:35:24 CET 2007 (tk) |
|
1 |
+Sat Mar 24 01:51:30 CET 2007 (acab) |
|
2 |
+----------------------------------- |
|
3 |
+ * libclamav: - merge the first set of pe cleanup changes |
|
4 |
+ - fix bb#397 |
|
5 |
+ |
|
6 |
+ Fri Mar 23 21:35:24 CET 2007 (tk) |
|
2 | 7 |
--------------------------------- |
3 | 8 |
* shared/cfgparser.c: multiple Clamuko*Path were not being handled properly |
4 | 9 |
(bb#420) |
... | ... |
@@ -26,10 +26,13 @@ |
26 | 26 |
struct cli_exe_section { |
27 | 27 |
uint32_t rva; |
28 | 28 |
uint32_t vsz; |
29 |
- uint32_t uvsz; /* unaligned vsz */ |
|
30 | 29 |
uint32_t raw; |
31 | 30 |
uint32_t rsz; |
32 |
- uint32_t ursz; |
|
31 |
+ uint32_t chr; |
|
32 |
+ uint32_t urva; /* PE - unaligned VirtualAddress */ |
|
33 |
+ uint32_t uvsz; /* PE - unaligned VirtualSize */ |
|
34 |
+ uint32_t uraw; /* PE - unaligned PointerToRawData */ |
|
35 |
+ uint32_t ursz; /* PE - unaligned SizeOfRawData */ |
|
33 | 36 |
}; |
34 | 37 |
|
35 | 38 |
struct cli_exe_info { |
... | ... |
@@ -84,12 +84,12 @@ struct offset_list { |
84 | 84 |
struct offset_list *next; |
85 | 85 |
}; |
86 | 86 |
|
87 |
-static uint32_t cli_rawaddr(uint32_t rva, struct cli_exe_section *shp, uint16_t nos, unsigned int *err, size_t fsize) |
|
87 |
+static uint32_t cli_rawaddr(uint32_t rva, struct cli_exe_section *shp, uint16_t nos, unsigned int *err, size_t fsize, uint32_t hdr_size) |
|
88 | 88 |
{ |
89 | 89 |
int i, found = 0; |
90 | 90 |
uint32_t ret; |
91 | 91 |
|
92 |
- if (rva<0x1000) { /* Out of section EP - mapped to imagebase+rva */ |
|
92 |
+ if (rva<hdr_size) { /* Out of section EP - mapped to imagebase+rva */ |
|
93 | 93 |
if (rva >= fsize) { |
94 | 94 |
*err=1; |
95 | 95 |
return 0; |
... | ... |
@@ -252,9 +252,9 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
252 | 252 |
unsigned int ssize = 0, dsize = 0, dll = 0, pe_plus = 0; |
253 | 253 |
int (*upxfn)(char *, uint32_t, char *, uint32_t *, uint32_t, uint32_t, uint32_t) = NULL; |
254 | 254 |
char *src = NULL, *dest = NULL; |
255 |
- int ndesc, ret = CL_CLEAN, upack = 0; |
|
255 |
+ int ndesc, ret = CL_CLEAN, upack = 0, native=0; |
|
256 | 256 |
size_t fsize; |
257 |
- uint32_t valign, falign; |
|
257 |
+ uint32_t valign, falign, hdr_size; |
|
258 | 258 |
struct cli_exe_section *exe_sections; |
259 | 259 |
|
260 | 260 |
|
... | ... |
@@ -500,7 +500,7 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
500 | 500 |
cli_dbgmsg("MajorSubsystemVersion: %d\n", EC16(optional_hdr32.MajorSubsystemVersion)); |
501 | 501 |
cli_dbgmsg("MinorSubsystemVersion: %d\n", EC16(optional_hdr32.MinorSubsystemVersion)); |
502 | 502 |
cli_dbgmsg("SizeOfImage: 0x%x\n", EC32(optional_hdr32.SizeOfImage)); |
503 |
- cli_dbgmsg("SizeOfHeaders: 0x%x\n", EC32(optional_hdr32.SizeOfHeaders)); |
|
503 |
+ cli_dbgmsg("SizeOfHeaders: 0x%x\n", (hdr_size = EC32(optional_hdr32.SizeOfHeaders))); |
|
504 | 504 |
cli_dbgmsg("NumberOfRvaAndSizes: %d\n", EC32(optional_hdr32.NumberOfRvaAndSizes)); |
505 | 505 |
|
506 | 506 |
} else { /* PE+ */ |
... | ... |
@@ -530,23 +530,10 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
530 | 530 |
cli_dbgmsg("MajorSubsystemVersion: %d\n", EC16(optional_hdr64.MajorSubsystemVersion)); |
531 | 531 |
cli_dbgmsg("MinorSubsystemVersion: %d\n", EC16(optional_hdr64.MinorSubsystemVersion)); |
532 | 532 |
cli_dbgmsg("SizeOfImage: 0x%x\n", EC32(optional_hdr64.SizeOfImage)); |
533 |
- cli_dbgmsg("SizeOfHeaders: 0x%x\n", EC32(optional_hdr64.SizeOfHeaders)); |
|
533 |
+ cli_dbgmsg("SizeOfHeaders: 0x%x\n", (hdr_size = EC32(optional_hdr32.SizeOfHeaders))); |
|
534 | 534 |
cli_dbgmsg("NumberOfRvaAndSizes: %d\n", EC32(optional_hdr64.NumberOfRvaAndSizes)); |
535 | 535 |
} |
536 | 536 |
|
537 |
- if (DETECT_BROKEN && (pe_plus?EC16(optional_hdr64.Subsystem):EC16(optional_hdr32.Subsystem))!= 1 && (!(pe_plus?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment)) || (pe_plus?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment))%0x1000)) { |
|
538 |
- cli_dbgmsg("Bad virtual alignemnt\n"); |
|
539 |
- if(ctx->virname) |
|
540 |
- *ctx->virname = "Broken.Executable"; |
|
541 |
- return CL_VIRUS; |
|
542 |
- } |
|
543 |
- |
|
544 |
- if (DETECT_BROKEN && (pe_plus?EC16(optional_hdr64.Subsystem):EC16(optional_hdr32.Subsystem))!= 1 && (!(pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment)) || (pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment))%0x200)) { |
|
545 |
- cli_dbgmsg("Bad file alignemnt\n"); |
|
546 |
- if(ctx->virname) |
|
547 |
- *ctx->virname = "Broken.Executable"; |
|
548 |
- return CL_VIRUS; |
|
549 |
- } |
|
550 | 537 |
|
551 | 538 |
switch(pe_plus ? EC16(optional_hdr64.Subsystem) : EC16(optional_hdr32.Subsystem)) { |
552 | 539 |
case 0: |
... | ... |
@@ -554,6 +541,7 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
554 | 554 |
break; |
555 | 555 |
case 1: |
556 | 556 |
cli_dbgmsg("Subsystem: Native (svc)\n"); |
557 |
+ native = 1; |
|
557 | 558 |
break; |
558 | 559 |
case 2: |
559 | 560 |
cli_dbgmsg("Subsystem: Win32 GUI\n"); |
... | ... |
@@ -588,6 +576,20 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
588 | 588 |
|
589 | 589 |
cli_dbgmsg("------------------------------------\n"); |
590 | 590 |
|
591 |
+ if (DETECT_BROKEN && !native && (!(pe_plus?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment)) || (pe_plus?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment))%0x1000)) { |
|
592 |
+ cli_dbgmsg("Bad virtual alignemnt\n"); |
|
593 |
+ if(ctx->virname) |
|
594 |
+ *ctx->virname = "Broken.Executable"; |
|
595 |
+ return CL_VIRUS; |
|
596 |
+ } |
|
597 |
+ |
|
598 |
+ if (DETECT_BROKEN && !native && (!(pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment)) || (pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment))%0x200)) { |
|
599 |
+ cli_dbgmsg("Bad file alignemnt\n"); |
|
600 |
+ if(ctx->virname) |
|
601 |
+ *ctx->virname = "Broken.Executable"; |
|
602 |
+ return CL_VIRUS; |
|
603 |
+ } |
|
604 |
+ |
|
591 | 605 |
if(fstat(desc, &sb) == -1) { |
592 | 606 |
cli_dbgmsg("fstat failed\n"); |
593 | 607 |
return CL_EIO; |
... | ... |
@@ -634,18 +636,23 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
634 | 634 |
} |
635 | 635 |
} |
636 | 636 |
|
637 |
+ hdr_size = PESALIGN(hdr_size, valign); /* Aligned headers virtual size */ |
|
638 |
+ |
|
637 | 639 |
for(i = 0; i < nsections; i++) { |
638 | 640 |
strncpy(sname, (char *) section_hdr[i].Name, 8); |
639 | 641 |
sname[8] = 0; |
640 | 642 |
exe_sections[i].rva = PEALIGN(EC32(section_hdr[i].VirtualAddress), valign); |
641 | 643 |
exe_sections[i].vsz = PESALIGN(EC32(section_hdr[i].VirtualSize), valign); |
642 |
- exe_sections[i].uvsz = EC32(section_hdr[i].VirtualSize); |
|
643 | 644 |
exe_sections[i].raw = PEALIGN(EC32(section_hdr[i].PointerToRawData), falign); |
644 | 645 |
exe_sections[i].rsz = PESALIGN(EC32(section_hdr[i].SizeOfRawData), falign); |
646 |
+ exe_sections[i].chr = EC32(section_hdr[i].Characteristics); |
|
647 |
+ exe_sections[i].urva = EC32(section_hdr[i].VirtualAddress); /* Just in case */ |
|
648 |
+ exe_sections[i].uvsz = EC32(section_hdr[i].VirtualSize); |
|
649 |
+ exe_sections[i].uraw = EC32(section_hdr[i].PointerToRawData); |
|
645 | 650 |
exe_sections[i].ursz = EC32(section_hdr[i].SizeOfRawData); |
646 | 651 |
|
647 | 652 |
if (!exe_sections[i].vsz && exe_sections[i].rsz) |
648 |
- exe_sections[i].vsz=PESALIGN(EC32(section_hdr[i].SizeOfRawData), valign); |
|
653 |
+ exe_sections[i].vsz=PESALIGN(exe_sections[i].ursz, valign); |
|
649 | 654 |
|
650 | 655 |
if (exe_sections[i].rsz && fsize>exe_sections[i].raw && !CLI_ISCONTAINED(0, (uint32_t) fsize, exe_sections[i].raw, exe_sections[i].rsz)) |
651 | 656 |
exe_sections[i].rsz = fsize - exe_sections[i].raw; |
... | ... |
@@ -653,12 +660,12 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
653 | 653 |
cli_dbgmsg("Section %d\n", i); |
654 | 654 |
cli_dbgmsg("Section name: %s\n", sname); |
655 | 655 |
cli_dbgmsg("Section data (from headers - in memory)\n"); |
656 |
- cli_dbgmsg("VirtualSize: 0x%x 0x%x\n", EC32(section_hdr[i].VirtualSize), exe_sections[i].vsz); |
|
657 |
- cli_dbgmsg("VirtualAddress: 0x%x 0x%x\n", EC32(section_hdr[i].VirtualAddress), exe_sections[i].rva); |
|
658 |
- cli_dbgmsg("SizeOfRawData: 0x%x 0x%x\n", EC32(section_hdr[i].SizeOfRawData), exe_sections[i].rsz); |
|
659 |
- cli_dbgmsg("PointerToRawData: 0x%x 0x%x\n", EC32(section_hdr[i].PointerToRawData), exe_sections[i].raw); |
|
656 |
+ cli_dbgmsg("VirtualSize: 0x%x 0x%x\n", exe_sections[i].uvsz, exe_sections[i].vsz); |
|
657 |
+ cli_dbgmsg("VirtualAddress: 0x%x 0x%x\n", exe_sections[i].urva, exe_sections[i].rva); |
|
658 |
+ cli_dbgmsg("SizeOfRawData: 0x%x 0x%x\n", exe_sections[i].ursz, exe_sections[i].rsz); |
|
659 |
+ cli_dbgmsg("PointerToRawData: 0x%x 0x%x\n", exe_sections[i].uraw, exe_sections[i].raw); |
|
660 | 660 |
|
661 |
- if(EC32(section_hdr[i].Characteristics) & 0x20) { |
|
661 |
+ if(exe_sections[i].chr & 0x20) { |
|
662 | 662 |
cli_dbgmsg("Section contains executable code\n"); |
663 | 663 |
|
664 | 664 |
if(exe_sections[i].vsz < exe_sections[i].rsz) { |
... | ... |
@@ -671,15 +678,15 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
671 | 671 |
} |
672 | 672 |
} |
673 | 673 |
|
674 |
- if(EC32(section_hdr[i].Characteristics) & 0x20000000) |
|
674 |
+ if(exe_sections[i].chr & 0x20000000) |
|
675 | 675 |
cli_dbgmsg("Section's memory is executable\n"); |
676 | 676 |
|
677 |
- if(EC32(section_hdr[i].Characteristics) & 0x80000000) |
|
677 |
+ if(exe_sections[i].chr & 0x80000000) |
|
678 | 678 |
cli_dbgmsg("Section's memory is writeable\n"); |
679 | 679 |
|
680 | 680 |
cli_dbgmsg("------------------------------------\n"); |
681 | 681 |
|
682 |
- if (DETECT_BROKEN && EC32(section_hdr[i].VirtualAddress)%valign) { /* Bad virtual alignment */ |
|
682 |
+ if (DETECT_BROKEN && (exe_sections[i].urva % valign)) { /* Bad virtual alignment */ |
|
683 | 683 |
cli_dbgmsg("VirtualAddress is misaligned\n"); |
684 | 684 |
if(ctx->virname) |
685 | 685 |
*ctx->virname = "Broken.Executable"; |
... | ... |
@@ -730,7 +737,7 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
730 | 730 |
} |
731 | 731 |
|
732 | 732 |
if(!i) { |
733 |
- if (DETECT_BROKEN && (pe_plus?EC16(optional_hdr64.Subsystem):EC16(optional_hdr32.Subsystem))!= 1 && EC32(section_hdr[i].VirtualAddress)!=valign) { /* Bad first section RVA */ |
|
733 |
+ if (DETECT_BROKEN && exe_sections[i].urva!=hdr_size) { /* Bad first section RVA */ |
|
734 | 734 |
cli_dbgmsg("First section is in the wrong place\n"); |
735 | 735 |
if(ctx->virname) |
736 | 736 |
*ctx->virname = "Broken.Executable"; |
... | ... |
@@ -741,7 +748,7 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
741 | 741 |
min = exe_sections[i].rva; |
742 | 742 |
max = exe_sections[i].rva + exe_sections[i].rsz; |
743 | 743 |
} else { |
744 |
- if (DETECT_BROKEN && EC32(section_hdr[i].VirtualAddress)-EC32(section_hdr[i-1].VirtualAddress)!= exe_sections[i-1].vsz) { /* No holes, no overlapping, no virtual disorder */ |
|
744 |
+ if (DETECT_BROKEN && exe_sections[i].urva - exe_sections[i-1].urva != exe_sections[i-1].vsz) { /* No holes, no overlapping, no virtual disorder */ |
|
745 | 745 |
cli_dbgmsg("Virtually misplaced section (wrong order, overlapping, non contiguous)\n"); |
746 | 746 |
if(ctx->virname) |
747 | 747 |
*ctx->virname = "Broken.Executable"; |
... | ... |
@@ -758,7 +765,7 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
758 | 758 |
|
759 | 759 |
if(SCAN_ALGO && (DCONF & PE_CONF_POLIPOS) && !strlen(sname)) { |
760 | 760 |
if(exe_sections[i].vsz > 40000 && exe_sections[i].vsz < 70000) { |
761 |
- if(EC32(section_hdr[i].Characteristics) == 0xe0000060) { |
|
761 |
+ if(exe_sections[i].chr == 0xe0000060) { |
|
762 | 762 |
polipos = i; |
763 | 763 |
} |
764 | 764 |
} |
... | ... |
@@ -766,9 +773,10 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
766 | 766 |
|
767 | 767 |
} |
768 | 768 |
|
769 |
- if(!(ep = cli_rawaddr(vep, exe_sections, nsections, &err, fsize)) && err) { |
|
769 |
+ free(section_hdr); |
|
770 |
+ |
|
771 |
+ if(!(ep = cli_rawaddr(vep, exe_sections, nsections, &err, fsize, hdr_size)) && err) { |
|
770 | 772 |
cli_dbgmsg("EntryPoint out of file\n"); |
771 |
- free(section_hdr); |
|
772 | 773 |
free(exe_sections); |
773 | 774 |
if(DETECT_BROKEN) { |
774 | 775 |
if(ctx->virname) |
... | ... |
@@ -781,11 +789,11 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
781 | 781 |
cli_dbgmsg("EntryPoint offset: 0x%x (%d)\n", ep, ep); |
782 | 782 |
|
783 | 783 |
if(pe_plus) { /* Do not continue for PE32+ files */ |
784 |
- free(section_hdr); |
|
785 | 784 |
free(exe_sections); |
786 | 785 |
return CL_CLEAN; |
787 | 786 |
} |
788 | 787 |
|
788 |
+ |
|
789 | 789 |
/* Attempt to detect some popular polymorphic viruses */ |
790 | 790 |
|
791 | 791 |
/* W32.Parite.B */ |
... | ... |
@@ -799,7 +807,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
799 | 799 |
pt += 15; |
800 | 800 |
if(((dw1 = cli_readint32(pt)) ^ (dw2 = cli_readint32(pt + 4))) == 0x505a4f && ((dw1 = cli_readint32(pt + 8)) ^ (dw2 = cli_readint32(pt + 12))) == 0xffffb && ((dw1 = cli_readint32(pt + 16)) ^ (dw2 = cli_readint32(pt + 20))) == 0xb8) { |
801 | 801 |
*ctx->virname = "W32.Parite.B"; |
802 |
- free(section_hdr); |
|
803 | 802 |
free(exe_sections); |
804 | 803 |
return CL_VIRUS; |
805 | 804 |
} |
... | ... |
@@ -862,7 +869,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
862 | 862 |
break; |
863 | 863 |
} |
864 | 864 |
*ctx->virname = "Win32.Kriz"; |
865 |
- free(section_hdr); |
|
866 | 865 |
free(exe_sections); |
867 | 866 |
return CL_VIRUS; |
868 | 867 |
} |
... | ... |
@@ -870,7 +876,7 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
870 | 870 |
} |
871 | 871 |
|
872 | 872 |
/* W32.Magistr.A/B */ |
873 |
- if(SCAN_ALGO && (DCONF & PE_CONF_MAGISTR) && !dll && (EC32(section_hdr[nsections - 1].Characteristics) & 0x80000000)) { |
|
873 |
+ if(SCAN_ALGO && (DCONF & PE_CONF_MAGISTR) && !dll && (nsections>1) && (exe_sections[nsections - 1].chr & 0x80000000)) { |
|
874 | 874 |
uint32_t rsize, vsize, dam = 0; |
875 | 875 |
|
876 | 876 |
vsize = exe_sections[nsections - 1].uvsz; |
... | ... |
@@ -887,7 +893,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
887 | 887 |
if(cli_readn(desc, buff, 4096) == 4096) { |
888 | 888 |
if(cli_memstr(buff, 4091, "\xe8\x2c\x61\x00\x00", 5)) { |
889 | 889 |
*ctx->virname = dam ? "W32.Magistr.A.dam" : "W32.Magistr.A"; |
890 |
- free(section_hdr); |
|
891 | 890 |
free(exe_sections); |
892 | 891 |
return CL_VIRUS; |
893 | 892 |
} |
... | ... |
@@ -900,7 +905,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
900 | 900 |
if(cli_readn(desc, buff, 4096) == 4096) { |
901 | 901 |
if(cli_memstr(buff, 4091, "\xe8\x04\x72\x00\x00", 5)) { |
902 | 902 |
*ctx->virname = dam ? "W32.Magistr.B.dam" : "W32.Magistr.B"; |
903 |
- free(section_hdr); |
|
904 | 903 |
free(exe_sections); |
905 | 904 |
return CL_VIRUS; |
906 | 905 |
} |
... | ... |
@@ -933,12 +937,11 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
933 | 933 |
} |
934 | 934 |
val = cli_readint32(jpt + 1); |
935 | 935 |
val += 5 + exe_sections[0].rva + total + shift; |
936 |
- raddr = cli_rawaddr(val, exe_sections, nsections, &err, fsize); |
|
936 |
+ raddr = cli_rawaddr(val, exe_sections, nsections, &err, fsize, hdr_size); |
|
937 | 937 |
|
938 | 938 |
if(!err && (raddr >= exe_sections[polipos].raw && raddr < exe_sections[polipos].raw + exe_sections[polipos].rsz) && (!offlist || (raddr != offlist->offset))) { |
939 | 939 |
offnode = (struct offset_list *) cli_malloc(sizeof(struct offset_list)); |
940 | 940 |
if(!offnode) { |
941 |
- free(section_hdr); |
|
942 | 941 |
free(exe_sections); |
943 | 942 |
while(offlist) { |
944 | 943 |
offnode = offlist; |
... | ... |
@@ -995,7 +998,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
995 | 995 |
} |
996 | 996 |
|
997 | 997 |
if(ret == CL_VIRUS) { |
998 |
- free(section_hdr); |
|
999 | 998 |
free(exe_sections); |
1000 | 999 |
return CL_VIRUS; |
1001 | 1000 |
} |
... | ... |
@@ -1011,7 +1013,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1011 | 1011 |
|
1012 | 1012 |
if(lseek(desc, ep-4, SEEK_SET) == -1) { |
1013 | 1013 |
cli_dbgmsg("SUE: lseek() failed\n"); |
1014 |
- free(section_hdr); |
|
1015 | 1014 |
free(exe_sections); |
1016 | 1015 |
return CL_EIO; |
1017 | 1016 |
} |
... | ... |
@@ -1030,7 +1031,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1030 | 1030 |
(sue=sudecrypt(desc, fsize, exe_sections, nsections-1, sue, key, cli_readint32(buff), e_lfanew))) { |
1031 | 1031 |
if(!(tempfile = cli_gentemp(NULL))) { |
1032 | 1032 |
free(sue); |
1033 |
- free(section_hdr); |
|
1034 | 1033 |
free(exe_sections); |
1035 | 1034 |
return CL_EMEM; |
1036 | 1035 |
} |
... | ... |
@@ -1039,7 +1039,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1039 | 1039 |
cli_dbgmsg("sue: Can't create file %s\n", tempfile); |
1040 | 1040 |
free(tempfile); |
1041 | 1041 |
free(sue); |
1042 |
- free(section_hdr); |
|
1043 | 1042 |
free(exe_sections); |
1044 | 1043 |
return CL_EIO; |
1045 | 1044 |
} |
... | ... |
@@ -1049,7 +1048,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1049 | 1049 |
close(ndesc); |
1050 | 1050 |
free(tempfile); |
1051 | 1051 |
free(sue); |
1052 |
- free(section_hdr); |
|
1053 | 1052 |
free(exe_sections); |
1054 | 1053 |
return CL_EIO; |
1055 | 1054 |
} |
... | ... |
@@ -1063,7 +1061,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1063 | 1063 |
lseek(ndesc, 0, SEEK_SET); |
1064 | 1064 |
|
1065 | 1065 |
if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) { |
1066 |
- free(section_hdr); |
|
1067 | 1066 |
free(exe_sections); |
1068 | 1067 |
close(ndesc); |
1069 | 1068 |
if(!cli_leavetemps_flag) |
... | ... |
@@ -1086,7 +1083,7 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1086 | 1086 |
found = 0; |
1087 | 1087 |
if(DCONF & (PE_CONF_UPX | PE_CONF_FSG | PE_CONF_MEW)) { |
1088 | 1088 |
for(i = 0; i < (unsigned int) nsections - 1; i++) { |
1089 |
- if(!section_hdr[i].SizeOfRawData && section_hdr[i].VirtualSize && section_hdr[i + 1].SizeOfRawData && section_hdr[i + 1].VirtualSize) { |
|
1089 |
+ if(!exe_sections[i].rsz && exe_sections[i].vsz && exe_sections[i + 1].rsz && exe_sections[i + 1].vsz) { |
|
1090 | 1090 |
found = 1; |
1091 | 1091 |
cli_dbgmsg("UPX/FSG/MEW: empty section found - assuming compression\n"); |
1092 | 1092 |
break; |
... | ... |
@@ -1100,7 +1097,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1100 | 1100 |
/* Check EP for MEW */ |
1101 | 1101 |
if(lseek(desc, ep, SEEK_SET) == -1) { |
1102 | 1102 |
cli_dbgmsg("MEW: lseek() failed\n"); |
1103 |
- free(section_hdr); |
|
1104 | 1103 |
free(exe_sections); |
1105 | 1104 |
return CL_EIO; |
1106 | 1105 |
} |
... | ... |
@@ -1108,7 +1104,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1108 | 1108 |
if((bytes = read(desc, buff, 25)) != 25 && bytes < 16) { |
1109 | 1109 |
cli_dbgmsg("MEW: Can't read at least 16 bytes at 0x%x (%d) %d\n", ep, ep, bytes); |
1110 | 1110 |
cli_dbgmsg("MEW: Broken or not compressed file\n"); |
1111 |
- free(section_hdr); |
|
1112 | 1111 |
free(exe_sections); |
1113 | 1112 |
return CL_CLEAN; |
1114 | 1113 |
} |
... | ... |
@@ -1124,7 +1119,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1124 | 1124 |
|
1125 | 1125 |
if(lseek(desc, fileoffset, SEEK_SET) == -1) { |
1126 | 1126 |
cli_dbgmsg("MEW: lseek() failed\n"); |
1127 |
- free(section_hdr); |
|
1128 | 1127 |
free(exe_sections); |
1129 | 1128 |
return CL_EIO; |
1130 | 1129 |
} |
... | ... |
@@ -1149,7 +1143,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1149 | 1149 |
|
1150 | 1150 |
if(lseek(desc, exe_sections[i + 1].raw, SEEK_SET) == -1) { |
1151 | 1151 |
cli_dbgmsg("MEW: lseek() failed\n"); /* ACAB: lseek won't fail here but checking doesn't hurt even */ |
1152 |
- free(section_hdr); |
|
1153 | 1152 |
free(exe_sections); |
1154 | 1153 |
return CL_EIO; |
1155 | 1154 |
} |
... | ... |
@@ -1159,7 +1152,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1159 | 1159 |
cli_dbgmsg("MEW: ssize %08x dsize %08x offdiff: %08x\n", ssize, dsize, offdiff); |
1160 | 1160 |
if(ctx->limits && ctx->limits->maxfilesize && (ssize + dsize > ctx->limits->maxfilesize || exe_sections[i + 1].rsz > ctx->limits->maxfilesize)) { |
1161 | 1161 |
cli_dbgmsg("MEW: Sizes exceeded (ssize: %u, dsize: %u, max: %lu)\n", ssize, dsize , ctx->limits->maxfilesize); |
1162 |
- free(section_hdr); |
|
1163 | 1162 |
free(exe_sections); |
1164 | 1163 |
if(BLOCKMAX) { |
1165 | 1164 |
*ctx->virname = "PE.MEW.ExceededFileSize"; |
... | ... |
@@ -1171,7 +1163,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1171 | 1171 |
|
1172 | 1172 |
/* allocate needed buffer */ |
1173 | 1173 |
if (!(src = cli_calloc (ssize + dsize, sizeof(char)))) { |
1174 |
- free(section_hdr); |
|
1175 | 1174 |
free(exe_sections); |
1176 | 1175 |
return CL_EMEM; |
1177 | 1176 |
} |
... | ... |
@@ -1185,7 +1176,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1185 | 1185 |
|
1186 | 1186 |
if((bytes = read(desc, src + dsize, exe_sections[i + 1].rsz)) != exe_sections[i + 1].rsz) { |
1187 | 1187 |
cli_dbgmsg("MEW: Can't read %d bytes [readed: %d]\n", exe_sections[i + 1].rsz, bytes); |
1188 |
- free(section_hdr); |
|
1189 | 1188 |
free(exe_sections); |
1190 | 1189 |
free(src); |
1191 | 1190 |
return CL_EIO; |
... | ... |
@@ -1205,7 +1195,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1205 | 1205 |
uselzma = 0; |
1206 | 1206 |
|
1207 | 1207 |
if(!(tempfile = cli_gentemp(NULL))) { |
1208 |
- free(section_hdr); |
|
1209 | 1208 |
free(exe_sections); |
1210 | 1209 |
free(src); |
1211 | 1210 |
return CL_EMEM; |
... | ... |
@@ -1213,7 +1202,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1213 | 1213 |
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) { |
1214 | 1214 |
cli_dbgmsg("MEW: Can't create file %s\n", tempfile); |
1215 | 1215 |
free(tempfile); |
1216 |
- free(section_hdr); |
|
1217 | 1216 |
free(exe_sections); |
1218 | 1217 |
free(src); |
1219 | 1218 |
return CL_EIO; |
... | ... |
@@ -1228,7 +1216,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1228 | 1228 |
|
1229 | 1229 |
cli_dbgmsg("***** Scanning rebuilt PE file *****\n"); |
1230 | 1230 |
if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) { |
1231 |
- free(section_hdr); |
|
1232 | 1231 |
free(exe_sections); |
1233 | 1232 |
close(ndesc); |
1234 | 1233 |
if(!cli_leavetemps_flag) |
... | ... |
@@ -1240,7 +1227,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1240 | 1240 |
if(!cli_leavetemps_flag) |
1241 | 1241 |
unlink(tempfile); |
1242 | 1242 |
free(tempfile); |
1243 |
- free(section_hdr); |
|
1244 | 1243 |
free(exe_sections); |
1245 | 1244 |
return CL_CLEAN; |
1246 | 1245 |
default: /* Everything gone wrong */ |
... | ... |
@@ -1259,7 +1245,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1259 | 1259 |
/* Check EP for UPX vs. FSG vs. Upack */ |
1260 | 1260 |
if(lseek(desc, ep, SEEK_SET) == -1) { |
1261 | 1261 |
cli_dbgmsg("UPX/FSG: lseek() failed\n"); |
1262 |
- free(section_hdr); |
|
1263 | 1262 |
free(exe_sections); |
1264 | 1263 |
return CL_EIO; |
1265 | 1264 |
} |
... | ... |
@@ -1267,7 +1252,6 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1267 | 1267 |
if(cli_readn(desc, buff, 168) != 168) { |
1268 | 1268 |
cli_dbgmsg("UPX/FSG: Can't read 168 bytes at 0x%x (%d)\n", ep, ep); |
1269 | 1269 |
cli_dbgmsg("UPX/FSG: Broken or not UPX/FSG compressed file\n"); |
1270 |
- free(section_hdr); |
|
1271 | 1270 |
free(exe_sections); |
1272 | 1271 |
return CL_CLEAN; |
1273 | 1272 |
} |
... | ... |
@@ -1292,46 +1276,54 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1292 | 1292 |
* |
1293 | 1293 |
*/ |
1294 | 1294 |
/* upack 0.39-3s + sample 0151477*/ |
1295 |
- if((upack && buff[0] == '\xbe' && cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) > min && /* mov esi */ |
|
1296 |
- buff[5] == '\xad' && buff[6] == '\x50' && /* lodsd; push eax */ |
|
1297 |
- EC16(file_hdr.NumberOfSections) == 3) || /* 3 sections */ |
|
1298 |
- /* based on 0297729 sample from aCaB */ |
|
1299 |
- (upack && buff[0] == '\xbe' && cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) > min && /* mov esi */ |
|
1300 |
- buff[5] == '\xff' && buff[6] == '\x36' && /* push [esi] */ |
|
1301 |
- EC16(file_hdr.NumberOfSections) == 3) || |
|
1302 |
- /* upack 0.39-2s */ |
|
1303 |
- (!upack && buff[0] == '\x60' && buff[1] == '\xe8' && cli_readint32(buff+2) == 0x9 && /* pusha; call+9 */ |
|
1304 |
- EC16(file_hdr.NumberOfSections) == 2) || /* 2 sections */ |
|
1305 |
- /* upack 1.1/1.2, based on 2 samples */ |
|
1306 |
- (!upack && buff[0] == '\xbe' && cli_readint32(buff+1) - EC32(optional_hdr32.ImageBase) < min && /* mov esi */ |
|
1307 |
- cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) > 0 && |
|
1308 |
- buff[5] == '\xad' && buff[6] == '\x8b' && buff[7] == '\xf8' && /* loads; mov edi, eax */ |
|
1309 |
- EC16(file_hdr.NumberOfSections) == 2)) { /* 2 sections */ |
|
1295 |
+ if(((upack && nsections == 3) && /* 3 sections */ |
|
1296 |
+ ( |
|
1297 |
+ buff[0] == '\xbe' && cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) > min && /* mov esi */ |
|
1298 |
+ buff[5] == '\xad' && buff[6] == '\x50' /* lodsd; push eax */ |
|
1299 |
+ ) |
|
1300 |
+ || |
|
1301 |
+ /* based on 0297729 sample from aCaB */ |
|
1302 |
+ (buff[0] == '\xbe' && cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) > min && /* mov esi */ |
|
1303 |
+ buff[5] == '\xff' && buff[6] == '\x36' /* push [esi] */ |
|
1304 |
+ ) |
|
1305 |
+ ) |
|
1306 |
+ || |
|
1307 |
+ ((!upack && nsections == 2) && /* 2 sections */ |
|
1308 |
+ ( /* upack 0.39-2s */ |
|
1309 |
+ buff[0] == '\x60' && buff[1] == '\xe8' && cli_readint32(buff+2) == 0x9 /* pusha; call+9 */ |
|
1310 |
+ ) |
|
1311 |
+ || |
|
1312 |
+ ( /* upack 1.1/1.2, based on 2 samples */ |
|
1313 |
+ buff[0] == '\xbe' && cli_readint32(buff+1) - EC32(optional_hdr32.ImageBase) < min && /* mov esi */ |
|
1314 |
+ cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) > 0 && |
|
1315 |
+ buff[5] == '\xad' && buff[6] == '\x8b' && buff[7] == '\xf8' /* loads; mov edi, eax */ |
|
1316 |
+ ) |
|
1317 |
+ ) |
|
1318 |
+ ){ |
|
1310 | 1319 |
uint32_t vma, off; |
1311 |
- int a,b,c, file; |
|
1320 |
+ int a,b,c; |
|
1312 | 1321 |
|
1313 | 1322 |
cli_dbgmsg("Upack characteristics found.\n"); |
1314 |
- a = EC32(section_hdr[0].VirtualSize); |
|
1315 |
- b = EC32(section_hdr[1].VirtualSize); |
|
1323 |
+ a = exe_sections[0].vsz; |
|
1324 |
+ b = exe_sections[1].vsz; |
|
1316 | 1325 |
if (upack) { |
1317 |
- cli_dbgmsg("upack var set\n"); |
|
1318 |
- c = EC32(section_hdr[2].VirtualSize); |
|
1319 |
- ssize = EC32(section_hdr[0].SizeOfRawData) + EC32(section_hdr[0].PointerToRawData); |
|
1320 |
- off = EC32(section_hdr[0].VirtualAddress); |
|
1321 |
- vma = EC32(optional_hdr32.ImageBase) + EC32(section_hdr[0].VirtualAddress); |
|
1326 |
+ cli_dbgmsg("Upack: var set\n"); |
|
1327 |
+ c = exe_sections[2].vsz; |
|
1328 |
+ ssize = exe_sections[0].ursz + exe_sections[0].uraw; |
|
1329 |
+ off = exe_sections[0].rva; |
|
1330 |
+ vma = EC32(optional_hdr32.ImageBase) + exe_sections[0].rva; |
|
1322 | 1331 |
} else { |
1323 |
- cli_dbgmsg("upack var NOT set\n"); |
|
1324 |
- c = EC32(section_hdr[1].VirtualAddress); |
|
1325 |
- ssize = EC32(section_hdr[1].PointerToRawData); |
|
1332 |
+ cli_dbgmsg("Upack: var NOT set\n"); |
|
1333 |
+ c = exe_sections[1].rva; |
|
1334 |
+ ssize = exe_sections[1].uraw; |
|
1326 | 1335 |
off = 0; |
1327 |
- vma = EC32(section_hdr[1].VirtualAddress) - EC32(section_hdr[1].PointerToRawData); |
|
1336 |
+ vma = exe_sections[1].rva - exe_sections[1].uraw; |
|
1328 | 1337 |
} |
1329 | 1338 |
|
1330 | 1339 |
dsize = a+b+c; |
1331 |
- if (ctx->limits && ctx->limits->maxfilesize && (dsize > ctx->limits->maxfilesize || ssize > ctx->limits->maxfilesize || EC32(section_hdr[1].SizeOfRawData) > ctx->limits->maxfilesize)) |
|
1340 |
+ if (ctx->limits && ctx->limits->maxfilesize && (dsize > ctx->limits->maxfilesize || ssize > ctx->limits->maxfilesize || exe_sections[1].ursz > ctx->limits->maxfilesize)) |
|
1332 | 1341 |
{ |
1333 | 1342 |
cli_dbgmsg("Upack: Sizes exceeded (a: %u, b: %u, c: %ux, max: %lu)\n", a, b, c, ctx->limits->maxfilesize); |
1334 |
- free(section_hdr); |
|
1335 | 1343 |
free(exe_sections); |
1336 | 1344 |
if(BLOCKMAX) { |
1337 | 1345 |
*ctx->virname = "PE.Upack.ExceededFileSize"; |
... | ... |
@@ -1341,90 +1333,80 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
1341 | 1341 |
} |
1342 | 1342 |
} |
1343 | 1343 |
/* these are unsigned so if vaddr - off < 0, it should be ok */ |
1344 |
- if (EC32(section_hdr[1].VirtualAddress) - off > dsize || EC32(section_hdr[1].VirtualAddress) - off > dsize - EC32(section_hdr[1].SizeOfRawData) || (upack && (EC32(section_hdr[2].VirtualAddress) - EC32(section_hdr[0].VirtualAddress) > dsize || EC32(section_hdr[2].VirtualAddress) - EC32(section_hdr[0].VirtualAddress) > dsize - ssize)) || ssize > dsize) |
|
1344 |
+ if (exe_sections[1].rva - off > dsize || exe_sections[1].rva - off > dsize - exe_sections[1].ursz || (upack && (exe_sections[2].rva - exe_sections[0].rva > dsize || exe_sections[2].rva - exe_sections[0].rva > dsize - ssize)) || ssize > dsize) |
|
1345 | 1345 |
{ |
1346 | 1346 |
cli_dbgmsg("Upack: probably malformed pe-header, skipping to next unpacker\n"); |
1347 |
- goto skip_upack_and_go_to_next_unpacker; /* I didn't want to add additional do while + break, can it be this way ? */ |
|
1347 |
+ goto skip_upack_and_go_to_next_unpacker; |
|
1348 | 1348 |
} |
1349 | 1349 |
|
1350 | 1350 |
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) { |
1351 |
- free(section_hdr); |
|
1352 | 1351 |
free(exe_sections); |
1353 | 1352 |
return CL_EMEM; |
1354 | 1353 |
} |
1355 | 1354 |
src = NULL; |
1356 |
- cli_dbgmsg("Upack: min: %08x %08x max: %08x\n", dest, a+b+c, dest+a+b+c); |
|
1357 | 1355 |
|
1358 | 1356 |
lseek(desc, 0, SEEK_SET); |
1359 |
- if(read(desc, dest, ssize) != ssize) { /* 2vGiM: i think this can be overflowed - should you check for ssize < dsize ? |
|
1360 |
- * yup, I think you're right, added above |
|
1361 |
- */ |
|
1357 |
+ if(read(desc, dest, ssize) != ssize) { |
|
1362 | 1358 |
cli_dbgmsg("Upack: Can't read raw data of section 0\n"); |
1363 |
- free(section_hdr); |
|
1364 | 1359 |
free(exe_sections); |
1365 | 1360 |
free(dest); |
1366 | 1361 |
return CL_EIO; |
1367 | 1362 |
} |
1368 | 1363 |
|
1369 | 1364 |
if (upack) |
1370 |
- memmove(dest + EC32(section_hdr[2].VirtualAddress) - EC32(section_hdr[0].VirtualAddress), dest, ssize); |
|
1365 |
+ memmove(dest + exe_sections[2].rva - exe_sections[0].rva, dest, ssize); |
|
1371 | 1366 |
|
1372 |
- lseek(desc, EC32(section_hdr[1].PointerToRawData), SEEK_SET); |
|
1367 |
+ lseek(desc, exe_sections[1].uraw, SEEK_SET); |
|
1373 | 1368 |
|
1374 |
- if(read(desc, dest+EC32(section_hdr[1].VirtualAddress) - off, EC32(section_hdr[1].SizeOfRawData)) != EC32(section_hdr[1].SizeOfRawData)) { |
|
1369 |
+ if(read(desc, dest + exe_sections[1].rva - off, exe_sections[1].ursz) != exe_sections[1].ursz) { |
|
1375 | 1370 |
cli_dbgmsg("Upack: Can't read raw data of section 1\n"); |
1376 |
- free(section_hdr); |
|
1377 | 1371 |
free(exe_sections); |
1378 | 1372 |
free(dest); |
1379 | 1373 |
return CL_EIO; |
1380 | 1374 |
} |
1381 | 1375 |
|
1382 | 1376 |
if(!(tempfile = cli_gentemp(NULL))) { |
1383 |
- free(section_hdr); |
|
1384 | 1377 |
free(exe_sections); |
1385 | 1378 |
free(dest); |
1386 | 1379 |
return CL_EMEM; |
1387 | 1380 |
} |
1388 | 1381 |
|
1389 |
- if((file = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) { |
|
1382 |
+ if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) { |
|
1390 | 1383 |
cli_dbgmsg("Upack: Can't create file %s\n", tempfile); |
1391 | 1384 |
free(tempfile); |
1392 |
- free(section_hdr); |
|
1393 | 1385 |
free(exe_sections); |
1394 | 1386 |
free(dest); |
1395 | 1387 |
return CL_EIO; |
1396 | 1388 |
} |
1397 | 1389 |
|
1398 |
- switch (unupack(upack, dest, dsize, buff, vma, ep, EC32(optional_hdr32.ImageBase), EC32(section_hdr[0].VirtualAddress), file)) |
|
1390 |
+ switch (unupack(upack, dest, dsize, buff, vma, ep, EC32(optional_hdr32.ImageBase), exe_sections[0].rva, ndesc)) |
|
1399 | 1391 |
{ |
1400 | 1392 |
case 1: /* Everything OK */ |
1401 | 1393 |
cli_dbgmsg("Upack: Unpacked and rebuilt executable saved in %s\n", tempfile); |
1402 | 1394 |
free(dest); |
1403 |
- fsync(file); |
|
1404 |
- lseek(file, 0, SEEK_SET); |
|
1395 |
+ fsync(ndesc); |
|
1396 |
+ lseek(ndesc, 0, SEEK_SET); |
|
1405 | 1397 |
|
1406 | 1398 |
cli_dbgmsg("***** Scanning rebuilt PE file *****\n"); |
1407 |
- if(cli_magic_scandesc(file, ctx) == CL_VIRUS) { |
|
1408 |
- free(section_hdr); |
|
1399 |
+ if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) { |
|
1409 | 1400 |
free(exe_sections); |
1410 |
- close(file); |
|
1401 |
+ close(ndesc); |
|
1411 | 1402 |
if(!cli_leavetemps_flag) |
1412 | 1403 |
unlink(tempfile); |
1413 | 1404 |
free(tempfile); |
1414 | 1405 |
return CL_VIRUS; |
1415 | 1406 |
} |
1416 | 1407 |
|
1417 |
- close(file); |
|
1408 |
+ close(ndesc); |
|
1418 | 1409 |
if(!cli_leavetemps_flag) |
1419 | 1410 |
unlink(tempfile); |
1420 | 1411 |
free(tempfile); |
1421 |
- free(section_hdr); |
|
1422 | 1412 |
free(exe_sections); |
1423 | 1413 |
return CL_CLEAN; |
1424 | 1414 |
|
1425 | 1415 |
default: /* Everything gone wrong */ |
1426 | 1416 |
cli_dbgmsg("Upack: Unpacking failed\n"); |
1427 |
- close(file); |
|
1417 |
+ close(ndesc); |
|
1428 | 1418 |
unlink(tempfile); /* It's empty anyway */ |
1429 | 1419 |
free(tempfile); |
1430 | 1420 |
free(dest); |
... | ... |
@@ -1445,7 +1427,6 @@ skip_upack_and_go_to_next_unpacker: |
1445 | 1445 |
|
1446 | 1446 |
if(ctx->limits && ctx->limits->maxfilesize && (ssize > ctx->limits->maxfilesize || dsize > ctx->limits->maxfilesize)) { |
1447 | 1447 |
cli_dbgmsg("FSG: Sizes exceeded (ssize: %u, dsize: %u, max: %lu)\n", ssize, dsize , ctx->limits->maxfilesize); |
1448 |
- free(section_hdr); |
|
1449 | 1448 |
free(exe_sections); |
1450 | 1449 |
if(BLOCKMAX) { |
1451 | 1450 |
*ctx->virname = "PE.FSG.ExceededFileSize"; |
... | ... |
@@ -1457,7 +1438,6 @@ skip_upack_and_go_to_next_unpacker: |
1457 | 1457 |
|
1458 | 1458 |
if(ssize <= 0x19 || dsize <= ssize) { |
1459 | 1459 |
cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize); |
1460 |
- free(section_hdr); |
|
1461 | 1460 |
free(exe_sections); |
1462 | 1461 |
return CL_CLEAN; |
1463 | 1462 |
} |
... | ... |
@@ -1469,7 +1449,6 @@ skip_upack_and_go_to_next_unpacker: |
1469 | 1469 |
} |
1470 | 1470 |
|
1471 | 1471 |
if((src = (char *) cli_malloc(ssize)) == NULL) { |
1472 |
- free(section_hdr); |
|
1473 | 1472 |
free(exe_sections); |
1474 | 1473 |
return CL_EMEM; |
1475 | 1474 |
} |
... | ... |
@@ -1477,7 +1456,6 @@ skip_upack_and_go_to_next_unpacker: |
1477 | 1477 |
lseek(desc, exe_sections[i + 1].raw, SEEK_SET); |
1478 | 1478 |
if((unsigned int) cli_readn(desc, src, ssize) != ssize) { |
1479 | 1479 |
cli_dbgmsg("Can't read raw data of section %d\n", i + 1); |
1480 |
- free(section_hdr); |
|
1481 | 1480 |
free(exe_sections); |
1482 | 1481 |
free(src); |
1483 | 1482 |
return CL_EIO; |
... | ... |
@@ -1531,14 +1509,12 @@ skip_upack_and_go_to_next_unpacker: |
1531 | 1531 |
cli_dbgmsg("FSG: found old EP @%x\n",newedx); |
1532 | 1532 |
|
1533 | 1533 |
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) { |
1534 |
- free(section_hdr); |
|
1535 | 1534 |
free(exe_sections); |
1536 | 1535 |
free(src); |
1537 | 1536 |
return CL_EMEM; |
1538 | 1537 |
} |
1539 | 1538 |
|
1540 | 1539 |
if(!(tempfile = cli_gentemp(NULL))) { |
1541 |
- free(section_hdr); |
|
1542 | 1540 |
free(exe_sections); |
1543 | 1541 |
free(src); |
1544 | 1542 |
free(dest); |
... | ... |
@@ -1548,7 +1524,6 @@ skip_upack_and_go_to_next_unpacker: |
1548 | 1548 |
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) { |
1549 | 1549 |
cli_dbgmsg("FSG: Can't create file %s\n", tempfile); |
1550 | 1550 |
free(tempfile); |
1551 |
- free(section_hdr); |
|
1552 | 1551 |
free(exe_sections); |
1553 | 1552 |
free(src); |
1554 | 1553 |
free(dest); |
... | ... |
@@ -1565,7 +1540,6 @@ skip_upack_and_go_to_next_unpacker: |
1565 | 1565 |
|
1566 | 1566 |
cli_dbgmsg("***** Scanning rebuilt PE file *****\n"); |
1567 | 1567 |
if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) { |
1568 |
- free(section_hdr); |
|
1569 | 1568 |
free(exe_sections); |
1570 | 1569 |
close(ndesc); |
1571 | 1570 |
if(!cli_leavetemps_flag) |
... | ... |
@@ -1578,7 +1552,6 @@ skip_upack_and_go_to_next_unpacker: |
1578 | 1578 |
if(!cli_leavetemps_flag) |
1579 | 1579 |
unlink(tempfile); |
1580 | 1580 |
free(tempfile); |
1581 |
- free(section_hdr); |
|
1582 | 1581 |
free(exe_sections); |
1583 | 1582 |
return CL_CLEAN; |
1584 | 1583 |
|
... | ... |
@@ -1621,7 +1594,6 @@ skip_upack_and_go_to_next_unpacker: |
1621 | 1621 |
|
1622 | 1622 |
if(ctx->limits && ctx->limits->maxfilesize && (ssize > ctx->limits->maxfilesize || dsize > ctx->limits->maxfilesize)) { |
1623 | 1623 |
cli_dbgmsg("FSG: Sizes exceeded (ssize: %u, dsize: %u, max: %lu)\n", ssize, dsize, ctx->limits->maxfilesize); |
1624 |
- free(section_hdr); |
|
1625 | 1624 |
free(exe_sections); |
1626 | 1625 |
if(BLOCKMAX) { |
1627 | 1626 |
*ctx->virname = "PE.FSG.ExceededFileSize"; |
... | ... |
@@ -1633,12 +1605,11 @@ skip_upack_and_go_to_next_unpacker: |
1633 | 1633 |
|
1634 | 1634 |
if(ssize <= 0x19 || dsize <= ssize) { |
1635 | 1635 |
cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize); |
1636 |
- free(section_hdr); |
|
1637 | 1636 |
free(exe_sections); |
1638 | 1637 |
return CL_CLEAN; |
1639 | 1638 |
} |
1640 | 1639 |
|
1641 |
- if(!(gp = cli_rawaddr(cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize)) && err ) { |
|
1640 |
+ if(!(gp = cli_rawaddr(cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size)) && err ) { |
|
1642 | 1641 |
cli_dbgmsg("FSG: Support data out of padding area\n"); |
1643 | 1642 |
break; |
1644 | 1643 |
} |
... | ... |
@@ -1648,7 +1619,6 @@ skip_upack_and_go_to_next_unpacker: |
1648 | 1648 |
|
1649 | 1649 |
if(ctx->limits && ctx->limits->maxfilesize && (unsigned int) gp > ctx->limits->maxfilesize) { |
1650 | 1650 |
cli_dbgmsg("FSG: Buffer size exceeded (size: %d, max: %lu)\n", gp, ctx->limits->maxfilesize); |
1651 |
- free(section_hdr); |
|
1652 | 1651 |
free(exe_sections); |
1653 | 1652 |
if(BLOCKMAX) { |
1654 | 1653 |
*ctx->virname = "PE.FSG.ExceededFileSize"; |
... | ... |
@@ -1659,14 +1629,12 @@ skip_upack_and_go_to_next_unpacker: |
1659 | 1659 |
} |
1660 | 1660 |
|
1661 | 1661 |
if((support = (char *) cli_malloc(gp)) == NULL) { |
1662 |
- free(section_hdr); |
|
1663 | 1662 |
free(exe_sections); |
1664 | 1663 |
return CL_EMEM; |
1665 | 1664 |
} |
1666 | 1665 |
|
1667 | 1666 |
if((int)cli_readn(desc, support, gp) != (int)gp) { |
1668 | 1667 |
cli_dbgmsg("Can't read %d bytes from padding area\n", gp); |
1669 |
- free(section_hdr); |
|
1670 | 1668 |
free(exe_sections); |
1671 | 1669 |
free(support); |
1672 | 1670 |
return CL_EIO; |
... | ... |
@@ -1714,7 +1682,6 @@ skip_upack_and_go_to_next_unpacker: |
1714 | 1714 |
} |
1715 | 1715 |
|
1716 | 1716 |
if((sections = (struct cli_exe_section *) cli_malloc((sectcnt + 1) * sizeof(struct cli_exe_section))) == NULL) { |
1717 |
- free(section_hdr); |
|
1718 | 1717 |
free(exe_sections); |
1719 | 1718 |
free(support); |
1720 | 1719 |
return CL_EMEM; |
... | ... |
@@ -1727,7 +1694,6 @@ skip_upack_and_go_to_next_unpacker: |
1727 | 1727 |
free(support); |
1728 | 1728 |
|
1729 | 1729 |
if((src = (char *) cli_malloc(ssize)) == NULL) { |
1730 |
- free(section_hdr); |
|
1731 | 1730 |
free(exe_sections); |
1732 | 1731 |
free(sections); |
1733 | 1732 |
return CL_EMEM; |
... | ... |
@@ -1736,7 +1702,6 @@ skip_upack_and_go_to_next_unpacker: |
1736 | 1736 |
lseek(desc, exe_sections[i + 1].raw, SEEK_SET); |
1737 | 1737 |
if((unsigned int) cli_readn(desc, src, ssize) != ssize) { |
1738 | 1738 |
cli_dbgmsg("Can't read raw data of section %d\n", i); |
1739 |
- free(section_hdr); |
|
1740 | 1739 |
free(exe_sections); |
1741 | 1740 |
free(sections); |
1742 | 1741 |
free(src); |
... | ... |
@@ -1744,7 +1709,6 @@ skip_upack_and_go_to_next_unpacker: |
1744 | 1744 |
} |
1745 | 1745 |
|
1746 | 1746 |
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) { |
1747 |
- free(section_hdr); |
|
1748 | 1747 |
free(exe_sections); |
1749 | 1748 |
free(src); |
1750 | 1749 |
free(sections); |
... | ... |
@@ -1755,7 +1719,6 @@ skip_upack_and_go_to_next_unpacker: |
1755 | 1755 |
cli_dbgmsg("FSG: found old EP @%x\n", oldep); |
1756 | 1756 |
|
1757 | 1757 |
if(!(tempfile = cli_gentemp(NULL))) { |
1758 |
- free(section_hdr); |
|
1759 | 1758 |
free(exe_sections); |
1760 | 1759 |
free(src); |
1761 | 1760 |
free(dest); |
... | ... |
@@ -1766,7 +1729,6 @@ skip_upack_and_go_to_next_unpacker: |
1766 | 1766 |
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) { |
1767 | 1767 |
cli_dbgmsg("FSG: Can't create file %s\n", tempfile); |
1768 | 1768 |
free(tempfile); |
1769 |
- free(section_hdr); |
|
1770 | 1769 |
free(exe_sections); |
1771 | 1770 |
free(src); |
1772 | 1771 |
free(dest); |
... | ... |
@@ -1785,7 +1747,6 @@ skip_upack_and_go_to_next_unpacker: |
1785 | 1785 |
|
1786 | 1786 |
cli_dbgmsg("***** Scanning rebuilt PE file *****\n"); |
1787 | 1787 |
if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) { |
1788 |
- free(section_hdr); |
|
1789 | 1788 |
free(exe_sections); |
1790 | 1789 |
close(ndesc); |
1791 | 1790 |
if(!cli_leavetemps_flag) |
... | ... |
@@ -1798,7 +1759,6 @@ skip_upack_and_go_to_next_unpacker: |
1798 | 1798 |
if(!cli_leavetemps_flag) |
1799 | 1799 |
unlink(tempfile); |
1800 | 1800 |
free(tempfile); |
1801 |
- free(section_hdr); |
|
1802 | 1801 |
free(exe_sections); |
1803 | 1802 |
return CL_CLEAN; |
1804 | 1803 |
|
... | ... |
@@ -1838,7 +1798,7 @@ skip_upack_and_go_to_next_unpacker: |
1838 | 1838 |
while(found) { |
1839 | 1839 |
int sectcnt = 0; |
1840 | 1840 |
uint32_t t; |
1841 |
- uint32_t gp = cli_rawaddr(cli_readint32(buff+1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize); |
|
1841 |
+ uint32_t gp = cli_rawaddr(cli_readint32(buff+1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size); |
|
1842 | 1842 |
char *support; |
1843 | 1843 |
uint32_t newesi = cli_readint32(buff+11) - EC32(optional_hdr32.ImageBase); |
1844 | 1844 |
uint32_t newedi = cli_readint32(buff+6) - EC32(optional_hdr32.ImageBase); |
... | ... |
@@ -1862,7 +1822,6 @@ skip_upack_and_go_to_next_unpacker: |
1862 | 1862 |
|
1863 | 1863 |
if(ctx->limits && ctx->limits->maxfilesize && (ssize > ctx->limits->maxfilesize || dsize > ctx->limits->maxfilesize)) { |
1864 | 1864 |
cli_dbgmsg("FSG: Sizes exceeded (ssize: %u, dsize: %u, max: %lu)\n", ssize, dsize, ctx->limits->maxfilesize); |
1865 |
- free(section_hdr); |
|
1866 | 1865 |
free(exe_sections); |
1867 | 1866 |
if(BLOCKMAX) { |
1868 | 1867 |
*ctx->virname = "PE.FSG.ExceededFileSize"; |
... | ... |
@@ -1874,7 +1833,6 @@ skip_upack_and_go_to_next_unpacker: |
1874 | 1874 |
|
1875 | 1875 |
if(ssize <= 0x19 || dsize <= ssize) { |
1876 | 1876 |
cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize); |
1877 |
- free(section_hdr); |
|
1878 | 1877 |
free(exe_sections); |
1879 | 1878 |
return CL_CLEAN; |
1880 | 1879 |
} |
... | ... |
@@ -1884,7 +1842,6 @@ skip_upack_and_go_to_next_unpacker: |
1884 | 1884 |
|
1885 | 1885 |
if(ctx->limits && ctx->limits->maxfilesize && gp > ctx->limits->maxfilesize) { |
1886 | 1886 |
cli_dbgmsg("FSG: Buffer size exceeded (size: %d, max: %lu)\n", gp, ctx->limits->maxfilesize); |
1887 |
- free(section_hdr); |
|
1888 | 1887 |
free(exe_sections); |
1889 | 1888 |
if(BLOCKMAX) { |
1890 | 1889 |
*ctx->virname = "PE.FSG.ExceededFileSize"; |
... | ... |
@@ -1895,14 +1852,12 @@ skip_upack_and_go_to_next_unpacker: |
1895 | 1895 |
} |
1896 | 1896 |
|
1897 | 1897 |
if((support = (char *) cli_malloc(gp)) == NULL) { |
1898 |
- free(section_hdr); |
|
1899 | 1898 |
free(exe_sections); |
1900 | 1899 |
return CL_EMEM; |
1901 | 1900 |
} |
1902 | 1901 |
|
1903 | 1902 |
if(cli_readn(desc, support, gp) != (int)gp) { |
1904 | 1903 |
cli_dbgmsg("Can't read %d bytes from padding area\n", gp); |
1905 |
- free(section_hdr); |
|
1906 | 1904 |
free(exe_sections); |
1907 | 1905 |
free(support); |
1908 | 1906 |
return CL_EIO; |
... | ... |
@@ -1930,7 +1885,6 @@ skip_upack_and_go_to_next_unpacker: |
1930 | 1930 |
} |
1931 | 1931 |
|
1932 | 1932 |
if((sections = (struct cli_exe_section *) cli_malloc((sectcnt + 1) * sizeof(struct cli_exe_section))) == NULL) { |
1933 |
- free(section_hdr); |
|
1934 | 1933 |
free(exe_sections); |
1935 | 1934 |
free(support); |
1936 | 1935 |
return CL_EMEM; |
... | ... |
@@ -1944,7 +1898,6 @@ skip_upack_and_go_to_next_unpacker: |
1944 | 1944 |
free(support); |
1945 | 1945 |
|
1946 | 1946 |
if((src = (char *) cli_malloc(ssize)) == NULL) { |
1947 |
- free(section_hdr); |
|
1948 | 1947 |
free(exe_sections); |
1949 | 1948 |
free(sections); |
1950 | 1949 |
return CL_EMEM; |
... | ... |
@@ -1953,7 +1906,6 @@ skip_upack_and_go_to_next_unpacker: |
1953 | 1953 |
lseek(desc, exe_sections[i + 1].raw, SEEK_SET); |
1954 | 1954 |
if((unsigned int) cli_readn(desc, src, ssize) != ssize) { |
1955 | 1955 |
cli_dbgmsg("FSG: Can't read raw data of section %d\n", i); |
1956 |
- free(section_hdr); |
|
1957 | 1956 |
free(exe_sections); |
1958 | 1957 |
free(sections); |
1959 | 1958 |
free(src); |
... | ... |
@@ -1961,7 +1913,6 @@ skip_upack_and_go_to_next_unpacker: |
1961 | 1961 |
} |
1962 | 1962 |
|
1963 | 1963 |
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) { |
1964 |
- free(section_hdr); |
|
1965 | 1964 |
free(exe_sections); |
1966 | 1965 |
free(src); |
1967 | 1966 |
free(sections); |
... | ... |
@@ -1974,7 +1925,6 @@ skip_upack_and_go_to_next_unpacker: |
1974 | 1974 |
cli_dbgmsg("FSG: found old EP @%x\n", oldep); |
1975 | 1975 |
|
1976 | 1976 |
if(!(tempfile = cli_gentemp(NULL))) { |
1977 |
- free(section_hdr); |
|
1978 | 1977 |
free(exe_sections); |
1979 | 1978 |
free(src); |
1980 | 1979 |
free(dest); |
... | ... |
@@ -1985,7 +1935,6 @@ skip_upack_and_go_to_next_unpacker: |
1985 | 1985 |
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) { |
1986 | 1986 |
cli_dbgmsg("FSG: Can't create file %s\n", tempfile); |
1987 | 1987 |
free(tempfile); |
1988 |
- free(section_hdr); |
|
1989 | 1988 |
free(exe_sections); |
1990 | 1989 |
free(src); |
1991 | 1990 |
free(dest); |
... | ... |
@@ -1993,7 +1942,7 @@ skip_upack_and_go_to_next_unpacker: |
1993 | 1993 |
return CL_EIO; |
1994 | 1994 |
} |
1995 | 1995 |
|
1996 |
- switch(unfsg_133(src + newesi - EC32(section_hdr[i + 1].VirtualAddress), dest, ssize + EC32(section_hdr[i + 1].VirtualAddress) - newesi, dsize, sections, sectcnt, EC32(optional_hdr32.ImageBase), oldep, ndesc)) { |
|
1996 |
+ switch(unfsg_133(src + newesi - exe_sections[i + 1].rva, dest, ssize + exe_sections[i + 1].rva - newesi, dsize, sections, sectcnt, EC32(optional_hdr32.ImageBase), oldep, ndesc)) { |
|
1997 | 1997 |
case 1: /* Everything OK */ |
1998 | 1998 |
cli_dbgmsg("FSG: Unpacked and rebuilt executable saved in %s\n", tempfile); |
1999 | 1999 |
free(src); |
... | ... |
@@ -2004,7 +1953,6 @@ skip_upack_and_go_to_next_unpacker: |
2004 | 2004 |
|
2005 | 2005 |
cli_dbgmsg("***** Scanning rebuilt PE file *****\n"); |
2006 | 2006 |
if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) { |
2007 |
- free(section_hdr); |
|
2008 | 2007 |
free(exe_sections); |
2009 | 2008 |
close(ndesc); |
2010 | 2009 |
if(!cli_leavetemps_flag) |
... | ... |
@@ -2017,7 +1965,6 @@ skip_upack_and_go_to_next_unpacker: |
2017 | 2017 |
if(!cli_leavetemps_flag) |
2018 | 2018 |
unlink(tempfile); |
2019 | 2019 |
free(tempfile); |
2020 |
- free(section_hdr); |
|
2021 | 2020 |
free(exe_sections); |
2022 | 2021 |
return CL_CLEAN; |
2023 | 2022 |
|
... | ... |
@@ -2051,23 +1998,12 @@ skip_upack_and_go_to_next_unpacker: |
2051 | 2051 |
|
2052 | 2052 |
/* UPX support */ |
2053 | 2053 |
|
2054 |
- strncpy(sname, (char *) section_hdr[i].Name, 8); |
|
2055 |
- sname[8] = 0; |
|
2056 |
- cli_dbgmsg("UPX: Section %d name: %s\n", i, sname); |
|
2057 |
- strncpy(sname, (char *) section_hdr[i + 1].Name, 8); |
|
2058 |
- sname[8] = 0; |
|
2059 |
- cli_dbgmsg("UPX: Section %d name: %s\n", i + 1, sname); |
|
2060 |
- |
|
2061 |
- if(strncmp((char *) section_hdr[i].Name, "UPX0", 4) || strncmp((char *) section_hdr[i + 1].Name, "UPX1", 4)) |
|
2062 |
- cli_dbgmsg("UPX: Possibly hacked UPX section headers\n"); |
|
2063 |
- |
|
2064 | 2054 |
/* we assume (i + 1) is UPX1 */ |
2065 | 2055 |
ssize = exe_sections[i + 1].rsz; |
2066 | 2056 |
dsize = exe_sections[i].vsz + exe_sections[i + 1].vsz; |
2067 | 2057 |
|
2068 | 2058 |
if(ctx->limits && ctx->limits->maxfilesize && (ssize > ctx->limits->maxfilesize || dsize > ctx->limits->maxfilesize)) { |
2069 | 2059 |
cli_dbgmsg("UPX: Sizes exceeded (ssize: %u, dsize: %u, max: %lu)\n", ssize, dsize , ctx->limits->maxfilesize); |
2070 |
- free(section_hdr); |
|
2071 | 2060 |
free(exe_sections); |
2072 | 2061 |
if(BLOCKMAX) { |
2073 | 2062 |
*ctx->virname = "PE.UPX.ExceededFileSize"; |
... | ... |
@@ -2079,28 +2015,23 @@ skip_upack_and_go_to_next_unpacker: |
2079 | 2079 |
|
2080 | 2080 |
if(ssize <= 0x19 || dsize <= ssize) { /* FIXME: What are reasonable values? */ |
2081 | 2081 |
cli_dbgmsg("UPX: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize); |
2082 |
- free(section_hdr); |
|
2083 | 2082 |
free(exe_sections); |
2084 | 2083 |
return CL_CLEAN; |
2085 | 2084 |
} |
2086 | 2085 |
|
2087 |
- /* FIXME: use file operations in case of big files */ |
|
2088 | 2086 |
if((src = (char *) cli_malloc(ssize)) == NULL) { |
2089 |
- free(section_hdr); |
|
2090 | 2087 |
free(exe_sections); |
2091 | 2088 |
return CL_EMEM; |
2092 | 2089 |
} |
2093 | 2090 |
|
2094 | 2091 |
if(dsize > CLI_MAX_ALLOCATION) { |
2095 | 2092 |
cli_errmsg("UPX: Too big value of dsize\n"); |
2096 |
- free(section_hdr); |
|
2097 | 2093 |
free(exe_sections); |
2098 | 2094 |
free(src); |
2099 | 2095 |
return CL_EMEM; |
2100 | 2096 |
} |
2101 | 2097 |
|
2102 | 2098 |
if((dest = (char *) cli_calloc(dsize + 8192, sizeof(char))) == NULL) { |
2103 |
- free(section_hdr); |
|
2104 | 2099 |
free(exe_sections); |
2105 | 2100 |
free(src); |
2106 | 2101 |
return CL_EMEM; |
... | ... |
@@ -2109,7 +2040,6 @@ skip_upack_and_go_to_next_unpacker: |
2109 | 2109 |
lseek(desc, exe_sections[i + 1].raw, SEEK_SET); |
2110 | 2110 |
if((unsigned int) cli_readn(desc, src, ssize) != ssize) { |
2111 | 2111 |
cli_dbgmsg("UPX: Can't read raw data of section %d\n", i+1); |
2112 |
- free(section_hdr); |
|
2113 | 2112 |
free(exe_sections); |
2114 | 2113 |
free(src); |
2115 | 2114 |
free(dest); |
... | ... |
@@ -2120,7 +2050,6 @@ skip_upack_and_go_to_next_unpacker: |
2120 | 2120 |
|
2121 | 2121 |
if(lseek(desc, ep, SEEK_SET) == -1) { |
2122 | 2122 |
cli_dbgmsg("UPX: lseek() failed\n"); |
2123 |
- free(section_hdr); |
|
2124 | 2123 |
free(exe_sections); |
2125 | 2124 |
free(src); |
2126 | 2125 |
free(dest); |
... | ... |
@@ -2130,7 +2059,6 @@ skip_upack_and_go_to_next_unpacker: |
2130 | 2130 |
if(cli_readn(desc, buff, 126) != 126) { /* i.e. 0x69 + 13 + 8 */ |
2131 | 2131 |
cli_dbgmsg("UPX: Can't read 126 bytes at 0x%x (%d)\n", ep, ep); |
2132 | 2132 |
cli_dbgmsg("UPX: Broken or not UPX compressed file\n"); |
2133 |
- free(section_hdr); |
|
2134 | 2133 |
free(exe_sections); |
2135 | 2134 |
free(src); |
2136 | 2135 |
free(dest); |
... | ... |
@@ -2206,7 +2134,6 @@ skip_upack_and_go_to_next_unpacker: |
2206 | 2206 |
|
2207 | 2207 |
if(upx_success) { |
2208 | 2208 |
free(src); |
2209 |
- free(section_hdr); |
|
2210 | 2209 |
free(exe_sections); |
2211 | 2210 |
|
2212 | 2211 |
if(!(tempfile = cli_gentemp(NULL))) { |
... | ... |
@@ -2261,13 +2188,12 @@ skip_upack_and_go_to_next_unpacker: |
2261 | 2261 |
memset(buff, 0, sizeof(buff)); |
2262 | 2262 |
if(cli_readn(desc, buff, 200) == -1) { |
2263 | 2263 |
cli_dbgmsg("cli_readn() failed\n"); |
2264 |
- free(section_hdr); |
|
2265 | 2264 |
free(exe_sections); |
2266 | 2265 |
return CL_EIO; |
2267 | 2266 |
} |
2268 | 2267 |
|
2269 |
- if(buff[0] != '\xb8' || (uint32_t) cli_readint32(buff + 1) != EC32(section_hdr[nsections - 1].VirtualAddress) + EC32(optional_hdr32.ImageBase)) { |
|
2270 |
- if(nsections < 2 || buff[0] != '\xb8' || (uint32_t) cli_readint32(buff + 1) != EC32(section_hdr[nsections - 2].VirtualAddress) + EC32(optional_hdr32.ImageBase)) |
|
2268 |
+ if(buff[0] != '\xb8' || (uint32_t) cli_readint32(buff + 1) != exe_sections[nsections - 1].rva + EC32(optional_hdr32.ImageBase)) { |
|
2269 |
+ if(nsections < 2 || buff[0] != '\xb8' || (uint32_t) cli_readint32(buff + 1) != exe_sections[nsections - 2].rva + EC32(optional_hdr32.ImageBase)) |
|
2271 | 2270 |
found = 0; |
2272 | 2271 |
else |
2273 | 2272 |
found = 1; |
... | ... |
@@ -2283,7 +2209,6 @@ skip_upack_and_go_to_next_unpacker: |
2283 | 2283 |
|
2284 | 2284 |
if(ctx->limits && ctx->limits->maxfilesize && dsize > ctx->limits->maxfilesize) { |
2285 | 2285 |
cli_dbgmsg("Petite: Size exceeded (dsize: %u, max: %lu)\n", dsize, ctx->limits->maxfilesize); |
2286 |
- free(section_hdr); |
|
2287 | 2286 |
free(exe_sections); |
2288 | 2287 |
if(BLOCKMAX) { |
2289 | 2288 |
*ctx->virname = "PE.Petite.ExceededFileSize"; |
... | ... |
@@ -2295,17 +2220,15 @@ skip_upack_and_go_to_next_unpacker: |
2295 | 2295 |
|
2296 | 2296 |
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) { |
2297 | 2297 |
cli_dbgmsg("Petite: Can't allocate %d bytes\n", dsize); |
2298 |
- free(section_hdr); |
|
2299 | 2298 |
free(exe_sections); |
2300 | 2299 |
return CL_EMEM; |
2301 | 2300 |
} |
2302 | 2301 |
|
2303 | 2302 |
for(i = 0 ; i < nsections; i++) { |
2304 |
- if(section_hdr[i].SizeOfRawData) { |
|
2305 |
- uint32_t offset = cli_rawaddr(EC32(section_hdr[i].VirtualAddress), exe_sections, nsections, &err, fsize); |
|
2303 |
+ if(exe_sections[i].raw) { |
|
2304 |
+ uint32_t offset = exe_sections[i].raw; |
|
2306 | 2305 |
|
2307 |
- if(err || lseek(desc, offset, SEEK_SET) == -1 || (unsigned int) cli_readn(desc, dest + EC32(section_hdr[i].VirtualAddress) - min, EC32(section_hdr[i].SizeOfRawData)) != EC32(section_hdr[i].SizeOfRawData)) { |
|
2308 |
- free(section_hdr); |
|
2306 |
+ if(lseek(desc, offset, SEEK_SET) == -1 || (unsigned int) cli_readn(desc, dest + exe_sections[i].rva - min, exe_sections[i].ursz) != exe_sections[i].ursz) { |
|
2309 | 2307 |
free(exe_sections); |
2310 | 2308 |
free(dest); |
2311 | 2309 |
return CL_EIO; |
... | ... |
@@ -2315,7 +2238,6 @@ skip_upack_and_go_to_next_unpacker: |
2315 | 2315 |
|
2316 | 2316 |
if(!(tempfile = cli_gentemp(NULL))) { |
2317 | 2317 |
free(dest); |
2318 |
- free(section_hdr); |
|
2319 | 2318 |
free(exe_sections); |
2320 | 2319 |
return CL_EMEM; |
2321 | 2320 |
} |
... | ... |
@@ -2323,14 +2245,13 @@ skip_upack_and_go_to_next_unpacker: |
2323 | 2323 |
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) { |
2324 | 2324 |
cli_dbgmsg("Petite: Can't create file %s\n", tempfile); |
2325 | 2325 |
free(tempfile); |
2326 |
- free(section_hdr); |
|
2327 | 2326 |
free(exe_sections); |
2328 | 2327 |
free(dest); |
2329 | 2328 |
return CL_EIO; |
2330 | 2329 |
} |
2331 | 2330 |
|
2332 | 2331 |
/* aCaB: Fixed to allow petite v2.1 unpacking (last section is a ghost) */ |
2333 |
- if (!petite_inflate2x_1to9(dest, min, max - min, section_hdr, |
|
2332 |
+ if (!petite_inflate2x_1to9(dest, min, max - min, exe_sections, |
|
2334 | 2333 |
nsections - (found == 1 ? 1 : 0), EC32(optional_hdr32.ImageBase), |
2335 | 2334 |
vep, ndesc, found, EC32(optional_hdr32.DataDirectory[2].VirtualAddress), |
2336 | 2335 |
EC32(optional_hdr32.DataDirectory[2].Size))) { |
... | ... |
@@ -2340,7 +2261,6 @@ skip_upack_and_go_to_next_unpacker: |
2340 | 2340 |
fsync(ndesc); |
2341 | 2341 |
lseek(ndesc, 0, SEEK_SET); |
2342 | 2342 |
if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) { |
2343 |
- free(section_hdr); |
|
2344 | 2343 |
free(exe_sections); |
2345 | 2344 |
close(ndesc); |
2346 | 2345 |
if(!cli_leavetemps_flag) { |
... | ... |
@@ -2365,15 +2285,14 @@ skip_upack_and_go_to_next_unpacker: |
2365 | 2365 |
/* PESpin 1.1 */ |
2366 | 2366 |
|
2367 | 2367 |
if((DCONF & PE_CONF_PESPIN) && nsections > 1 && |
2368 |
- vep >= EC32(section_hdr[nsections - 1].VirtualAddress) && |
|
2369 |
- vep < EC32(section_hdr[nsections - 1].VirtualAddress) + EC32(section_hdr[nsections - 1].SizeOfRawData) - 0x3217 - 4 && |
|
2368 |
+ vep >= exe_sections[nsections - 1].rva && |
|
2369 |
+ vep < exe_sections[nsections - 1].rva + exe_sections[nsections - 1].rsz - 0x3217 - 4 && |
|
2370 | 2370 |
memcmp(buff+4, "\xe8\x00\x00\x00\x00\x8b\x1c\x24\x83\xc3", 10) == 0) { |
2371 | 2371 |
|
2372 | 2372 |
char *spinned; |
2373 | 2373 |
|
2374 | 2374 |
if(ctx->limits && ctx->limits->maxfilesize && fsize > ctx->limits->maxfilesize) { |
2375 | 2375 |
cli_dbgmsg("PEspin: Size exceeded (fsize: %u, max: %lu)\n", fsize, ctx->limits->maxfilesize); |
2376 |
- free(section_hdr); |
|
2377 | 2376 |
free(exe_sections); |
2378 | 2377 |
if(BLOCKMAX) { |
2379 | 2378 |
*ctx->virname = "PE.Pespin.ExceededFileSize"; |
... | ... |
@@ -2384,7 +2303,6 @@ skip_upack_and_go_to_next_unpacker: |
2384 | 2384 |
} |
2385 | 2385 |
|
2386 | 2386 |
if((spinned = (char *) cli_malloc(fsize)) == NULL) { |
2387 |
- free(section_hdr); |
|
2388 | 2387 |
free(exe_sections); |
2389 | 2388 |
return CL_EMEM; |
2390 | 2389 |
} |
... | ... |
@@ -2393,14 +2311,12 @@ skip_upack_and_go_to_next_unpacker: |
2393 | 2393 |
if((size_t) cli_readn(desc, spinned, fsize) != fsize) { |
2394 | 2394 |
cli_dbgmsg("PESpin: Can't read %d bytes\n", fsize); |
2395 | 2395 |
free(spinned); |
2396 |
- free(section_hdr); |
|
2397 | 2396 |
free(exe_sections); |
2398 | 2397 |
return CL_EIO; |
2399 | 2398 |
} |
2400 | 2399 |
|
2401 | 2400 |
if(!(tempfile = cli_gentemp(NULL))) { |
2402 | 2401 |
free(spinned); |
2403 |
- free(section_hdr); |
|
2404 | 2402 |
free(exe_sections); |
2405 | 2403 |
return CL_EMEM; |
2406 | 2404 |
} |
... | ... |
@@ -2409,12 +2325,11 @@ skip_upack_and_go_to_next_unpacker: |
2409 | 2409 |
cli_dbgmsg("PESpin: Can't create file %s\n", tempfile); |
2410 | 2410 |
free(tempfile); |
2411 | 2411 |
free(spinned); |
2412 |
- free(section_hdr); |
|
2413 | 2412 |
free(exe_sections); |
2414 | 2413 |
return CL_EIO; |
2415 | 2414 |
} |
2416 | 2415 |
|
2417 |
- switch(unspin(spinned, fsize, section_hdr, nsections - 1, vep, ndesc, ctx)) { |
|
2416 |
+ switch(unspin(spinned, fsize, exe_sections, nsections - 1, vep, ndesc, ctx)) { |
|
2418 | 2417 |
case 0: |
2419 | 2418 |
free(spinned); |
2420 | 2419 |
if(cli_leavetemps_flag) |
... | ... |
@@ -2428,7 +2343,6 @@ skip_upack_and_go_to_next_unpacker: |
2428 | 2428 |
if(!cli_leavetemps_flag) |
2429 | 2429 |
unlink(tempfile); |
2430 | 2430 |
free(tempfile); |
2431 |
- free(section_hdr); |
|
2432 | 2431 |
free(exe_sections); |
2433 | 2432 |
return CL_VIRUS; |
2434 | 2433 |
} |
... | ... |
@@ -2449,7 +2363,6 @@ skip_upack_and_go_to_next_unpacker: |
2449 | 2449 |
cli_dbgmsg("PESpin: Size exceeded\n"); |
2450 | 2450 |
if(BLOCKMAX) { |
2451 | 2451 |
free(tempfile); |
2452 |
- free(section_hdr); |
|
2453 | 2452 |
free(exe_sections); |
2454 | 2453 |
*ctx->virname = "PE.Pespin.ExceededFileSize"; |
2455 | 2454 |
return CL_VIRUS; |
... | ... |
@@ -2463,14 +2376,13 @@ skip_upack_and_go_to_next_unpacker: |
2463 | 2463 |
/* yC 1.3 */ |
2464 | 2464 |
|
2465 | 2465 |
if((DCONF & PE_CONF_YC) && nsections > 1 && |
2466 |
- EC32(optional_hdr32.AddressOfEntryPoint) == EC32(section_hdr[nsections - 1].VirtualAddress) + 0x60 && |
|
2466 |
+ EC32(optional_hdr32.AddressOfEntryPoint) == exe_sections[nsections - 1].rva + 0x60 && |
|
2467 | 2467 |
memcmp(buff, "\x55\x8B\xEC\x53\x56\x57\x60\xE8\x00\x00\x00\x00\x5D\x81\xED\x6C\x28\x40\x00\xB9\x5D\x34\x40\x00\x81\xE9\xC6\x28\x40\x00\x8B\xD5\x81\xC2\xC6\x28\x40\x00\x8D\x3A\x8B\xF7\x33\xC0\xEB\x04\x90\xEB\x01\xC2\xAC", 51) == 0) { |
2468 | 2468 |
|
2469 | 2469 |
char *spinned; |
2470 | 2470 |
|
2471 |
- if ( fsize >= EC32(section_hdr[nsections - 1].PointerToRawData) + 0xC6 + 0xb97 ) { /* size check on yC sect */ |
|
2471 |
+ if ( fsize >= exe_sections[nsections - 1].raw + 0xC6 + 0xb97 ) { /* size check on yC sect */ |
|
2472 | 2472 |
if((spinned = (char *) cli_malloc(fsize)) == NULL) { |
2473 |
- free(section_hdr); |
|
2474 | 2473 |
free(exe_sections); |
2475 | 2474 |
return CL_EMEM; |
2476 | 2475 |
} |
... | ... |
@@ -2479,14 +2391,12 @@ skip_upack_and_go_to_next_unpacker: |
2479 | 2479 |
if((size_t) cli_readn(desc, spinned, fsize) != fsize) { |
2480 | 2480 |
cli_dbgmsg("yC: Can't read %d bytes\n", fsize); |
2481 | 2481 |
free(spinned); |
2482 |
- free(section_hdr); |
|
2483 | 2482 |
free(exe_sections); |
2484 | 2483 |
return CL_EIO; |
2485 | 2484 |
} |
2486 | 2485 |
|
2487 | 2486 |
if(!(tempfile = cli_gentemp(NULL))) { |
2488 | 2487 |
free(spinned); |
2489 |
- free(section_hdr); |
|
2490 | 2488 |
free(exe_sections); |
2491 | 2489 |
return CL_EMEM; |
2492 | 2490 |
} |
... | ... |
@@ -2495,19 +2405,17 @@ skip_upack_and_go_to_next_unpacker: |
2495 | 2495 |
cli_dbgmsg("yC: Can't create file %s\n", tempfile); |
2496 | 2496 |
free(tempfile); |
2497 | 2497 |
free(spinned); |
2498 |
- free(section_hdr); |
|
2499 | 2498 |
free(exe_sections); |
2500 | 2499 |
return CL_EIO; |
2501 | 2500 |
} |
2502 | 2501 |
|
2503 |
- if(!yc_decrypt(spinned, fsize, section_hdr, nsections-1, e_lfanew, ndesc)) { |
|
2502 |
+ if(!yc_decrypt(spinned, fsize, exe_sections, nsections-1, e_lfanew, ndesc)) { |
|
2504 | 2503 |
free(spinned); |
2505 | 2504 |
cli_dbgmsg("yC: Unpacked and rebuilt executable saved in %s\n", tempfile); |
2506 | 2505 |
fsync(ndesc); |
2507 | 2506 |
lseek(ndesc, 0, SEEK_SET); |
2508 | 2507 |
|
2509 | 2508 |
if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) { |
2510 |
- free(section_hdr); |
|
2511 | 2509 |
free(exe_sections); |
2512 | 2510 |
close(ndesc); |
2513 | 2511 |
if(!cli_leavetemps_flag) { |
... | ... |
@@ -2554,7 +2462,6 @@ skip_upack_and_go_to_next_unpacker: |
2554 | 2554 |
|
2555 | 2555 |
if(ctx->limits && ctx->limits->maxfilesize && dsize > ctx->limits->maxfilesize) { |
2556 | 2556 |
cli_dbgmsg("WWPack: Size exceeded (dsize: %u, max: %lu)\n", dsize, ctx->limits->maxfilesize); |
2557 |
- free(section_hdr); |
|
2558 | 2557 |
free(exe_sections); |
2559 | 2558 |
if(BLOCKMAX) { |
2560 | 2559 |
*ctx->virname = "PE.WWPack.ExceededFileSize"; |
... | ... |
@@ -2566,7 +2473,6 @@ skip_upack_and_go_to_next_unpacker: |
2566 | 2566 |
|
2567 | 2567 |
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) { |
2568 | 2568 |
cli_dbgmsg("WWPack: Can't allocate %d bytes\n", dsize); |
2569 |
- free(section_hdr); |
|
2570 | 2569 |
free(exe_sections); |
2571 | 2570 |
return CL_EMEM; |
2572 | 2571 |
} |
... | ... |
@@ -2575,7 +2481,6 @@ skip_upack_and_go_to_next_unpacker: |
2575 | 2575 |
if((size_t) cli_readn(desc, dest, headsize) != headsize) { |
2576 | 2576 |
cli_dbgmsg("WWPack: Can't read %d bytes from headers\n", headsize); |
2577 | 2577 |
free(dest); |
2578 |
- free(section_hdr); |
|
2579 | 2578 |
free(exe_sections); |
2580 | 2579 |
return CL_EIO; |
2581 | 2580 |
} |
... | ... |
@@ -2586,7 +2491,6 @@ skip_upack_and_go_to_next_unpacker: |
2586 | 2586 |
|
2587 | 2587 |
if(err || lseek(desc, offset, SEEK_SET) == -1 || (unsigned int) cli_readn(desc, dest + headsize + exe_sections[i].rva - min, exe_sections[i].rsz) != exe_sections[i].rsz) { |
2588 | 2588 |
free(dest); |
2589 |
- free(section_hdr); |
|
2590 | 2589 |
free(exe_sections); |
2591 | 2590 |
return CL_EIO; |
2592 | 2591 |
} |
... | ... |
@@ -2596,7 +2500,6 @@ skip_upack_and_go_to_next_unpacker: |
2596 | 2596 |
if((wwp = (char *) cli_calloc(exe_sections[nsections - 1].rsz, sizeof(char))) == NULL) { |
2597 | 2597 |
cli_dbgmsg("WWPack: Can't allocate %d bytes\n", exe_sections[nsections - 1].rsz); |
2598 | 2598 |
free(dest); |
2599 |
- free(section_hdr); |
|
2600 | 2599 |
free(exe_sections); |
2601 | 2600 |
return CL_EMEM; |
2602 | 2601 |
} |
... | ... |
@@ -2606,7 +2509,6 @@ skip_upack_and_go_to_next_unpacker: |
2606 | 2606 |
cli_dbgmsg("WWPack: Can't read %d bytes from wwpack sect\n", exe_sections[nsections - 1].rsz); |
2607 | 2607 |
free(dest); |
2608 | 2608 |
free(wwp); |
2609 |
- free(section_hdr); |
|
2610 | 2609 |
free(exe_sections); |
2611 | 2610 |
return CL_EIO; |
2612 | 2611 |
} |
... | ... |
@@ -2617,7 +2519,6 @@ skip_upack_and_go_to_next_unpacker: |
2617 | 2617 |
|
2618 | 2618 |
if(!(tempfile = cli_gentemp(NULL))) { |
2619 | 2619 |
free(dest); |
2620 |
- free(section_hdr); |
|
2621 | 2620 |
free(exe_sections); |
2622 | 2621 |
return CL_EMEM; |
2623 | 2622 |
} |
... | ... |
@@ -2626,7 +2527,6 @@ skip_upack_and_go_to_next_unpacker: |
2626 | 2626 |
cli_dbgmsg("WWPack: Can't create file %s\n", tempfile); |
2627 | 2627 |
free(tempfile); |
2628 | 2628 |
free(dest); |
2629 |
- free(section_hdr); |
|
2630 | 2629 |
free(exe_sections); |
2631 | 2630 |
return CL_EIO; |
2632 | 2631 |
} |
... | ... |
@@ -2636,7 +2536,6 @@ skip_upack_and_go_to_next_unpacker: |
2636 | 2636 |
close(ndesc); |
2637 | 2637 |
free(tempfile); |
2638 | 2638 |
free(dest); |
2639 |
- free(section_hdr); |
|
2640 | 2639 |
free(exe_sections); |
2641 | 2640 |
return CL_EIO; |
2642 | 2641 |
} |
... | ... |
@@ -2651,7 +2550,6 @@ skip_upack_and_go_to_next_unpacker: |
2651 | 2651 |
lseek(ndesc, 0, SEEK_SET); |
2652 | 2652 |
|
2653 | 2653 |
if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) { |
2654 |
- free(section_hdr); |
|
2655 | 2654 |
free(exe_sections); |
2656 | 2655 |
close(ndesc); |
2657 | 2656 |
if(!cli_leavetemps_flag) |
... | ... |
@@ -2679,11 +2577,10 @@ skip_upack_and_go_to_next_unpacker: |
2679 | 2679 |
unsigned int nowinldr; |
2680 | 2680 |
char nbuff[24]; |
2681 | 2681 |
char *src=buff, *dest; |
2682 |
- FILE *asd; |
|
2683 | 2682 |
|
2684 | 2683 |
if (*buff=='\xe9') { /* bitched headers */ |
2685 | 2684 |
eprva = cli_readint32(buff+1)+vep+5; |
2686 |
- if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize)) && err) break; |
|
2685 |
+ if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize, hdr_size)) && err) break; |
|
2687 | 2686 |
if (lseek(desc, rep, SEEK_SET)==-1) break; |
2688 | 2687 |
if (cli_readn(desc, nbuff, 24)!=24) break; |
2689 | 2688 |
src = nbuff; |
... | ... |
@@ -2710,7 +2607,6 @@ skip_upack_and_go_to_next_unpacker: |
2710 | 2710 |
|
2711 | 2711 |
if(ctx->limits && ctx->limits->maxfilesize && (ssize > ctx->limits->maxfilesize || dsize > ctx->limits->maxfilesize)) { |
2712 | 2712 |
cli_dbgmsg("NsPack: Size exceeded\n"); |
2713 |
- free(section_hdr); |
|
2714 | 2713 |
free(exe_sections); |
2715 | 2714 |
if(BLOCKMAX) { |
2716 | 2715 |
*ctx->virname = "PE.NsPack.ExceededFileSize"; |
... | ... |
@@ -2733,7 +2629,7 @@ skip_upack_and_go_to_next_unpacker: |
2733 | 2733 |
cli_readn(desc, src, ssize); |
2734 | 2734 |
|
2735 | 2735 |
eprva+=0x27a; |
2736 |
- if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize)) && err) break; |
|
2736 |
+ if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize, hdr_size)) && err) break; |
|
2737 | 2737 |
if (lseek(desc, rep, SEEK_SET)==-1) break; |
2738 | 2738 |
if (cli_readn(desc, nbuff, 5)!=5) break; |
2739 | 2739 |
eprva=eprva+5+cli_readint32(nbuff+1); |
... | ... |
@@ -2742,7 +2638,6 @@ skip_upack_and_go_to_next_unpacker: |
2742 | 2742 |
if(!(tempfile = cli_gentemp(NULL))) { |
2743 | 2743 |
free(src); |
2744 | 2744 |
free(dest); |
2745 |
- free(section_hdr); |
|
2746 | 2745 |
free(exe_sections); |
2747 | 2746 |
return CL_EMEM; |
2748 | 2747 |
} |
... | ... |
@@ -2752,7 +2647,6 @@ skip_upack_and_go_to_next_unpacker: |
2752 | 2752 |
free(tempfile); |
2753 | 2753 |
free(src); |
2754 | 2754 |
free(dest); |
2755 |
- free(section_hdr); |
|
2756 | 2755 |
free(exe_sections); |
2757 | 2756 |
return CL_EIO; |
2758 | 2757 |
} |
... | ... |
@@ -2768,7 +2662,6 @@ skip_upack_and_go_to_next_unpacker: |
2768 | 2768 |
lseek(ndesc, 0, SEEK_SET); |
2769 | 2769 |
|
2770 | 2770 |
if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) { |
2771 |
- free(section_hdr); |
|
2772 | 2771 |
free(exe_sections); |
2773 | 2772 |
close(ndesc); |
2774 | 2773 |
if(!cli_leavetemps_flag) unlink(tempfile); |
... | ... |
@@ -2788,7 +2681,6 @@ skip_upack_and_go_to_next_unpacker: |
2788 | 2788 |
|
2789 | 2789 |
/* to be continued ... */ |
2790 | 2790 |
|
2791 |
- free(section_hdr); |
|
2792 | 2791 |
free(exe_sections); |
2793 | 2792 |
return CL_CLEAN; |
2794 | 2793 |
} |
... | ... |
@@ -2809,7 +2701,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo) |
2809 | 2809 |
struct stat sb; |
2810 | 2810 |
int i; |
2811 | 2811 |
unsigned int err, pe_plus = 0; |
2812 |
- uint32_t valign, falign; |
|
2812 |
+ uint32_t valign, falign, hdr_size; |
|
2813 | 2813 |
size_t fsize; |
2814 | 2814 |
|
2815 | 2815 |
cli_dbgmsg("in cli_peheader\n"); |
... | ... |
@@ -2862,7 +2754,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo) |
2862 | 2862 |
return -1; |
2863 | 2863 |
} |
2864 | 2864 |
|
2865 |
- peinfo->nsections = EC16(file_hdr.NumberOfSections); |
|
2865 |
+ if ( (peinfo->nsections = EC16(file_hdr.NumberOfSections)) < 1 || peinfo->nsections > 96 ) return -1; |
|
2866 | 2866 |
|
2867 | 2867 |
if (EC16(file_hdr.SizeOfOptionalHeader) < sizeof(struct pe_image_optional_hdr32)) { |
2868 | 2868 |
cli_dbgmsg("SizeOfOptionalHeader too small\n"); |
... | ... |
@@ -2874,33 +2766,30 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo) |
2874 | 2874 |
return -1; |
2875 | 2875 |
} |
2876 | 2876 |
|
2877 |
- if(EC32(optional_hdr64.Magic)==PE32P_SIGNATURE) { |
|
2877 |
+ if(EC32(optional_hdr64.Magic)==PE32P_SIGNATURE) { /* PE+ */ |
|
2878 | 2878 |
if(EC16(file_hdr.SizeOfOptionalHeader)!=sizeof(struct pe_image_optional_hdr64)) { |
2879 | 2879 |
cli_dbgmsg("Incorrect SizeOfOptionalHeader for PE32+\n"); |
2880 | 2880 |
return -1; |
2881 | 2881 |
} |
2882 |
- pe_plus = 1; |
|
2883 |
- } |
|
2884 |
- |
|
2885 |
- if(!pe_plus) { /* PE */ |
|
2886 |
- cli_dbgmsg("File format: PE\n"); |
|
2887 |
- if (EC16(file_hdr.SizeOfOptionalHeader)!=sizeof(struct pe_image_optional_hdr32)) { |
|
2888 |
- /* Seek to the end of the long header */ |
|
2889 |
- lseek(desc, (EC16(file_hdr.SizeOfOptionalHeader)-sizeof(struct pe_image_optional_hdr32)), SEEK_CUR); |
|
2890 |
- } |
|
2891 |
- |
|
2892 |
- } else { /* PE+ */ |
|
2893 | 2882 |
if(cli_readn(desc, &optional_hdr32 + 1, sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) { |
2894 | 2883 |
cli_dbgmsg("Can't read optional file header\n"); |
2895 | 2884 |
return -1; |
2896 | 2885 |
} |
2897 |
- |
|
2898 |
- cli_dbgmsg("File format: PE32+\n"); |
|
2886 |
+ hdr_size = EC32(optional_hdr64.SizeOfHeaders); |
|
2887 |
+ pe_plus=1; |
|
2888 |
+ } else { /* PE */ |
|
2889 |
+ if (EC16(file_hdr.SizeOfOptionalHeader)!=sizeof(struct pe_image_optional_hdr32)) { |
|
2890 |
+ /* Seek to the end of the long header */ |
|
2891 |
+ lseek(desc, (EC16(file_hdr.SizeOfOptionalHeader)-sizeof(struct pe_image_optional_hdr32)), SEEK_CUR); |
|
2892 |
+ } |
|
2893 |
+ hdr_size = EC32(optional_hdr32.SizeOfHeaders); |
|
2899 | 2894 |
} |
2900 | 2895 |
|
2901 | 2896 |
valign = (pe_plus)?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment); |
2902 | 2897 |
falign = (pe_plus)?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment); |
2903 | 2898 |
|
2899 |
+ hdr_size = PESALIGN(hdr_size, valign); |
|
2900 |
+ |
|
2904 | 2901 |
peinfo->section = (struct cli_exe_section *) cli_calloc(peinfo->nsections, sizeof(struct cli_exe_section)); |
2905 | 2902 |
|
2906 | 2903 |
if(!peinfo->section) { |
... | ... |
@@ -2917,37 +2806,33 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo) |
2917 | 2917 |
return -1; |
2918 | 2918 |
} |
2919 | 2919 |
|
2920 |
- for(i = 0; i < peinfo->nsections; i++) { |
|
2920 |
+ if(cli_readn(desc, section_hdr, peinfo->nsections * sizeof(struct pe_image_section_hdr)) != peinfo->nsections * sizeof(struct pe_image_section_hdr)) { |
|
2921 |
+ cli_dbgmsg("Can't read section header\n"); |
|
2922 |
+ cli_dbgmsg("Possibly broken PE file\n"); |
|
2923 |
+ free(section_hdr); |
|
2924 |
+ free(peinfo->section); |
|
2925 |
+ peinfo->section = NULL; |
|
2926 |
+ return -1; |
|
2927 |
+ } |
|
2921 | 2928 |
|
2922 |
- if(cli_readn(desc, §ion_hdr[i], sizeof(struct pe_image_section_hdr)) != sizeof(struct pe_image_section_hdr)) { |
|
2923 |
- cli_dbgmsg("Can't read section header\n"); |
|
2924 |
- cli_dbgmsg("Possibly broken PE file\n"); |
|
2925 |
- free(section_hdr); |
|
2926 |
- free(peinfo->section); |
|
2927 |
- peinfo->section = NULL; |
|
2928 |
- return -1; |
|
2929 |
+ for(i = 0; falign!=0x200 && i<peinfo->nsections; i++) { |
|
2930 |
+ /* file alignment fallback mode - blah */ |
|
2931 |
+ if (falign && section_hdr[i].SizeOfRawData && EC32(section_hdr[i].PointerToRawData)%falign && !(EC32(section_hdr[i].PointerToRawData)%0x200)) { |
|
2932 |
+ falign = 0x200; |
|
2929 | 2933 |
} |
2934 |
+ } |
|
2930 | 2935 |
|
2931 |
- peinfo->section[i].rva = PEALIGN(EC32(section_hdr[i].VirtualAddress), valign); |
|
2936 |
+ for(i = 0; i < peinfo->nsections; i++) { |
|
2937 |
+ peinfo->section[i].rva = PEALIGN(EC32(section_hdr[i].VirtualAddress), valign); |
|
2932 | 2938 |
peinfo->section[i].vsz = PESALIGN(EC32(section_hdr[i].VirtualSize), valign); |
2933 | 2939 |
peinfo->section[i].raw = PEALIGN(EC32(section_hdr[i].PointerToRawData), falign); |
2934 | 2940 |
peinfo->section[i].rsz = PESALIGN(EC32(section_hdr[i].SizeOfRawData), falign); |
2935 |
- if (peinfo->section[i].rsz && !CLI_ISCONTAINED(0, (uint32_t) fsize, peinfo->section[i].raw, peinfo->section[i].rsz)) |
|
2936 |
- peinfo->section[i].rsz = (fsize - peinfo->section[i].raw)*(fsize>peinfo->section[i].raw); |
|
2937 | 2941 |
|
2938 |
- /* cli_rawaddr now handles the whole process space |
|
2939 |
- * TO BE REMOVED |
|
2940 |
- if(!i) { |
|
2941 |
- min = peinfo->section[i].rva; |
|
2942 |
- max = peinfo->section[i].rva + peinfo->section[i].rsz; |
|
2943 |
- } else { |
|
2944 |
- if(EC32(section_hdr[i].VirtualAddress) < min) |
|
2945 |
- min = EC32(section_hdr[i].VirtualAddress); |
|
2942 |
+ if (!peinfo->section[i].vsz && peinfo->section[i].rsz) |
|
2943 |
+ peinfo->section[i].vsz=PESALIGN(EC32(section_hdr[i].SizeOfRawData), valign); |
|
2946 | 2944 |
|
2947 |
- if(EC32(section_hdr[i].VirtualAddress) + EC32(section_hdr[i].SizeOfRawData) > max) |
|
2948 |
- max = EC32(section_hdr[i].VirtualAddress) + EC32(section_hdr[i].SizeOfRawData); |
|
2949 |
- } |
|
2950 |
- */ |
|
2945 |
+ if (peinfo->section[i].rsz && !CLI_ISCONTAINED(0, (uint32_t) fsize, peinfo->section[i].raw, peinfo->section[i].rsz)) |
|
2946 |
+ peinfo->section[i].rsz = (fsize - peinfo->section[i].raw)*(fsize>peinfo->section[i].raw); |
|
2951 | 2947 |
} |
2952 | 2948 |
|
2953 | 2949 |
if(pe_plus) |
... | ... |
@@ -2955,16 +2840,12 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo) |
2955 | 2955 |
else |
2956 | 2956 |
peinfo->ep = EC32(optional_hdr32.AddressOfEntryPoint); |
2957 | 2957 |
|
2958 |
- if(!(peinfo->ep = cli_rawaddr(peinfo->ep, peinfo->section, peinfo->nsections, &err, fsize)) && err) { |
|
2959 |
-#ifdef ACAB_REGRESSION |
|
2960 |
- peinfo->ep = 0x7fffffff; |
|
2961 |
-#else |
|
2958 |
+ if(!(peinfo->ep = cli_rawaddr(peinfo->ep, peinfo->section, peinfo->nsections, &err, fsize, hdr_size)) && err) { |
|
2962 | 2959 |
cli_dbgmsg("Broken PE file\n"); |
2963 | 2960 |
free(section_hdr); |
2964 | 2961 |
free(peinfo->section); |
2965 | 2962 |
peinfo->section = NULL; |
2966 | 2963 |
return -1; |
2967 |
-#endif /* ACAB_REGRESSION */ |
|
2968 | 2964 |
} |
2969 | 2965 |
|
2970 | 2966 |
free(section_hdr); |
... | ... |
@@ -52,13 +52,11 @@ |
52 | 52 |
#include <string.h> |
53 | 53 |
|
54 | 54 |
#include "cltypes.h" |
55 |
-#include "pe.h" |
|
56 | 55 |
#include "rebuildpe.h" |
57 | 56 |
#include "execs.h" |
58 | 57 |
#include "others.h" |
59 | 58 |
#include "petite.h" |
60 | 59 |
|
61 |
-#define EC32(x) le32_to_host(x) /* Convert little endian to host */ |
|
62 | 60 |
|
63 | 61 |
static int doubledl(char **scur, uint8_t *mydlptr, char *buffer, uint32_t buffersize) |
64 | 62 |
{ |
... | ... |
@@ -77,7 +75,7 @@ static int doubledl(char **scur, uint8_t *mydlptr, char *buffer, uint32_t buffer |
77 | 77 |
return (olddl>>7)&1; |
78 | 78 |
} |
79 | 79 |
|
80 |
-int petite_inflate2x_1to9(char *buf, uint32_t minrva, uint32_t bufsz, struct pe_image_section_hdr *sections, unsigned int sectcount, uint32_t Imagebase, uint32_t pep, int desc, int version, uint32_t ResRva, uint32_t ResSize) |
|
80 |
+int petite_inflate2x_1to9(char *buf, uint32_t minrva, uint32_t bufsz, struct cli_exe_section *sections, unsigned int sectcount, uint32_t Imagebase, uint32_t pep, int desc, int version, uint32_t ResRva, uint32_t ResSize) |
|
81 | 81 |
{ |
82 | 82 |
char *adjbuf = buf - minrva; |
83 | 83 |
char *packed = NULL; |
... | ... |
@@ -98,9 +96,9 @@ int petite_inflate2x_1to9(char *buf, uint32_t minrva, uint32_t bufsz, struct pe_ |
98 | 98 |
*/ |
99 | 99 |
|
100 | 100 |
if ( version == 2 ) |
101 |
- packed = adjbuf + EC32(sections[sectcount-1].VirtualAddress) + 0x1b8; |
|
101 |
+ packed = adjbuf + sections[sectcount-1].rva + 0x1b8; |
|
102 | 102 |
if ( version == 1 ) { |
103 |
- packed = adjbuf + EC32(sections[sectcount-1].VirtualAddress) + 0x178; |
|
103 |
+ packed = adjbuf + sections[sectcount-1].rva + 0x178; |
|
104 | 104 |
grown=0x323; /* My name is Harry potter */ |
105 | 105 |
skew=0x34; |
106 | 106 |
} |
... | ... |
@@ -150,7 +148,7 @@ int petite_inflate2x_1to9(char *buf, uint32_t minrva, uint32_t bufsz, struct pe_ |
150 | 150 |
if ( usects[t].vsz != usects[t+1].rva - usects[t].rva ) |
151 | 151 |
usects[t].vsz = usects[t+1].rva - usects[t].rva; |
152 | 152 |
} |
153 |
- |
|
153 |
+ |
|
154 | 154 |
/* |
155 | 155 |
* Our encryption is pathetic and out software is lame but |
156 | 156 |
* we need to claim it's unbreakable. |
... | ... |
@@ -193,7 +191,7 @@ int petite_inflate2x_1to9(char *buf, uint32_t minrva, uint32_t bufsz, struct pe_ |
193 | 193 |
} else { |
194 | 194 |
api = 0xbff01337; /* KERNEL32!leet */ |
195 | 195 |
} |
196 |
- if (EC32(sections[sectcount-1].VirtualAddress)+Imagebase < api ) |
|
196 |
+ if (sections[sectcount-1].rva+Imagebase < api ) |
|
197 | 197 |
enc_ep--; |
198 | 198 |
if ( api < virtaddr ) |
199 | 199 |
enc_ep--; |
... | ... |
@@ -316,10 +314,10 @@ int petite_inflate2x_1to9(char *buf, uint32_t minrva, uint32_t bufsz, struct pe_ |
316 | 316 |
if (!check4resources) { |
317 | 317 |
unsigned int q; |
318 | 318 |
for ( q = 0 ; q < sectcount ; q++ ) { |
319 |
- if ( thisrva <= EC32(sections[q].VirtualAddress) || thisrva >= EC32(sections[q].VirtualAddress) + EC32(sections[q].VirtualSize)) |
|
319 |
+ if ( thisrva <= sections[q].rva || thisrva >= sections[q].rva + sections[q].vsz) |
|
320 | 320 |
continue; |
321 |
- usects[j].rva = EC32(sections[q].VirtualAddress); |
|
322 |
- usects[j].rsz = thisrva - EC32(sections[q].VirtualAddress) + size; |
|
321 |
+ usects[j].rva = sections[q].rva; |
|
322 |
+ usects[j].rsz = thisrva - sections[q].rva + size; |
|
323 | 323 |
break; |
324 | 324 |
} |
325 | 325 |
} |
... | ... |
@@ -23,6 +23,6 @@ |
23 | 23 |
#include "cltypes.h" |
24 | 24 |
#include "pe.h" |
25 | 25 |
|
26 |
-int petite_inflate2x_1to9(char *buf, uint32_t minrva, uint32_t bufsz, struct pe_image_section_hdr *sections, unsigned int sectcount, uint32_t Imagebase, uint32_t pep, int desc, int version, uint32_t ResRva, uint32_t ResSize); |
|
26 |
+int petite_inflate2x_1to9(char *buf, uint32_t minrva, uint32_t bufsz, struct cli_exe_section *sections, unsigned int sectcount, uint32_t Imagebase, uint32_t pep, int desc, int version, uint32_t ResRva, uint32_t ResSize); |
|
27 | 27 |
|
28 | 28 |
#endif |
... | ... |
@@ -119,45 +119,57 @@ struct IMAGE_PE_HEADER { |
119 | 119 |
|
120 | 120 |
int cli_rebuildpe(char *buffer, struct cli_exe_section *sections, int sects, uint32_t base, uint32_t ep, uint32_t ResRva, uint32_t ResSize, int file) |
121 | 121 |
{ |
122 |
- int i; |
|
123 |
- uint32_t datasize=0, rawbase; |
|
122 |
+ uint32_t datasize=0, rawbase=PESALIGN(0x148+0x80+0x28*sects, 0x200); |
|
124 | 123 |
char *pefile=NULL, *curpe; |
125 | 124 |
struct IMAGE_PE_HEADER *fakepe; |
125 |
+ int i, gotghost=(sections[0].rva > PESALIGN(rawbase, 0x1000)); |
|
126 | 126 |
|
127 |
- if(sects > 96) |
|
127 |
+ if (gotghost) rawbase=PESALIGN(0x148+0x80+0x28*(sects+1), 0x200); |
|
128 |
+ |
|
129 |
+ if(sects+gotghost > 96) |
|
128 | 130 |
return 0; |
129 | 131 |
|
130 | 132 |
for (i=0; i < sects; i++) |
131 | 133 |
datasize+=PESALIGN(sections[i].rsz, 0x200); |
132 | 134 |
|
133 |
- rawbase = PESALIGN(0x148+0x80+0x28*sects, 0x200); |
|
134 |
- |
|
135 | 135 |
if(datasize > CLI_MAX_ALLOCATION) |
136 | 136 |
return 0; |
137 | 137 |
|
138 | 138 |
if((pefile = (char *) cli_calloc(rawbase+datasize, 1))) { |
139 | 139 |
memcpy(pefile, HEADERS, 0x148); |
140 | 140 |
|
141 |
- datasize = 0x1000; |
|
141 |
+ datasize = PESALIGN(rawbase, 0x1000); |
|
142 | 142 |
|
143 | 143 |
fakepe = (struct IMAGE_PE_HEADER *)(pefile+0xd0); |
144 |
- fakepe->NumberOfSections = EC16(sects); |
|
144 |
+ fakepe->NumberOfSections = EC16(sects+gotghost); |
|
145 | 145 |
fakepe->AddressOfEntryPoint = EC32(ep); |
146 | 146 |
fakepe->ImageBase = EC32(base); |
147 |
+ fakepe->SizeOfHeaders = EC32(rawbase); |
|
147 | 148 |
memset(pefile+0x148, 0, 0x80); |
148 | 149 |
cli_writeint32(pefile+0x148+0x10, ResRva); |
149 | 150 |
cli_writeint32(pefile+0x148+0x14, ResSize); |
150 | 151 |
curpe = pefile+0x148+0x80; |
151 | 152 |
|
153 |
+ if (gotghost) { |
|
154 |
+ snprintf(curpe, 8, "empty"); |
|
155 |
+ cli_writeint32(curpe+8, sections[0].rva-datasize); /* vsize */ |
|
156 |
+ cli_writeint32(curpe+12, datasize); /* rva */ |
|
157 |
+ cli_writeint32(curpe+0x24, 0xffffffff); |
|
158 |
+ curpe+=40; |
|
159 |
+ datasize+=PESALIGN(sections[0].rva-datasize, 0x1000); |
|
160 |
+ } |
|
161 |
+ |
|
152 | 162 |
for (i=0; i < sects; i++) { |
153 | 163 |
snprintf(curpe, 8, ".clam%.2d", i+1); |
154 | 164 |
cli_writeint32(curpe+8, sections[i].vsz); |
155 | 165 |
cli_writeint32(curpe+12, sections[i].rva); |
156 | 166 |
cli_writeint32(curpe+16, sections[i].rsz); |
157 | 167 |
cli_writeint32(curpe+20, rawbase); |
168 |
+ /* already zeroed |
|
158 | 169 |
cli_writeint32(curpe+24, 0); |
159 | 170 |
cli_writeint32(curpe+28, 0); |
160 | 171 |
cli_writeint32(curpe+32, 0); |
172 |
+ */ |
|
161 | 173 |
cli_writeint32(curpe+0x24, 0xffffffff); |
162 | 174 |
memcpy(pefile+rawbase, buffer+sections[i].raw, sections[i].rsz); |
163 | 175 |
rawbase+=PESALIGN(sections[i].rsz, 0x200); |
... | ... |
@@ -62,7 +62,6 @@ |
62 | 62 |
#include "packlibs.h" |
63 | 63 |
#include "spin.h" |
64 | 64 |
|
65 |
-#define EC32(x) le32_to_host(x) /* Convert little endian to host */ |
|
66 | 65 |
|
67 | 66 |
static char exec86(uint8_t aelle, uint8_t cielle, char *curremu, int *retval) { |
68 | 67 |
int len = 0; |
... | ... |
@@ -157,7 +156,7 @@ static uint32_t summit (char *src, int size) |
157 | 157 |
} |
158 | 158 |
|
159 | 159 |
|
160 |
-int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sectcnt, uint32_t nep, int desc, cli_ctx *ctx) { |
|
160 |
+int unspin(char *src, int ssize, struct cli_exe_section *sections, int sectcnt, uint32_t nep, int desc, cli_ctx *ctx) { |
|
161 | 161 |
char *curr, *emu, *ep, *spinned; |
162 | 162 |
char **sects; |
163 | 163 |
int blobsz=0, j; |
... | ... |
@@ -167,11 +166,11 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect |
167 | 167 |
|
168 | 168 |
cli_dbgmsg("in unspin\n"); |
169 | 169 |
|
170 |
- if ( (spinned = (char *) cli_malloc(EC32(sections[sectcnt].SizeOfRawData))) == NULL ) |
|
170 |
+ if ((spinned = (char *) cli_malloc(sections[sectcnt].rsz)) == NULL ) |
|
171 | 171 |
return 1; |
172 | 172 |
|
173 |
- memcpy(spinned, src + EC32(sections[sectcnt].PointerToRawData), EC32(sections[sectcnt].SizeOfRawData)); |
|
174 |
- ep = spinned + nep - sections[sectcnt].VirtualAddress; |
|
173 |
+ memcpy(spinned, src + sections[sectcnt].raw, sections[sectcnt].rsz); |
|
174 |
+ ep = spinned + nep - sections[sectcnt].rva; |
|
175 | 175 |
|
176 | 176 |
curr = ep+0xdb; |
177 | 177 |
if ( *curr != '\xbb' ) { |
... | ... |
@@ -196,7 +195,7 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect |
196 | 196 |
|
197 | 197 |
cli_dbgmsg("spin: Key8 is %x, Len is %x\n", key8, len); |
198 | 198 |
|
199 |
- if (!CLI_ISCONTAINED(spinned, EC32(sections[sectcnt].SizeOfRawData), ep, len+0x1fe5-1)) { |
|
199 |
+ if (!CLI_ISCONTAINED(spinned, sections[sectcnt].rsz, ep, len+0x1fe5-1)) { |
|
200 | 200 |
free(spinned); |
201 | 201 |
cli_dbgmsg("spin: len out of bounds, giving up\n"); |
202 | 202 |
return 1; |
... | ... |
@@ -214,7 +213,7 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect |
214 | 214 |
curr--; |
215 | 215 |
} |
216 | 216 |
|
217 |
- if (!CLI_ISCONTAINED(spinned, EC32(sections[sectcnt].SizeOfRawData), ep+0x3217, 4)) { |
|
217 |
+ if (!CLI_ISCONTAINED(spinned, sections[sectcnt].rsz, ep+0x3217, 4)) { |
|
218 | 218 |
free(spinned); |
219 | 219 |
cli_dbgmsg("spin: key out of bounds, giving up\n"); |
220 | 220 |
return 1; |
... | ... |
@@ -250,9 +249,9 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect |
250 | 250 |
} |
251 | 251 |
key32 = cli_readint32(ep+0x3217) - summit(src,len); |
252 | 252 |
|
253 |
- memcpy(src + EC32(sections[sectcnt].PointerToRawData), spinned, EC32(sections[sectcnt].SizeOfRawData)); |
|
253 |
+ memcpy(src + sections[sectcnt].raw, spinned, sections[sectcnt].rsz); |
|
254 | 254 |
free(spinned); /* done CRC'ing - can have a dirty buffer now */ |
255 |
- ep = src + nep + sections[sectcnt].PointerToRawData - sections[sectcnt].VirtualAddress; /* Fix the helper */ |
|
255 |
+ ep = src + nep + sections[sectcnt].raw - sections[sectcnt].rva; /* Fix the helper */ |
|
256 | 256 |
|
257 | 257 |
if (!CLI_ISCONTAINED(src, ssize, ep+0x3207, 4)) { /* this one holds all ep based checks */ |
258 | 258 |
cli_dbgmsg("spin: key out of bounds, giving up\n"); |
... | ... |
@@ -265,8 +264,8 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect |
265 | 265 |
for (j=0; j<sectcnt; j++) { |
266 | 266 |
|
267 | 267 |
if (bitmap&1) { |
268 |
- uint32_t size = EC32(sections[j].SizeOfRawData); |
|
269 |
- char *ptr = src + EC32(sections[j].PointerToRawData); |
|
268 |
+ uint32_t size = sections[j].rsz; |
|
269 |
+ char *ptr = src + sections[j].raw; |
|
270 | 270 |
uint32_t keydup = key32; |
271 | 271 |
|
272 | 272 |
if (!CLI_ISCONTAINED(src, ssize, ptr, size)) { |
... | ... |
@@ -347,9 +346,9 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect |
347 | 347 |
|
348 | 348 |
for (j=0; j<sectcnt; j++) { |
349 | 349 |
if (bitmap&1) { |
350 |
- uint32_t notthesamelen = EC32(sections[j].SizeOfRawData); |
|
350 |
+ uint32_t notthesamelen = sections[j].rsz; |
|
351 | 351 |
|
352 |
- emu = src + EC32(sections[j].PointerToRawData); |
|
352 |
+ emu = src + sections[j].raw; |
|
353 | 353 |
|
354 | 354 |
if (!CLI_ISCONTAINED(src,ssize,curr,0x24)) { /* section bounds already checked twice now */ |
355 | 355 |
cli_dbgmsg("spin: poly1 emucode is out of file?\n"); |
... | ... |
@@ -379,8 +378,8 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect |
379 | 379 |
|
380 | 380 |
for (j=0; j<sectcnt; j++) { |
381 | 381 |
if (bitmap&1) { |
382 |
- if ( filesize > ctx->limits->maxfilesize || (uint32_t)EC32(sections[j].VirtualSize) > ctx->limits->maxfilesize - filesize ) return 2; |
|
383 |
- filesize += (uint32_t)EC32(sections[j].VirtualSize); |
|
382 |
+ if ( filesize > ctx->limits->maxfilesize || sections[j].vsz > ctx->limits->maxfilesize - filesize ) return 2; |
|
383 |
+ filesize += sections[j].vsz; |
|
384 | 384 |
} |
385 | 385 |
bitmap>>=1; |
386 | 386 |
} |
... | ... |
@@ -395,21 +394,21 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect |
395 | 395 |
len = 0; |
396 | 396 |
for (j=0; j<sectcnt; j++) { |
397 | 397 |
if (bitmap&1) { |
398 |
- if ( (sects[j] = (char *) cli_malloc(EC32(sections[j].VirtualSize)) ) == NULL ) { |
|
399 |
- cli_dbgmsg("spin: malloc(%d) failed\n", EC32(sections[j].VirtualSize)); |
|
398 |
+ if ( (sects[j] = (char *) cli_malloc(sections[j].vsz) ) == NULL ) { |
|
399 |
+ cli_dbgmsg("spin: malloc(%d) failed\n", sections[j].vsz); |
|
400 | 400 |
len = 1; |
401 | 401 |
break; |
402 | 402 |
} |
403 |
- blobsz+=EC32(sections[j].VirtualSize); |
|
404 |
- memset(sects[j], 0, EC32(sections[j].VirtualSize)); |
|
405 |
- cli_dbgmsg("spin: Growing sect%d: was %x will be %x\n", j, EC32(sections[j].SizeOfRawData), EC32(sections[j].VirtualSize)); |
|
406 |
- if ( cli_unfsg(src + EC32(sections[j].PointerToRawData), sects[j], EC32(sections[j].SizeOfRawData), EC32(sections[j].VirtualSize), NULL, NULL) == -1 ) { |
|
403 |
+ blobsz+=sections[j].vsz; |
|
404 |
+ memset(sects[j], 0, sections[j].vsz); |
|
405 |
+ cli_dbgmsg("spin: Growing sect%d: was %x will be %x\n", j, sections[j].rsz, sections[j].vsz); |
|
406 |
+ if ( cli_unfsg(src + sections[j].raw, sects[j], sections[j].rsz, sections[j].vsz, NULL, NULL) == -1 ) { |
|
407 | 407 |
len++; |
408 | 408 |
cli_dbgmsg("spin: Unpack failure\n"); |
409 | 409 |
} |
410 | 410 |
} else { |
411 |
- blobsz+=EC32(sections[j].SizeOfRawData); |
|
412 |
- sects[j] = src + EC32(sections[j].PointerToRawData); |
|
411 |
+ blobsz+=sections[j].rsz; |
|
412 |
+ sects[j] = src + sections[j].raw; |
|
413 | 413 |
cli_dbgmsg("spin: Not growing sect%d\n", j); |
414 | 414 |
} |
415 | 415 |
bitmap>>=1; |
... | ... |
@@ -434,30 +433,30 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect |
434 | 434 |
/* len = cli_readint32(ep+0x2fc8); -- Using vsizes instead */ |
435 | 435 |
|
436 | 436 |
for (j=0; j<sectcnt; j++) { |
437 |
- if (EC32(sections[j].VirtualAddress) <= key32 && EC32(sections[j].VirtualAddress)+EC32(sections[j].SizeOfRawData) > key32) |
|
437 |
+ if (sections[j].rva <= key32 && sections[j].rva+sections[j].rsz > key32) |
|
438 | 438 |
break; |
439 | 439 |
} |
440 | 440 |
|
441 | 441 |
if (j!=sectcnt && ((bitman & (1<<j)) == 0)) { /* FIXME: not really sure either the res sect is lamed or just compressed, but this'll save some major headakes */ |
442 |
- cli_dbgmsg("spin: Resources (sect%d) appear to be compressed\n\tuncompressed offset %x, len %x\n\tcompressed offset %x, len %x\n", j, EC32(sections[j].VirtualAddress), key32 - EC32(sections[j].VirtualAddress), key32, EC32(sections[j].VirtualSize) - (key32 - EC32(sections[j].VirtualAddress))); |
|
442 |
+ cli_dbgmsg("spin: Resources (sect%d) appear to be compressed\n\tuncompressed offset %x, len %x\n\tcompressed offset %x, len %x\n", j, sections[j].rva, key32 - sections[j].rva, key32, sections[j].vsz - (key32 - sections[j].rva)); |
|
443 | 443 |
|
444 |
- if ( (curr=(char *)cli_malloc(EC32(sections[j].VirtualSize))) != NULL ) { |
|
445 |
- memcpy(curr, src + EC32(sections[j].PointerToRawData), key32 - EC32(sections[j].VirtualAddress)); /* Uncompressed part */ |
|
446 |
- memset(curr + key32 - EC32(sections[j].VirtualAddress), 0, EC32(sections[j].VirtualSize) - (key32 - EC32(sections[j].VirtualAddress))); /* bzero */ |
|
447 |
- if ( cli_unfsg(src + EC32(sections[j].PointerToRawData) + key32 - EC32(sections[j].VirtualAddress), curr + key32 - EC32(sections[j].VirtualAddress), EC32(sections[j].SizeOfRawData) - (key32 - EC32(sections[j].VirtualAddress)), EC32(sections[j].VirtualSize) - (key32 - EC32(sections[j].VirtualAddress)), NULL, NULL) ) { |
|
444 |
+ if ( (curr=(char *)cli_malloc(sections[j].vsz)) != NULL ) { |
|
445 |
+ memcpy(curr, src + sections[j].raw, key32 - sections[j].rva); /* Uncompressed part */ |
|
446 |
+ memset(curr + key32 - sections[j].rva, 0, sections[j].vsz - (key32 - sections[j].rva)); /* bzero */ |
|
447 |
+ if ( cli_unfsg(src + sections[j].raw + key32 - sections[j].rva, curr + key32 - sections[j].rva, sections[j].rsz - (key32 - sections[j].rva), sections[j].vsz - (key32 - sections[j].rva), NULL, NULL) ) { |
|
448 | 448 |
|
449 | 449 |
free(curr); |
450 | 450 |
cli_dbgmsg("spin: Failed to grow resources, continuing anyway\n"); |
451 |
- blobsz+=EC32(sections[j].SizeOfRawData); |
|
451 |
+ blobsz+=sections[j].rsz; |
|
452 | 452 |
} else { |
453 | 453 |
sects[j]=curr; |
454 | 454 |
bitman|=1<<j; |
455 | 455 |
cli_dbgmsg("spin: Resources grown\n"); |
456 |
- blobsz+=EC32(sections[j].VirtualSize); |
|
456 |
+ blobsz+=sections[j].vsz; |
|
457 | 457 |
} |
458 | 458 |
} else { |
459 | 459 |
/* malloc failed but i'm too deep into this crap to quit without leaking more :( */ |
460 |
- blobsz+=EC32(sections[j].SizeOfRawData); |
|
460 |
+ blobsz+=sections[j].rsz; |
|
461 | 461 |
} |
462 | 462 |
} else { |
463 | 463 |
cli_dbgmsg("spin: No res?!\n"); |
... | ... |
@@ -474,10 +473,10 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect |
474 | 474 |
int retval = 0; |
475 | 475 |
|
476 | 476 |
for (j = 0; j < sectcnt; j++) { |
477 |
- rebhlp[j].raw = (j>0)*(rebhlp[j-1].raw + rebhlp[j-1].rsz); |
|
478 |
- rebhlp[j].rsz = (bitmap &1) ? EC32(sections[j].VirtualSize) : EC32(sections[j].SizeOfRawData); |
|
479 |
- rebhlp[j].rva = EC32(sections[j].VirtualAddress); |
|
480 |
- rebhlp[j].vsz = EC32(sections[j].VirtualSize); |
|
477 |
+ rebhlp[j].raw = (j>0)?(rebhlp[j-1].raw + rebhlp[j-1].rsz):0; |
|
478 |
+ rebhlp[j].rsz = (bitmap &1) ? sections[j].vsz : sections[j].rsz; |
|
479 |
+ rebhlp[j].rva = sections[j].rva; |
|
480 |
+ rebhlp[j].vsz = sections[j].vsz; |
|
481 | 481 |
|
482 | 482 |
memcpy(to, sects[j], rebhlp[j].rsz); |
483 | 483 |
to+=rebhlp[j].rsz; |
... | ... |
@@ -36,7 +36,6 @@ |
36 | 36 |
#include "others.h" |
37 | 37 |
#include "yc.h" |
38 | 38 |
|
39 |
-#define EC32(x) le32_to_host(x) /* Convert little endian to host */ |
|
40 | 39 |
#define EC16(x) le16_to_host(x) /* Convert little endian to host */ |
41 | 40 |
|
42 | 41 |
/* ========================================================================== */ |
... | ... |
@@ -165,11 +164,12 @@ static int yc_poly_emulator(char* decryptor_offset, char* code, unsigned int ecx |
165 | 165 |
/* ========================================================================== */ |
166 | 166 |
/* Main routine which calls all others */ |
167 | 167 |
|
168 |
-int yc_decrypt(char *fbuf, unsigned int filesize, struct pe_image_section_hdr *sections, unsigned int sectcount, uint32_t peoffset, int desc) |
|
168 |
+int yc_decrypt(char *fbuf, unsigned int filesize, struct cli_exe_section *sections, unsigned int sectcount, uint32_t peoffset, int desc) |
|
169 | 169 |
{ |
170 |
- uint32_t ycsect = EC32(sections[sectcount].PointerToRawData); |
|
170 |
+ uint32_t ycsect = sections[sectcount].raw; |
|
171 | 171 |
unsigned int i; |
172 | 172 |
struct pe_image_file_hdr *pe = (struct pe_image_file_hdr*) (fbuf + peoffset); |
173 |
+ char *sname = (char *)pe + EC16(pe->SizeOfOptionalHeader) + 0x18; |
|
173 | 174 |
|
174 | 175 |
/* |
175 | 176 |
|
... | ... |
@@ -183,7 +183,7 @@ int yc_decrypt(char *fbuf, unsigned int filesize, struct pe_image_section_hdr *s |
183 | 183 |
cli_dbgmsg("yC: decrypting decryptor on sect %d\n", sectcount); |
184 | 184 |
if (yc_poly_emulator(fbuf + ycsect + 0x93, fbuf + ycsect + 0xc6 ,0xB97)) |
185 | 185 |
return 1; |
186 |
- filesize-=EC32(sections[sectcount].SizeOfRawData); |
|
186 |
+ filesize-=sections[sectcount].ursz; |
|
187 | 187 |
|
188 | 188 |
/* |
189 | 189 |
|
... | ... |
@@ -199,8 +199,10 @@ int yc_decrypt(char *fbuf, unsigned int filesize, struct pe_image_section_hdr *s |
199 | 199 |
/* Loop through all sections and decrypt them... */ |
200 | 200 |
for(i=0;i<sectcount;i++) |
201 | 201 |
{ |
202 |
- uint32_t name = (uint32_t) cli_readint32((char *)sections[i].Name); |
|
203 |
- if ( name == 0x63727372 || /* rsrc */ |
|
202 |
+ uint32_t name = (uint32_t) cli_readint32(sname+i*0x28); |
|
203 |
+ if ( !sections[i].raw || |
|
204 |
+ !sections[i].rsz || |
|
205 |
+ name == 0x63727372 || /* rsrc */ |
|
204 | 206 |
name == 0x7273722E || /* .rsr */ |
205 | 207 |
name == 0x6F6C6572 || /* relo */ |
206 | 208 |
name == 0x6C65722E || /* .rel */ |
... | ... |
@@ -208,16 +210,15 @@ int yc_decrypt(char *fbuf, unsigned int filesize, struct pe_image_section_hdr *s |
208 | 208 |
name == 0x6164722E || /* .rda */ |
209 | 209 |
name == 0x6164692E || /* .ida */ |
210 | 210 |
name == 0x736C742E || /* .tls */ |
211 |
- ((name&0xffff) == 0x4379) || /* yC */ |
|
212 |
- EC32(sections[i].PointerToRawData) == 0 || |
|
213 |
- EC32(sections[i].SizeOfRawData) == 0 ) continue; |
|
211 |
+ (name&0xffff) == 0x4379 /* yC */ |
|
212 |
+ ) continue; |
|
214 | 213 |
cli_dbgmsg("yC: decrypting sect%d\n",i); |
215 |
- if (yc_poly_emulator(fbuf + ycsect + 0x457, fbuf + EC32(sections[i].PointerToRawData), EC32(sections[i].SizeOfRawData))) |
|
214 |
+ if (yc_poly_emulator(fbuf + ycsect + 0x457, fbuf + sections[i].raw, sections[i].ursz)) |
|
216 | 215 |
return 1; |
217 | 216 |
} |
218 | 217 |
|
219 | 218 |
/* Remove yC section */ |
220 |
- pe->NumberOfSections=EC16(pe->NumberOfSections)-1; |
|
219 |
+ pe->NumberOfSections=EC16(sectcount); |
|
221 | 220 |
|
222 | 221 |
/* Remove IMPORT_DIRECTORY information */ |
223 | 222 |
memset((char *)pe + sizeof(struct pe_image_file_hdr) + 0x68, 0, 8); |
... | ... |
@@ -227,7 +228,7 @@ int yc_decrypt(char *fbuf, unsigned int filesize, struct pe_image_section_hdr *s |
227 | 227 |
cli_writeint32((char *)pe + sizeof(struct pe_image_file_hdr) + 16, cli_readint32(fbuf + ycsect + 0xa0f)); |
228 | 228 |
|
229 | 229 |
/* Fix SizeOfImage */ |
230 |
- cli_writeint32((char *)pe + sizeof(struct pe_image_file_hdr) + 0x38, cli_readint32((char *)pe + sizeof(struct pe_image_file_hdr) + 0x38) - EC32(sections[sectcount].VirtualSize)); |
|
230 |
+ cli_writeint32((char *)pe + sizeof(struct pe_image_file_hdr) + 0x38, cli_readint32((char *)pe + sizeof(struct pe_image_file_hdr) + 0x38) - sections[sectcount].vsz); |
|
231 | 231 |
|
232 | 232 |
if (cli_writen(desc, fbuf, filesize)==-1) { |
233 | 233 |
cli_dbgmsg("yC: Cannot write unpacked file\n"); |
... | ... |
@@ -24,6 +24,6 @@ |
24 | 24 |
#include "execs.h" |
25 | 25 |
#include "cltypes.h" |
26 | 26 |
|
27 |
-int yc_decrypt(char *, unsigned int, struct pe_image_section_hdr *, unsigned int, uint32_t, int); |
|
27 |
+int yc_decrypt(char *, unsigned int, struct cli_exe_section *, unsigned int, uint32_t, int); |
|
28 | 28 |
|
29 | 29 |
#endif |