Browse code

moved sigopts handler to separate function reason: sigopts weren't handled for yara sigs

Kevin Lin authored on 2015/02/25 03:37:09
Showing 2 changed files
... ...
@@ -41,6 +41,8 @@
41 41
 #define ACPATT_OPTION_WIDE     0x04
42 42
 #define ACPATT_OPTION_ASCII    0x08
43 43
 
44
+#define ACPATT_OPTION_ONCE     0x80
45
+
44 46
 struct cli_ac_data {
45 47
     int32_t ***offmatrix;
46 48
     uint32_t partsigs, lsigs, reloffsigs;
... ...
@@ -115,6 +115,110 @@ char *cli_virname(const char *virname, unsigned int official)
115 115
     return newname;
116 116
 }
117 117
 
118
+static int sigopts_handler(struct cli_matcher *root, const char *virname, const char *hexsig, uint8_t sigopts, uint16_t rtype, uint16_t type, const char *offset, uint8_t target, const uint32_t *lsigid, unsigned int options)
119
+{
120
+    char *hexcpy;
121
+    int i, ret = CL_SUCCESS;
122
+
123
+    cli_errmsg("%s: %s %02x\n", virname, hexsig, sigopts);
124
+
125
+    if (sigopts && !(sigopts & ACPATT_OPTION_ONCE)) {
126
+        hexcpy = cli_strdup(hexsig);
127
+        if (!hexcpy)
128
+            return CL_EMEM;
129
+
130
+        sigopts |= ACPATT_OPTION_ONCE;
131
+
132
+        /* FULLWORD sigopt handling - only happens once */
133
+        if (sigopts & ACPATT_OPTION_FULLWORD) {
134
+            char *rechar;
135
+            char *hexovr = cli_calloc(strlen(hexcpy)+7, sizeof(char));
136
+            if (!hexovr)
137
+                return CL_EMEM;
138
+
139
+            snprintf(hexovr, strlen(hexcpy)+7, "(W)%s(W)", hexcpy);
140
+
141
+            /* change the '[' and ']' to '{' and '}' since there are now two bytes */
142
+            rechar = hexovr;
143
+            while ((rechar = strchr(rechar, '['))) { //TEST TODO
144
+                *rechar = '{';
145
+
146
+                if (!(rechar = strchr(rechar, ']'))) {
147
+                    cli_errmsg("cli_parse_add: unmatched '[' in signature %s\n", virname);
148
+                    return CL_EMALFDB;
149
+                }
150
+                *rechar = '}';
151
+            }
152
+
153
+            free(hexcpy);
154
+            hexcpy = hexovr;
155
+        }
156
+
157
+        /* WIDE sigopt handling - only happens once (after fullword)
158
+         * TODO - consider handling in cli_ac_addpatt? (two pattern possibility)
159
+         */
160
+        if (sigopts & ACPATT_OPTION_WIDE) {
161
+            size_t ovrlen = 2*strlen(hexcpy)+1;
162
+            char *hexovr = cli_calloc(ovrlen, sizeof(char));
163
+            if (!hexovr)
164
+                return CL_EMEM;
165
+
166
+            /* clamav-specific wildcards need to be handled here! */
167
+            for (i = 0; i < strlen(hexcpy); ++i) {
168
+                size_t len = strlen(hexovr);
169
+
170
+                if (hexcpy[i] == '*' || hexcpy[i] == '|' || hexcpy[i] == ')') {
171
+                    hexovr[len] = hexcpy[i];
172
+                } else if (hexcpy[i] == '[') {
173
+                    /* change the '[' and ']' to '{' and '}' since there are now two bytes */
174
+                    hexovr[len++] = '{';
175
+                    ++i;
176
+                    while (i < strlen(hexcpy) && hexcpy[i] != ']')
177
+                        hexovr[len++] = hexcpy[i++];
178
+
179
+                    hexovr[len] = '}';
180
+                } else if (hexcpy[i] == '{') {
181
+                    while (i < strlen(hexcpy) && hexcpy[i] != '}')
182
+                        hexovr[len++] = hexcpy[i++];
183
+
184
+                    hexovr[len] = '}';
185
+                } else if (hexcpy[i] == '!' || hexcpy[i] == '(') {
186
+                    if (hexcpy[i] == '!')
187
+                        hexovr[len++] = hexcpy[i++];
188
+
189
+                    /* copies '(' */
190
+                    hexovr[len] = hexcpy[i];
191
+
192
+                    if (hexcpy[i+1] == 'B' || hexcpy[i+1] == 'L' || hexcpy[i+1] == 'W') {
193
+                        ++len; ++i;
194
+                        hexovr[len++] = hexcpy[i++];
195
+                        if (hexcpy[i] != ')') {
196
+                            return CL_EMALFDB;
197
+                        }
198
+                        hexovr[len] = hexcpy[i];
199
+                    }
200
+                } else {
201
+                    //snprintf(hexovr+len, ovrlen-len, "%02x%c%c", 0, hexcpy[i], hexcpy[i+1]);
202
+                    snprintf(hexovr+len, ovrlen-len, "%c%c%02x", hexcpy[i], hexcpy[i+1], 0);
203
+                    ++i;
204
+                }
205
+            }
206
+
207
+            /* NOCASE sigopt is handled in cli_ac_addsig */
208
+            ret = cli_parse_add(root, virname, hexovr, sigopts, rtype, type, offset, target, lsigid, options);
209
+            if (ret != CL_SUCCESS || !(sigopts & ACPATT_OPTION_ASCII)) {
210
+                free(hexcpy);
211
+                return ret;
212
+            }
213
+        }
214
+    }
215
+
216
+    /* NOCASE sigopt is handled in cli_ac_addsig */
217
+    ret = cli_parse_add(root, virname, hexcpy, sigopts, rtype, type, offset, target, lsigid, options);
218
+    free(hexcpy);
219
+    return ret;
220
+}
221
+
118 222
 #define PCRE_TOKENS 4
