Browse code

pe_cleanup merge

git-svn: trunk@2967

aCaB authored on 2007/03/24 11:47:35
Showing 10 changed files
... ...
@@ -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, &section_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;
... ...
@@ -23,6 +23,6 @@
23 23
 #include "cltypes.h"
24 24
 #include "rebuildpe.h"
25 25
 
26
-int unspin(char *, int, struct pe_image_section_hdr *, int, uint32_t, int, cli_ctx *);
26
+int unspin(char *, int, struct cli_exe_section *, int, uint32_t, int, cli_ctx *);
27 27
 
28 28
 #endif
... ...
@@ -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