Browse code

sync cli_peheader and cleanup

git-svn-id: file:///var/lib/svn/clamav-devel/branches/temp_branch_pe_cleanup@2950 77e5149b-7576-45b1-b177-96237e5ba77b

aCaB authored on 2007/03/19 09:35:27
Showing 1 changed files
... ...
@@ -788,14 +788,6 @@ int cli_scanpe(int desc, cli_ctx *ctx)
788 788
 
789 789
     cli_dbgmsg("EntryPoint offset: 0x%x (%d)\n", ep, ep);
790 790
 
791
-
792
-
793
-    /* -----------------------
794
-        BREAK HERE IF WE GOT 
795
-        CALLED AS cli_peheader
796
-       ----------------------- */
797
-
798
-
799 791
     if(pe_plus) { /* Do not continue for PE32+ files */
800 792
 	free(exe_sections);
801 793
 	return CL_CLEAN;
... ...
@@ -2709,7 +2701,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
2709 2709
 	struct stat sb;
2710 2710
 	int i;
2711 2711
 	unsigned int err, pe_plus = 0;
2712
-	uint32_t valign, falign;
2712
+	uint32_t valign, falign, hdr_size;
2713 2713
 	size_t fsize;
2714 2714
 
2715 2715
     cli_dbgmsg("in cli_peheader\n");
... ...
@@ -2762,7 +2754,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
2762 2762
 	return -1;
2763 2763
     }
2764 2764
 
2765
-    peinfo->nsections = EC16(file_hdr.NumberOfSections);
2765
+    if ( (peinfo->nsections = EC16(file_hdr.NumberOfSections)) < 1 || peinfo->nsections > 96 ) return -1;
2766 2766
 
2767 2767
     if (EC16(file_hdr.SizeOfOptionalHeader) < sizeof(struct pe_image_optional_hdr32)) {
2768 2768
         cli_dbgmsg("SizeOfOptionalHeader too small\n");
... ...
@@ -2774,33 +2766,30 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
2774 2774
 	return -1;
2775 2775
     }
2776 2776
 
2777
-    if(EC32(optional_hdr64.Magic)==PE32P_SIGNATURE) {
2777
+    if(EC32(optional_hdr64.Magic)==PE32P_SIGNATURE) { /* PE+ */
2778 2778
         if(EC16(file_hdr.SizeOfOptionalHeader)!=sizeof(struct pe_image_optional_hdr64)) {
2779 2779
 	    cli_dbgmsg("Incorrect SizeOfOptionalHeader for PE32+\n");
2780 2780
 	    return -1;
2781 2781
 	}
2782
-	pe_plus = 1;
2783
-    }
2784
-
2785
-    if(!pe_plus) { /* PE */
2786
-	cli_dbgmsg("File format: PE\n");
2787
-	if (EC16(file_hdr.SizeOfOptionalHeader)!=sizeof(struct pe_image_optional_hdr32)) {
2788
-	    /* Seek to the end of the long header */
2789
-	    lseek(desc, (EC16(file_hdr.SizeOfOptionalHeader)-sizeof(struct pe_image_optional_hdr32)), SEEK_CUR);
2790
-	}
2791
-
2792
-    } else { /* PE+ */
2793 2782
         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)) {
2794 2783
 	    cli_dbgmsg("Can't read optional file header\n");
2795 2784
 	    return -1;
2796 2785
 	}
2797
-
2798
-	cli_dbgmsg("File format: PE32+\n");
2786
+	hdr_size = EC32(optional_hdr64.SizeOfHeaders);
2787
+	pe_plus=1;
2788
+    } else { /* PE */
2789
+	if (EC16(file_hdr.SizeOfOptionalHeader)!=sizeof(struct pe_image_optional_hdr32)) {
2790
+	    /* Seek to the end of the long header */
2791
+	    lseek(desc, (EC16(file_hdr.SizeOfOptionalHeader)-sizeof(struct pe_image_optional_hdr32)), SEEK_CUR);
2792
+	}
2793
+	hdr_size = EC32(optional_hdr32.SizeOfHeaders);
2799 2794
     }
2800 2795
 
2801 2796
     valign = (pe_plus)?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment);
2802 2797
     falign = (pe_plus)?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment);
2803 2798
 
