1 /*
2 Copyright (c) 2013. The YARA Authors. All Rights Reserved.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 #include <string.h>
18 #include <assert.h>
19 #include <time.h>
20
21 #if REAL_YARA
22 #include <yara/exec.h>
23 #include <yara/limits.h>
24 #include <yara/error.h>
25 #include <yara/object.h>
26 #include <yara/modules.h>
27 #include <yara/re.h>
28
29
30 #include <yara.h>
31 #else
32 #include <stdint.h>
33 //Temp for ClamAV compilation
34 typedef struct _YR_MATCH
35 {
36 int64_t base;
37 int64_t offset;
38 int32_t length;
39
40 union {
41 uint8_t* data; // Confirmed matches use "data",
42 int32_t chain_length; // unconfirmed ones use "chain_length"
43 };
44
45 struct _YR_MATCH* prev;
46 struct _YR_MATCH* next;
47
48 } YR_MATCH;
49
50 // End of temp for clamAV
51 #include "matcher.h"
52 #include "matcher-ac.h"
53 #include "yara_clam.h"
54 #include "yara_exec.h"
55 #endif
56
57 #define STACK_SIZE 16384
58 #define MEM_SIZE MAX_LOOP_NESTING * LOOP_LOCAL_VARS
59
60
61 #define push(x) \
62 do { \
63 if (sp < STACK_SIZE) stack[sp++] = (x); \
64 else return ERROR_EXEC_STACK_OVERFLOW; \
65 } while(0)
66
67
68 #define pop(x) x = stack[--sp]
69
70
71 #define operation(operator, op1, op2) \
72 (IS_UNDEFINED(op1) || IS_UNDEFINED(op2)) ? (UNDEFINED) : (op1 operator op2)
73
74
75 #define comparison(operator, op1, op2) \
76 (IS_UNDEFINED(op1) || IS_UNDEFINED(op2)) ? (0) : (op1 operator op2)
77
78
79 #if REAL_YARA
80 #define function_read(type) \
81 int64_t read_##type(YR_MEMORY_BLOCK* block, size_t offset) \
82 { \
83 while (block != NULL) \
84 { \
85 if (offset >= block->base && \
86 block->size >= sizeof(type) && \
87 offset <= block->base + block->size - sizeof(type)) \
88 { \
89 return *((type *) (block->data + offset - block->base)); \
90 } \
91 block = block->next; \
92 } \
93 return UNDEFINED; \
94 };
95 #else
96 #define function_read(type) \
97 int64_t read_##type(fmap_t * fmap, size_t offset) \
98 { \
99 const void *data; \
100 if (offset + sizeof(type) >= fmap->len) \
101 return UNDEFINED; \
102 data = fmap_need_off_once(fmap, offset, sizeof(type)); \
103 if (!data) \
104 return UNDEFINED; \
105 return *((type *) data); \
106 };
107 #endif
108
109 function_read(uint8_t)
function_read(uint16_t)110 function_read(uint16_t)
111 function_read(uint32_t)
112 function_read(int8_t)
113 function_read(int16_t)
114 function_read(int32_t)
115
116 int yr_execute_code(
117 #if REAL_YARA
118 YR_RULES* rules,
119 #else
120 struct cli_ac_lsig * aclsig,
121 struct cli_ac_data * acdata,
122 #endif
123 YR_SCAN_CONTEXT* context,
124 int timeout,
125 time_t start_time)
126 {
127 int64_t r1;
128 int64_t r2;
129 int64_t r3;
130 int64_t mem[MEM_SIZE];
131 int64_t stack[STACK_SIZE];
132 int64_t args[MAX_FUNCTION_ARGS];
133 int32_t sp = 0;
134 #if REAL_YARA
135 uint8_t* ip = rules->code_start;
136 #else
137 uint8_t* ip = aclsig->u.code_start;
138 uint32_t lsig_id;
139 uint32_t rule_matches = 0;
140 struct cli_lsig_matches * ls_matches;
141 struct cli_subsig_matches * ss_matches;
142 uint32_t * offs;
143 #endif
144
145 YR_RULE* rule;
146 YR_STRING* string;
147 #if REAL_YARA
148 YR_MATCH* match;
149 #endif
150 YR_OBJECT* object;
151 YR_OBJECT_FUNCTION* function;
152
153 char* identifier;
154
155 uint32_t i_u32;
156 int64_t i_i64;
157 int found;
158 int count;
159 int result = -1;
160 int cycle = 0;
161 #if REAL_YARA
162 int tidx = yr_get_tidx();
163 #else
164
165 cli_dbgmsg("yara_exec: beginning execution for lsig %u (%s)\n", aclsig->id, aclsig->virname);
166 #endif
167
168 #ifdef PROFILING_ENABLED
169 clock_t start = clock();
170 #endif
171
172 while(1)
173 {
174 cli_dbgmsg("yara_exec: executing %d\n", *ip);
175 switch(*ip)
176 {
177 case OP_HALT:
178 // When the halt instruction is reached the stack
179 // should be empty.
180 if (sp != 0) {
181 cli_dbgmsg("error executing yara rule, stack should be empty when halt instruction reached\n");
182 return CL_EPARSE;
183 }
184 #if REAL_YARA
185 return ERROR_SUCCESS;
186 #else
187 if (rule_matches != 0)
188 return CL_VIRUS;
189 return CL_SUCCESS;
190 #endif
191
192 case OP_PUSH:
193 memcpy(&r1, ip + 1, sizeof(uint64_t));
194 ip += sizeof(uint64_t);
195 push(r1);
196 break;
197
198 case OP_POP:
199 pop(r1);
200 break;
201
202 case OP_CLEAR_M:
203 memcpy(&r1, ip + 1, sizeof(uint64_t));
204 ip += sizeof(uint64_t);
205 mem[r1] = 0;
206 break;
207
208 case OP_ADD_M:
209 memcpy(&r1, ip + 1, sizeof(uint64_t));
210 ip += sizeof(uint64_t);
211 pop(r2);
212 mem[r1] += r2;
213 break;
214
215 case OP_INCR_M:
216 memcpy(&r1, ip + 1, sizeof(uint64_t));
217 ip += sizeof(uint64_t);
218 mem[r1]++;
219 break;
220
221 case OP_PUSH_M:
222 memcpy(&r1, ip + 1, sizeof(uint64_t));
223 ip += sizeof(uint64_t);
224 push(mem[r1]);
225 break;
226
227 case OP_POP_M:
228 memcpy(&r1, ip + 1, sizeof(uint64_t));
229 ip += sizeof(uint64_t);
230 pop(mem[r1]);
231 break;
232
233 case OP_SWAPUNDEF:
234 memcpy(&r1, ip + 1, sizeof(uint64_t));
235 ip += sizeof(uint64_t);
236 pop(r2);
237 if (r2 != UNDEFINED)
238 push(r2);
239 else
240 push(mem[r1]);
241 break;
242
243 case OP_JNUNDEF:
244 pop(r1);
245 push(r1);
246
247 if (r1 != UNDEFINED)
248 {
249 ip = *(uint8_t**)(ip + 1);
250 // ip will be incremented at the end of the loop,
251 // decrement it here to compensate.
252 ip--;
253 }
254 else
255 {
256 ip += sizeof(uint64_t);
257 }
258 break;
259
260 case OP_JLE:
261 pop(r2);
262 pop(r1);
263 push(r1);
264 push(r2);
265
266 if (r1 <= r2)
267 {
268 ip = *(uint8_t**)(ip + 1);
269 // ip will be incremented at the end of the loop,
270 // decrement it here to compensate.
271 ip--;
272 }
273 else
274 {
275 ip += sizeof(uint64_t);
276 }
277 break;
278
279 case OP_AND:
280 pop(r2);
281 pop(r1);
282 if (IS_UNDEFINED(r1) || IS_UNDEFINED(r2))
283 push(0);
284 else
285 push(r1 & r2);
286 break;
287
288 case OP_OR:
289 pop(r2);
290 pop(r1);
291 if (IS_UNDEFINED(r1))
292 push(r2);
293 else if (IS_UNDEFINED(r2))
294 push(r1);
295 else
296 push(r1 | r2);
297 break;
298
299 case OP_NOT:
300 pop(r1);
301 if (IS_UNDEFINED(r1))
302 push(UNDEFINED);
303 else
304 push(!r1);
305 break;
306
307 case OP_LT:
308 pop(r2);
309 pop(r1);
310 push(comparison(<, r1, r2));
311 break;
312
313 case OP_GT:
314 pop(r2);
315 pop(r1);
316 push(comparison(>, r1, r2));
317 break;
318
319 case OP_LE:
320 pop(r2);
321 pop(r1);
322 push(comparison(<=, r1, r2));
323 break;
324
325 case OP_GE:
326 pop(r2);
327 pop(r1);
328 push(comparison(>=, r1, r2));
329 break;
330
331 case OP_EQ:
332 pop(r2);
333 pop(r1);
334 push(comparison(==, r1, r2));
335 break;
336
337 case OP_NEQ:
338 pop(r2);
339 pop(r1);
340 push(comparison(!=, r1, r2));
341 break;
342
343 case OP_SZ_EQ:
344 pop(r2);
345 pop(r1);
346
347 if (IS_UNDEFINED(r1) || IS_UNDEFINED(r2))
348 push(UNDEFINED);
349 else
350 push(strcmp(UINT64_TO_PTR(char*, r1),
351 UINT64_TO_PTR(char*, r2)) == 0);
352 break;
353
354 case OP_SZ_NEQ:
355 pop(r2);
356 pop(r1);
357
358 if (IS_UNDEFINED(r1) || IS_UNDEFINED(r2))
359 push(UNDEFINED);
360 else
361 push(strcmp(UINT64_TO_PTR(char*, r1),
362 UINT64_TO_PTR(char*, r2)) != 0);
363 break;
364
365 case OP_SZ_TO_BOOL:
366 pop(r1);
367
368 if (IS_UNDEFINED(r1))
369 push(UNDEFINED);
370 else
371 push(strlen(UINT64_TO_PTR(char*, r1)) > 0);
372
373 break;
374
375 case OP_ADD:
376 pop(r2);
377 pop(r1);
378 push(operation(+, r1, r2));
379 break;
380
381 case OP_SUB:
382 pop(r2);
383 pop(r1);
384 push(operation(-, r1, r2));
385 break;
386
387 case OP_MUL:
388 pop(r2);
389 pop(r1);
390 push(operation(*, r1, r2));
391 break;
392
393 case OP_DIV:
394 pop(r2);
395 pop(r1);
396 push(operation(/, r1, r2));
397 break;
398
399 case OP_MOD:
400 pop(r2);
401 pop(r1);
402 push(operation(%, r1, r2));
403 break;
404
405 case OP_NEG:
406 pop(r1);
407 push(IS_UNDEFINED(r1) ? UNDEFINED : ~r1);
408 break;
409
410 case OP_SHR:
411 pop(r2);
412 pop(r1);
413 push(operation(>>, r1, r2));
414 break;
415
416 case OP_SHL:
417 pop(r2);
418 pop(r1);
419 push(operation(<<, r1, r2));
420 break;
421
422 case OP_XOR:
423 pop(r2);
424 pop(r1);
425 push(operation(^, r1, r2));
426 break;
427
428 case OP_PUSH_RULE:
429 rule = *(YR_RULE**)(ip + 1);
430 ip += sizeof(uint64_t);
431 #if REAL_YARA
432 push(rule->t_flags[tidx] & RULE_TFLAGS_MATCH ? 1 : 0);
433 #else
434 push(acdata->yr_matches[rule->lsigid]);
435 #endif
436 break;
437
438 case OP_MATCH_RULE:
439 pop(r1);
440 rule = *(YR_RULE**)(ip + 1);
441 ip += sizeof(uint64_t);
442
443 if (!IS_UNDEFINED(r1) && r1)
444 #if REAL_YARA
445 rule->t_flags[tidx] |= RULE_TFLAGS_MATCH;
446 #else
447 {
448 rule_matches++;
449 acdata->yr_matches[aclsig->id] = 1;
450 }
451 #endif
452
453 #ifdef PROFILING_ENABLED
454 rule->clock_ticks += clock() - start;
455 start = clock();
456 #endif
457 break;
458
459 case OP_OBJ_LOAD:
460 identifier = *(char**)(ip + 1);
461 ip += sizeof(uint64_t);
462
463 object = (YR_OBJECT*) yr_hash_table_lookup(
464 context->objects_table,
465 identifier,
466 NULL);
467
468 assert(object != NULL);
469 push(PTR_TO_UINT64(object));
470 break;
471
472 #if REAL_YARA
473 case OP_OBJ_FIELD:
474 pop(r1);
475
476 identifier = *(char**)(ip + 1);
477 ip += sizeof(uint64_t);
478
479 if (IS_UNDEFINED(r1))
480 {
481 push(UNDEFINED);
482 break;
483 }
484
485 object = UINT64_TO_PTR(YR_OBJECT*, r1);
486 object = yr_object_lookup_field(object, identifier);
487 assert(object != NULL);
488 push(PTR_TO_UINT64(object));
489 break;
490 #endif
491
492 case OP_OBJ_VALUE:
493 pop(r1);
494
495 if (IS_UNDEFINED(r1))
496 {
497 push(UNDEFINED);
498 break;
499 }
500
501 object = UINT64_TO_PTR(YR_OBJECT*, r1);
502
503 switch(object->type)
504 {
505 case OBJECT_TYPE_INTEGER:
506 push(((YR_OBJECT_INTEGER*) object)->value);
507 break;
508
509 case OBJECT_TYPE_STRING:
510 if (((YR_OBJECT_STRING*) object)->value != NULL)
511 push(PTR_TO_UINT64(((YR_OBJECT_STRING*) object)->value));
512 else
513 push(UNDEFINED);
514 break;
515
516 default:
517 assert(FALSE);
518 }
519
520 break;
521
522 #if REAL_YARA
523 case OP_INDEX_ARRAY:
524 pop(r1);
525 pop(r2);
526
527 if (r1 == UNDEFINED)
528 {
529 push(UNDEFINED);
530 break;
531 }
532
533 object = UINT64_TO_PTR(YR_OBJECT*, r2);
534 assert(object->type == OBJECT_TYPE_ARRAY);
535 object = yr_object_array_get_item(object, 0, r1);
536
537 if (object != NULL)
538 push(PTR_TO_UINT64(object));
539 else
540 push(UNDEFINED);
541
542 break;
543 #endif
544
545 case OP_CALL:
546
547 // r1 = number of arguments
548
549 memcpy(&r1, ip + 1, sizeof(uint64_t));
550 ip += sizeof(uint64_t);
551
552 // pop arguments from stack and copy them to args array
553
554 while (r1 > 0)
555 {
556 pop(args[r1 - 1]);
557 r1--;
558 }
559
560 pop(r2);
561
562 function = UINT64_TO_PTR(YR_OBJECT_FUNCTION*, r2);
563 result = function->code((void*) args, context, function);
564
565 if (result == ERROR_SUCCESS)
566 push(PTR_TO_UINT64(function->return_obj));
567 else
568 return result;
569
570 break;
571
572 case OP_STR_FOUND:
573 pop(r1);
574 string = UINT64_TO_PTR(YR_STRING*, r1);
575 #if REAL_YARA
576 push(string->matches[tidx].tail != NULL ? 1 : 0);
577 #else
578 push(acdata->lsigsuboff_first[aclsig->id][string->subsig_id] != CLI_OFF_NONE ? 1 : 0);
579 #endif
580 break;
581
582 case OP_STR_FOUND_AT:
583 pop(r2);
584 pop(r1);
585
586 if (IS_UNDEFINED(r1))
587 {
588 push(0);
589 break;
590 }
591
592 string = UINT64_TO_PTR(YR_STRING*, r2);
593 #if REAL_YARA
594 match = string->matches[tidx].head;
595 found = 0;
596
597 while (match != NULL)
598 {
599 if (r1 == match->base + match->offset)
600 {
601 push(1);
602 found = 1;
603 break;
604 }
605
606 if (r1 < match->base + match->offset)
607 break;
608
609 match = match->next;
610 }
611 #else
612 found = 0;
613 ls_matches = acdata->lsig_matches[aclsig->id];
614 if (ls_matches != NULL) {
615 ss_matches = ls_matches->matches[string->subsig_id];
616 if (ss_matches != NULL) {
617 offs = ss_matches->offsets;
618 for (i_u32 = 0; i_u32 < ss_matches->next; i_u32++) {
619 if (offs[i_u32] == r1) {
620 push(1);
621 found = 1;
622 break;
623 }
624 if (r1 < offs[i_u32])
625 break;
626 }
627 }
628 }
629 #endif
630 if (!found)
631 push(0);
632
633 break;
634
635 case OP_STR_FOUND_IN:
636 pop(r3);
637 pop(r2);
638 pop(r1);
639
640 if (IS_UNDEFINED(r1) || IS_UNDEFINED(r2))
641 {
642 push(0);
643 break;
644 }
645
646 string = UINT64_TO_PTR(YR_STRING*, r3);
647 #if REAL_YARA
648 match = string->matches[tidx].head;
649 found = FALSE;
650
651 while (match != NULL && !found)
652 {
653 if (match->base + match->offset >= r1 &&
654 match->base + match->offset <= r2)
655 {
656 push(1);
657 found = TRUE;
658 }
659
660 if (match->base + match->offset > r2)
661 break;
662
663 match = match->next;
664 }
665 #else
666 found = FALSE;
667 ls_matches = acdata->lsig_matches[aclsig->id];
668 if (ls_matches != NULL) {
669 ss_matches = ls_matches->matches[string->subsig_id];
670 if (ss_matches != NULL) {
671 offs = ss_matches->offsets;
672 for (i_u32 = 0; i_u32 < ss_matches->next; i_u32++) {
673 if (offs[i_u32] >= r1 &&
674 offs[i_u32] <= r2) {
675 push(1);
676 found = TRUE;
677 break;
678 }
679 if (r2 < offs[i_u32])
680 break;
681 }
682 }
683 }
684 #endif
685
686 if (!found)
687 push(0);
688
689 break;
690
691 case OP_STR_COUNT:
692 pop(r1);
693 string = UINT64_TO_PTR(YR_STRING*, r1);
694 #if REAL_YARA
695 push(string->matches[tidx].count);
696 #else
697 push(acdata->lsigcnt[aclsig->id][string->subsig_id]);
698 #endif
699 break;
700
701 case OP_STR_OFFSET:
702 pop(r2);
703 pop(r1);
704
705 if (IS_UNDEFINED(r1))
706 {
707 push(UNDEFINED);
708 break;
709 }
710
711 string = UINT64_TO_PTR(YR_STRING*, r2);
712 #if REAL_YARA
713 match = string->matches[tidx].head;
714 i_i64 = 1;
715 found = FALSE;
716
717 while (match != NULL && !found)
718 {
719 if (r1 == i_i64)
720 {
721 push(match->base + match->offset);
722 found = TRUE;
723 }
724
725 i_i64++;
726 match = match->next;
727 }
728 #else
729 i_i64 = r1 - 1;
730 found = FALSE;
731 ls_matches = acdata->lsig_matches[aclsig->id];
732 if (ls_matches != NULL && i_i64 >= 0) {
733 ss_matches = ls_matches->matches[string->subsig_id];
734 if (ss_matches != NULL) {
735 if (i_i64 < ss_matches->next) {
736 push(ss_matches->offsets[i_i64]);
737 found = TRUE;
738 }
739 }
740 }
741 #endif
742
743 if (!found)
744 push(UNDEFINED);
745
746 break;
747
748 case OP_OF:
749 found = 0;
750 count = 0;
751 pop(r1);
752
753 #if REAL_YARA
754 while (r1 != UNDEFINED)
755 {
756 string = UINT64_TO_PTR(YR_STRING*, r1);
757 if (string->matches[tidx].tail != NULL)
758 found++;
759 count++;
760 pop(r1);
761 }
762 #else
763 while (r1 != UNDEFINED)
764 {
765 string = UINT64_TO_PTR(YR_STRING*, r1);
766 lsig_id = string->subsig_id;
767 if (acdata->lsigsuboff_first[aclsig->id][lsig_id] != CLI_OFF_NONE)
768 found++;
769 count++;
770 pop(r1);
771 }
772 #endif
773
774 pop(r2);
775
776 if (r2 != UNDEFINED)
777 push(found >= r2 ? 1 : 0);
778 else
779 push(found >= count ? 1 : 0);
780
781 break;
782
783 case OP_FILESIZE:
784 push(context->file_size);
785 break;
786
787 case OP_ENTRYPOINT:
788 push(context->entry_point);
789 break;
790
791 #if REAL_YARA
792 case OP_INT8:
793 pop(r1);
794 push(read_int8_t(context->mem_block, r1));
795 break;
796
797 case OP_INT16:
798 pop(r1);
799 push(read_int16_t(context->mem_block, r1));
800 break;
801
802 case OP_INT32:
803 pop(r1);
804 push(read_int32_t(context->mem_block, r1));
805 break;
806
807 case OP_UINT8:
808 pop(r1);
809 push(read_uint8_t(context->mem_block, r1));
810 break;
811
812 case OP_UINT16:
813 pop(r1);
814 push(read_uint16_t(context->mem_block, r1));
815 break;
816
817 case OP_UINT32:
818 pop(r1);
819 push(read_uint32_t(context->mem_block, r1));
820 break;
821 #else
822 case OP_INT8:
823 pop(r1);
824 push(read_int8_t(context->fmap, r1));
825 break;
826
827 case OP_INT16:
828 pop(r1);
829 push(read_int16_t(context->fmap, r1));
830 break;
831
832 case OP_INT32:
833 pop(r1);
834 push(read_int32_t(context->fmap, r1));
835 break;
836
837 case OP_UINT8:
838 pop(r1);
839 push(read_uint8_t(context->fmap, r1));
840 break;
841
842 case OP_UINT16:
843 pop(r1);
844 push(read_uint16_t(context->fmap, r1));
845 break;
846
847 case OP_UINT32:
848 pop(r1);
849 push(read_uint32_t(context->fmap, r1));
850 break;
851 #endif
852
853 case OP_CONTAINS:
854 pop(r2);
855 pop(r1);
856 push(strstr(UINT64_TO_PTR(char*, r1),
857 UINT64_TO_PTR(char*, r2)) != NULL);
858 break;
859
860
861 #if REAL_YARA //not supported ClamAV
862 case OP_IMPORT:
863 memcpy(&r1, ip + 1, sizeof(uint64_t));
864 ip += sizeof(uint64_t);
865
866 FAIL_ON_ERROR(yr_modules_load(
867 UINT64_TO_PTR(char*, r1),
868 context));
869
870 break;
871 #endif
872
873 case OP_MATCHES:
874 pop(r2);
875 pop(r1);
876
877 count = strlen(UINT64_TO_PTR(char*, r1));
878
879 if (count == 0)
880 {
881 push(FALSE);
882 break;
883 }
884
885 #if REAL_YARA
886 result = yr_re_exec(
887 UINT64_TO_PTR(uint8_t*, r2),
888 UINT64_TO_PTR(uint8_t*, r1),
889 count,
890 RE_FLAGS_SCAN,
891 NULL,
892 NULL);
893 #else
894 result = -1; //matches not currently supported in ClamAV. push(FALSE).
895 #endif
896
897 push(result >= 0);
898 break;
899
900 default:
901 // Unknown instruction, this shouldn't happen.
902 assert(FALSE);
903 }
904
905 if (timeout > 0) // timeout == 0 means no timeout
906 {
907 // Check for timeout every 10 instruction cycles.
908
909 if (++cycle == 10)
910 {
911 if (difftime(time(NULL), start_time) > timeout)
912 return ERROR_SCAN_TIMEOUT;
913
914 cycle = 0;
915 }
916 }
917
918 ip++;
919 }
920
921 // After executing the code the stack should be empty.
922 assert(sp == 0);
923
924 return ERROR_SUCCESS;
925 }
926