Browse code

Add the rest of the prefiltering glue code.

This is still disabled for now (see the & 0).

Török Edvin authored on 2010/02/10 18:39:47
Showing 4 changed files
... ...
@@ -42,6 +42,7 @@
42 42
 #include "str.h"
43 43
 #include "readdb.h"
44 44
 #include "default.h"
45
+#include "filtering.h"
45 46
 
46 47
 #include "mpool.h"
47 48
 
... ...
@@ -383,6 +384,18 @@ int cli_ac_init(struct cli_matcher *root, uint8_t mindepth, uint8_t maxdepth)
383 383
     root->ac_mindepth = mindepth;
384 384
     root->ac_maxdepth = maxdepth;
385 385
 
386
+    /* TODO: dconf here ?*/
387
+    if (cli_mtargets[root->type].enable_prefiltering && 0) {/* Disabled for now */
388
+	root->filter = mpool_malloc(root->mempool, sizeof(*root->filter));
389
+	if (!root->filter) {
390
+	    cli_errmsg("cli_ac_init: Can't allocate memory for ac_root->filter\n");
391
+	    mpool_free(root->mempool, root->ac_root->trans);
392
+	    mpool_free(root->mempool, root->ac_root);
393
+	    return CL_EMEM;
394
+	}
395
+	filter_init(root->filter);
396
+    }
397
+
386 398
     return CL_SUCCESS;
387 399
 }
388 400
 
... ...
@@ -446,6 +459,8 @@ void cli_ac_free(struct cli_matcher *root)
446 446
 	mpool_free(root->mempool, root->ac_root->trans);
447 447
 	mpool_free(root->mempool, root->ac_root);
448 448
     }
449
+    if (root->filter)
450
+	mpool_free(root->mempool, root->filter);
449 451
 }
450 452
 
