Browse code

Capture YARA compiled condition string and anchor in struct cli_ac_lsig.

Steven Morgan authored on 2015/03/07 07:10:47
Showing 5 changed files
... ...
@@ -86,7 +86,7 @@ struct cli_ac_lsig {
86 86
     uint8_t type;
87 87
     union {
88 88
         char *logic;
89
-        void *other;
89
+        uint8_t *code_start;
90 90
     } u;
91 91
     const char *virname;
92 92
     struct cli_lsig_tdb tdb;
... ...
@@ -3402,30 +3402,31 @@ static int load_oneyara(YR_RULE *rule, struct cl_engine *engine, unsigned int op
3402 3402
     /*** conditional verification step (ex. do we define too many strings versus used?)  ***/
3403 3403
     /*** additional string table population (ex. offsets), second translation table pass ***/
3404 3404
 
3405
-    lsize = 3*ytable.tbl_cnt;
3406
-    logic = cli_calloc(lsize, sizeof(char));
3407
-    if (!logic) {
3408
-        cli_errmsg("load_oneyara: cannot allocate memory for logic statement\n");
3409
-        ytable_delete(&ytable);
3410
-        return CL_EMEM;
3411
-    }
3412
-
3413
-    if (rule->g_flags & RULE_ALL && rule->g_flags & RULE_THEM)
3414
-        exp_op = "&";
3415
-    else {
3416
-        exp_op = "|";
3417
-        if ((!(rule->g_flags & RULE_ANY && rule->g_flags & RULE_THEM) && ytable.tbl_cnt > 1) &&
3418
-            !(rule->g_flags & RULE_EP && ytable.tbl_cnt == 1))
3419
-            yara_complex++;
3405
+    if (rule->g_flags & RULE_ALL ||  rule->g_flags & RULE_ANY) {
3406
+        lsize = 3*ytable.tbl_cnt;
3407
+        logic = cli_calloc(lsize, sizeof(char));
3408
+        if (!logic) {
3409
+            cli_errmsg("load_oneyara: cannot allocate memory for logic statement\n");
3410
+            ytable_delete(&ytable);
3411
+            return CL_EMEM;
3412
+        }
3413
+        
3414
+        if (rule->g_flags & RULE_ALL && rule->g_flags & RULE_THEM)
3415
+            exp_op = "&";
3416
+        else {
3417
+            exp_op = "|";
3418
+            if ((!(rule->g_flags & RULE_ANY && rule->g_flags & RULE_THEM) && ytable.tbl_cnt > 1) &&
3419
+                !(rule->g_flags & RULE_EP && ytable.tbl_cnt == 1))
3420
+                yara_complex++;
3421
+        }
3422
+        
3423
+        for (i=0; i<ytable.tbl_cnt; i++) {
3424
+            size_t len=strlen(logic);
3425
+            snprintf(logic+len, lsize-len, "%u%s", i, (i+1 == ytable.tbl_cnt) ? "" : exp_op);
3426
+        }    
3427
+        
3428
+        /*** END CONDITIONAL HANDLING ***/
3420 3429
     }
3421
-
3422
-    for (i=0; i<ytable.tbl_cnt; i++) {
3423
-        size_t len=strlen(logic);
3424
-        snprintf(logic+len, lsize-len, "%u%s", i, (i+1 == ytable.tbl_cnt) ? "" : exp_op);
3425
-    }    
3426
-
3427
-    /*** END CONDITIONAL HANDLING ***/
3428
-
3429 3430
     /* TDB */
3430 3431
     if (rule->g_flags & RULE_EP && ytable.tbl_cnt == 1)
3431 3432
         target_str = cli_strdup(YARATARGET1);
... ...
@@ -3461,23 +3462,26 @@ static int load_oneyara(YR_RULE *rule, struct cl_engine *engine, unsigned int op
3461 3461
 
3462 3462
         lsig->type = CLI_NORMAL_LSIG;
3463 3463
         lsig->u.logic = cli_mpool_strdup(engine->mempool, logic);
3464
+        free(logic);
3464 3465
         if(!lsig->u.logic) {
3465 3466
             cli_errmsg("load_oneyara: Can't allocate memory for lsig->logic\n");
3466 3467
             FREE_TDB(tdb);
3467 3468
             ytable_delete(&ytable);
3468
-            free(logic);
3469 3469
             mpool_free(engine->mempool, lsig);
3470 3470
             return CL_EMEM;
3471 3471
         }
3472 3472
     } else {
3473
-        cli_errmsg("load_oneyara: Unsupported logic type\n");
3474
-        FREE_TDB(tdb);
3475
-        ytable_delete(&ytable);
3476
-        free(logic);
3477
-        mpool_free(engine->mempool, lsig);
3478
-        return CL_EMEM;
3473
+        if (NULL != (lsig->u.code_start = rule->code_start)) {
3474
+        lsig->type = CLI_NORMAL_YARA;
3475
+        } else {
3476
+            cli_errmsg("load_oneyara: code start is NULL\n");
3477
+            FREE_TDB(tdb);
3478
+            ytable_delete(&ytable);
3479
+            mpool_free(engine->mempool, lsig);
3480
+            return CL_EMEM;
3481
+        }
3479 3482
     }
3480
-    free(logic);
3483
+
3481 3484
 
3482 3485
     lsigid[0] = lsig->id = root->ac_lsigs;
3483 3486
 
... ...
@@ -4325,6 +4329,8 @@ int cl_engine_free(struct cl_engine *engine)
4325 4325
 		    for(j = 0; j < root->ac_lsigs; j++) {
4326 4326
 			if (root->ac_lsigtable[j]->type == CLI_NORMAL_LSIG)
4327 4327
 			    mpool_free(engine->mempool, root->ac_lsigtable[j]->u.logic);
4328
+			else if (root->ac_lsigtable[j]->type == CLI_NORMAL_YARA)
4329
+			    free(root->ac_lsigtable[j]->u.code_start);
4328 4330
 			FREE_TDB(root->ac_lsigtable[j]->tdb);
4329 4331
 			mpool_free(engine->mempool, root->ac_lsigtable[j]);
4330 4332
 		    }
... ...
@@ -295,7 +295,7 @@ void yr_arena_destroy(
295 295
   yr_free(arena);
296 296
 }
297 297
 
298
-#if REAL_YARA
298
+
299 299
 //
300 300
 // yr_arena_base_address
301 301
 //
... ...
@@ -333,7 +333,6 @@ void* yr_arena_base_address(
333 333
 // Returns:
334 334
 //    A pointer
335 335
 //
336
-#endif
337 336
 
338 337
 void* yr_arena_next_address(
339 338
   YR_ARENA* arena,
... ...
@@ -384,7 +383,7 @@ void* yr_arena_next_address(
384 384
   return NULL;
385 385
 }
386 386
 
387
-#if REAL_YARA
387
+
388 388
 //
389 389
 // yr_arena_coalesce
390 390
 //
... ...
@@ -488,7 +487,6 @@ int yr_arena_coalesce(
488 488
 
489 489
   return ERROR_SUCCESS;
490 490
 }
491
-#endif
492 491
 
493 492
 //
494 493
 // yr_arena_reserve_memory
... ...
@@ -539,6 +539,7 @@ struct _yc_rule {
539 539
     STAILQ_HEAD(sq, _yc_string) strings;
540 540
     char * identifier;
541 541
     uint32_t g_flags;
542
+    uint8_t * code_start;
542 543
 };
543 544
 typedef struct _yc_rule yc_rule;
544 545
 typedef struct _yc_string {
... ...
@@ -702,6 +702,7 @@ int yr_parser_reduce_rule_declaration(
702 702
 
703 703
   YR_RULE* rule;
704 704
   YR_STRING* string;
705
+  int8_t halt = OP_HALT;
705 706
 
706 707
   if (yr_hash_table_lookup(
707 708
         compiler->rules_table,
... ...
@@ -799,6 +800,19 @@ int yr_parser_reduce_rule_declaration(
799 799
   compiler->current_rule_strings = NULL;
800 800
 #else
801 801
   compiler->current_rule_flags = 0;
802
+  // Write halt instruction at the end of code.
803
+  yr_arena_write_data(
804
+      compiler->code_arena,
805
+      &halt,
806
+      sizeof(int8_t),
807
+      NULL);
808
+  //TBD: seems like we will need the following yr_arena_coalesce, but it is not working.
809
+  //Yara condition code will work OK as long as it is less than 64K.
810
+  //FAIL_ON_COMPILER_ERROR(yr_arena_coalesce(compiler->code_arena));
811
+  rule->code_start = yr_arena_base_address(compiler->code_arena);
812
+  compiler->code_arena->page_list_head->address = NULL;
813
+  yr_arena_destroy(compiler->code_arena);
814
+  FAIL_ON_COMPILER_ERROR(yr_arena_create(65536, 0, &compiler->code_arena));
802 815
   STAILQ_INSERT_TAIL(&compiler->rule_q, rule, link); 
803 816
 #endif
804 817
   return compiler->last_result;