Browse code

Add YARA condition evaluation function. Add support for YARA 'of' clauses.

Steven Morgan authored on 2015/03/19 07:26:59
Showing 5 changed files
... ...
@@ -55,6 +55,7 @@
55 55
 #include "perflogging.h"
56 56
 #include "bytecode_priv.h"
57 57
 #include "bytecode_api_impl.h"
58
+#include "yara_clam.h"
58 59
 
59 60
 #ifdef CLI_PERF_LOGGING
60 61
 
... ...
@@ -751,7 +752,17 @@ static int lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data
751 751
 
752 752
 static int yara_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acdata, struct cli_target_info *target_info, const char *hash, uint32_t lsid)
753 753
 {
754
-    return CL_CLEAN;
754
+    struct cli_ac_lsig *ac_lsig = root->ac_lsigtable[lsid];
755
+    uint8_t * code_start = ac_lsig->u.code_start;
756
+    int rc = 0;
757
+    YR_SCAN_CONTEXT context = {0}; //FIXME (populate from ldb)
758
+  
759
+    rc = yr_execute_code(ac_lsig, acdata, &context, 0, 0);
760
+
761
+    if (rc == CL_VIRUS)
762
+        cli_append_virus(ctx, ac_lsig->virname);
763
+
764
+    return rc;
755 765
 }
756 766
 
757 767
 int cli_exp_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acdata, struct cli_target_info *target_info, const char *hash)
... ...
@@ -3456,6 +3456,7 @@ static int load_oneyara(YR_RULE *rule, struct cl_engine *engine, unsigned int op
3456 3456
             cli_yaramsg("STRING_FITS_IN_ATOM       yes\n");
3457 3457
         */
3458 3458
 #endif
3459
+        string->subsig_id = ytable.tbl_cnt;
3459 3460
     }
3460 3461
 
