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