Browse code

add W32.Magistr.A/B detection

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

Tomasz Kojm authored on 2005/03/21 09:17:24
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Mon Mar 21 01:13:41 CET 2005 (tk)
2
+---------------------------------
3
+  * libclamav/pe.c: add W32.Magistr.A/B detection
4
+
1 5
 Sat Mar 19 21:30:33 CET 2005 (tk)
2 6
 ---------------------------------
3 7
   * clamd: add support for environment variables CLAM_VIRUSEVENT_FILENAME and
... ...
@@ -157,9 +157,9 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
157 157
 	struct pe_image_optional_hdr optional_hdr;
158 158
 	struct pe_image_section_hdr *section_hdr;
159 159
 	struct stat sb;
160
-	char sname[9], buff[4096], *tempfile;
161
-	unsigned int i, found, upx_success = 0, min = 0, max = 0, err;
162
-	unsigned int ssize = 0, dsize = 0;
160
+	char sname[9], buff[8192], *tempfile;
161
+	unsigned int i, found, upx_success = 0, min = 0, max = 0, err, broken = 0;
162
+	unsigned int ssize = 0, dsize = 0, dll = 0;
163 163
 	int (*upxfn)(char *, int , char *, int *, uint32_t, uint32_t, uint32_t) = NULL;
164 164
 	char *src = NULL, *dest = NULL;
165 165
 	int ndesc, ret;
... ...
@@ -212,6 +212,13 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
212 212
 	return CL_CLEAN;
213 213
     }
214 214
 
215
+    if(EC16(file_hdr.Characteristics) & 0x2000) {
216
+	cli_dbgmsg("File type: DLL\n");
217
+	dll = 1;
218
+    } else if(EC16(file_hdr.Characteristics) & 0x01) {
219
+	cli_dbgmsg("File type: Executable\n");
220
+    }
221
+
215 222
     switch(EC16(file_hdr.Machine)) {
216 223
 	case 0x14c:
217 224
 	    cli_dbgmsg("Machine type: 80386\n");
... ...
@@ -413,17 +420,21 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
413 413
 
414 414
 	if(EC32(section_hdr[i].Characteristics) & 0x20000000)
415 415
 	    cli_dbgmsg("Section's memory is executable\n");
416
+
417
+	if(EC32(section_hdr[i].Characteristics) & 0x80000000)
418
+	    cli_dbgmsg("Section's memory is writeable\n");
419
+
416 420
 	cli_dbgmsg("------------------------------------\n");
417 421
 
418 422
 	if(EC32(section_hdr[i].PointerToRawData) + EC32(section_hdr[i].SizeOfRawData) > (unsigned long int) sb.st_size) {
419 423
 	    cli_dbgmsg("Possibly broken PE file - Section %d out of file (Offset@ %d, Rsize %d, Total filesize %d)\n", i, EC32(section_hdr[i].PointerToRawData), EC32(section_hdr[i].SizeOfRawData), sb.st_size);
420
-	    free(section_hdr);
421 424
 	    if(DETECT_BROKEN) {
422 425
 		if(virname)
423 426
 		    *virname = "Broken.Executable";
427
+		free(section_hdr);
424 428
 		return CL_VIRUS;
425 429
 	    }
426
-	    return CL_CLEAN;
430
+	    broken = 1;
427 431
 	}
428 432
 
429 433
 	if(!i) {
... ...
@@ -455,7 +466,7 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
455 455
     /* Attempt to detect some popular polymorphic viruses */
456 456
 
457 457
     /* W32.Parite.B */
458
-    if(ep == EC32(section_hdr[nsections - 1].PointerToRawData)) {
458
+    if(!dll && ep == EC32(section_hdr[nsections - 1].PointerToRawData)) {
459 459
 	lseek(desc, ep, SEEK_SET);
460 460
 	if(read(desc, buff, 4096) == 4096) {
461 461
 		const char *pt = cli_memstr(buff, 4040, "\x47\x65\x74\x50\x72\x6f\x63\x41\x64\x64\x72\x65\x73\x73\x00", 15);
... ...
@@ -472,6 +483,42 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
472 472
 	}
473 473
     }
474 474
 
475
+    /* W32.Magistr.A/B */
476
+    if(!dll && (EC32(section_hdr[nsections - 1].Characteristics) & 0x80000000)) {
477
+	    uint32_t rsize, vsize;
478
+
479
+	rsize = EC32(section_hdr[nsections - 1].SizeOfRawData);
480
+	vsize = EC32(section_hdr[nsections - 1].VirtualSize);
481
+
482
+	if(rsize >= 0x612c && vsize >= 0x612c && ((vsize & 0xff) == 0xec)) {
483
+		int bw = rsize < 0x7000 ? rsize : 0x7000;
484
+
485
+	    lseek(desc, EC32(section_hdr[nsections - 1].PointerToRawData) + rsize - bw, SEEK_SET);
486
+	    if(read(desc, buff, 4096) == 4096) {
487
+		if(cli_memstr(buff, 4091, "\xe8\x2c\x61\x00\x00", 5)) {
488
+		    *virname = "W32.Magistr.A";
489
+		    free(section_hdr);
490
+		    return CL_VIRUS;
491
+		} 
492
+	    }
493
+
494
+	} else if(rsize >= 0x7000 && vsize >= 0x7000 && ((vsize & 0xff) == 0xed)) {
495
+		int bw = rsize < 0x8000 ? rsize : 0x8000;
496
+
497
+	    lseek(desc, EC32(section_hdr[nsections - 1].PointerToRawData) + rsize - bw, SEEK_SET);
498
+	    if(read(desc, buff, 4096) == 4096) {
499
+		if(cli_memstr(buff, 4091, "\xe8\x04\x72\x00\x00", 5)) {
500
+		    *virname = "W32.Magistr.B";
501
+		    free(section_hdr);
502
+		    return CL_VIRUS;
503
+		} 
504
+	    }
505
+	}
506
+    }
507
+
508
+    if(broken)
509
+	return CL_CLEAN;
510
+
475 511
     /* UPX & FSG support */
476 512
 
477 513
     /* try to find the first section with physical size == 0 */