... | ... |
@@ -79,108 +79,37 @@ static char boundary[256] = { |
79 | 79 |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
80 | 80 |
}; |
81 | 81 |
|
82 |
-int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern) |
|
82 |
+static inline int insert_pattlist(mpool_t *mempool, struct cli_ac_patt *pattern, struct cli_ac_node *pt) |
|
83 | 83 |
{ |
84 |
- struct cli_ac_node *pt, *next; |
|
85 |
- struct cli_ac_patt *ph, *ph_prev, *ph_add_after; |
|
86 |
- void *newtable; |
|
84 |
+ struct cli_ac_pattlist *ph, *new, *ph_prev, *ph_add_after; |
|
85 |
+ struct cli_ac_patt *php; |
|
87 | 86 |
struct cli_ac_special *a1, *a2; |
88 | 87 |
uint8_t i, match; |
89 |
- uint16_t len = MIN(root->ac_maxdepth, pattern->length); |
|
90 |
- |
|
91 |
- for(i = 0; i < len; i++) { |
|
92 |
- if(pattern->pattern[i] & CLI_MATCH_WILDCARD) { |
|
93 |
- len = i; |
|
94 |
- break; |
|
95 |
- } |
|
96 |
- } |
|
97 |
- |
|
98 |
- if(len < root->ac_mindepth) { |
|
99 |
- /* cli_errmsg("cli_ac_addpatt: Signature for %s is too short\n", pattern->virname); */ |
|
100 |
- return CL_EMALFDB; |
|
101 |
- } |
|
102 |
- |
|
103 |
- pt = root->ac_root; |
|
104 |
- |
|
105 |
- for(i = 0; i < len; i++) { |
|
106 |
- if(!pt->trans) { |
|
107 |
- pt->trans = (struct cli_ac_node **) mpool_calloc(root->mempool, 256, sizeof(struct cli_ac_node *)); |
|
108 |
- if(!pt->trans) { |
|
109 |
- cli_errmsg("cli_ac_addpatt: Can't allocate memory for pt->trans\n"); |
|
110 |
- return CL_EMEM; |
|
111 |
- } |
|
112 |
- } |
|
113 |
- |
|
114 |
- if (root->ac_opts & AC_OPTION_NOCASE) |
|
115 |
- next = pt->trans[cli_nocase((unsigned char) (pattern->pattern[i] & 0xff))]; |
|
116 |
- else |
|
117 |
- next = pt->trans[(unsigned char) (pattern->pattern[i] & 0xff)]; |
|
118 |
- |
|
119 |
- if(!next) { |
|
120 |
- next = (struct cli_ac_node *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_node)); |
|
121 |
- if(!next) { |
|
122 |
- cli_errmsg("cli_ac_addpatt: Can't allocate memory for AC node\n"); |
|
123 |
- return CL_EMEM; |
|
124 |
- } |
|
125 |
- |
|
126 |
- if(i != len - 1) { |
|
127 |
- next->trans = (struct cli_ac_node **) mpool_calloc(root->mempool, 256, sizeof(struct cli_ac_node *)); |
|
128 |
- if(!next->trans) { |
|
129 |
- cli_errmsg("cli_ac_addpatt: Can't allocate memory for next->trans\n"); |
|
130 |
- mpool_free(root->mempool, next); |
|
131 |
- return CL_EMEM; |
|
132 |
- } |
|
133 |
- } |
|
134 |
- |
|
135 |
- root->ac_nodes++; |
|
136 |
- newtable = mpool_realloc(root->mempool, root->ac_nodetable, root->ac_nodes * sizeof(struct cli_ac_node *)); |
|
137 |
- if(!newtable) { |
|
138 |
- root->ac_nodes--; |
|
139 |
- cli_errmsg("cli_ac_addpatt: Can't realloc ac_nodetable\n"); |
|
140 |
- if(next->trans) |
|
141 |
- mpool_free(root->mempool, next->trans); |
|
142 |
- mpool_free(root->mempool, next); |
|
143 |
- return CL_EMEM; |
|
144 |
- } |
|
145 |
- |
|
146 |
- root->ac_nodetable = (struct cli_ac_node **) newtable; |
|
147 |
- root->ac_nodetable[root->ac_nodes - 1] = next; |
|
148 | 88 |
|
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; |
|
153 |
- } |
|
154 |
- |
|
155 |
- pt = next; |
|
156 |
- } |
|
157 |
- |
|
158 |
- root->ac_patterns++; |
|
159 |
- newtable = mpool_realloc(root->mempool, root->ac_pattable, root->ac_patterns * sizeof(struct cli_ac_patt *)); |
|
160 |
- if(!newtable) { |
|
161 |
- root->ac_patterns--; |
|
162 |
- cli_errmsg("cli_ac_addpatt: Can't realloc ac_pattable\n"); |
|
89 |
+ if (mempool) |
|
90 |
+ new = (struct cli_ac_pattlist *)mpool_calloc(mempool, 1, sizeof(struct cli_ac_pattlist)); |
|
91 |
+ else |
|
92 |
+ new = cli_calloc(1, sizeof(struct cli_ac_pattlist)); |
|
93 |
+ if (!new) { |
|
94 |
+ cli_errmsg("cli_ac_addpatt: Can't allocate memory for pattlist node\n"); |
|
163 | 95 |
return CL_EMEM; |
164 | 96 |
} |
165 |
- |
|
166 |
- root->ac_pattable = (struct cli_ac_patt **) newtable; |
|
167 |
- root->ac_pattable[root->ac_patterns - 1] = pattern; |
|
168 |
- |
|
169 |
- pattern->depth = i; |
|
97 |
+ new->me = pattern; |
|
170 | 98 |
|
171 | 99 |
ph = pt->list; |
172 | 100 |
ph_add_after = ph_prev = NULL; |
173 | 101 |
while(ph) { |
174 |
- if(!ph_add_after && ph->partno <= pattern->partno && (!ph->next || ph->next->partno > pattern->partno)) |
|
102 |
+ php = ph->me; |
|
103 |
+ if(!ph_add_after && php->partno <= pattern->partno && (!ph->next || ph->next->me->partno > pattern->partno)) |
|
175 | 104 |
ph_add_after = ph; |
176 |
- if((ph->length == pattern->length) && (ph->prefix_length == pattern->prefix_length) && (ph->ch[0] == pattern->ch[0]) && (ph->ch[1] == pattern->ch[1])) { |
|
177 |
- if(!memcmp(ph->pattern, pattern->pattern, ph->length * sizeof(uint16_t)) && !memcmp(ph->prefix, pattern->prefix, ph->prefix_length * sizeof(uint16_t))) { |
|
178 |
- if(!ph->special && !pattern->special) { |
|
105 |
+ if((php->length == pattern->length) && (php->prefix_length == pattern->prefix_length) && (php->ch[0] == pattern->ch[0]) && (php->ch[1] == pattern->ch[1])) { |
|
106 |
+ if(!memcmp(php->pattern, pattern->pattern, php->length * sizeof(uint16_t)) && !memcmp(php->prefix, pattern->prefix, php->prefix_length * sizeof(uint16_t))) { |
|
107 |
+ if(!php->special && !pattern->special) { |
|
179 | 108 |
match = 1; |
180 |
- } else if(ph->special == pattern->special) { |
|
109 |
+ } else if(php->special == pattern->special) { |
|
181 | 110 |
match = 1; |
182 |
- for(i = 0; i < ph->special; i++) { |
|
183 |
- a1 = ph->special_table[i]; |
|
111 |
+ for(i = 0; i < php->special; i++) { |
|
112 |
+ a1 = php->special_table[i]; |
|
184 | 113 |
a2 = pattern->special_table[i]; |
185 | 114 |
|
186 | 115 |
if(a1->num != a2->num) { |
... | ... |
@@ -198,8 +127,8 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern) |
198 | 198 |
break; |
199 | 199 |
} else if(a1->type == AC_SPECIAL_ALT_CHAR) { |
200 | 200 |
if(memcmp(a1->str, a2->str, a1->num)) { |
201 |
- match = 0; |
|
202 |
- break; |
|
201 |
+ match = 0; |
|
202 |
+ break; |
|
203 | 203 |
} |
204 | 204 |
} else if(a1->type == AC_SPECIAL_ALT_STR) { |
205 | 205 |
while(a1 && a2) { |
... | ... |
@@ -220,8 +149,8 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern) |
220 | 220 |
} |
221 | 221 |
|
222 | 222 |
if(match) { |
223 |
- if(pattern->partno < ph->partno) { |
|
224 |
- pattern->next_same = ph; |
|
223 |
+ if(pattern->partno < php->partno) { |
|
224 |
+ new->next_same = ph; |
|
225 | 225 |
if(ph_prev) |
226 | 226 |
ph_prev->next = ph->next; |
227 | 227 |
else |
... | ... |
@@ -230,11 +159,11 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern) |
230 | 230 |
ph->next = NULL; |
231 | 231 |
break; |
232 | 232 |
} else { |
233 |
- while(ph->next_same && ph->next_same->partno < pattern->partno) |
|
233 |
+ while(ph->next_same && ph->next_same->me->partno < pattern->partno) |
|
234 | 234 |
ph = ph->next_same; |
235 | 235 |
|
236 |
- pattern->next_same = ph->next_same; |
|
237 |
- ph->next_same = pattern; |
|
236 |
+ new->next_same = ph->next_same; |
|
237 |
+ ph->next_same = new; |
|
238 | 238 |
return CL_SUCCESS; |
239 | 239 |
} |
240 | 240 |
} |
... | ... |
@@ -243,19 +172,140 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern) |
243 | 243 |
|
244 | 244 |
ph_prev = ph; |
245 | 245 |
ph = ph->next; |
246 |
+ |
|
246 | 247 |
} |
247 | 248 |
|
248 | 249 |
if(ph_add_after) { |
249 |
- pattern->next = ph_add_after->next; |
|
250 |
- ph_add_after->next = pattern; |
|
250 |
+ new->next = ph_add_after->next; |
|
251 |
+ ph_add_after->next = new; |
|
251 | 252 |
} else { |
252 |
- pattern->next = pt->list; |
|
253 |
- pt->list = pattern; |
|
253 |
+ new->next = pt->list; |
|
254 |
+ pt->list = new; |
|
254 | 255 |
} |
255 | 256 |
|
256 | 257 |
return CL_SUCCESS; |
257 | 258 |
} |
258 | 259 |
|
260 |
+static inline struct cli_ac_node *add_new_node(struct cli_matcher *root, uint16_t i, uint16_t len) |
|
261 |
+{ |
|
262 |
+ struct cli_ac_node *new; |
|
263 |
+ struct cli_ac_node **newtable; |
|
264 |
+ |
|
265 |
+ new = (struct cli_ac_node *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_node)); |
|
266 |
+ if(!new) { |
|
267 |
+ cli_errmsg("cli_ac_addpatt: Can't allocate memory for AC node\n"); |
|
268 |
+ return NULL; |
|
269 |
+ } |
|
270 |
+ |
|
271 |
+ if(i != len - 1) { |
|
272 |
+ new->trans = (struct cli_ac_node **) mpool_calloc(root->mempool, 256, sizeof(struct cli_ac_node *)); |
|
273 |
+ if(!new->trans) { |
|
274 |
+ cli_errmsg("cli_ac_addpatt: Can't allocate memory for new->trans\n"); |
|
275 |
+ mpool_free(root->mempool, new); |
|
276 |
+ return NULL; |
|
277 |
+ } |
|
278 |
+ } |
|
279 |
+ |
|
280 |
+ root->ac_nodes++; |
|
281 |
+ newtable = mpool_realloc(root->mempool, root->ac_nodetable, root->ac_nodes * sizeof(struct cli_ac_node *)); |
|
282 |
+ if(!newtable) { |
|
283 |
+ root->ac_nodes--; |
|
284 |
+ cli_errmsg("cli_ac_addpatt: Can't realloc ac_nodetable\n"); |
|
285 |
+ if(new->trans) |
|
286 |
+ mpool_free(root->mempool, new->trans); |
|
287 |
+ mpool_free(root->mempool, new); |
|
288 |
+ return NULL; |
|
289 |
+ } |
|
290 |
+ |
|
291 |
+ root->ac_nodetable = newtable; |
|
292 |
+ root->ac_nodetable[root->ac_nodes - 1] = new; |
|
293 |
+ |
|
294 |
+ return new; |
|
295 |
+} |
|
296 |
+ |
|
297 |
+static int cli_ac_addpatt_recursive(struct cli_matcher *root, struct cli_ac_patt *pattern, struct cli_ac_node *pt, uint16_t i, uint16_t len) |
|
298 |
+{ |
|
299 |
+ struct cli_ac_node *next; |
|
300 |
+ int ret; |
|
301 |
+ |
|
302 |
+ /* last node, insert pattern here (base case)*/ |
|
303 |
+ if(i >= len) { |
|
304 |
+ return insert_pattlist(root->mempool, pattern, pt); |
|
305 |
+ } |
|
306 |
+ |
|
307 |
+ /* if current node has no trans table, generate one */ |
|
308 |
+ if(!pt->trans) { |
|
309 |
+ pt->trans = (struct cli_ac_node **) mpool_calloc(root->mempool, 256, sizeof(struct cli_ac_node *)); |
|
310 |
+ if(!pt->trans) { |
|
311 |
+ cli_errmsg("cli_ac_addpatt: Can't allocate memory for pt->trans\n"); |
|
312 |
+ return CL_EMEM; |
|
313 |
+ } |
|
314 |
+ } |
|
315 |
+ |
|
316 |
+ /* if pattern is nocase, we need to enumerate all the combinations if applicable |
|
317 |
+ * it's why this function was re-written to be recursive |
|
318 |
+ */ |
|
319 |
+ if(pattern->nocase && isalpha(pattern->pattern[i] & 0xff)) { |
|
320 |
+ next = pt->trans[cli_nocasei((unsigned char) (pattern->pattern[i] & 0xff))]; |
|
321 |
+ if(!next) |
|
322 |
+ next = add_new_node(root, i, len); |
|
323 |
+ if(!next) |
|
324 |
+ return CL_EMEM; |
|
325 |
+ else |
|
326 |
+ pt->trans[cli_nocasei((unsigned char) (pattern->pattern[i] & 0xff))] = next; |
|
327 |
+ |
|
328 |
+ if ((ret = cli_ac_addpatt_recursive(root, pattern, next, i+1, len)) != CL_SUCCESS) |
|
329 |
+ return ret; |
|
330 |
+ } |
|
331 |
+ |
|
332 |
+ /* normal transition, also enumerates the 'normal' nocase */ |
|
333 |
+ next = pt->trans[(unsigned char) (pattern->pattern[i] & 0xff)]; |
|
334 |
+ if(!next) |
|
335 |
+ next = add_new_node(root, i, len); |
|
336 |
+ if(!next) |
|
337 |
+ return CL_EMEM; |
|
338 |
+ else |
|
339 |
+ pt->trans[(unsigned char) (pattern->pattern[i] & 0xff)] = next; |
|
340 |
+ |
|
341 |
+ return cli_ac_addpatt_recursive(root, pattern, next, i+1, len); |
|
342 |
+} |
|
343 |
+ |
|
344 |
+int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern) |
|
345 |
+{ |
|
346 |
+ struct cli_ac_node *pt; |
|
347 |
+ struct cli_ac_patt **newtable; |
|
348 |
+ uint16_t len = MIN(root->ac_maxdepth, pattern->length); |
|
349 |
+ uint8_t i; |
|
350 |
+ |
|
351 |
+ for(i = 0; i < len; i++) { |
|
352 |
+ if(pattern->pattern[i] & CLI_MATCH_WILDCARD) { |
|
353 |
+ len = i; |
|
354 |
+ break; |
|
355 |
+ } |
|
356 |
+ } |
|
357 |
+ |
|
358 |
+ if(len < root->ac_mindepth) { |
|
359 |
+ /* cli_errmsg("cli_ac_addpatt: Signature for %s is too short\n", pattern->virname); */ |
|
360 |
+ return CL_EMALFDB; |
|
361 |
+ } |
|
362 |
+ |
|
363 |
+ /* pattern added to master list */ |
|
364 |
+ root->ac_patterns++; |
|
365 |
+ newtable = mpool_realloc(root->mempool, root->ac_pattable, root->ac_patterns * sizeof(struct cli_ac_patt *)); |
|
366 |
+ if(!newtable) { |
|
367 |
+ root->ac_patterns--; |
|
368 |
+ cli_errmsg("cli_ac_addpatt: Can't realloc ac_pattable\n"); |
|
369 |
+ return CL_EMEM; |
|
370 |
+ } |
|
371 |
+ |
|
372 |
+ root->ac_pattable = newtable; |
|
373 |
+ root->ac_pattable[root->ac_patterns - 1] = pattern; |
|
374 |
+ |
|
375 |
+ pattern->depth = len; |
|
376 |
+ |
|
377 |
+ return cli_ac_addpatt_recursive(root, pattern, root->ac_root, 0, len); |
|
378 |
+} |
|
379 |
+ |
|
259 | 380 |
struct bfs_list { |
260 | 381 |
struct cli_ac_node *node; |
261 | 382 |
struct bfs_list *next; |
... | ... |
@@ -372,7 +422,7 @@ static int ac_maketrans(struct cli_matcher *root) |
372 | 372 |
failtarget = failtarget->trans[i]; |
373 | 373 |
node->trans[i] = failtarget; |
374 | 374 |
} else if (IS_FINAL(child) && IS_LEAF(child)) { |
375 |
- struct cli_ac_patt *list; |
|
375 |
+ struct cli_ac_pattlist *list; |
|
376 | 376 |
|
377 | 377 |
list = child->list; |
378 | 378 |
if (list) { |
... | ... |
@@ -776,7 +826,7 @@ int cli_ac_chklsig(const char *expr, const char *end, uint32_t *lsigcnt, unsigne |
776 | 776 |
break; \ |
777 | 777 |
\ |
778 | 778 |
case CLI_MATCH_NOCASE: \ |
779 |
- if(cli_nocase((unsigned char)(p & 0xff)) != cli_nocase(b)) \ |
|
779 |
+ if((unsigned char)(p & 0xff) != cli_nocase(b)) \ |
|
780 | 780 |
match = 0; \ |
781 | 781 |
break; \ |
782 | 782 |
\ |
... | ... |
@@ -1241,6 +1291,7 @@ void cli_ac_chkmacro(struct cli_matcher *root, struct cli_ac_data *data, unsigne |
1241 | 1241 |
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) |
1242 | 1242 |
{ |
1243 | 1243 |
struct cli_ac_node *current; |
1244 |
+ struct cli_ac_pattlist *pattN, *ptN; |
|
1244 | 1245 |
struct cli_ac_patt *patt, *pt; |
1245 | 1246 |
uint32_t i, bp, realoff, matchend; |
1246 | 1247 |
uint16_t j; |
... | ... |
@@ -1263,69 +1314,71 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v |
1263 | 1263 |
current = current->trans[buffer[i]]; |
1264 | 1264 |
|
1265 | 1265 |
if(UNLIKELY(IS_FINAL(current))) { |
1266 |
- struct cli_ac_patt *faillist = current->fail->list; |
|
1267 |
- patt = current->list; |
|
1268 |
- while(patt) { |
|
1266 |
+ struct cli_ac_pattlist *faillist = current->fail->list; |
|
1267 |
+ pattN = current->list; |
|
1268 |
+ while(pattN) { |
|
1269 |
+ patt = pattN->me; |
|
1269 | 1270 |
if(patt->partno > mdata->min_partno) { |
1270 |
- patt = faillist; |
|
1271 |
+ pattN = faillist; |
|
1271 | 1272 |
faillist = NULL; |
1272 | 1273 |
continue; |
1273 | 1274 |
} |
1274 | 1275 |
bp = i + 1 - patt->depth; |
1275 |
- if(patt->offdata[0] != CLI_OFF_VERSION && patt->offdata[0] != CLI_OFF_MACRO && !patt->next_same && (patt->offset_min != CLI_OFF_ANY) && (!patt->sigid || patt->partno == 1)) { |
|
1276 |
+ if(patt->offdata[0] != CLI_OFF_VERSION && patt->offdata[0] != CLI_OFF_MACRO && !pattN->next_same && (patt->offset_min != CLI_OFF_ANY) && (!patt->sigid || patt->partno == 1)) { |
|
1276 | 1277 |
if(patt->offset_min == CLI_OFF_NONE) { |
1277 |
- patt = patt->next; |
|
1278 |
+ pattN = pattN->next; |
|
1278 | 1279 |
continue; |
1279 | 1280 |
} |
1280 | 1281 |
realoff = offset + bp - patt->prefix_length; |
1281 | 1282 |
if(patt->offdata[0] == CLI_OFF_ABSOLUTE) { |
1282 | 1283 |
if(patt->offset_max < realoff || patt->offset_min > realoff) { |
1283 |
- patt = patt->next; |
|
1284 |
+ pattN = pattN->next; |
|
1284 | 1285 |
continue; |
1285 | 1286 |
} |
1286 | 1287 |
} else { |
1287 | 1288 |
if(mdata->offset[patt->offset_min] == CLI_OFF_NONE || mdata->offset[patt->offset_max] < realoff || mdata->offset[patt->offset_min] > realoff) { |
1288 |
- patt = patt->next; |
|
1289 |
+ pattN = pattN->next; |
|
1289 | 1290 |
continue; |
1290 | 1291 |
} |
1291 | 1292 |
} |
1292 | 1293 |
} |
1293 | 1294 |
|
1294 |
- pt = patt; |
|
1295 |
+ ptN = pattN; |
|
1295 | 1296 |
if(ac_findmatch(buffer, bp, offset + bp - patt->prefix_length, length, patt, &matchend)) { |
1296 |
- while(pt) { |
|
1297 |
+ while(ptN) { |
|
1298 |
+ pt = ptN->me; |
|
1297 | 1299 |
if(pt->partno > mdata->min_partno) |
1298 | 1300 |
break; |
1299 | 1301 |
|
1300 | 1302 |
if((pt->type && !(mode & AC_SCAN_FT)) || (!pt->type && !(mode & AC_SCAN_VIR))) { |
1301 |
- pt = pt->next_same; |
|
1303 |
+ ptN = ptN->next_same; |
|
1302 | 1304 |
continue; |
1303 | 1305 |
} |
1304 | 1306 |
|
1305 | 1307 |
realoff = offset + bp - pt->prefix_length; |
1306 | 1308 |
if(pt->offdata[0] == CLI_OFF_VERSION) { |
1307 | 1309 |
if(!cli_hashset_contains_maybe_noalloc(mdata->vinfo, realoff)) { |
1308 |
- pt = pt->next_same; |
|
1310 |
+ ptN = ptN->next_same; |
|
1309 | 1311 |
continue; |
1310 | 1312 |
} |
1311 | 1313 |
cli_dbgmsg("cli_ac_scanbuff: VI match for offset %x\n", realoff); |
1312 | 1314 |
} else if(pt->offdata[0] == CLI_OFF_MACRO) { |
1313 | 1315 |
mdata->macro_lastmatch[patt->offdata[1]] = realoff; |
1314 |
- pt = pt->next_same; |
|
1316 |
+ ptN = ptN->next_same; |
|
1315 | 1317 |
continue; |
1316 | 1318 |
} else if(pt->offset_min != CLI_OFF_ANY && (!pt->sigid || pt->partno == 1)) { |
1317 | 1319 |
if(pt->offset_min == CLI_OFF_NONE) { |
1318 |
- pt = pt->next_same; |
|
1320 |
+ ptN = ptN->next_same; |
|
1319 | 1321 |
continue; |
1320 | 1322 |
} |
1321 | 1323 |
if(pt->offdata[0] == CLI_OFF_ABSOLUTE) { |
1322 | 1324 |
if(pt->offset_max < realoff || pt->offset_min > realoff) { |
1323 |
- pt = pt->next_same; |
|
1325 |
+ ptN = ptN->next_same; |
|
1324 | 1326 |
continue; |
1325 | 1327 |
} |
1326 | 1328 |
} else { |
1327 | 1329 |
if(mdata->offset[pt->offset_min] == CLI_OFF_NONE || mdata->offset[pt->offset_max] < realoff || mdata->offset[pt->offset_min] > realoff) { |
1328 |
- pt = pt->next_same; |
|
1330 |
+ ptN = ptN->next_same; |
|
1329 | 1331 |
continue; |
1330 | 1332 |
} |
1331 | 1333 |
} |
... | ... |
@@ -1335,7 +1388,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v |
1335 | 1335 |
|
1336 | 1336 |
/* if 2nd or later part, confirm some prior part has matched */ |
1337 | 1337 |
if(pt->partno != 1 && (!mdata->offmatrix[pt->sigid - 1] || !mdata->offmatrix[pt->sigid - 1][pt->partno - 2][0])) { |
1338 |
- pt = pt->next_same; |
|
1338 |
+ ptN = ptN->next_same; |
|
1339 | 1339 |
continue; |
1340 | 1340 |
} |
1341 | 1341 |
|
... | ... |
@@ -1429,7 +1482,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v |
1429 | 1429 |
} else { /* !pt->type */ |
1430 | 1430 |
if(pt->lsigid[0]) { |
1431 | 1431 |
lsig_sub_matched(root, mdata, pt->lsigid[1], pt->lsigid[2], offmatrix[pt->parts - 1][1], 1); |
1432 |
- pt = pt->next_same; |
|
1432 |
+ ptN = ptN->next_same; |
|
1433 | 1433 |
continue; |
1434 | 1434 |
} |
1435 | 1435 |
|
... | ... |
@@ -1445,7 +1498,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v |
1445 | 1445 |
newres->offset = offmatrix[pt->parts - 1][1]; |
1446 | 1446 |
*res = newres; |
1447 | 1447 |
|
1448 |
- pt = pt->next_same; |
|
1448 |
+ ptN = ptN->next_same; |
|
1449 | 1449 |
continue; |
1450 | 1450 |
} else { |
1451 | 1451 |
if(ctx && SCAN_ALL) { |
... | ... |
@@ -1458,7 +1511,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v |
1458 | 1458 |
*customdata = pt->customdata; |
1459 | 1459 |
if (!ctx || !SCAN_ALL) |
1460 | 1460 |
return CL_VIRUS; |
1461 |
- pt = pt->next_same; |
|
1461 |
+ ptN = ptN->next_same; |
|
1462 | 1462 |
continue; |
1463 | 1463 |
} |
1464 | 1464 |
} |
... | ... |
@@ -1482,7 +1535,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v |
1482 | 1482 |
} else { |
1483 | 1483 |
if(pt->lsigid[0]) { |
1484 | 1484 |
lsig_sub_matched(root, mdata, pt->lsigid[1], pt->lsigid[2], realoff, 0); |
1485 |
- pt = pt->next_same; |
|
1485 |
+ ptN = ptN->next_same; |
|
1486 | 1486 |
continue; |
1487 | 1487 |
} |
1488 | 1488 |
|
... | ... |
@@ -1498,7 +1551,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v |
1498 | 1498 |
newres->next = *res; |
1499 | 1499 |
*res = newres; |
1500 | 1500 |
|
1501 |
- pt = pt->next_same; |
|
1501 |
+ ptN = ptN->next_same; |
|
1502 | 1502 |
continue; |
1503 | 1503 |
} else { |
1504 | 1504 |
if(ctx && SCAN_ALL) { |
... | ... |
@@ -1515,15 +1568,15 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v |
1515 | 1515 |
if (!ctx || !SCAN_ALL) |
1516 | 1516 |
return CL_VIRUS; |
1517 | 1517 |
|
1518 |
- pt = pt->next_same; |
|
1518 |
+ ptN = ptN->next_same; |
|
1519 | 1519 |
continue; |
1520 | 1520 |
} |
1521 | 1521 |
} |
1522 | 1522 |
} |
1523 |
- pt = pt->next_same; |
|
1523 |
+ ptN = ptN->next_same; |
|
1524 | 1524 |
} |
1525 | 1525 |
} |
1526 |
- patt = patt->next; |
|
1526 |
+ pattN = pattN->next; |
|
1527 | 1527 |
} |
1528 | 1528 |
} |
1529 | 1529 |
} |
... | ... |
@@ -1879,14 +1932,17 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex |
1879 | 1879 |
new->length = strlen(hex ? hex : hexsig) / 2; |
1880 | 1880 |
free(hex); |
1881 | 1881 |
|
1882 |
- /* setting nocase match */ |
|
1882 |
+ /* setting nocase match; TODO - move this to cli_realhex2ui and adjust for nocase, alter MATCH_CHAR too */ |
|
1883 | 1883 |
if (nocase) { |
1884 |
+ new->nocase = 1; |
|
1884 | 1885 |
for (i = 0; i < new->length; ++i) |
1885 |
- if ((new->pattern[i] & CLI_MATCH_METADATA) == CLI_MATCH_CHAR) |
|
1886 |
+ if ((new->pattern[i] & CLI_MATCH_METADATA) == CLI_MATCH_CHAR) { |
|
1887 |
+ new->pattern[i] = cli_nocase(new->pattern[i] & 0xff); |
|
1886 | 1888 |
new->pattern[i] += CLI_MATCH_NOCASE; |
1889 |
+ } |
|
1887 | 1890 |
} |
1888 | 1891 |
|
1889 |
- if (root->filter) { |
|
1892 |
+ if (root->filter) { //TODO - fix filters for nocase state, also fix for sigtool as well |
|
1890 | 1893 |
/* so that we can show meaningful messages */ |
1891 | 1894 |
new->virname = (char*)virname; |
1892 | 1895 |
if (filter_add_acpatt(root->filter, new) == -1) { |
... | ... |
@@ -69,15 +69,20 @@ struct cli_ac_patt { |
69 | 69 |
uint16_t ch_maxdist[2]; |
70 | 70 |
uint16_t parts, partno, special, special_pattern; |
71 | 71 |
struct cli_ac_special **special_table; |
72 |
- struct cli_ac_patt *next, *next_same; |
|
73 | 72 |
uint16_t rtype, type; |
74 | 73 |
uint32_t offdata[4], offset_min, offset_max; |
75 | 74 |
uint32_t boundary; |
76 | 75 |
uint8_t depth; |
76 |
+ uint8_t nocase; |
|
77 |
+}; |
|
78 |
+ |
|
79 |
+struct cli_ac_pattlist { |
|
80 |
+ struct cli_ac_patt *me; |
|
81 |
+ struct cli_ac_pattlist *next, *next_same; |
|
77 | 82 |
}; |
78 | 83 |
|
79 | 84 |
struct cli_ac_node { |
80 |
- struct cli_ac_patt *list; |
|
85 |
+ struct cli_ac_pattlist *list; |
|
81 | 86 |
struct cli_ac_node **trans, *fail; |
82 | 87 |
}; |
83 | 88 |
|
... | ... |
@@ -34,6 +34,7 @@ const char *cli_strcasestr(const char *haystack, const char *needle); |
34 | 34 |
|
35 | 35 |
#include <stdio.h> |
36 | 36 |
#define cli_nocase(val) tolower(val) |
37 |
+#define cli_nocasei(val) toupper(val) |
|
37 | 38 |
|
38 | 39 |
int cli_strbcasestr(const char *haystack, const char *needle); |
39 | 40 |
int cli_chomp(char *string); |