2799
+    hdr_size = PESALIGN(hdr_size, ((pe_plus ? EC16(optional_hdr64.Subsystem) : EC16(optional_hdr32.Subsystem))==1) ? falign : 0x200);
2800
+
2804 2801
     peinfo->section = (struct cli_exe_section *) cli_calloc(peinfo->nsections, sizeof(struct cli_exe_section));
2805 2802
 
2806 2803
     if(!peinfo->section) {
... ...
@@ -2817,23 +2806,35 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
2817 2817
 	return -1;
2818 2818
     }
2819 2819
 
2820
-    for(i = 0; i < peinfo->nsections; i++) {
2820
+    if(cli_readn(desc, section_hdr, peinfo->nsections * sizeof(struct pe_image_section_hdr)) != peinfo->nsections * sizeof(struct pe_image_section_hdr)) {
2821
+        cli_dbgmsg("Can't read section header\n");
2822
+	cli_dbgmsg("Possibly broken PE file\n");
2823
+	free(section_hdr);
2824
+	free(peinfo->section);
2825
+	peinfo->section = NULL;
2826
+	return -1;
2827
+    }
2821 2828
 
2822
-	if(cli_readn(desc, &section_hdr[i], sizeof(struct pe_image_section_hdr)) != sizeof(struct pe_image_section_hdr)) {
2823
-	    cli_dbgmsg("Can't read section header\n");
2824
-	    cli_dbgmsg("Possibly broken PE file\n");
2825
-	    free(section_hdr);
2826
-	    free(peinfo->section);
2827
-	    peinfo->section = NULL;
2828
-	    return -1;
2829
+    for(i = 0; falign!=0x200 && i<peinfo->nsections; i++) {
2830
+	/* file alignment fallback mode - blah */
2831
+	if (falign && section_hdr[i].SizeOfRawData && EC32(section_hdr[i].PointerToRawData)%falign && !(EC32(section_hdr[i].PointerToRawData)%0x200)) {
2832
+	    cli_dbgmsg("Found misaligned section, using 0x200\n");
2833
+	    falign = 0x200;
2829 2834
 	}
2835
+    }
2830 2836
 
2831
-	peinfo->section[i].rva = PEALIGN(EC32(section_hdr[i].VirtualAddress), valign);
2837
+    for(i = 0; i < peinfo->nsections; i++) {
2838
+        peinfo->section[i].rva = PEALIGN(EC32(section_hdr[i].VirtualAddress), valign);
2832 2839
 	peinfo->section[i].vsz = PESALIGN(EC32(section_hdr[i].VirtualSize), valign);
2833 2840
 	peinfo->section[i].raw = PEALIGN(EC32(section_hdr[i].PointerToRawData), falign);
2834 2841
 	peinfo->section[i].rsz = PESALIGN(EC32(section_hdr[i].SizeOfRawData), falign);
2842
+
2843
+	if (!peinfo->section[i].vsz && peinfo->section[i].rsz)
2844
+	    peinfo->section[i].vsz=PESALIGN(EC32(section_hdr[i].SizeOfRawData), valign);
2845
+
2835 2846
 	if (peinfo->section[i].rsz && !CLI_ISCONTAINED(0, (uint32_t) fsize, peinfo->section[i].raw, peinfo->section[i].rsz))
2836 2847
 	    peinfo->section[i].rsz = (fsize - peinfo->section[i].raw)*(fsize>peinfo->section[i].raw);
2848
+
2837 2849
     }
2838 2850
 
2839 2851
     if(pe_plus)
... ...
@@ -2841,7 +2842,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
2841 2841
     else
2842 2842
 	peinfo->ep = EC32(optional_hdr32.AddressOfEntryPoint);
2843 2843
 
2844
-    if(!(peinfo->ep = cli_rawaddr(peinfo->ep, peinfo->section, peinfo->nsections, &err, fsize, 0x1000)) && err) { /* HARDCODED for now - to be wiped anyway */
2844
+    if(!(peinfo->ep = cli_rawaddr(peinfo->ep, peinfo->section, peinfo->nsections, &err, fsize, hdr_size)) && err) {
2845 2845
 	cli_dbgmsg("Broken PE file\n");
2846 2846
 	free(section_hdr);
2847 2847
 	free(peinfo->section);