3461 3462
     if (str_error > 0) {
... ...
@@ -3651,10 +3652,10 @@ static int cli_loadyara(FILE *fs, struct cl_engine *engine, unsigned int *signo,
3651 3651
         cli_errmsg("cli_loadyara: failed to parse rules file %s, error count %i\n", dbname, rc);
3652 3652
         yr_hash_table_destroy(compiler.rules_table, NULL);
3653 3653
         yr_hash_table_destroy(compiler.objects_table, NULL);
3654
-        yr_arena_destroy(compiler.sz_arena);
3655
-        yr_arena_destroy(compiler.rules_arena);
3654
+        //        yr_arena_destroy(compiler.sz_arena);
3655
+        //        yr_arena_destroy(compiler.rules_arena);
3656 3656
         yr_arena_destroy(compiler.code_arena);
3657
-        yr_arena_destroy(compiler.strings_arena);
3657
+        //        yr_arena_destroy(compiler.strings_arena);
3658 3658
         yr_arena_destroy(compiler.metas_arena);
3659 3659
 #ifdef YARA_FINISHED
3660 3660
         return CL_EMALFDB;
... ...
@@ -3680,10 +3681,10 @@ static int cli_loadyara(FILE *fs, struct cl_engine *engine, unsigned int *signo,
3680 3680
 
3681 3681
     yr_hash_table_destroy(compiler.rules_table, NULL);
3682 3682
     yr_hash_table_destroy(compiler.objects_table, NULL);
3683
-    yr_arena_destroy(compiler.sz_arena);
3684
-    yr_arena_destroy(compiler.rules_arena);
3683
+    //    yr_arena_destroy(compiler.sz_arena);
3684
+    //    yr_arena_destroy(compiler.rules_arena);
3685 3685
     yr_arena_destroy(compiler.code_arena);
3686
-    yr_arena_destroy(compiler.strings_arena);
3686
+    //    yr_arena_destroy(compiler.strings_arena);
3687 3687
     yr_arena_destroy(compiler.metas_arena);
3688 3688
 
3689 3689
     if(rc)
... ...
@@ -54,6 +54,7 @@ limitations under the License.
54 54
 #define META_TYPE_STRING    2
55 55
 #define META_TYPE_BOOLEAN   3
56 56
 
57
+
57 58
 #define STRING_GFLAGS_REFERENCED        0x01
58 59
 #define STRING_GFLAGS_HEXADECIMAL       0x02
59 60
 #define STRING_GFLAGS_NO_CASE           0x04
... ...
@@ -546,10 +547,12 @@ typedef struct _yc_string {
546 546
     STAILQ_ENTRY(_yc_string) link;
547 547
     int32_t g_flags;
548 548
     int32_t length;
549
-    
549
+
550 550
     DECLARE_REFERENCE(char*, identifier);
551 551
     DECLARE_REFERENCE(uint8_t*, string);
552 552
     DECLARE_REFERENCE(struct _YR_STRING*, chained_to);
553
+
554
+    int32_t subsig_id;
553 555
 } yc_string;
554 556
 
555 557
 typedef struct _yc_compiler {
... ...
@@ -48,6 +48,7 @@ typedef struct _YR_MATCH
48 48
 } YR_MATCH;
49 49
 
50 50
 // End of temp for clamAV
51
+#include "matcher.h"
51 52
 #include "yara_clam.h"
52 53
 #include "yara_exec.h"
53 54
 #endif
... ...
@@ -103,7 +104,8 @@ int yr_execute_code(
103 103
 #if REAL_YARA
104 104
     YR_RULES* rules,
105 105
 #else
106
-    uint8_t* ip,
106
+    struct cli_ac_lsig * aclsig,
107
+    struct cli_ac_data * acdata,
107 108
 #endif
108 109
     YR_SCAN_CONTEXT* context,
109 110
     int timeout,
... ...
@@ -118,6 +120,10 @@ int yr_execute_code(
118 118
   int32_t sp = 0;
119 119
 #if REAL_YARA
120 120
   uint8_t* ip = rules->code_start;
121
+#else
122
+  uint8_t* ip = aclsig->u.code_start;
123
+  uint32_t lsig_id;
124
+  uint32_t rule_matches = 0;
121 125
 #endif
122 126
 
123 127
   YR_RULE* rule;
... ...
@@ -143,13 +149,20 @@ int yr_execute_code(
143 143
 
144 144
   while(1)
145 145
   {
146
+    cli_errmsg("yara_exec: executing %i\n", *ip);
146 147
     switch(*ip)
147 148
     {
148 149
       case OP_HALT:
149 150
         // When the halt instruction is reached the stack
150 151
         // should be empty.
151 152
         assert(sp == 0);
153
+#if REAL_YARA
152 154
         return ERROR_SUCCESS;
155
+#else
156
+        if (rule_matches != 0)
157
+            return CL_VIRUS;
158
+        return CL_SUCCESS;
159
+#endif
153 160
 
154 161
       case OP_PUSH:
155 162
         r1 = *(uint64_t*)(ip + 1);
... ...
@@ -407,8 +420,7 @@ int yr_execute_code(
407 407
 #if REAL_YARA
408 408
           rule->t_flags[tidx] |= RULE_TFLAGS_MATCH;
409 409
 #else
410
-        //tbd clamav
411
-          rule->g_flags |= RULE_TFLAGS_MATCH;
410
+        rule_matches++;
412 411
 #endif
413 412
 
414 413
         #ifdef PROFILING_ENABLED
... ...
@@ -674,18 +686,28 @@ int yr_execute_code(
674 674
         count = 0;
675 675
         pop(r1);
676 676
 
677
+#if REAL_YARA
677 678
         while (r1 != UNDEFINED)
678 679
         {
679 680
           string = UINT64_TO_PTR(YR_STRING*, r1);
680
-#if REAL_YARA
681 681
           if (string->matches[tidx].tail != NULL)
682 682
             found++;
683
+          count++;
684
+          pop(r1);
685
+        }
683 686
 #else
684
-        //TBD: clamav
685
-#endif
687
+        lsig_id = aclsig->id;
688
+        for (i = 0; i < aclsig->tdb.subsigs; i++) {
689
+            if (acdata->lsigsuboff_first[lsig_id][i] != CLI_OFF_NONE) {
690
+                found++;
691
+            }
692
+        }
693
+        while (r1 != UNDEFINED)
694
+        {
686 695
           count++;
687 696
           pop(r1);
688 697
         }
698
+#endif
689 699
 
690 700
         pop(r2);
691 701
 
... ...
@@ -90,7 +90,8 @@ int yr_execute_code(
90 90
 #if REAL_YARA
91 91
     YR_RULES* rules,
92 92
 #else
93
-    uint8_t* ip,
93
+    struct cli_ac_lsig * aclsig,
94
+    struct cli_ac_data * acdata,
94 95
 #endif
95 96
     YR_SCAN_CONTEXT* context,
96 97
     int timeout,