Browse code

bruteforce sfx detection

git-svn: trunk@1817

Tomasz Kojm authored on 2006/01/16 00:46:36
Showing 8 changed files
... ...
@@ -1,3 +1,7 @@
1
+Sun Jan 15 16:43:36 CET 2006 (tk)
2
+---------------------------------
3
+  * libclamav: bruteforce sfx detection
4
+
1 5
 Fri Jan 14 14:51:01 CET 2006 (acab)
2 6
 ---------------------------------
3 7
   * libclamav: added yC support
... ...
@@ -33,7 +33,7 @@
33 33
 #include "matcher-ac.h"
34 34
 
35 35
 struct cli_magic_s {
36
-    int offset;
36
+    size_t offset;
37 37
     const char *magic;
38 38
     size_t length;
39 39
     const char *descr;
... ...
@@ -126,7 +126,7 @@ static const struct cli_magic_s cli_magic[] = {
126 126
     {0,  "\060\046\262\165\216\146\317", 7, "WMA/WMV/ASF",	  CL_TYPE_DATA},
127 127
     {0,  ".RMF" ,			 4, "Real Media File",	  CL_TYPE_DATA},
128 128
 
129
-    {-1, NULL,				 0, NULL,		  CL_TYPE_UNKNOWN_DATA}
129
+    {0, NULL,				 0, NULL,		  CL_TYPE_UNKNOWN_DATA}
130 130
 };
131 131
 
132 132
 static const struct cli_smagic_s cli_smagic[] = {
... ...
@@ -51,11 +51,18 @@ typedef enum {
51 51
     /* bigger numbers have higher priority (in o-t-f detection) */
52 52
     CL_TYPE_HTML, /* on the fly */
53 53
     CL_TYPE_MAIL,  /* magic + on the fly */
54
+    CL_TYPE_SFX, /* foo SFX marker */
54 55
     CL_TYPE_ZIPSFX, /* on the fly */
55 56
     CL_TYPE_RARSFX /* on the fly */
56 57
 
57 58
 } cli_file_t;
58 59
 
60
+struct cli_matched_type {
61
+    cli_file_t type;
62
+    size_t offset;
63
+    struct cli_matched_type *next;
64
+};
65
+
59 66
 cli_file_t cli_filetype(const char *buf, size_t buflen);
60 67
 cli_file_t cli_filetype2(int desc);
61 68
 int cli_addtypesigs(struct cl_engine *engine);
... ...
@@ -260,12 +260,13 @@ inline static int cli_findpos(const char *buffer, unsigned int depth, unsigned i
260 260
     return 1;
261 261
 }
262 262
 
263
-int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cli_matcher *root, int *partcnt, short otfrec, unsigned long int offset, unsigned long int *partoff, unsigned short ftype, int fd, unsigned long int *ftoffset)
263
+int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cli_matcher *root, int *partcnt, short otfrec, unsigned long int offset, unsigned long int *partoff, unsigned short ftype, int fd, struct cli_matched_type **ftoffset)
264 264
 {
265 265
 	struct cli_ac_node *current;
266 266
 	struct cli_ac_patt *pt;
267 267
 	int type = CL_CLEAN, dist, t;
268 268
         unsigned int i, position;
269
+	struct cli_matched_type *tnode;
269 270
 
270 271
 
271 272
     if(!root->ac_root)
... ...
@@ -316,11 +317,19 @@ int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virnam
316 316
 				if(++partcnt[pt->sigid] == pt->parts) { /* the last one */
317 317
 				    if(pt->type) {
318 318
 					if(otfrec) {
319
-					    if(pt->type > type) {
319
+					    if(pt->type > type || pt->type >= CL_TYPE_SFX) {
320 320
 						cli_dbgmsg("Matched signature for file type: %s\n", pt->virname);
321 321
 						type = pt->type;
322
-						if(ftoffset)
323
-						    *ftoffset = offset + position;
322
+						if(ftoffset && ftype == CL_TYPE_MSEXE && type >= CL_TYPE_SFX) {
323
+						    if(!(tnode = cli_calloc(1, sizeof(struct cli_matched_type)))) {
324
+							cli_errmsg("Can't alloc memory for new type node\n");
325
+							return CL_EMEM;
326
+						    }
327
+						    tnode->type = type;
328
+						    tnode->offset = offset + position;
329
+						    tnode->next = *ftoffset;
330
+						    *ftoffset = tnode;
331
+						}
324 332
 					    }
325 333
 					}
326 334
 				    } else {
... ...
@@ -336,12 +345,20 @@ int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virnam
336 336
 		    } else { /* old type signature */
337 337
 			if(pt->type) {
338 338
 			    if(otfrec) {
339
-				if(pt->type > type) {
339
+				if(pt->type > type || pt->type >= CL_TYPE_SFX) {
340 340
 				    cli_dbgmsg("Matched signature for file type: %s\n", pt->virname);
341 341
 
342 342
 				    type = pt->type;
343
-				    if(ftoffset)
344
-					*ftoffset = offset + position;
343
+				    if(ftoffset && ftype == CL_TYPE_MSEXE && type >= CL_TYPE_SFX) {
344
+					if(!(tnode = cli_calloc(1, sizeof(struct cli_matched_type)))) {
345
+					    cli_errmsg("Can't alloc memory for new type node\n");
346
+					    return CL_EMEM;
347
+					}
348
+					tnode->type = type;
349
+					tnode->offset = offset + position;
350
+					tnode->next = *ftoffset;
351
+					*ftoffset = tnode;
352
+				    }
345 353
 				}
346 354
 			    }
347 355
 			} else {
... ...
@@ -21,11 +21,12 @@
21 21
 
22 22
 #include "clamav.h"
23 23
 #include "matcher.h"
24
+#include "filetypes.h"
24 25
 
25 26
 #define AC_DEFAULT_DEPTH 2
26 27
 
27 28
 int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern);
28
-int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cli_matcher *root, int *partcnt, short otfrec, unsigned long int offset, unsigned long int *partoff, unsigned short ftype, int fd, unsigned long int *ftoffset);
29
+int cli_ac_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cli_matcher *root, int *partcnt, short otfrec, unsigned long int offset, unsigned long int *partoff, unsigned short ftype, int fd, struct cli_matched_type **ftoffset);
29 30
 int cli_ac_buildtrie(struct cli_matcher *root);
30 31
 void cli_ac_free(struct cli_matcher *root);
31 32
 void cli_ac_setdepth(unsigned int depth);
... ...
@@ -274,7 +274,7 @@ int cli_validatesig(unsigned short target, unsigned short ftype, const char *off
274 274
     return 1;
275 275
 }
276 276
 
277
-int cli_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, short otfrec, unsigned short ftype, unsigned long int *ftoffset)
277
+int cli_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, short otfrec, unsigned short ftype, struct cli_matched_type **ftoffset)
278 278
 {
279 279
  	char *buffer, *buff, *endbl, *pt;
280 280
 	int bytes, buffsize, length, ret, *gpartcnt, *tpartcnt;
... ...
@@ -20,10 +20,11 @@
20 20
 #define __MATCHER_H
21 21
 
22 22
 #include "clamav.h"
23
+#include "filetypes.h"
23 24
 
24 25
 #define CL_TARGET_TABLE_SIZE 7
25 26
 
26
-int cli_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, short otfrec, unsigned short ftype, unsigned long int *ftoffset);
27
+int cli_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, short otfrec, unsigned short ftype, struct cli_matched_type **ftoffset);
27 28
 