119 223
 int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hexsig, uint8_t sigopts, uint16_t rtype, uint16_t type, const char *offset, uint8_t target, const uint32_t *lsigid, unsigned int options)
120 224
 {
... ...
@@ -251,91 +355,7 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex
251 251
                 opt++;
252 252
             }
253 253
 
254
-            /* FULLWORD sigopt handling - only happens once */
255
-            if (sigopts & ACPATT_OPTION_FULLWORD) {
256
-                char *rechar;
257
-                char *hexovr = cli_calloc(strlen(hexcpy)+7, sizeof(char));
258
-                if (!hexovr)
259
-                    return CL_EMEM;
260
-
261
-                snprintf(hexovr, strlen(hexcpy)+7, "(W)%s(W)", hexcpy);
262
-
263
-                /* change the '[' and ']' to '{' and '}' since there are now two bytes */
264
-                rechar = hexovr;
265
-                while ((rechar = strchr(rechar, '['))) { //TEST TODO
266
-                    *rechar = '{';
267
-
268
-                    if (!(rechar = strchr(rechar, ']'))) {
269
-                        cli_errmsg("cli_parse_add: unmatched '[' in signature %s\n", virname);
270
-                        return CL_EMALFDB;
271
-                    }
272
-                    *rechar = '}';
273
-                }
274
-
275
-                free(hexcpy);
276
-                hexcpy = hexovr;
277
-            }
278
-
279
-            /* WIDE sigopt handling - only happens once (after fullword)
280
-             * TODO - consider handling in cli_ac_addpatt? (two pattern possibility)
281
-             */
282
-            if (sigopts & ACPATT_OPTION_WIDE) {
283
-                size_t ovrlen = 2*strlen(hexcpy)+1;
284
-                char *hexovr = cli_calloc(ovrlen, sizeof(char));
285
-                if (!hexovr)
286
-                    return CL_EMEM;
287
-
288
-                /* clamav-specific wildcards need to be handled here! */
289
-                for (i = 0; i < strlen(hexcpy); ++i) {
290
-                    size_t len = strlen(hexovr);
291
-
292
-                    if (hexcpy[i] == '*' || hexcpy[i] == '|' || hexcpy[i] == ')') {
293
-                        hexovr[len] = hexcpy[i];
294
-                    } else if (hexcpy[i] == '[') {
295
-                        /* change the '[' and ']' to '{' and '}' since there are now two bytes */
296
-                        hexovr[len++] = '{';
297
-                        ++i;
298
-                        while (i < strlen(hexcpy) && hexcpy[i] != ']')
299
-                            hexovr[len++] = hexcpy[i++];
300
-
301
-                        hexovr[len] = '}';
302
-                    } else if (hexcpy[i] == '{') {
303
-                        while (i < strlen(hexcpy) && hexcpy[i] != '}')
304
-                            hexovr[len++] = hexcpy[i++];
305
-
306
-                        hexovr[len] = '}';
307
-                    } else if (hexcpy[i] == '!' || hexcpy[i] == '(') {
308
-                        if (hexcpy[i] == '!')
309
-                            hexovr[len++] = hexcpy[i++];
310
-
311
-                        /* copies '(' */
312
-                        hexovr[len] = hexcpy[i];
313
-
314
-                        if (hexcpy[i+1] == 'B' || hexcpy[i+1] == 'L' || hexcpy[i+1] == 'W') {
315
-                            ++len; ++i;
316
-                            hexovr[len++] = hexcpy[i++];
317
-                            if (hexcpy[i] != ')') {
318
-                                return CL_EMALFDB;
319
-                            }
320
-                            hexovr[len] = hexcpy[i];
321
-                        }
322
-                   } else {
323
-                        //snprintf(hexovr+len, ovrlen-len, "%02x%c%c", 0, hexcpy[i], hexcpy[i+1]);
324
-                        snprintf(hexovr+len, ovrlen-len, "%c%c%02x", hexcpy[i], hexcpy[i+1], 0);
325
-                        ++i;
326
-                    }
327
-                }
328
-
329
-                /* get called; NOCASE sigopt is handled in cli_ac_addsig */
330
-                ret = cli_parse_add(root, virname, hexovr, sigopts, rtype, type, offset, target, lsigid, options);
331
-                if (ret != CL_SUCCESS || !(sigopts & ACPATT_OPTION_ASCII)) {
332
-                    free(hexcpy);
333
-                    return ret;
334
-                }
335
-            }
336
-
337
-            /* get called; NOCASE sigopt is handled in cli_ac_addsig */
338
-            ret = cli_parse_add(root, virname, hexcpy, sigopts, rtype, type, offset, target, lsigid, options);
254
+            ret = sigopts_handler(root, virname, hexcpy, sigopts, rtype, type, offset, target, lsigid, options);
339 255
             free(hexcpy);
