... | ... |
@@ -111,7 +111,7 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern) |
111 | 111 |
} |
112 | 112 |
} |
113 | 113 |
|
114 |
- if (root->ac_nocase) |
|
114 |
+ if (root->ac_opts & AC_OPTION_NOCASE) |
|
115 | 115 |
next = pt->trans[cli_nocase((unsigned char) (pattern->pattern[i] & 0xff))]; |
116 | 116 |
else |
117 | 117 |
next = pt->trans[(unsigned char) (pattern->pattern[i] & 0xff)]; |
... | ... |
@@ -146,7 +146,10 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern) |
146 | 146 |
root->ac_nodetable = (struct cli_ac_node **) newtable; |
147 | 147 |
root->ac_nodetable[root->ac_nodes - 1] = next; |
148 | 148 |
|
149 |
- pt->trans[(unsigned char) (pattern->pattern[i] & 0xff)] = next; |
|
149 |
+ if (root->ac_opts & AC_OPTION_NOCASE) |
|
150 |
+ pt->trans[cli_nocase((unsigned char) (pattern->pattern[i] & 0xff))] = next; |
|
151 |
+ else |
|
152 |
+ pt->trans[(unsigned char) (pattern->pattern[i] & 0xff)] = next; |
|
150 | 153 |
} |
151 | 154 |
|
152 | 155 |
pt = next; |
... | ... |
@@ -408,7 +411,7 @@ int cli_ac_buildtrie(struct cli_matcher *root) |
408 | 408 |
return ac_maketrans(root); |
409 | 409 |
} |
410 | 410 |
|
411 |
-int cli_ac_init(struct cli_matcher *root, uint8_t mindepth, uint8_t maxdepth, uint8_t dconf_prefiltering) |
|
411 |
+int cli_ac_init(struct cli_matcher *root, uint8_t mindepth, uint8_t maxdepth, uint8_t dconf_prefiltering, uint8_t ac_opts) |
|
412 | 412 |
{ |
413 | 413 |
#ifdef USE_MPOOL |
414 | 414 |
assert(root->mempool && "mempool must be initialized"); |
... | ... |
@@ -429,6 +432,7 @@ int cli_ac_init(struct cli_matcher *root, uint8_t mindepth, uint8_t maxdepth, ui |
429 | 429 |
|
430 | 430 |
root->ac_mindepth = mindepth; |
431 | 431 |
root->ac_maxdepth = maxdepth; |
432 |
+ root->ac_opts = ac_opts; |
|
432 | 433 |
|
433 | 434 |
if (cli_mtargets[root->type].enable_prefiltering && dconf_prefiltering) { |
434 | 435 |
root->filter = mpool_malloc(root->mempool, sizeof(*root->filter)); |
... | ... |
@@ -843,9 +847,9 @@ int cli_ac_chklsig(const char *expr, const char *end, uint32_t *lsigcnt, unsigne |
843 | 843 |
match = 0; \ |
844 | 844 |
} |
845 | 845 |
|
846 |
-inline static int ac_findmatch(const unsigned char *buffer, uint32_t offset, uint32_t fileoffset, uint32_t length, const struct cli_ac_patt *pattern, uint32_t *end) |
|
846 |
+inline static int ac_findmatch(const unsigned char *buffer, uint32_t offset, uint32_t fileoffset, uint32_t length, const struct cli_ac_patt *pattern, uint32_t *end, uint8_t ac_opts) |
|
847 | 847 |
{ |
848 |
- uint32_t bp, match; |
|
848 |
+ uint32_t bp, pstart, match; |
|
849 | 849 |
uint16_t wc, i, j, specialcnt = pattern->special_pattern; |
850 | 850 |
struct cli_ac_special *special; |
851 | 851 |
|
... | ... |
@@ -853,10 +857,17 @@ inline static int ac_findmatch(const unsigned char *buffer, uint32_t offset, uin |
853 | 853 |
if((offset + pattern->length > length) || (pattern->prefix_length > offset)) |
854 | 854 |
return 0; |
855 | 855 |
|
856 |
- bp = offset + pattern->depth; |
|
856 |
+ if (!pattern->nocase && (ac_opts & AC_OPTION_NOCASE)) { |
|
857 |
+ bp = offset; |
|
858 |
+ pstart = 0; |
|
859 |
+ } |
|
860 |
+ else { |
|
861 |
+ bp = offset + pattern->depth; |
|
862 |
+ pstart = pattern->depth; |
|
863 |
+ } |
|
857 | 864 |
|
858 | 865 |
match = 1; |
859 |
- for(i = pattern->depth; i < pattern->length && bp < length; i++) { |
|
866 |
+ for(i = pstart; i < pattern->length && bp < length; i++) { |
|
860 | 867 |
AC_MATCH_CHAR(pattern->pattern[i],buffer[bp]); |
861 | 868 |
if(!match) |
862 | 869 |
return 0; |
... | ... |
@@ -1257,7 +1268,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v |
1257 | 1257 |
current = root->ac_root; |
1258 | 1258 |
|
1259 | 1259 |
for(i = 0; i < length; i++) { |
1260 |
- if (root->ac_nocase) |
|
1260 |
+ if (root->ac_opts & AC_OPTION_NOCASE) |
|
1261 | 1261 |
current = current->trans[cli_nocase(buffer[i])]; |
1262 | 1262 |
else |
1263 | 1263 |
current = current->trans[buffer[i]]; |
... | ... |
@@ -1292,7 +1303,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v |
1292 | 1292 |
} |
1293 | 1293 |
|
1294 | 1294 |
pt = patt; |
1295 |
- if(ac_findmatch(buffer, bp, offset + bp - patt->prefix_length, length, patt, &matchend)) { |
|
1295 |
+ if(ac_findmatch(buffer, bp, offset + bp - patt->prefix_length, length, patt, &matchend, root->ac_opts)) { |
|
1296 | 1296 |
while(pt) { |
1297 | 1297 |
if(pt->partno > mdata->min_partno) |
1298 | 1298 |
break; |
... | ... |
@@ -1561,19 +1572,23 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex |
1561 | 1561 |
} |
1562 | 1562 |
|
1563 | 1563 |
if (sigopts) { |
1564 |
- i = 0; |
|
1565 |
- while (sigopts[i] != '\0') { |
|
1566 |
- switch (sigopts[i]) { |
|
1567 |
- case 'i': |
|
1568 |
- nocase = 1; |
|
1569 |
- break; |
|
1570 |
- default: |
|
1571 |
- cli_errmsg("cli_ac_addsig: Signature for %s uses invalid option: %02x\n", virname, sigopts[i]); |
|
1572 |
- return CL_EMALFDB; |
|
1573 |
- } |
|
1564 |
+ i = 0; |
|
1565 |
+ while (sigopts[i] != '\0') { |
|
1566 |
+ switch (sigopts[i]) { |
|
1567 |
+ case 'i': |
|
1568 |
+ if (!(root->ac_opts & AC_OPTION_NOCASE)) { |
|
1569 |
+ cli_errmsg("cli_ac_addsig: Signature for %s using nocase cannot be added to case-sensitive AC trie\n", virname); |
|
1570 |
+ return CL_EMALFDB; |
|
1571 |
+ } |
|
1572 |
+ nocase = 1; |
|
1573 |
+ break; |
|
1574 |
+ default: |
|
1575 |
+ cli_errmsg("cli_ac_addsig: Signature for %s uses invalid option: %02x\n", virname, sigopts[i]); |
|
1576 |
+ return CL_EMALFDB; |
|
1577 |
+ } |
|
1574 | 1578 |
|
1575 |
- i++; |
|
1576 |
- } |
|
1579 |
+ i++; |
|
1580 |
+ } |
|
1577 | 1581 |
} |
1578 | 1582 |
|
1579 | 1583 |
if((new = (struct cli_ac_patt *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_patt))) == NULL) |
... | ... |
@@ -1881,6 +1896,8 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex |
1881 | 1881 |
|
1882 | 1882 |
/* setting nocase match */ |
1883 | 1883 |
if (nocase) { |
1884 |
+ new->nocase = 1; |
|
1885 |
+ |
|
1884 | 1886 |
for (i = 0; i < new->length; ++i) |
1885 | 1887 |
if ((new->pattern[i] & CLI_MATCH_METADATA) == CLI_MATCH_CHAR) |
1886 | 1888 |
new->pattern[i] += CLI_MATCH_NOCASE; |
... | ... |
@@ -30,9 +30,14 @@ |
30 | 30 |
|
31 | 31 |
#define AC_CH_MAXDIST 32 |
32 | 32 |
|
33 |
+/* AC scanning modes */ |
|
33 | 34 |
#define AC_SCAN_VIR 1 |
34 | 35 |
#define AC_SCAN_FT 2 |
35 | 36 |
|
37 |
+/* AC trie options */ |
|
38 |
+#define AC_OPTION_NOOPTS 0x0 |
|
39 |
+#define AC_OPTION_NOCASE 0x1 |
|
40 |
+ |
|
36 | 41 |
struct cli_ac_data { |
37 | 42 |
int32_t ***offmatrix; |
38 | 43 |
uint32_t partsigs, lsigs, reloffsigs; |
... | ... |
@@ -69,6 +74,7 @@ struct cli_ac_patt { |
69 | 69 |
uint32_t offdata[4], offset_min, offset_max; |
70 | 70 |
uint32_t boundary; |
71 | 71 |
uint8_t depth; |
72 |
+ uint8_t nocase; |
|
72 | 73 |
}; |
73 | 74 |
|
74 | 75 |
struct cli_ac_node { |
... | ... |
@@ -96,7 +102,7 @@ int cli_ac_chklsig(const char *expr, const char *end, uint32_t *lsigcnt, unsigne |
96 | 96 |
void cli_ac_freedata(struct cli_ac_data *data); |
97 | 97 |
int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, void **customdata, struct cli_ac_result **res, const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t offset, cli_file_t ftype, struct cli_matched_type **ftoffset, unsigned int mode, cli_ctx *ctx); |
98 | 98 |
int cli_ac_buildtrie(struct cli_matcher *root); |
99 |
-int cli_ac_init(struct cli_matcher *root, uint8_t mindepth, uint8_t maxdepth, uint8_t dconf_prefiltering); |
|
99 |
+int cli_ac_init(struct cli_matcher *root, uint8_t mindepth, uint8_t maxdepth, uint8_t dconf_prefiltering, uint8_t ac_opts); |
|
100 | 100 |
int cli_ac_caloff(const struct cli_matcher *root, struct cli_ac_data *data, const struct cli_target_info *info); |
101 | 101 |
void cli_ac_free(struct cli_matcher *root); |
102 | 102 |
int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hexsig, const char *sigopts, uint32_t sigid, uint16_t parts, uint16_t partno, uint16_t rtype, uint16_t type, uint32_t mindist, uint32_t maxdist, const char *offset, const uint32_t *lsigid, unsigned int options); |
... | ... |
@@ -442,7 +442,7 @@ int cli_initroots(struct cl_engine *engine, unsigned int options) |
442 | 442 |
root->ac_only = 1; |
443 | 443 |
|
444 | 444 |
cli_dbgmsg("Initialising AC pattern matcher of root[%d]\n", i); |
445 |
- if((ret = cli_ac_init(root, engine->ac_mindepth, engine->ac_maxdepth, engine->dconf->other&OTHER_CONF_PREFILTERING))) { |
|
445 |
+ if((ret = cli_ac_init(root, engine->ac_mindepth, engine->ac_maxdepth, engine->dconf->other&OTHER_CONF_PREFILTERING, 0))) { |
|
446 | 446 |
/* no need to free previously allocated memory here */ |
447 | 447 |
cli_errmsg("cli_initroots: Can't initialise AC pattern matcher\n"); |
448 | 448 |
return ret; |
... | ... |
@@ -270,7 +270,7 @@ int init_regex_list(struct regex_matcher* matcher, uint8_t dconf_prefiltering) |
270 | 270 |
matcher->suffixes.mempool = mp; |
271 | 271 |
assert(mp && "mempool must be initialized"); |
272 | 272 |
#endif |
273 |
- if((rc = cli_ac_init(&matcher->suffixes, 2, 32, dconf_prefiltering))) { |
|
273 |
+ if((rc = cli_ac_init(&matcher->suffixes, 2, 32, dconf_prefiltering, 0))) { |
|
274 | 274 |
return rc; |
275 | 275 |
} |
276 | 276 |
#ifdef USE_MPOOL |
... | ... |
@@ -94,7 +94,7 @@ START_TEST (test_ac_scanbuff) { |
94 | 94 |
#ifdef USE_MPOOL |
95 | 95 |
root->mempool = mpool_create(); |
96 | 96 |
#endif |
97 |
- ret = cli_ac_init(root, CLI_DEFAULT_AC_MINDEPTH, CLI_DEFAULT_AC_MAXDEPTH, 1); |
|
97 |
+ ret = cli_ac_init(root, CLI_DEFAULT_AC_MINDEPTH, CLI_DEFAULT_AC_MAXDEPTH, 1, 0); |
|
98 | 98 |
fail_unless(ret == CL_SUCCESS, "cli_ac_init() failed"); |
99 | 99 |
|
100 | 100 |
|
... | ... |
@@ -164,7 +164,7 @@ START_TEST (test_ac_scanbuff_allscan) { |
164 | 164 |
#ifdef USE_MPOOL |
165 | 165 |
root->mempool = mpool_create(); |
166 | 166 |
#endif |
167 |
- ret = cli_ac_init(root, CLI_DEFAULT_AC_MINDEPTH, CLI_DEFAULT_AC_MAXDEPTH, 1); |
|
167 |
+ ret = cli_ac_init(root, CLI_DEFAULT_AC_MINDEPTH, CLI_DEFAULT_AC_MAXDEPTH, 1, 0); |
|
168 | 168 |
fail_unless(ret == CL_SUCCESS, "cli_ac_init() failed"); |
169 | 169 |
|
170 | 170 |
|