... | ... |
@@ -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 |
} |