340 256
             return ret;
341 257
         }
... ...
@@ -3469,9 +3489,13 @@ static int load_oneyara(YR_RULE *rule, struct cl_engine *engine, unsigned int op
3469 3469
     for (i = 0; i < ytable.tbl_cnt; ++i) {
3470 3470
         lsigid[1] = i;
3471 3471
 
3472
-        cli_yaramsg("%d: [%s] [%s] [%x]\n", i, ytable.table[i]->hexstr, ytable.table[i]->offset, ytable.table[i]->sigopts);
3472
+        cli_yaramsg("%d: [%s] [%s] [%s%s%s%s]\n", i, ytable.table[i]->hexstr, ytable.table[i]->offset,
3473
+                    (ytable.table[i]->sigopts & ACPATT_OPTION_NOCASE) ? "i" : "",
3474
+                    (ytable.table[i]->sigopts & ACPATT_OPTION_FULLWORD) ? "f" : "",
3475
+                    (ytable.table[i]->sigopts & ACPATT_OPTION_WIDE) ? "w" : "",
3476
+                    (ytable.table[i]->sigopts & ACPATT_OPTION_ASCII) ? "a" : "");
3473 3477
 
3474
-        if((ret = cli_parse_add(root, rule->id, ytable.table[i]->hexstr, ytable.table[i]->sigopts, 0, 0, ytable.table[i]->offset, target, lsigid, options)) != CL_SUCCESS) {
3478
+        if((ret = sigopts_handler(root, rule->id, ytable.table[i]->hexstr, ytable.table[i]->sigopts, 0, 0, ytable.table[i]->offset, target, lsigid, options)) != CL_SUCCESS) {
3475 3479
             yara_malform++;
3476 3480
             return ret;
3477 3481
         }