Browse code

Fix some Trojan.Swizzor.Gen false positives (bb #1558).

git-svn: trunk@5036

Török Edvin authored on 2009/04/10 22:23:13
Showing 4 changed files
... ...
@@ -1,3 +1,8 @@
1
+Fri Apr 10 16:23:00 EEST 2009 (edwin)
2
+-------------------------------------
3
+ * libclamav/pe.c, libclamav/special.c, libclamav/special.h: Fix some
4
+ Trojan.Swizzor.Gen false positives (bb #1558).
5
+
1 6
 Fri Apr 10 15:06:43 EEST 2009 (edwin)
2 7
 -------------------------------------
3 8
  * shared/output.c: logg flags documentation
... ...
@@ -357,6 +357,10 @@ static void cli_parseres_special(uint32_t base, uint32_t rva, int srcfd, struct
357 357
     }*/
358 358
     for (i=0; i<unnamed; i++, entry += 8) {
359 359
 	uint32_t id, offs;
360
+	if (stats->errors >= SWIZZ_MAXERRORS) {
361
+	    cli_dbgmsg("cli_parseres_special: resources broken, ignoring\n");
362
+	    return;
363
+	}
360 364
 	id = cli_readint32(entry)&0x7fffffff;
361 365
 	if(level==0) {
362 366
 		type = 0;
... ...
@@ -396,6 +400,7 @@ static void cli_parseres_special(uint32_t base, uint32_t rva, int srcfd, struct
396 396
 					cli_dbgmsg("cli_parseres_special: invalid resource table entry: %lu + %lu\n", 
397 397
 							(unsigned long)rawaddr, 
398 398
 							(unsigned long)isz);
399
+					stats->errors++;
399 400
 					continue;
400 401
 				}
401 402
 				str = cli_malloc(isz);
... ...
@@ -380,6 +380,7 @@ void cli_detect_swizz_str(const unsigned char *str, uint32_t len, struct swizz_s
380 380
 	uint16_t words = 0;
381 381
 	int ret;
382 382
 
383
+	stats->entries++;
383 384
 	for(i=0;i<len-1 && j < sizeof(stri)-2;i += 2) {
384 385
 		unsigned char c = str[i];
385 386
 		if (str[i+1] || !c) {
... ...
@@ -430,6 +431,7 @@ void cli_detect_swizz_str(const unsigned char *str, uint32_t len, struct swizz_s
430 430
 		ngram_cnts[i] = (v<<10)/all;
431 431
 	}
432 432
 	ret = swizz_j48(ngram_cnts) ? CL_VIRUS : CL_CLEAN;
433
+	if (!words) ret = CL_CLEAN;
433 434
 	cli_dbgmsg("cli_detect_swizz_str: %s, %u words\n", ret == CL_VIRUS ? "suspicious" : "ok", words);
434 435
 	if (ret == CL_VIRUS) {
435 436
 		stats->suspicious += j;
... ...
@@ -494,11 +496,15 @@ int cli_detect_swizz(struct swizz_stats *stats)
494 494
 		cli_dbgmsg("\ncli_detect_swizz: global: %s\n", global_swizz ? "suspicious" : "clean");
495 495
 	}
496 496
 
497
+	if (stats->errors > stats->entries || stats->errors >= SWIZZ_MAXERRORS) {
498
+	    cli_dbgmsg("cli_detect_swizz: resources broken, ignoring\n");
499
+	    return CL_CLEAN;
500
+	}
497 501
 	if (stats->total <= 337)
498
-		return CL_CLEAN;
502
+	    return CL_CLEAN;
499 503
 	if (stats->suspicious<<10 > 20*stats->total)
500
-		return CL_VIRUS;
501
-  if (!stats->suspicious)
502
-    return CL_CLEAN;
504
+	    return CL_VIRUS;
505
+	if (!stats->suspicious)
506
+	    return CL_CLEAN;
503 507
 	return global_swizz;
504 508
 }
... ...
@@ -22,12 +22,15 @@
22 22
 #define __SPECIAL_H
23 23
 
24 24
 #include "others.h"
25
+#define SWIZZ_MAXERRORS 2000
25 26
 struct swizz_stats {
26 27
 	uint16_t gngrams[17576];
27 28
 	uint32_t total;
28 29
 	uint32_t suspicious;
29 30
 	int has_version;
30 31
 	int has_manifest;
32
+	int errors;
33
+	int entries;
31 34
 };
32 35
 
33 36
 int cli_check_mydoom_log(int desc, const char **virname);