Browse code

YARA: capture offsets in matcher and use for processing YARA condition 'at' clauses.

Steven Morgan authored on 2015/03/31 06:12:01
Showing 10 changed files
... ...
@@ -1142,9 +1142,23 @@ int cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t lsigs,
1142 1142
             data->lsigcnt[i] = data->lsigcnt[0] + 64 * i;
1143 1143
 
1144 1144
         /* subsig offsets */
1145
+        data->lsig_matches = (struct cli_lsig_matches **) cli_calloc(lsigs * sizeof(struct cli_lsig_matches *), sizeof(struct cli_lsig_matches *));
1146
+        if(!data->lsig_matches) {
1147
+            free(data->lsigcnt[0]);
1148
+            free(data->lsigcnt);
1149
+            if(partsigs)
1150
+                free(data->offmatrix);
1151
+
1152
+            if(reloffsigs)
1153
+                free(data->offset);
1154
+
1155
+            cli_errmsg("cli_ac_init: Can't allocate memory for data->lsig_matches\n");
1156
+            return CL_EMEM;
1157
+        }
1145 1158
         data->lsigsuboff_last = (uint32_t **) cli_malloc(lsigs * sizeof(uint32_t *));
1146 1159
         data->lsigsuboff_first = (uint32_t **) cli_malloc(lsigs * sizeof(uint32_t *));
