Browse code

implemented second nocase AC matcher using full enumerations

Kevin Lin authored on 2015/02/10 12:28:39
Showing 3 changed files
... ...
@@ -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);