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... | ... |
@@ -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 */ |