451 453
 /*
... ...
@@ -1670,6 +1685,16 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
1670 1670
     new->length = strlen(hex ? hex : hexsig) / 2;
1671 1671
     free(hex);
1672 1672
 
1673
+    if (root->filter) {
1674
+	/* so that we can show meaningful messages */
1675
+	new->virname = (char*)virname;
1676
+	if (filter_add_acpatt(root->filter, new) == -1) {
1677
+	    cli_warnmsg("cli_ac_addpatt: cannot use filter for trie\n");
1678
+	    mpool_free(root->mempool, root->filter);
1679
+	    root->filter = NULL;
1680
+	}
1681
+    }
1682
+
1673 1683
     for(i = 0; i < root->ac_maxdepth && i < new->length; i++) {
1674 1684
 	if(new->pattern[i] & CLI_MATCH_WILDCARD) {
1675 1685
 	    wprefix = 1;
... ...
@@ -62,6 +62,16 @@ int cli_bm_addpatt(struct cli_matcher *root, struct cli_bm_patt *pattern, const
62 62
 	    root->bm_reloff_num++;
63 63
     }
64 64
 
65
+    if(root->filter) {
66
+	/* the bm_suffix load balancing below can shorten the sig,
67
+	 * we want to see the entire signature! */
68
+	if (filter_add_static(root->filter, pattern->pattern, pattern->length, pattern->virname) == -1) {
69
+	    cli_warnmsg("cli_bm_addpatt: cannot use filter for trie\n");
70
+	    mpool_free(root->mempool, root->filter);
71
+	    root->filter = NULL;
72
+	}
73
+    }
74
+
65 75
 #if BM_MIN_LENGTH == BM_BLOCK_SIZE
66 76
     /* try to load balance bm_suffix (at the cost of bm_shift) */
67 77
     for(i = 0; i < pattern->length - BM_BLOCK_SIZE + 1; i++) {
... ...
@@ -48,6 +48,31 @@
48 48
 #include "fmap.h"
49 49
 #include "pe_icons.h"
50 50
 #include "regex/regex.h"
51
+#include "filtering.h"
52
+#include "perflogging.h"
53
+
54
+#ifdef CLI_PERF_LOGGING
55
+
56
+static inline void PERF_LOG_FILTER(int32_t pos, int32_t length, int8_t trie)
57
+{
58
+    cli_perf_log_add(RAW_BYTES_SCANNED, length);
59
+    cli_perf_log_add(FILTER_BYTES_SCANNED, length - pos);
60
+    cli_perf_log_count2(TRIE_SCANNED, trie, length - pos);
61
+}
62
+
63
+static inline int PERF_LOG_TRIES(int8_t acmode, int8_t bm_called, int32_t length)
64
+{
65
+    if (bm_called)
66
+	cli_perf_log_add(BM_SCANNED, length);
67
+    if (acmode)
68
+	cli_perf_log_add(AC_SCANNED, length);
69
+    return 0;
70
+}
71
+
72
+#else
73
+static inline void PERF_LOG_FILTER(int32_t pos, uint32_t length, int8_t trie) {}
74
+static inline int PERF_LOG_TRIES(int8_t acmode, int8_t bm_called, int32_t length) { return 0; }
75
+#endif
51 76
 
52 77
 static inline int matcher_run(const struct cli_matcher *root,
53 78
 			      const unsigned char *buffer, uint32_t length,
... ...
@@ -60,8 +85,31 @@ static inline int matcher_run(const struct cli_matcher *root,
60 60
 			      struct cli_bm_off *offdata)
61 61
 {
62 62
     int ret;
63
-    if (root->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, NULL, root, offset, map, offdata)) != CL_VIRUS)
63
+    int32_t pos = 0;
64
+    struct filter_match_info info;
65
+    if (root->filter) {
66
+	if(filter_search_ext(root->filter, buffer, length, &info) == -1) {
67
+	    /*  for safety always scan last maxpatlen bytes */
68
+	    pos = length - root->maxpatlen - 1;
69
+	    if (pos < 0) pos = 0;
70
+	    PERF_LOG_FILTER(pos, length, root->type);
71
+	} else {
72
+	    /* must not cut buffer for 64[4-4]6161, because we must be able to check
73
+	     * 64! */
74
+	    pos = info.first_match - root->maxpatlen - 1;
75
+	    if (pos < 0) pos = 0;
76
+	    PERF_LOG_FILTER(pos, length, root->type);
77
+	}
78
+    } else {
79
+	PERF_LOG_FILTER(0, length, root->type);
80
+    }
81
+    length -= pos;
82
+    buffer += pos;
83
+    offset += pos;
84
+    if (root->ac_only || PERF_LOG_TRIES(0,1, length) || (ret = cli_bm_scanbuff(buffer, length, virname, NULL, root, offset, map, offdata)) != CL_VIRUS) {
85
+	PERF_LOG_TRIES(acmode, 0, length);
64 86
 	ret = cli_ac_scanbuff(buffer, length, virname, NULL, NULL, root, mdata, offset, ftype, ftoffset, acmode, NULL);
87
+    }
65 88
     return ret;
66 89
 }
67 90
 
... ...
@@ -95,6 +95,7 @@ struct cli_matcher {
95 95
     struct cli_ac_patt **ac_reloff;
96 96
     uint32_t ac_reloff_num, ac_absoff_num;
97 97
     uint8_t ac_mindepth, ac_maxdepth;
98
+    struct filter *filter;
98 99
 
99 100
     uint16_t maxpatlen;
100 101
     uint8_t ac_only;
... ...
@@ -126,20 +127,21 @@ struct cli_mtarget {
126 126
     const char *name;
127 127
     uint8_t idx;    /* idx of matcher */
128 128
     uint8_t ac_only;
129
+    uint8_t enable_prefiltering;
129 130
 };
130 131
 
131 132
 #define CLI_MTARGETS 10
132 133
 static const struct cli_mtarget cli_mtargets[CLI_MTARGETS] =  {
133
-    { 0,		    "GENERIC",	    0,	0   },
134
-    { CL_TYPE_MSEXE,	    "PE",	    1,	0   },
135
-    { CL_TYPE_MSOLE2,	    "OLE2",	    2,	1   },
136
-    { CL_TYPE_HTML,	    "HTML",	    3,	1   },
137
-    { CL_TYPE_MAIL,	    "MAIL",	    4,	1   },
138
-    { CL_TYPE_GRAPHICS,	    "GRAPHICS",	    5,	1   },
139
-    { CL_TYPE_ELF,	    "ELF",	    6,	1   },
140
-    { CL_TYPE_TEXT_ASCII,   "ASCII",	    7,	1   },
141
-    { CL_TYPE_ERROR,        "NOT USED",	    8,	1   },
142
-    { CL_TYPE_MACHO,	    "MACH-O",	    9,	1   }
134
+    { 0,                    "GENERIC",      0,  0, 1 },
135
+    { CL_TYPE_MSEXE,        "PE",           1,  0, 1 },
136
+    { CL_TYPE_MSOLE2,       "OLE2",         2,  1, 0 },
137
+    { CL_TYPE_HTML,         "HTML",         3,  1, 0 },
138
+    { CL_TYPE_MAIL,         "MAIL",         4,  1, 1 },
139
+    { CL_TYPE_GRAPHICS,     "GRAPHICS",     5,  1, 0 },
140
+    { CL_TYPE_ELF,          "ELF",          6,  1, 0 },
141
+    { CL_TYPE_TEXT_ASCII,   "ASCII",        7,  1, 1 },
142
+    { CL_TYPE_ERROR,        "NOT USED",     8,  1, 0 },
143
+    { CL_TYPE_MACHO,        "MACH-O",       9,  1, 0 }
143 144
 };
144 145
 
145 146
 struct cli_target_info {