28 29
 int cli_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_engine *engine, unsigned short ftype);
29 30
 
... ...
@@ -285,7 +285,6 @@ static int cli_scanzip(int desc, const char **virname, unsigned long int *scanne
285 285
 	lseek(desc, offset, SEEK_SET);
286 286
 
287 287
     if((zdir = zzip_dir_fdopen(dup(desc), &err)) == NULL) {
288
-	cli_dbgmsg("Zip: Not supported file format ?.\n");
289 288
 	cli_dbgmsg("Zip: zzip_dir_fdopen() return code: %d\n", err);
290 289
 	/* no return with CL_EZIP due to password protected zips */
291 290
 	return CL_CLEAN;
... ...
@@ -1646,7 +1645,7 @@ int cli_magic_scandesc(int desc, const char **virname, unsigned long int *scanne
1646 1646
 
1647 1647
     if(type != CL_TYPE_DATA && ret != CL_VIRUS) { /* scan the raw file */
1648 1648
 	    int ftrec;
1649
-	    unsigned long int ftoffset;
1649
+	    struct cli_matched_type *ftoffset = NULL, *fpt;
1650 1650
 
1651 1651
 	switch(type) {
1652 1652
 	    case CL_TYPE_UNKNOWN_TEXT:
... ...
@@ -1685,19 +1684,36 @@ int cli_magic_scandesc(int desc, const char **virname, unsigned long int *scanne
1685 1685
 		    break;
1686 1686
 
1687 1687
 		case CL_TYPE_RARSFX:
1688
-		    if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE) {
1689
-			cli_dbgmsg("RAR-SFX found at %d\n", ftoffset);
1690
-			if(cli_scanrar(desc, virname, scanned, engine, limits, options, arec, mrec, ftoffset) == CL_VIRUS)
1691
-			    return CL_VIRUS;
1692
-                    }
1688
+		case CL_TYPE_ZIPSFX:
1689
+		    if(type == CL_TYPE_MSEXE) {
1690
+			if(SCAN_ARCHIVE) {
1691
+			    fpt = ftoffset;
1692
+			    while(fpt) {
1693
+				if(fpt->type == CL_TYPE_RARSFX) {
1694
+				    cli_dbgmsg("RAR-SFX signature found at %d\n", fpt->offset);
1695
+				    if((ret = cli_scanrar(desc, virname, scanned, engine, limits, options, arec, mrec, fpt->offset) == CL_VIRUS))
1696
+					break;
1697
+				} else if(fpt->type == CL_TYPE_ZIPSFX) {
1698
+				    cli_dbgmsg("ZIP-SFX signature found at %d\n", fpt->offset);
1699
+				    if((ret = cli_scanzip(desc, virname, scanned, engine, limits, options, arec, mrec, fpt->offset) == CL_VIRUS))
1700
+					break;
1701
+				}
1702
+				fpt = fpt->next;
1703
+			    }
1704
+			}
1705
+
1706
+			while(ftoffset) {
1707
+			    fpt = ftoffset;
1708
+			    ftoffset = ftoffset->next;
1709
+			    free(fpt);
1710
+			}
1711
+
1712
+			if(ret == CL_VIRUS)
1713
+			    return ret;
1714
+		    }
1693 1715
 		    break;
1694 1716
 
1695
-		case CL_TYPE_ZIPSFX:
1696
-		    if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE) {
1697
-			cli_dbgmsg("ZIP-SFX found at %d\n", ftoffset);
1698
-			if(cli_scanzip(desc, virname, scanned, engine, limits, options, arec, mrec, ftoffset) == CL_VIRUS)
1699
-			    return CL_VIRUS;
1700
-                    }
1717
+		default:
1701 1718
 		    break;
1702 1719
 	    }
1703 1720
 	    nret == CL_TYPE_MAIL ? mrec-- : arec--;