Browse code

attempt to detect W32.Parite.B using cryptanalysis

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

Tomasz Kojm authored on 2005/01/16 14:38:06
Showing 2 changed files
... ...
@@ -1,3 +1,8 @@
1
+Sun Jan 16 06:28:59 CET 2005 (tk)
2
+---------------------------------
3
+  * libclamav/pe.c: attempt to detect W32.Parite.B using cryptanalysis (thanks
4
+		    to aCaB for info on detection)
5
+
1 6
 Sat Jan 15 18:33:41 CET 2005 (tk)
2 7
 ---------------------------------
3 8
   * libclamav/str.c: cli_memstr: return substring address
... ...
@@ -1,5 +1,5 @@
1 1
 /*
2
- *  Copyright (C) 2004 Tomasz Kojm <tkojm@clamav.net>
2
+ *  Copyright (C) 2004 - 2005 Tomasz Kojm <tkojm@clamav.net>
3 3
  *
4 4
  *  With additions from aCaB <acab@clamav.net>
5 5
  *
... ...
@@ -40,6 +40,7 @@
40 40
 #include "fsg.h"
41 41
 #include "scanners.h"
42 42
 #include "rebuildpe.h"
43
+#include "str.h"
43 44
 
44 45
 #define IMAGE_DOS_SIGNATURE	    0x5a4d	    /* MZ */
45 46
 #define IMAGE_DOS_SIGNATURE_OLD	    0x4d5a          /* ZM */
... ...
@@ -152,7 +153,7 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
152 152
 	struct pe_image_optional_hdr optional_hdr;
153 153
 	struct pe_image_section_hdr *section_hdr;
154 154
 	struct stat sb;
155
-	char sname[9], buff[256], *tempfile;
155
+	char sname[9], buff[4096], *tempfile;
156 156
 	int i, found, upx_success = 0, min = 0, max = 0, ret;
157 157
 	int (*upxfn)(char *, int , char *, int *, uint32_t, uint32_t, uint32_t) = NULL;
158 158
 	char *src = NULL, *dest = NULL;
... ...
@@ -436,6 +437,25 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
436 436
 
437 437
     cli_dbgmsg("EntryPoint offset: 0x%x (%d)\n", ep, ep);
438 438
 
439
+    /* Attempt to detect some popular polymorphic viruses */
440
+
441
+    /* W32.Parite.B */
442
+    if(ep == EC32(section_hdr[nsections - 1].PointerToRawData)) {
443
+	lseek(desc, ep, SEEK_SET);
444
+	if(read(desc, buff, 4096) == 4096) {
445
+		char *pt = cli_memstr(buff, 4040, "\x47\x65\x74\x50\x72\x6f\x63\x41\x64\x64\x72\x65\x73\x73\x00", 15);
446
+	    if(pt) {
447
+		    uint32_t dw1, dw2;
448
+
449
+		pt += 15;
450
+		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) {
451
+		    *virname = "W32.Parite.B";
452
+		    return CL_VIRUS;
453
+		}
454
+	    }
455
+	}
456
+    }
457
+
439 458
     /* UPX & FSG support */
440 459
 
441 460
     /* try to find the first section with physical size == 0 */
... ...
@@ -803,7 +823,7 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
803 803
 		    return CL_CLEAN;
804 804
 		}
805 805
 
806
-		if( gp >= EC32(section_hdr[i + 1].PointerToRawData) || gp < 0) {
806
+		if(gp >= EC32(section_hdr[i + 1].PointerToRawData) || gp < 0) {
807 807
 		    cli_dbgmsg("FSG: Support data out of padding area (newedi: %d, vaddr: %d)\n", newedi, EC32(section_hdr[i].VirtualAddress));
808 808
 		    break;
809 809
 		}
... ...
@@ -845,7 +865,7 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
845 845
 		  }
846 846
 		}
847 847
 
848
-		if( t >= gp-10 || cli_readint32(support + t + 6) != 2 ) {
848
+		if(t >= gp-10 || cli_readint32(support + t + 6) != 2) {
849 849
 		    free(support);
850 850
 		    break;
851 851
 		}
... ...
@@ -1037,7 +1057,7 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
1037 1037
 	    if(upxfn) {
1038 1038
 		    int skew = cli_readint32(buff + 2) - EC32(optional_hdr.ImageBase) - EC32(section_hdr[i + 1].VirtualAddress);
1039 1039
 
1040
-		if(buff[1] != '\xbe' || skew <= 0 || skew > 0xfff ) { /* FIXME: legit skews?? */
1040
+		if(buff[1] != '\xbe' || skew <= 0 || skew > 0xfff) { /* FIXME: legit skews?? */
1041 1041
 		    skew = 0; 
1042 1042
 		    if(upxfn(src, ssize, dest, &dsize, EC32(section_hdr[i].VirtualAddress), EC32(section_hdr[i + 1].VirtualAddress), EC32(optional_hdr.AddressOfEntryPoint)) >= 0)
1043 1043
 			upx_success = 1;