This is still disabled for now (see the & 0).
Török Edvin authored on 2010/02/10 18:39:47... | ... |
@@ -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 { |