1147 1160
         if(!data->lsigsuboff_last || !data->lsigsuboff_first) {
1161
+            free(data->lsig_matches);
1148 1162
             free(data->lsigsuboff_last);
1149 1163
             free(data->lsigsuboff_first);
1150 1164
             free(data->lsigcnt[0]);
... ...
@@ -1161,6 +1175,7 @@ int cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t lsigs,
1161 1161
         data->lsigsuboff_last[0] = (uint32_t *) cli_calloc(lsigs * 64, sizeof(uint32_t));
1162 1162
         data->lsigsuboff_first[0] = (uint32_t *) cli_calloc(lsigs * 64, sizeof(uint32_t));
1163 1163
         if(!data->lsigsuboff_last[0] || !data->lsigsuboff_first[0]) {
1164
+            free(data->lsig_matches);
1164 1165
             free(data->lsigsuboff_last[0]);
1165 1166
             free(data->lsigsuboff_first[0]);
1166 1167
             free(data->lsigsuboff_last);
... ...
@@ -1225,7 +1240,10 @@ void cli_ac_freedata(struct cli_ac_data *data)
1225 1225
 {
1226 1226
     uint32_t i;
1227 1227
 
1228
-    if(data && data->partsigs) {
1228
+    if (!data)
1229
+        return;
1230
+
1231
+    if(data->partsigs) {
1229 1232
         for(i = 0; i < data->partsigs; i++) {
1230 1233
             if(data->offmatrix[i]) {
1231 1234
                 free(data->offmatrix[i][0]);
... ...
@@ -1237,7 +1255,25 @@ void cli_ac_freedata(struct cli_ac_data *data)
1237 1237
         data->partsigs = 0;
1238 1238
     }
1239 1239
 
1240
-    if(data && data->lsigs) {
1240
+    if(data->lsigs) {
1241
+        if (data->lsig_matches) {
1242
+            for (i = 0; i < data->lsigs; i++) {
1243
+                struct cli_lsig_matches * ls_matches;
1244
+                if ((ls_matches = data->lsig_matches[i])) {
1245
+                    uint32_t j;
1246
+                    for (j = 0; j < ls_matches->subsigs; j++) {
1247
+                        if (ls_matches->matches[j]) {
1248
+                            free(ls_matches->matches[j]);
1249
+                            ls_matches->matches[j] = 0;
1250
+                        }
1251
+                    }
1252
+                    free(data->lsig_matches[i]);
1253
+                    data->lsig_matches[i] = 0;
1254
+                }
1255
+            }
1256
+            free(data->lsig_matches);
1257
+            data->lsig_matches = 0;
1258
+        }
1241 1259
         free(data->lsigcnt[0]);
1242 1260
         free(data->lsigcnt);
1243 1261
         free(data->lsigsuboff_last[0]);
... ...
@@ -1247,7 +1283,7 @@ void cli_ac_freedata(struct cli_ac_data *data)
1247 1247
         data->lsigs = 0;
1248 1248
     }
1249 1249
 
1250
-    if(data && data->reloffsigs) {
1250
+    if(data->reloffsigs) {
1251 1251
         free(data->offset);
1252 1252
         data->reloffsigs = 0;
1253 1253
     }
... ...
@@ -1287,22 +1323,62 @@ inline static int ac_addtype(struct cli_matched_type **list, cli_file_t type, of
1287 1287
     return CL_SUCCESS;
1288 1288
 }
1289 1289
 
1290
-void lsig_sub_matched(const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t lsigid1, uint32_t lsigid2, uint32_t realoff, int partial)
1290
+int lsig_sub_matched(const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t lsigid1, uint32_t lsigid2, uint32_t realoff, int partial)
1291 1291
 {
1292
-    const struct cli_lsig_tdb *tdb = &root->ac_lsigtable[lsigid1]->tdb;
1292
+    const struct cli_ac_lsig *ac_lsig = root->ac_lsigtable[lsigid1];
1293
+    const struct cli_lsig_tdb *tdb = &ac_lsig->tdb;
1293 1294
 
1294 1295
     if(realoff != CLI_OFF_NONE) {
1295 1296
         if(mdata->lsigsuboff_first[lsigid1][lsigid2] == CLI_OFF_NONE)
1296 1297
             mdata->lsigsuboff_first[lsigid1][lsigid2] = realoff;
1297 1298
 
1298 1299
         if(mdata->lsigsuboff_last[lsigid1][lsigid2] != CLI_OFF_NONE && ((!partial && realoff <= mdata->lsigsuboff_last[lsigid1][lsigid2]) || (partial && realoff < mdata->lsigsuboff_last[lsigid1][lsigid2])))
1299
-            return;
1300
+            return CL_SUCCESS;
1300 1301
 
1301 1302
         mdata->lsigcnt[lsigid1][lsigid2]++;
1302 1303
         if(mdata->lsigcnt[lsigid1][lsigid2] <= 1 || !tdb->macro_ptids || !tdb->macro_ptids[lsigid2])
1303 1304
             mdata->lsigsuboff_last[lsigid1][lsigid2] = realoff;
1304 1305
     }
1305 1306
 
1307
+    if (ac_lsig->type & CLI_YARA_OFFSET && realoff != CLI_OFF_NONE) {
1308
+        uint32_t * offs;
1309
+        struct cli_subsig_matches * ss_matches;
1310
+        struct cli_lsig_matches * ls_matches;
1311
+        cli_dbgmsg("lsig_sub_matched lsig %u:%u at %u\n", lsigid1, lsigid2, realoff);
1312
+
1313
+        ls_matches = mdata->lsig_matches[lsigid1];
1314
+        if (ls_matches == NULL) { /* allocate cli_lsig_matches */
1315
+            ls_matches = mdata->lsig_matches[lsigid1] = (struct cli_lsig_matches *)cli_calloc(1, sizeof(struct cli_lsig_matches) +
1316
+                                                                                              (ac_lsig->tdb.subsigs - 1) * sizeof(struct cli_subsig_matches *));
1317
+            if (ls_matches == NULL) {
1318
+                cli_errmsg("lsig_sub_matched: cli_calloc failed for cli_lsig_matches\n");
1319
+                return CL_EMEM;
1320
+            }
1321
+            ls_matches->subsigs = ac_lsig->tdb.subsigs;
1322
+        }
1323
+        ss_matches = ls_matches->matches[lsigid2];
1324
+        if (ss_matches == NULL) { /*  allocate cli_subsig_matches */
1325
+            ss_matches = ls_matches->matches[lsigid2] = cli_malloc(sizeof(struct cli_subsig_matches));
1326
+            if (ss_matches == NULL) {
1327
+                cli_errmsg("lsig_sub_matched: cli_malloc failed for cli_subsig_matches struct\n");
1328
+                return CL_EMEM;
1329
+            }
1330
+            ss_matches->next = 0;
1331
+            ss_matches->last = sizeof(ss_matches->offsets) / sizeof(uint32_t) - 1; 
1332
+        }
1333
+        if (ss_matches->next > ss_matches->last) {  /* cli_matches out of space? realloc */
1334
+            ss_matches = ls_matches->matches[lsigid2] = cli_realloc(ss_matches, sizeof(struct cli_subsig_matches) + sizeof(uint32_t) * ss_matches->last * 2);
1335
+            if (ss_matches == NULL) {
1336
+                cli_errmsg("lsig_sub_matched: cli_realloc failed for cli_subsig_matches struct\n");
1337
+                return CL_EMEM;
1338
+            }
1339
+            ss_matches->last = sizeof(ss_matches->offsets)/ sizeof(uint32_t) + ss_matches->last * 2 - 1;
1340
+        }
1341
+        
1342
+        ss_matches->offsets[ss_matches->next] = realoff; /* finally, store the offset */
1343
+        ss_matches->next++;
1344
+    }
1345
+
1306 1346
     if (mdata->lsigcnt[lsigid1][lsigid2] > 1) {
1307 1347
         /* Check that the previous match had a macro match following it at the 
1308 1348
          * correct distance. This check is only done after the 1st match.*/
... ...
@@ -1310,11 +1386,11 @@ void lsig_sub_matched(const struct cli_matcher *root, struct cli_ac_data *mdata,
1310 1310
         uint32_t id, last_macro_match, smin, smax, last_macroprev_match;
1311 1311
 
1312 1312
         if (!tdb->macro_ptids)
1313
-            return;
1313
+            return CL_SUCCESS;
1314 1314
 
1315 1315
         id = tdb->macro_ptids[lsigid2];
1316 1316
         if (!id)
1317
-            return;
1317
+            return CL_SUCCESS;
1318 1318
 
1319 1319
         macropt = root->ac_pattable[id];
1320 1320
         smin = macropt->ch_mindist[0];
... ...
@@ -1340,17 +1416,23 @@ void lsig_sub_matched(const struct cli_matcher *root, struct cli_ac_data *mdata,
1340 1340
             mdata->lsigsuboff_last[lsigid1][lsigid2+1] = last_macro_match;
1341 1341
         }
1342 1342
     }
1343
+    return CL_SUCCESS;
1343 1344
 }
1344 1345
 
1345
-void cli_ac_chkmacro(struct cli_matcher *root, struct cli_ac_data *data, unsigned lsigid1)
1346
+int cli_ac_chkmacro(struct cli_matcher *root, struct cli_ac_data *data, unsigned lsigid1)
1346 1347
 {
1347 1348
     const struct cli_lsig_tdb *tdb = &root->ac_lsigtable[lsigid1]->tdb;
1348 1349
     unsigned i;
1350
+    int rc;
1351
+
1349 1352
     /* Loop through all subsigs, and if they are tied to macros check that the
1350 1353
      * macro matched at a correct distance */
1351 1354
     for (i=0;i<tdb->subsigs;i++) {
1352
-        lsig_sub_matched(root, data, lsigid1, i, CLI_OFF_NONE, 0);
1355
+        rc = lsig_sub_matched(root, data, lsigid1, i, CLI_OFF_NONE, 0);
1356
+        if (rc != CL_SUCCESS)
1357
+            return rc;
1353 1358
     }
1359
+    return CL_SUCCESS;
1354 1360
 }
1355 1361
 
1356 1362
 
... ...
@@ -1365,6 +1447,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
1365 1365
     int32_t **offmatrix, swp;
1366 1366
     int type = CL_CLEAN;
1367 1367
     struct cli_ac_result *newres;
1368
+    int rc;
1368 1369
 
1369 1370
     if(!root->ac_root)
1370 1371
         return CL_CLEAN;
... ...
@@ -1547,7 +1630,9 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
1547 1547
 
1548 1548
                                 } else { /* !pt->type */
1549 1549
                                     if(pt->lsigid[0]) {
1550
-                                        lsig_sub_matched(root, mdata, pt->lsigid[1], pt->lsigid[2], offmatrix[pt->parts - 1][1], 1);
1550
+                                        rc = lsig_sub_matched(root, mdata, pt->lsigid[1], pt->lsigid[2], offmatrix[pt->parts - 1][1], 1);
1551
+                                        if (rc != CL_SUCCESS)
1552
+                                            return rc;
1551 1553
                                         ptN = ptN->next_same;
1552 1554
                                         continue;
1553 1555
                                     }
... ...
@@ -1599,8 +1684,10 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
1599 1599
                                     }
1600 1600
                                 }
1601 1601
                             } else {
1602
-                            if(pt->lsigid[0]) {
1603
-                                    lsig_sub_matched(root, mdata, pt->lsigid[1], pt->lsigid[2], realoff, 0);
1602
+                                if(pt->lsigid[0]) {
1603
+                                    rc = lsig_sub_matched(root, mdata, pt->lsigid[1], pt->lsigid[2], realoff, 0);
1604
+                                    if (rc != CL_SUCCESS)
1605
+                                        return rc;
1604 1606
                                     ptN = ptN->next_same;
1605 1607
                                     continue;
1606 1608
                                 }
... ...
@@ -43,11 +43,23 @@
43 43
 
44 44
 #define ACPATT_OPTION_ONCE     0x80
45 45
 
46
+struct cli_subsig_matches {
47
+    uint32_t last;
48
+    uint32_t next;
49
+    uint32_t offsets[16]; /* offsets[] is variable length */
50
+};
51
+
52
+struct cli_lsig_matches {
53
+    uint32_t subsigs;
54
+    struct cli_subsig_matches * matches[1]; /* matches[] is variable length */ 
55
+};
56
+
46 57
 struct cli_ac_data {
47 58
     int32_t ***offmatrix;
48 59
     uint32_t partsigs, lsigs, reloffsigs;
49 60
     uint32_t **lsigcnt;
50 61
     uint32_t **lsigsuboff_last, **lsigsuboff_first;
62
+    struct cli_lsig_matches **lsig_matches;
51 63
     uint32_t *offset;
52 64
     uint32_t macro_lastmatch[32];
53 65
     /** Hashset for versioninfo matching */
... ...
@@ -105,8 +117,8 @@ struct cli_ac_result {
105 105
 
106 106
 int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern);
107 107
 int cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t lsigs, uint32_t reloffsigs, uint8_t tracklen);
108
-void lsig_sub_matched(const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t lsigid1, uint32_t lsigid2, uint32_t realoff, int partial);
109
-void cli_ac_chkmacro(struct cli_matcher *root, struct cli_ac_data *data, unsigned lsigid1);
108
+int lsig_sub_matched(const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t lsigid1, uint32_t lsigid2, uint32_t realoff, int partial);
109
+int cli_ac_chkmacro(struct cli_matcher *root, struct cli_ac_data *data, unsigned lsigid1);
110 110
 int cli_ac_chklsig(const char *expr, const char *end, uint32_t *lsigcnt, unsigned int *cnt, uint64_t *ids, unsigned int parse_only);
111 111
 void cli_ac_freedata(struct cli_ac_data *data);
112 112
 int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, void **customdata, struct cli_ac_result **res, const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t offset, cli_file_t ftype, struct cli_matched_type **ftoffset, unsigned int mode, cli_ctx *ctx);
... ...
@@ -695,8 +695,11 @@ static int lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data
695 695
     struct cli_ac_lsig *ac_lsig = root->ac_lsigtable[lsid];
696 696
     char * exp = ac_lsig->u.logic;
697 697
     char* exp_end = exp + strlen(exp);
698
+    int rc;
698 699
 
699
-    cli_ac_chkmacro(root, acdata, lsid);
700
+    rc = cli_ac_chkmacro(root, acdata, lsid);
701
+    if (rc != CL_SUCCESS)
702
+        return rc;
700 703
     if (cli_ac_chklsig(exp, exp_end, acdata->lsigcnt[lsid], &evalcnt, &evalids, 0) == 1) {
701 704
         if(ac_lsig->tdb.container && ac_lsig->tdb.container[0] != ctx->container_type)
702 705
             return CL_CLEAN;
... ...
@@ -778,9 +781,9 @@ int cli_exp_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acd
778 778
     int32_t rc;
779 779
 
780 780
     for(i = 0; i < root->ac_lsigs; i++) {
781
-        if (root->ac_lsigtable[i]->type == CLI_NORMAL_LSIG)
781
+        if (root->ac_lsigtable[i]->type == CLI_LSIG_NORMAL)
782 782
             rc = lsig_eval(ctx, root, acdata, target_info, hash, i);
783
-        else if (root->ac_lsigtable[i]->type == CLI_NORMAL_YARA)
783
+        else if (root->ac_lsigtable[i]->type == CLI_YARA_NORMAL || root->ac_lsigtable[i]->type == CLI_YARA_OFFSET)
784 784
             rc = yara_eval(ctx, root, acdata, target_info, hash, i);
785 785
         if (rc == CL_VIRUS) {
786 786
             viruses_found = 1;
... ...
@@ -79,8 +79,9 @@ struct cli_lsig_tdb {
79 79
 
80 80
 struct cli_bc;
81 81
 struct cli_ac_lsig {
82
-#define CLI_NORMAL_LSIG 0
83
-#define CLI_NORMAL_YARA 1
82
+#define CLI_LSIG_NORMAL 0
83
+#define CLI_YARA_NORMAL 1
84
+#define CLI_YARA_OFFSET 2
84 85
     uint32_t id;
85 86
     unsigned bc_idx;
86 87
     uint8_t type;
... ...
@@ -1677,7 +1677,7 @@ static int load_oneldb(char *buffer, int chkpua, struct cl_engine *engine, unsig
1677 1677
         return CL_EMEM;
1678 1678
     }
1679 1679
 
1680
-    lsig->type = CLI_NORMAL_LSIG;
1680
+    lsig->type = CLI_LSIG_NORMAL;
1681 1681
     lsig->u.logic = cli_mpool_strdup(engine->mempool, logic);
1682 1682
     if(!lsig->u.logic) {
1683 1683
         cli_errmsg("cli_loadldb: Can't allocate memory for lsig->logic\n");
... ...
@@ -3482,7 +3482,7 @@ static int load_oneyara(YR_RULE *rule, struct cl_engine *engine, unsigned int op
3482 3482
     /*** conditional verification step (ex. do we define too many strings versus used?)  ***/
3483 3483
     /*** additional string table population (ex. offsets), second translation table pass ***/
3484 3484
 #if 0
3485
-    if (rule->g_flags & RULE_ALL ||  rule->g_flags & RULE_ANY) {
3485
+    if (rule->cl_flags & RULE_ALL ||  rule->cl_flags & RULE_ANY) {
3486 3486
         lsize = 3*ytable.tbl_cnt;
3487 3487
         logic = cli_calloc(lsize, sizeof(char));
3488 3488
         if (!logic) {
... ...
@@ -3491,12 +3491,12 @@ static int load_oneyara(YR_RULE *rule, struct cl_engine *engine, unsigned int op
3491 3491
             return CL_EMEM;
3492 3492
         }
3493 3493
         
3494
-        if (rule->g_flags & RULE_ALL && rule->g_flags & RULE_THEM)
3494
+        if (rule->cl_flags & RULE_ALL && rule->cl_flags & RULE_THEM)
3495 3495
             exp_op = "&";
3496 3496
         else {
3497 3497
             exp_op = "|";
3498
-            if ((!(rule->g_flags & RULE_ANY && rule->g_flags & RULE_THEM) && ytable.tbl_cnt > 1) &&
3499
-                !(rule->g_flags & RULE_EP && ytable.tbl_cnt == 1))
3498
+            if ((!(rule->cl_flags & RULE_ANY && rule->cl_flags & RULE_THEM) && ytable.tbl_cnt > 1) &&
3499
+                !(rule->cl_flags & RULE_EP && ytable.tbl_cnt == 1))
3500 3500
                 yara_complex++;
3501 3501
         }
3502 3502
         
... ...
@@ -3507,12 +3507,12 @@ static int load_oneyara(YR_RULE *rule, struct cl_engine *engine, unsigned int op
3507 3507
         
3508 3508
         /*** END CONDITIONAL HANDLING ***/
3509 3509
     }
3510
-#endif
3511 3510
 
3512 3511
     /* TDB */
3513
-    if (rule->g_flags & RULE_EP && ytable.tbl_cnt == 1)
3512
+    if (rule->cl_flags & RULE_EP && ytable.tbl_cnt == 1)
3514 3513
         target_str = cli_strdup(YARATARGET1);
3515 3514
     else
3515
+#endif
3516 3516
         target_str = cli_strdup(YARATARGET0);
3517 3517
 
3518 3518
     memset(&tdb, 0, sizeof(tdb));
... ...
@@ -3542,7 +3542,7 @@ static int load_oneyara(YR_RULE *rule, struct cl_engine *engine, unsigned int op
3542 3542
     if (logic) {
3543 3543
         cli_yaramsg("normal lsig triggered yara: %s\n", logic);
3544 3544
 
3545
-        lsig->type = CLI_NORMAL_LSIG;
3545
+        lsig->type = CLI_LSIG_NORMAL;
3546 3546
         lsig->u.logic = cli_mpool_strdup(engine->mempool, logic);
3547 3547
         free(logic);
3548 3548
         if(!lsig->u.logic) {
... ...
@@ -3554,7 +3554,7 @@ static int load_oneyara(YR_RULE *rule, struct cl_engine *engine, unsigned int op
3554 3554
         }
3555 3555
     } else {
3556 3556
         if (NULL != (lsig->u.code_start = rule->code_start)) {
3557
-        lsig->type = CLI_NORMAL_YARA;
3557
+            lsig->type = (rule->cl_flags & RULE_OFFSETS) ? CLI_YARA_OFFSET : CLI_YARA_NORMAL;
3558 3558
         } else {
3559 3559
             cli_errmsg("load_oneyara: code start is NULL\n");
3560 3560
             FREE_TDB(tdb);
... ...
@@ -4406,9 +4406,10 @@ int cl_engine_free(struct cl_engine *engine)
4406 4406
 		cli_ac_free(root);
4407 4407
 		if(root->ac_lsigtable) {
4408 4408
 		    for(j = 0; j < root->ac_lsigs; j++) {
4409
-			if (root->ac_lsigtable[j]->type == CLI_NORMAL_LSIG)
4409
+			if (root->ac_lsigtable[j]->type == CLI_LSIG_NORMAL)
4410 4410
 			    mpool_free(engine->mempool, root->ac_lsigtable[j]->u.logic);
4411
-			else if (root->ac_lsigtable[j]->type == CLI_NORMAL_YARA)
4411
+			else if (root->ac_lsigtable[j]->type == CLI_YARA_NORMAL ||
4412
+                                 root->ac_lsigtable[j]->type == CLI_YARA_NORMAL)
4412 4413
 			    free(root->ac_lsigtable[j]->u.code_start);
4413 4414
 			FREE_TDB(root->ac_lsigtable[j]->tdb);
4414 4415
 			mpool_free(engine->mempool, root->ac_lsigtable[j]);
... ...
@@ -518,11 +518,12 @@ struct RE {
518 518
 
519 519
 #define YARA_PROTO
520 520
 #ifdef YARA_PROTO
521
-#define RULE_ANY  1
522
-#define RULE_ALL  2
523
-#define RULE_ONE  4
524
-#define RULE_THEM 8
525
-#define RULE_EP   16
521
+#define RULE_ANY        1
522
+#define RULE_ALL        2
523
+#define RULE_ONE        4
524
+#define RULE_THEM       8
525
+#define RULE_EP         16
526
+#define RULE_OFFSETS    32
526 527
 #endif
527 528
 
528 529
 /* YARA to ClamAV function mappings */
... ...
@@ -540,6 +541,7 @@ struct _yc_rule {
540 540
     STAILQ_HEAD(sq, _yc_string) strings;
541 541
     char * identifier;
542 542
     uint32_t g_flags;
543
+    uint32_t cl_flags;
543 544
     uint8_t * code_start;
544 545
 };
545 546
 typedef struct _yc_rule yc_rule;
... ...
@@ -572,6 +574,7 @@ typedef struct _yc_compiler {
572 572
     YR_NAMESPACE*       current_namespace;
573 573
     yc_string*          current_rule_strings;
574 574
     uint32_t            current_rule_flags;
575
+    uint32_t            current_rule_clflags;
575 576
 
576 577
     int8_t*             loop_address[MAX_LOOP_NESTING];
577 578
     char*               loop_identifier[MAX_LOOP_NESTING];
... ...
@@ -49,6 +49,7 @@ typedef struct _YR_MATCH
49 49
 
50 50
 // End of temp for clamAV
51 51
 #include "matcher.h"
52
+#include "matcher-ac.h"
52 53
 #include "yara_clam.h"
53 54
 #include "yara_exec.h"
54 55
 #endif
... ...
@@ -124,6 +125,9 @@ int yr_execute_code(
124 124
   uint8_t* ip = aclsig->u.code_start;
125 125
   uint32_t lsig_id;
126 126
   uint32_t rule_matches = 0;
127
+  struct cli_lsig_matches * ls_matches;
128
+  struct cli_subsig_matches * ss_matches;
129
+  uint32_t * offs;
127 130
 #endif
128 131
 
129 132
   YR_RULE* rule;
... ...
@@ -572,6 +576,7 @@ int yr_execute_code(
572 572
 
573 573
         found = 0;
574 574
 
575
+#if REAL_YARA
575 576
         while (match != NULL)
576 577
         {
577 578
           if (r1 == match->base + match->offset)
... ...
@@ -586,7 +591,22 @@ int yr_execute_code(
586 586
 
587 587
           match = match->next;
588 588
         }
589
-
589
+#else
590
+        ls_matches = acdata->lsig_matches[aclsig->id];
591
+        if (ls_matches != NULL) {
592
+            ss_matches = ls_matches->matches[string->subsig_id];
593
+            if (ss_matches != NULL) {
594
+                offs = ss_matches->offsets;
595
+                for (i = 0; i < ss_matches->next; i++) {
596
+                    if (offs[i] == r1) {
597
+                        push(1);
598
+                        found = 1;
599
+                        break;
600
+                    }
601
+                }
602
+            }
603
+        }
604
+#endif
590 605
         if (!found)
591 606
           push(0);
592 607
 
... ...
@@ -659,13 +659,13 @@ static const yytype_uint16 yyrline[] =
659 659
      373,   390,   429,   430,   435,   451,   464,   477,   494,   495,
660 660
      500,   514,   513,   530,   547,   548,   553,   554,   555,   556,
661 661
      561,   646,   696,   719,   759,   762,   784,   817,   864,   882,
662
-     891,   900,   915,   929,   942,   957,   971,  1005,   970,  1116,
663
-    1115,  1191,  1197,  1203,  1209,  1217,  1226,  1235,  1244,  1253,
664
-    1280,  1307,  1334,  1338,  1346,  1347,  1352,  1374,  1386,  1402,
665
-    1401,  1407,  1419,  1420,  1425,  1430,  1439,  1440,  1447,  1458,
666
-    1462,  1471,  1486,  1497,  1508,  1519,  1530,  1541,  1552,  1561,
667
-    1586,  1599,  1612,  1632,  1667,  1676,  1685,  1694,  1703,  1712,
668
-    1721,  1730,  1739,  1747,  1756,  1765
662
+     891,   900,   915,   929,   942,   959,   973,  1007,   972,  1118,
663
+    1117,  1193,  1199,  1205,  1211,  1219,  1228,  1237,  1246,  1255,
664
+    1282,  1309,  1336,  1340,  1348,  1349,  1354,  1376,  1388,  1404,
665
+    1403,  1409,  1421,  1422,  1427,  1432,  1441,  1442,  1449,  1460,
666
+    1464,  1473,  1488,  1499,  1510,  1521,  1532,  1543,  1554,  1563,
667
+    1588,  1601,  1614,  1634,  1669,  1678,  1687,  1696,  1705,  1714,
668
+    1723,  1732,  1741,  1749,  1758,  1767
669 669
 };
670 670
 #endif
671 671
 
... ...
@@ -2751,6 +2751,8 @@ yyreduce:
2751 2751
     {
2752 2752
         CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "at");
2753 2753
 
2754
+        compiler->current_rule_clflags |= RULE_OFFSETS;
2755
+
2754 2756
         compiler->last_result = yr_parser_reduce_string_identifier(
2755 2757
             yyscanner,
2756 2758
             (yyvsp[(1) - (3)].c_string),
... ...
@@ -2767,7 +2769,7 @@ yyreduce:
2767 2767
   case 55:
2768 2768
 
2769 2769
 /* Line 1806 of yacc.c  */
2770
-#line 958 "yara_grammar.y"
2770
+#line 960 "yara_grammar.y"
2771 2771
     {
2772 2772
         compiler->last_result = yr_parser_reduce_string_identifier(
2773 2773
             yyscanner,
... ...
@@ -2785,7 +2787,7 @@ yyreduce:
2785 2785
   case 56:
2786 2786
 
2787 2787
 /* Line 1806 of yacc.c  */
2788
-#line 971 "yara_grammar.y"
2788
+#line 973 "yara_grammar.y"
2789 2789
     {
2790 2790
         int var_index;
2791 2791
 
... ...
@@ -2824,7 +2826,7 @@ yyreduce:
2824 2824
   case 57:
2825 2825
 
2826 2826
 /* Line 1806 of yacc.c  */
2827
-#line 1005 "yara_grammar.y"
2827
+#line 1007 "yara_grammar.y"
2828 2828
     {
2829 2829
         int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth;
2830 2830
 
... ...
@@ -2864,7 +2866,7 @@ yyreduce:
2864 2864
   case 58:
2865 2865
 
2866 2866
 /* Line 1806 of yacc.c  */
2867
-#line 1040 "yara_grammar.y"
2867
+#line 1042 "yara_grammar.y"
2868 2868
     {
2869 2869
         int mem_offset;
2870 2870
 
... ...
@@ -2945,7 +2947,7 @@ yyreduce:
2945 2945
   case 59:
2946 2946
 
2947 2947
 /* Line 1806 of yacc.c  */
2948
-#line 1116 "yara_grammar.y"
2948
+#line 1118 "yara_grammar.y"
2949 2949
     {
2950 2950
         int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth;
2951 2951
         int8_t* addr;
... ...
@@ -2980,7 +2982,7 @@ yyreduce:
2980 2980
   case 60:
2981 2981
 
2982 2982
 /* Line 1806 of yacc.c  */
2983
-#line 1146 "yara_grammar.y"
2983
+#line 1148 "yara_grammar.y"
2984 2984
     {
2985 2985
         int mem_offset;
2986 2986
 
... ...
@@ -3031,7 +3033,7 @@ yyreduce:
3031 3031
   case 61:
3032 3032
 
3033 3033
 /* Line 1806 of yacc.c  */
3034
-#line 1192 "yara_grammar.y"
3034
+#line 1194 "yara_grammar.y"
3035 3035
     {
3036 3036
         yr_parser_emit(yyscanner, OP_OF, NULL);
3037 3037
 
... ...
@@ -3042,7 +3044,7 @@ yyreduce:
3042 3042
   case 62:
3043 3043
 
3044 3044
 /* Line 1806 of yacc.c  */
3045
-#line 1198 "yara_grammar.y"
3045
+#line 1200 "yara_grammar.y"
3046 3046
     {
3047 3047
         yr_parser_emit(yyscanner, OP_NOT, NULL);
3048 3048
 
... ...
@@ -3053,7 +3055,7 @@ yyreduce:
3053 3053
   case 63:
3054 3054
 
3055 3055
 /* Line 1806 of yacc.c  */
3056
-#line 1204 "yara_grammar.y"
3056
+#line 1206 "yara_grammar.y"
3057 3057
     {
3058 3058
         yr_parser_emit(yyscanner, OP_AND, NULL);
3059 3059
 
... ...
@@ -3064,7 +3066,7 @@ yyreduce:
3064 3064
   case 64:
3065 3065
 
3066 3066
 /* Line 1806 of yacc.c  */
3067
-#line 1210 "yara_grammar.y"
3067
+#line 1212 "yara_grammar.y"
3068 3068
     {
3069 3069
         CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_BOOLEAN, "or");
3070 3070
 
... ...
@@ -3077,7 +3079,7 @@ yyreduce:
3077 3077
   case 65:
3078 3078
 
3079 3079
 /* Line 1806 of yacc.c  */
3080
-#line 1218 "yara_grammar.y"
3080
+#line 1220 "yara_grammar.y"
3081 3081
     {
3082 3082
         CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "<");
3083 3083
         CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "<");
... ...
@@ -3091,7 +3093,7 @@ yyreduce:
3091 3091
   case 66:
3092 3092
 
3093 3093
 /* Line 1806 of yacc.c  */
3094
-#line 1227 "yara_grammar.y"
3094
+#line 1229 "yara_grammar.y"
3095 3095
     {
3096 3096
         CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, ">");
3097 3097
         CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, ">");
... ...
@@ -3105,7 +3107,7 @@ yyreduce:
3105 3105
   case 67:
3106 3106
 
3107 3107
 /* Line 1806 of yacc.c  */
3108
-#line 1236 "yara_grammar.y"
3108
+#line 1238 "yara_grammar.y"
3109 3109
     {
3110 3110
         CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "<=");
3111 3111
         CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "<=");
... ...
@@ -3119,7 +3121,7 @@ yyreduce:
3119 3119
   case 68:
3120 3120
 
3121 3121
 /* Line 1806 of yacc.c  */
3122
-#line 1245 "yara_grammar.y"
3122
+#line 1247 "yara_grammar.y"
3123 3123
     {
3124 3124
         CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, ">=");
3125 3125
         CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, ">=");
... ...
@@ -3133,7 +3135,7 @@ yyreduce:
3133 3133
   case 69:
3134 3134
 
3135 3135
 /* Line 1806 of yacc.c  */
3136
-#line 1254 "yara_grammar.y"
3136
+#line 1256 "yara_grammar.y"
3137 3137
     {
3138 3138
         if ((yyvsp[(1) - (3)].expression_type) != (yyvsp[(3) - (3)].expression_type))
3139 3139
         {
... ...
@@ -3165,7 +3167,7 @@ yyreduce:
3165 3165
   case 70:
3166 3166
 
3167 3167
 /* Line 1806 of yacc.c  */
3168
-#line 1281 "yara_grammar.y"
3168
+#line 1283 "yara_grammar.y"
3169 3169
     {
3170 3170
         if ((yyvsp[(1) - (3)].expression_type) != (yyvsp[(3) - (3)].expression_type))
3171 3171
         {
... ...
@@ -3197,7 +3199,7 @@ yyreduce:
3197 3197
   case 71:
3198 3198
 
3199 3199
 /* Line 1806 of yacc.c  */
3200
-#line 1308 "yara_grammar.y"
3200
+#line 1310 "yara_grammar.y"
3201 3201
     {
3202 3202
         if ((yyvsp[(1) - (3)].expression_type) != (yyvsp[(3) - (3)].expression_type))
3203 3203
         {
... ...
@@ -3229,7 +3231,7 @@ yyreduce:
3229 3229
   case 72:
3230 3230
 
3231 3231
 /* Line 1806 of yacc.c  */
3232
-#line 1335 "yara_grammar.y"
3232
+#line 1337 "yara_grammar.y"
3233 3233
     {
3234 3234
         (yyval.expression_type) = (yyvsp[(1) - (1)].expression_type);
3235 3235
       }
... ...
@@ -3238,7 +3240,7 @@ yyreduce:
3238 3238
   case 73:
3239 3239
 
3240 3240
 /* Line 1806 of yacc.c  */
3241
-#line 1339 "yara_grammar.y"
3241
+#line 1341 "yara_grammar.y"
3242 3242
     {
3243 3243
         (yyval.expression_type) = (yyvsp[(2) - (3)].expression_type);
3244 3244
       }
... ...
@@ -3247,21 +3249,21 @@ yyreduce:
3247 3247
   case 74:
3248 3248
 
3249 3249
 /* Line 1806 of yacc.c  */
3250
-#line 1346 "yara_grammar.y"
3250
+#line 1348 "yara_grammar.y"
3251 3251
     { (yyval.integer) = INTEGER_SET_ENUMERATION; }
3252 3252
     break;
3253 3253
 
3254 3254
   case 75:
3255 3255
 
3256 3256
 /* Line 1806 of yacc.c  */
3257
-#line 1347 "yara_grammar.y"
3257
+#line 1349 "yara_grammar.y"
3258 3258
     { (yyval.integer) = INTEGER_SET_RANGE; }
3259 3259
     break;
3260 3260
 
3261 3261
   case 76:
3262 3262
 
3263 3263
 /* Line 1806 of yacc.c  */
3264
-#line 1353 "yara_grammar.y"
3264
+#line 1355 "yara_grammar.y"
3265 3265
     {
3266 3266
         if ((yyvsp[(2) - (6)].expression_type) != EXPRESSION_TYPE_INTEGER)
3267 3267
         {
... ...
@@ -3284,7 +3286,7 @@ yyreduce:
3284 3284
   case 77:
3285 3285
 
3286 3286
 /* Line 1806 of yacc.c  */
3287
-#line 1375 "yara_grammar.y"
3287
+#line 1377 "yara_grammar.y"
3288 3288
     {
3289 3289
         if ((yyvsp[(1) - (1)].expression_type) != EXPRESSION_TYPE_INTEGER)
3290 3290
         {
... ...
@@ -3301,7 +3303,7 @@ yyreduce:
3301 3301
   case 78:
3302 3302
 
3303 3303
 /* Line 1806 of yacc.c  */
3304
-#line 1387 "yara_grammar.y"
3304
+#line 1389 "yara_grammar.y"
3305 3305
     {
3306 3306
         if ((yyvsp[(3) - (3)].expression_type) != EXPRESSION_TYPE_INTEGER)
3307 3307
         {
... ...
@@ -3317,7 +3319,7 @@ yyreduce:
3317 3317
   case 79:
3318 3318
 
3319 3319
 /* Line 1806 of yacc.c  */
3320
-#line 1402 "yara_grammar.y"
3320
+#line 1404 "yara_grammar.y"
3321 3321
     {
3322 3322
         // Push end-of-list marker
3323 3323
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL);
... ...
@@ -3327,12 +3329,12 @@ yyreduce:
3327 3327
   case 81:
3328 3328
 
3329 3329
 /* Line 1806 of yacc.c  */
3330
-#line 1408 "yara_grammar.y"
3330
+#line 1410 "yara_grammar.y"
3331 3331
     {
3332 3332
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL);
3333 3333
         yr_parser_emit_pushes_for_strings(yyscanner, "$*");
3334 3334
 #ifdef YARA_PROTO
3335
-        compiler->current_rule_flags |= RULE_THEM;
3335
+        compiler->current_rule_clflags |= RULE_THEM;
3336 3336
 #endif
3337 3337
       }
3338 3338
     break;
... ...
@@ -3340,7 +3342,7 @@ yyreduce:
3340 3340
   case 84:
3341 3341
 
3342 3342
 /* Line 1806 of yacc.c  */
3343
-#line 1426 "yara_grammar.y"
3343
+#line 1428 "yara_grammar.y"
3344 3344
     {
3345 3345
         yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[(1) - (1)].c_string));
3346 3346
         yr_free((yyvsp[(1) - (1)].c_string));
... ...
@@ -3350,7 +3352,7 @@ yyreduce:
3350 3350
   case 85:
3351 3351
 
3352 3352
 /* Line 1806 of yacc.c  */
3353
-#line 1431 "yara_grammar.y"
3353
+#line 1433 "yara_grammar.y"
3354 3354
     {
3355 3355
         yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[(1) - (1)].c_string));
3356 3356
         yr_free((yyvsp[(1) - (1)].c_string));
... ...
@@ -3360,11 +3362,11 @@ yyreduce:
3360 3360
   case 87:
3361 3361
 
3362 3362
 /* Line 1806 of yacc.c  */
3363
-#line 1441 "yara_grammar.y"
3363
+#line 1443 "yara_grammar.y"
3364 3364
     {
3365 3365
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL);
3366 3366
 #ifdef YARA_PROTO
3367
-        compiler->current_rule_flags |= RULE_ALL;
3367
+        compiler->current_rule_clflags |= RULE_ALL;
3368 3368
 #endif
3369 3369
       }
3370 3370
     break;
... ...
@@ -3372,11 +3374,11 @@ yyreduce:
3372 3372
   case 88:
3373 3373
 
3374 3374
 /* Line 1806 of yacc.c  */
3375
-#line 1448 "yara_grammar.y"
3375
+#line 1450 "yara_grammar.y"
3376 3376
     {
3377 3377
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, 1, NULL);
3378 3378
 #ifdef YARA_PROTO
3379
-        compiler->current_rule_flags |= RULE_ANY;
3379
+        compiler->current_rule_clflags |= RULE_ANY;
3380 3380
 #endif
3381 3381
       }
3382 3382
     break;
... ...
@@ -3384,7 +3386,7 @@ yyreduce:
3384 3384
   case 89:
3385 3385
 
3386 3386
 /* Line 1806 of yacc.c  */
3387
-#line 1459 "yara_grammar.y"
3387
+#line 1461 "yara_grammar.y"
3388 3388
     {
3389 3389
         (yyval.expression_type) = (yyvsp[(2) - (3)].expression_type);
3390 3390
       }
... ...
@@ -3393,7 +3395,7 @@ yyreduce:
3393 3393
   case 90:
3394 3394
 
3395 3395
 /* Line 1806 of yacc.c  */
3396
-#line 1463 "yara_grammar.y"
3396
+#line 1465 "yara_grammar.y"
3397 3397
     {
3398 3398
         compiler->last_result = yr_parser_emit(
3399 3399
             yyscanner, OP_FILESIZE, NULL);
... ...
@@ -3407,13 +3409,13 @@ yyreduce:
3407 3407
   case 91:
3408 3408
 
3409 3409
 /* Line 1806 of yacc.c  */
3410
-#line 1472 "yara_grammar.y"
3410
+#line 1474 "yara_grammar.y"
3411 3411
     {
3412 3412
 #ifndef YARA_PROTO
3413 3413
         yywarning(yyscanner,
3414 3414
             "Using deprecated \"entrypoint\" keyword. Use the \"entry_point\" " "function from PE module instead.");
3415 3415
 #else
3416
-        compiler->current_rule_flags |= RULE_EP;
3416
+        compiler->current_rule_clflags |= RULE_EP;
3417 3417
 #endif
3418 3418
         compiler->last_result = yr_parser_emit(
3419 3419
             yyscanner, OP_ENTRYPOINT, NULL);
... ...
@@ -3427,7 +3429,7 @@ yyreduce:
3427 3427
   case 92:
3428 3428
 
3429 3429
 /* Line 1806 of yacc.c  */
3430
-#line 1487 "yara_grammar.y"
3430
+#line 1489 "yara_grammar.y"
3431 3431
     {
3432 3432
         CHECK_TYPE((yyvsp[(3) - (4)].expression_type), EXPRESSION_TYPE_INTEGER, "int8");
3433 3433
 
... ...
@@ -3443,7 +3445,7 @@ yyreduce:
3443 3443
   case 93:
3444 3444
 
3445 3445
 /* Line 1806 of yacc.c  */
3446
-#line 1498 "yara_grammar.y"
3446
+#line 1500 "yara_grammar.y"
3447 3447
     {
3448 3448
         CHECK_TYPE((yyvsp[(3) - (4)].expression_type), EXPRESSION_TYPE_INTEGER, "int16");
3449 3449
 
... ...
@@ -3459,7 +3461,7 @@ yyreduce:
3459 3459
   case 94:
3460 3460
 
3461 3461
 /* Line 1806 of yacc.c  */
3462
-#line 1509 "yara_grammar.y"
3462
+#line 1511 "yara_grammar.y"
3463 3463
     {
3464 3464
         CHECK_TYPE((yyvsp[(3) - (4)].expression_type), EXPRESSION_TYPE_INTEGER, "int32");
3465 3465
 
... ...
@@ -3475,7 +3477,7 @@ yyreduce:
3475 3475
   case 95:
3476 3476
 
3477 3477
 /* Line 1806 of yacc.c  */
3478
-#line 1520 "yara_grammar.y"
3478
+#line 1522 "yara_grammar.y"
3479 3479
     {
3480 3480
         CHECK_TYPE((yyvsp[(3) - (4)].expression_type), EXPRESSION_TYPE_INTEGER, "uint8");
3481 3481
 
... ...
@@ -3491,7 +3493,7 @@ yyreduce:
3491 3491
   case 96:
3492 3492
 
3493 3493
 /* Line 1806 of yacc.c  */
3494
-#line 1531 "yara_grammar.y"
3494
+#line 1533 "yara_grammar.y"
3495 3495
     {
3496 3496
         CHECK_TYPE((yyvsp[(3) - (4)].expression_type), EXPRESSION_TYPE_INTEGER, "uint16");
3497 3497
 
... ...
@@ -3507,7 +3509,7 @@ yyreduce:
3507 3507
   case 97:
3508 3508
 
3509 3509
 /* Line 1806 of yacc.c  */
3510
-#line 1542 "yara_grammar.y"
3510
+#line 1544 "yara_grammar.y"
3511 3511
     {
3512 3512
         CHECK_TYPE((yyvsp[(3) - (4)].expression_type), EXPRESSION_TYPE_INTEGER, "uint32");
3513 3513
 
... ...
@@ -3523,7 +3525,7 @@ yyreduce:
3523 3523
   case 98:
3524 3524
 
3525 3525
 /* Line 1806 of yacc.c  */
3526
-#line 1553 "yara_grammar.y"
3526
+#line 1555 "yara_grammar.y"
3527 3527
     {
3528 3528
         compiler->last_result = yr_parser_emit_with_arg(
3529 3529
             yyscanner, OP_PUSH, (yyvsp[(1) - (1)].integer), NULL);
... ...
@@ -3537,7 +3539,7 @@ yyreduce:
3537 3537
   case 99:
3538 3538
 
3539 3539
 /* Line 1806 of yacc.c  */
3540
-#line 1562 "yara_grammar.y"
3540
+#line 1564 "yara_grammar.y"
3541 3541
     {
3542 3542
         SIZED_STRING* sized_string = (yyvsp[(1) - (1)].sized_string);
3543 3543
         char* string;
... ...
@@ -3567,7 +3569,7 @@ yyreduce:
3567 3567
   case 100:
3568 3568
 
3569 3569
 /* Line 1806 of yacc.c  */
3570
-#line 1587 "yara_grammar.y"
3570
+#line 1589 "yara_grammar.y"
3571 3571
     {
3572 3572
         compiler->last_result = yr_parser_reduce_string_identifier(
3573 3573
             yyscanner,
... ...
@@ -3585,7 +3587,7 @@ yyreduce:
3585 3585
   case 101:
3586 3586
 
3587 3587
 /* Line 1806 of yacc.c  */
3588
-#line 1600 "yara_grammar.y"
3588
+#line 1602 "yara_grammar.y"
3589 3589
     {
3590 3590
         compiler->last_result = yr_parser_reduce_string_identifier(
3591 3591
             yyscanner,
... ...
@@ -3603,7 +3605,7 @@ yyreduce:
3603 3603
   case 102:
3604 3604
 
3605 3605
 /* Line 1806 of yacc.c  */
3606
-#line 1613 "yara_grammar.y"
3606
+#line 1615 "yara_grammar.y"
3607 3607
     {
3608 3608
         compiler->last_result = yr_parser_emit_with_arg(
3609 3609
             yyscanner,
... ...
@@ -3628,7 +3630,7 @@ yyreduce:
3628 3628
   case 103:
3629 3629
 
3630 3630
 /* Line 1806 of yacc.c  */
3631
-#line 1633 "yara_grammar.y"
3631
+#line 1635 "yara_grammar.y"
3632 3632
     {
3633 3633
         if ((yyvsp[(1) - (1)].object) == (YR_OBJECT*) -1)  // loop identifier
3634 3634
         {
... ...
@@ -3668,7 +3670,7 @@ yyreduce:
3668 3668
   case 104:
3669 3669
 
3670 3670
 /* Line 1806 of yacc.c  */
3671
-#line 1668 "yara_grammar.y"
3671
+#line 1670 "yara_grammar.y"
3672 3672
     {
3673 3673
         CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "+");
3674 3674
         CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "+");
... ...
@@ -3682,7 +3684,7 @@ yyreduce:
3682 3682
   case 105:
3683 3683
 
3684 3684
 /* Line 1806 of yacc.c  */
3685
-#line 1677 "yara_grammar.y"
3685
+#line 1679 "yara_grammar.y"
3686 3686
     {
3687 3687
         CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "-");
3688 3688
         CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "-");
... ...
@@ -3696,7 +3698,7 @@ yyreduce:
3696 3696
   case 106:
3697 3697
 
3698 3698
 /* Line 1806 of yacc.c  */
3699
-#line 1686 "yara_grammar.y"
3699
+#line 1688 "yara_grammar.y"
3700 3700
     {
3701 3701
         CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "*");
3702 3702
         CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "*");
... ...
@@ -3710,7 +3712,7 @@ yyreduce:
3710 3710
   case 107:
3711 3711
 
3712 3712
 /* Line 1806 of yacc.c  */
3713
-#line 1695 "yara_grammar.y"
3713
+#line 1697 "yara_grammar.y"
3714 3714
     {
3715 3715
         CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "\\");
3716 3716
         CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "\\");
... ...
@@ -3724,7 +3726,7 @@ yyreduce:
3724 3724
   case 108:
3725 3725
 
3726 3726
 /* Line 1806 of yacc.c  */
3727
-#line 1704 "yara_grammar.y"
3727
+#line 1706 "yara_grammar.y"
3728 3728
     {
3729 3729
         CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "%");
3730 3730
         CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "%");
... ...
@@ -3738,7 +3740,7 @@ yyreduce:
3738 3738
   case 109:
3739 3739
 
3740 3740
 /* Line 1806 of yacc.c  */
3741
-#line 1713 "yara_grammar.y"
3741
+#line 1715 "yara_grammar.y"
3742 3742
     {
3743 3743
         CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "^");
3744 3744
         CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "^");
... ...
@@ -3752,7 +3754,7 @@ yyreduce:
3752 3752
   case 110:
3753 3753
 
3754 3754
 /* Line 1806 of yacc.c  */
3755
-#line 1722 "yara_grammar.y"
3755
+#line 1724 "yara_grammar.y"
3756 3756
     {
3757 3757
         CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "^");
3758 3758
         CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "^");
... ...
@@ -3766,7 +3768,7 @@ yyreduce:
3766 3766
   case 111:
3767 3767
 
3768 3768
 /* Line 1806 of yacc.c  */
3769
-#line 1731 "yara_grammar.y"
3769
+#line 1733 "yara_grammar.y"
3770 3770
     {
3771 3771
         CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "|");
3772 3772
         CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "|");
... ...
@@ -3780,7 +3782,7 @@ yyreduce:
3780 3780
   case 112:
3781 3781
 
3782 3782
 /* Line 1806 of yacc.c  */
3783
-#line 1740 "yara_grammar.y"
3783
+#line 1742 "yara_grammar.y"
3784 3784
     {
3785 3785
         CHECK_TYPE((yyvsp[(2) - (2)].expression_type), EXPRESSION_TYPE_INTEGER, "~");
3786 3786
 
... ...
@@ -3793,7 +3795,7 @@ yyreduce:
3793 3793
   case 113:
3794 3794
 
3795 3795
 /* Line 1806 of yacc.c  */
3796
-#line 1748 "yara_grammar.y"
3796
+#line 1750 "yara_grammar.y"
3797 3797
     {
3798 3798
         CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "<<");
3799 3799
         CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, "<<");
... ...
@@ -3807,7 +3809,7 @@ yyreduce:
3807 3807
   case 114:
3808 3808
 
3809 3809
 /* Line 1806 of yacc.c  */
3810
-#line 1757 "yara_grammar.y"
3810
+#line 1759 "yara_grammar.y"
3811 3811
     {
3812 3812
         CHECK_TYPE((yyvsp[(1) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, ">>");
3813 3813
         CHECK_TYPE((yyvsp[(3) - (3)].expression_type), EXPRESSION_TYPE_INTEGER, ">>");
... ...
@@ -3821,7 +3823,7 @@ yyreduce:
3821 3821
   case 115:
3822 3822
 
3823 3823
 /* Line 1806 of yacc.c  */
3824
-#line 1766 "yara_grammar.y"
3824
+#line 1768 "yara_grammar.y"
3825 3825
     {
3826 3826
         (yyval.expression_type) = (yyvsp[(1) - (1)].expression_type);
3827 3827
       }
... ...
@@ -3830,7 +3832,7 @@ yyreduce:
3830 3830
 
3831 3831
 
3832 3832
 /* Line 1806 of yacc.c  */
3833
-#line 3834 "yara_grammar.c"
3833
+#line 3836 "yara_grammar.c"
3834 3834
       default: break;
3835 3835
     }
3836 3836
   /* User semantic actions sometimes alter yychar, and that requires
... ...
@@ -4061,6 +4063,6 @@ yyreturn:
4061 4061
 
4062 4062
 
4063 4063
 /* Line 2067 of yacc.c  */
4064
-#line 1771 "yara_grammar.y"
4064
+#line 1773 "yara_grammar.y"
4065 4065
 
4066 4066
 
... ...
@@ -943,6 +943,8 @@ expression
943 943
       {
944 944
         CHECK_TYPE($3, EXPRESSION_TYPE_INTEGER, "at");
945 945
 
946
+        compiler->current_rule_clflags |= RULE_OFFSETS;
947
+
946 948
         compiler->last_result = yr_parser_reduce_string_identifier(
947 949
             yyscanner,
948 950
             $1,
... ...
@@ -1409,7 +1411,7 @@ string_set
1409 1409
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL);
1410 1410
         yr_parser_emit_pushes_for_strings(yyscanner, "$*");
1411 1411
 #ifdef YARA_PROTO
1412
-        compiler->current_rule_flags |= RULE_THEM;
1412
+        compiler->current_rule_clflags |= RULE_THEM;
1413 1413
 #endif
1414 1414
       }
1415 1415
     ;
... ...
@@ -1441,14 +1443,14 @@ for_expression
1441 1441
       {
1442 1442
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL);
1443 1443
 #ifdef YARA_PROTO
1444
-        compiler->current_rule_flags |= RULE_ALL;
1444
+        compiler->current_rule_clflags |= RULE_ALL;
1445 1445
 #endif
1446 1446
       }
1447 1447
     | _ANY_
1448 1448
       {
1449 1449
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, 1, NULL);
1450 1450
 #ifdef YARA_PROTO
1451
-        compiler->current_rule_flags |= RULE_ANY;
1451
+        compiler->current_rule_clflags |= RULE_ANY;
1452 1452
 #endif
1453 1453
       }
1454 1454
     ;
... ...
@@ -1474,7 +1476,7 @@ primary_expression
1474 1474
         yywarning(yyscanner,
1475 1475
             "Using deprecated \"entrypoint\" keyword. Use the \"entry_point\" " "function from PE module instead.");
1476 1476
 #else
1477
-        compiler->current_rule_flags |= RULE_EP;
1477
+        compiler->current_rule_clflags |= RULE_EP;
1478 1478
 #endif
1479 1479
         compiler->last_result = yr_parser_emit(
1480 1480
             yyscanner, OP_ENTRYPOINT, NULL);
... ...
@@ -795,11 +795,12 @@ int yr_parser_reduce_rule_declaration(
795 795
       compiler->current_namespace->name,
796 796
       (void*) rule));
797 797
 
798
-#if REAL_YARA
799 798
   compiler->current_rule_flags = 0;
799
+#if REAL_YARA
800 800
   compiler->current_rule_strings = NULL;
801 801
 #else
802
-  compiler->current_rule_flags = 0;
802
+  rule->cl_flags = compiler->current_rule_clflags;
803
+  compiler->current_rule_clflags = 0;
803 804
   // Write halt instruction at the end of code.
804 805
   yr_arena_write_data(
805 806
       compiler->code_arena,