[Forensics-changes] [yara] 46/160: Fix issue with short-circuit evaluation

Hilko Bengen bengen at moszumanska.debian.org
Sat Jul 1 10:29:17 UTC 2017


This is an automated email from the git hooks/post-receive script.

bengen pushed a commit to annotated tag v3.4.0
in repository yara.

commit 71d43ec342d51bf53618245fd074cfce3a2022b9
Author: Victor Manuel Alvarez <vmalvarez at virustotal.com>
Date:   Sat Mar 14 16:54:17 2015 +0100

    Fix issue with short-circuit evaluation
    
    The destination addresses for the jump instructions were wrong in some situations were the code span across multiple arena pages.
---
 libyara/grammar.c               | 302 +++++++++++++++++++++++-----------------
 libyara/grammar.y               | 146 ++++++++++++-------
 libyara/include/yara/compiler.h |   2 +-
 libyara/include/yara/parser.h   |   9 +-
 libyara/include/yara/utils.h    |   2 +-
 libyara/parser.c                |  34 +++--
 6 files changed, 302 insertions(+), 193 deletions(-)

diff --git a/libyara/grammar.c b/libyara/grammar.c
index be06857..d22ad71 100644
--- a/libyara/grammar.c
+++ b/libyara/grammar.c
@@ -621,14 +621,14 @@ static const yytype_uint16 yyrline[] =
      233,   236,   264,   268,   296,   301,   302,   307,   308,   314,
      317,   335,   348,   385,   386,   391,   407,   420,   433,   450,
      451,   456,   470,   469,   488,   505,   506,   511,   512,   513,
-     514,   519,   607,   655,   715,   762,   765,   790,   826,   871,
-     888,   897,   906,   921,   935,   949,   965,   980,  1015,   979,
-    1129,  1128,  1207,  1213,  1220,  1219,  1262,  1261,  1302,  1311,
-    1320,  1329,  1338,  1347,  1356,  1360,  1368,  1369,  1374,  1396,
-    1408,  1424,  1423,  1429,  1438,  1439,  1444,  1449,  1458,  1459,
-    1463,  1471,  1475,  1485,  1499,  1515,  1525,  1534,  1557,  1572,
-    1587,  1609,  1653,  1672,  1690,  1708,  1726,  1744,  1754,  1764,
-    1774,  1784,  1794,  1804,  1814
+     514,   519,   610,   659,   719,   767,   770,   795,   831,   877,
+     894,   903,   912,   927,   941,   955,   971,   986,  1022,   985,
+    1138,  1137,  1217,  1223,  1230,  1229,  1289,  1288,  1346,  1355,
+    1364,  1373,  1382,  1391,  1400,  1404,  1412,  1413,  1418,  1440,
+    1452,  1468,  1467,  1473,  1482,  1483,  1488,  1493,  1502,  1503,
+    1507,  1515,  1519,  1529,  1543,  1559,  1569,  1578,  1602,  1617,
+    1632,  1655,  1699,  1718,  1736,  1754,  1772,  1790,  1800,  1810,
+    1820,  1830,  1840,  1850,  1860
 };
 #endif
 
@@ -2136,6 +2136,7 @@ yyreduce:
               yyscanner,
               OP_PUSH_M,
               LOOP_LOCAL_VARS * var_index,
+              NULL,
               NULL);
 
           (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
@@ -2176,7 +2177,8 @@ yyreduce:
               compiler->last_result = yr_parser_emit_with_arg_reloc(
                   yyscanner,
                   OP_OBJ_LOAD,
-                  PTR_TO_UINT64(id),
+                  PTR_TO_INT64(id),
+                  NULL,
                   NULL);
 
             (yyval.expression).type = EXPRESSION_TYPE_OBJECT;
@@ -2195,7 +2197,8 @@ yyreduce:
               compiler->last_result = yr_parser_emit_with_arg_reloc(
                   yyscanner,
                   OP_PUSH_RULE,
-                  PTR_TO_UINT64(rule),
+                  PTR_TO_INT64(rule),
+                  NULL,
                   NULL);
 
               (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
@@ -2217,7 +2220,7 @@ yyreduce:
     break;
 
   case 42:
-#line 608 "grammar.y"
+#line 611 "grammar.y"
     {
         YR_OBJECT* field = NULL;
 
@@ -2239,7 +2242,8 @@ yyreduce:
               compiler->last_result = yr_parser_emit_with_arg_reloc(
                   yyscanner,
                   OP_OBJ_FIELD,
-                  PTR_TO_UINT64(ident),
+                  PTR_TO_INT64(ident),
+                  NULL,
                   NULL);
 
             (yyval.expression).type = EXPRESSION_TYPE_OBJECT;
@@ -2268,7 +2272,7 @@ yyreduce:
     break;
 
   case 43:
-#line 656 "grammar.y"
+#line 660 "grammar.y"
     {
         if ((yyvsp[(1) - (4)].expression).type == EXPRESSION_TYPE_OBJECT &&
             (yyvsp[(1) - (4)].expression).value.object->type == OBJECT_TYPE_ARRAY)
@@ -2330,7 +2334,7 @@ yyreduce:
     break;
 
   case 44:
-#line 716 "grammar.y"
+#line 720 "grammar.y"
     {
         char* args_fmt;
 
@@ -2350,7 +2354,8 @@ yyreduce:
             compiler->last_result = yr_parser_emit_with_arg_reloc(
                 yyscanner,
                 OP_CALL,
-                PTR_TO_UINT64(args_fmt),
+                PTR_TO_INT64(args_fmt),
+                NULL,
                 NULL);
 
           YR_OBJECT_FUNCTION* function = (YR_OBJECT_FUNCTION*) (yyvsp[(1) - (4)].expression).value.object;
@@ -2375,14 +2380,14 @@ yyreduce:
     break;
 
   case 45:
-#line 762 "grammar.y"
+#line 767 "grammar.y"
     {
         (yyval.c_string) = yr_strdup("");
       }
     break;
 
   case 46:
-#line 766 "grammar.y"
+#line 771 "grammar.y"
     {
         (yyval.c_string) = (char*) yr_malloc(MAX_FUNCTION_ARGS + 1);
 
@@ -2410,7 +2415,7 @@ yyreduce:
     break;
 
   case 47:
-#line 791 "grammar.y"
+#line 796 "grammar.y"
     {
         if (strlen((yyvsp[(1) - (3)].c_string)) == MAX_FUNCTION_ARGS)
         {
@@ -2445,7 +2450,7 @@ yyreduce:
     break;
 
   case 48:
-#line 827 "grammar.y"
+#line 832 "grammar.y"
     {
         SIZED_STRING* sized_string = (yyvsp[(1) - (1)].sized_string);
         RE* re;
@@ -2477,7 +2482,8 @@ yyreduce:
           compiler->last_result = yr_parser_emit_with_arg_reloc(
               yyscanner,
               OP_PUSH,
-              PTR_TO_UINT64(re->root_node->forward_code),
+              PTR_TO_INT64(re->root_node->forward_code),
+              NULL,
               NULL);
 
         yr_re_destroy(re);
@@ -2489,7 +2495,7 @@ yyreduce:
     break;
 
   case 49:
-#line 872 "grammar.y"
+#line 878 "grammar.y"
     {
         if ((yyvsp[(1) - (1)].expression).type == EXPRESSION_TYPE_STRING)
         {
@@ -2506,10 +2512,10 @@ yyreduce:
     break;
 
   case 50:
-#line 889 "grammar.y"
+#line 895 "grammar.y"
     {
         compiler->last_result = yr_parser_emit_with_arg(
-            yyscanner, OP_PUSH, 1, NULL);
+            yyscanner, OP_PUSH, 1, NULL, NULL);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
@@ -2518,10 +2524,10 @@ yyreduce:
     break;
 
   case 51:
-#line 898 "grammar.y"
+#line 904 "grammar.y"
     {
         compiler->last_result = yr_parser_emit_with_arg(
-            yyscanner, OP_PUSH, 0, NULL);
+            yyscanner, OP_PUSH, 0, NULL, NULL);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
@@ -2530,7 +2536,7 @@ yyreduce:
     break;
 
   case 52:
-#line 907 "grammar.y"
+#line 913 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_STRING, "matches");
         CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_REGEXP, "matches");
@@ -2548,7 +2554,7 @@ yyreduce:
     break;
 
   case 53:
-#line 922 "grammar.y"
+#line 928 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_STRING, "contains");
         CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_STRING, "contains");
@@ -2565,7 +2571,7 @@ yyreduce:
     break;
 
   case 54:
-#line 936 "grammar.y"
+#line 942 "grammar.y"
     {
         int result = yr_parser_reduce_string_identifier(
             yyscanner,
@@ -2582,7 +2588,7 @@ yyreduce:
     break;
 
   case 55:
-#line 950 "grammar.y"
+#line 956 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "at");
 
@@ -2601,7 +2607,7 @@ yyreduce:
     break;
 
   case 56:
-#line 966 "grammar.y"
+#line 972 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner,
@@ -2618,7 +2624,7 @@ yyreduce:
     break;
 
   case 57:
-#line 980 "grammar.y"
+#line 986 "grammar.y"
     {
         int var_index;
 
@@ -2649,6 +2655,7 @@ yyreduce:
             yyscanner,
             OP_PUSH,
             UNDEFINED,
+            NULL,
             NULL);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
@@ -2656,7 +2663,7 @@ yyreduce:
     break;
 
   case 58:
-#line 1015 "grammar.y"
+#line 1022 "grammar.y"
     {
         int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth;
         uint8_t* addr;
@@ -2664,27 +2671,27 @@ yyreduce:
         // Clear counter for number of expressions evaluating
         // to TRUE.
         yr_parser_emit_with_arg(
-            yyscanner, OP_CLEAR_M, mem_offset + 1, NULL);
+            yyscanner, OP_CLEAR_M, mem_offset + 1, NULL, NULL);
 
         // Clear iterations counter
         yr_parser_emit_with_arg(
-            yyscanner, OP_CLEAR_M, mem_offset + 2, NULL);
+            yyscanner, OP_CLEAR_M, mem_offset + 2, NULL, NULL);
 
         if ((yyvsp[(6) - (7)].integer) == INTEGER_SET_ENUMERATION)
         {
           // Pop the first integer
           yr_parser_emit_with_arg(
-              yyscanner, OP_POP_M, mem_offset, &addr);
+              yyscanner, OP_POP_M, mem_offset, &addr, NULL);
         }
         else // INTEGER_SET_RANGE
         {
           // Pop higher bound of set range
           yr_parser_emit_with_arg(
-              yyscanner, OP_POP_M, mem_offset + 3, &addr);
+              yyscanner, OP_POP_M, mem_offset + 3, &addr, NULL);
 
           // Pop lower bound of set range
           yr_parser_emit_with_arg(
-              yyscanner, OP_POP_M, mem_offset, NULL);
+              yyscanner, OP_POP_M, mem_offset, NULL, NULL);
         }
 
         compiler->loop_address[compiler->loop_depth] = addr;
@@ -2694,7 +2701,7 @@ yyreduce:
     break;
 
   case 59:
-#line 1050 "grammar.y"
+#line 1057 "grammar.y"
     {
         int mem_offset;
 
@@ -2709,42 +2716,44 @@ yyreduce:
         // does nothing.
 
         yr_parser_emit_with_arg(
-            yyscanner, OP_ADD_M, mem_offset + 1, NULL);
+            yyscanner, OP_ADD_M, mem_offset + 1, NULL, NULL);
 
         // Increment iterations counter
         yr_parser_emit_with_arg(
-            yyscanner, OP_INCR_M, mem_offset + 2, NULL);
+            yyscanner, OP_INCR_M, mem_offset + 2, NULL, NULL);
 
         if ((yyvsp[(6) - (11)].integer) == INTEGER_SET_ENUMERATION)
         {
           yr_parser_emit_with_arg_reloc(
               yyscanner,
               OP_JNUNDEF,
-              PTR_TO_UINT64(
+              PTR_TO_INT64(
                   compiler->loop_address[compiler->loop_depth]),
+              NULL,
               NULL);
         }
         else // INTEGER_SET_RANGE
         {
           // Increment lower bound of integer set
           yr_parser_emit_with_arg(
-              yyscanner, OP_INCR_M, mem_offset, NULL);
+              yyscanner, OP_INCR_M, mem_offset, NULL, NULL);
 
           // Push lower bound of integer set
           yr_parser_emit_with_arg(
-              yyscanner, OP_PUSH_M, mem_offset, NULL);
+              yyscanner, OP_PUSH_M, mem_offset, NULL, NULL);
 
           // Push higher bound of integer set
           yr_parser_emit_with_arg(
-              yyscanner, OP_PUSH_M, mem_offset + 3, NULL);
+              yyscanner, OP_PUSH_M, mem_offset + 3, NULL, NULL);
 
           // Compare higher bound with lower bound, do loop again
           // if lower bound is still lower or equal than higher bound
           yr_parser_emit_with_arg_reloc(
               yyscanner,
               OP_JLE,
-              PTR_TO_UINT64(
+              PTR_TO_INT64(
                 compiler->loop_address[compiler->loop_depth]),
+              NULL,
               NULL);
 
           yr_parser_emit(yyscanner, OP_POP, NULL);
@@ -2759,12 +2768,12 @@ yyreduce:
         // is undefined (meaning "all") and replace it with the
         // iterations counter in that case.
         yr_parser_emit_with_arg(
-            yyscanner, OP_SWAPUNDEF, mem_offset + 2, NULL);
+            yyscanner, OP_SWAPUNDEF, mem_offset + 2, NULL, NULL);
 
         // Compare the loop quantifier with the number of
         // expressions evaluating to TRUE.
         yr_parser_emit_with_arg(
-            yyscanner, OP_PUSH_M, mem_offset + 1, NULL);
+            yyscanner, OP_PUSH_M, mem_offset + 1, NULL, NULL);
 
         yr_parser_emit(yyscanner, OP_INT_LE, NULL);
 
@@ -2776,7 +2785,7 @@ yyreduce:
     break;
 
   case 60:
-#line 1129 "grammar.y"
+#line 1138 "grammar.y"
     {
         int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth;
         uint8_t* addr;
@@ -2792,14 +2801,14 @@ yyreduce:
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
         yr_parser_emit_with_arg(
-            yyscanner, OP_CLEAR_M, mem_offset + 1, NULL);
+            yyscanner, OP_CLEAR_M, mem_offset + 1, NULL, NULL);
 
         yr_parser_emit_with_arg(
-            yyscanner, OP_CLEAR_M, mem_offset + 2, NULL);
+            yyscanner, OP_CLEAR_M, mem_offset + 2, NULL, NULL);
 
         // Pop the first string.
         yr_parser_emit_with_arg(
-            yyscanner, OP_POP_M, mem_offset, &addr);
+            yyscanner, OP_POP_M, mem_offset, &addr, NULL);
 
         compiler->loop_for_of_mem_offset = mem_offset;
         compiler->loop_address[compiler->loop_depth] = addr;
@@ -2809,7 +2818,7 @@ yyreduce:
     break;
 
   case 61:
-#line 1159 "grammar.y"
+#line 1168 "grammar.y"
     {
         int mem_offset;
 
@@ -2823,19 +2832,20 @@ yyreduce:
         // returned UNDEFINED the OP_ADD_M won't do anything.
 
         yr_parser_emit_with_arg(
-            yyscanner, OP_ADD_M, mem_offset + 1, NULL);
+            yyscanner, OP_ADD_M, mem_offset + 1, NULL, NULL);
 
         // Increment iterations counter.
         yr_parser_emit_with_arg(
-            yyscanner, OP_INCR_M, mem_offset + 2, NULL);
+            yyscanner, OP_INCR_M, mem_offset + 2, NULL, NULL);
 
         // If next string is not undefined, go back to the
         // begining of the loop.
         yr_parser_emit_with_arg_reloc(
             yyscanner,
             OP_JNUNDEF,
-            PTR_TO_UINT64(
+            PTR_TO_INT64(
                 compiler->loop_address[compiler->loop_depth]),
+            NULL,
             NULL);
 
         // Pop end-of-list marker.
@@ -2846,12 +2856,12 @@ yyreduce:
         // undefined (meaning "all") and replace it with the
         // iterations counter in that case.
         yr_parser_emit_with_arg(
-            yyscanner, OP_SWAPUNDEF, mem_offset + 2, NULL);
+            yyscanner, OP_SWAPUNDEF, mem_offset + 2, NULL, NULL);
 
         // Compare the loop quantifier with the number of
         // expressions evaluating to TRUE.
         yr_parser_emit_with_arg(
-            yyscanner, OP_PUSH_M, mem_offset + 1, NULL);
+            yyscanner, OP_PUSH_M, mem_offset + 1, NULL, NULL);
 
         yr_parser_emit(yyscanner, OP_INT_LE, NULL);
 
@@ -2861,7 +2871,7 @@ yyreduce:
     break;
 
   case 62:
-#line 1208 "grammar.y"
+#line 1218 "grammar.y"
     {
         yr_parser_emit(yyscanner, OP_OF, NULL);
 
@@ -2870,7 +2880,7 @@ yyreduce:
     break;
 
   case 63:
-#line 1214 "grammar.y"
+#line 1224 "grammar.y"
     {
         yr_parser_emit(yyscanner, OP_NOT, NULL);
 
@@ -2879,15 +2889,16 @@ yyreduce:
     break;
 
   case 64:
-#line 1220 "grammar.y"
+#line 1230 "grammar.y"
     {
-        uint8_t* jmp_addr;
+        int64_t* jmp_destination_addr;
 
         compiler->last_result = yr_parser_emit_with_arg_reloc(
             yyscanner,
             OP_JFALSE,
             0,          // still don't know the jump destination
-            &jmp_addr);
+            NULL,
+            &jmp_destination_addr);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
@@ -2899,43 +2910,60 @@ yyreduce:
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
-        fixup->address = (uint64_t*) (jmp_addr + 1);
+        fixup->address = jmp_destination_addr;
         fixup->next = compiler->fixup_stack_head;
         compiler->fixup_stack_head = fixup;
       }
     break;
 
   case 65:
-#line 1244 "grammar.y"
+#line 1255 "grammar.y"
     {
         uint8_t* and_addr;
 
+        // Ensure that we have at least two consecutive bytes in the arena's 
+        // current page, one for the AND opcode and one for opcode following the
+        // AND. This is necessary because we need to compute the address for the
+        // opcode following the AND, and we don't want the AND in one page and
+        // the following opcode in another page.
+
+        compiler->last_result = yr_arena_reserve_memory(compiler->code_arena, 2);
+
+        ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+
         compiler->last_result = yr_parser_emit(yyscanner, OP_AND, &and_addr);
 
+        ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+
         // Now we know the jump destination, which is the address of the
-        // instruction following the OP_AND. Let's fixup the jump address.
+        // instruction following the AND. Let's fixup the jump address.
 
         YR_FIXUP* fixup = compiler->fixup_stack_head;
-        *(fixup->address) = PTR_TO_UINT64(and_addr + 1);
+
+        // We know that the AND opcode and the following one are within the same
+        // page, so we can compute the address for the opcode following the AND
+        // by simply adding one to its address.
+        
+        *(fixup->address) = PTR_TO_INT64(and_addr + 1);
+        
         compiler->fixup_stack_head = fixup->next;
         yr_free(fixup);
 
-        ERROR_IF(compiler->last_result != ERROR_SUCCESS);
-
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
     break;
 
   case 66:
-#line 1262 "grammar.y"
+#line 1289 "grammar.y"
     {
-        uint8_t* jmp_addr;
+        int64_t* jmp_destination_addr;
 
         compiler->last_result = yr_parser_emit_with_arg_reloc(
             yyscanner,
             OP_JTRUE,
             0,         // still don't know the jump destination
-            &jmp_addr);
+            NULL,
+            &jmp_destination_addr);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
@@ -2946,35 +2974,51 @@ yyreduce:
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
-        fixup->address = (uint64_t*) (jmp_addr + 1);
+        fixup->address = jmp_destination_addr;
         fixup->next = compiler->fixup_stack_head;
         compiler->fixup_stack_head = fixup;
       }
     break;
 
   case 67:
-#line 1285 "grammar.y"
+#line 1313 "grammar.y"
     {
         uint8_t* or_addr;
 
+        // Ensure that we have at least two consecutive bytes in the arena's 
+        // current page, one for the OR opcode and one for opcode following the
+        // OR. This is necessary because we need to compute the address for the
+        // opcode following the OR, and we don't want the OR in one page and
+        // the following opcode in another page.
+
+        compiler->last_result = yr_arena_reserve_memory(compiler->code_arena, 2);
+
+        ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+
         compiler->last_result = yr_parser_emit(yyscanner, OP_OR, &or_addr);
 
+        ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+
         // Now we know the jump destination, which is the address of the
         // instruction following the OP_OR. Let's fixup the jump address.
 
         YR_FIXUP* fixup = compiler->fixup_stack_head;
-        *(fixup->address) = PTR_TO_UINT64(or_addr + 1);
+
+        // We know that the OR opcode and the following one are within the same
+        // page, so we can compute the address for the opcode following the OR
+        // by simply adding one to its address.
+
+        *(fixup->address) = PTR_TO_INT64(or_addr + 1);
+
         compiler->fixup_stack_head = fixup->next;
         yr_free(fixup);
 
-        ERROR_IF(compiler->last_result != ERROR_SUCCESS);
-
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
     break;
 
   case 68:
-#line 1303 "grammar.y"
+#line 1347 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "<", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -2986,7 +3030,7 @@ yyreduce:
     break;
 
   case 69:
-#line 1312 "grammar.y"
+#line 1356 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, ">", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -2998,7 +3042,7 @@ yyreduce:
     break;
 
   case 70:
-#line 1321 "grammar.y"
+#line 1365 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "<=", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -3010,7 +3054,7 @@ yyreduce:
     break;
 
   case 71:
-#line 1330 "grammar.y"
+#line 1374 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, ">=", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -3022,7 +3066,7 @@ yyreduce:
     break;
 
   case 72:
-#line 1339 "grammar.y"
+#line 1383 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "==", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -3034,7 +3078,7 @@ yyreduce:
     break;
 
   case 73:
-#line 1348 "grammar.y"
+#line 1392 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "!=", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -3046,31 +3090,31 @@ yyreduce:
     break;
 
   case 74:
-#line 1357 "grammar.y"
+#line 1401 "grammar.y"
     {
         (yyval.expression) = (yyvsp[(1) - (1)].expression);
       }
     break;
 
   case 75:
-#line 1361 "grammar.y"
+#line 1405 "grammar.y"
     {
         (yyval.expression) = (yyvsp[(2) - (3)].expression);
       }
     break;
 
   case 76:
-#line 1368 "grammar.y"
+#line 1412 "grammar.y"
     { (yyval.integer) = INTEGER_SET_ENUMERATION; }
     break;
 
   case 77:
-#line 1369 "grammar.y"
+#line 1413 "grammar.y"
     { (yyval.integer) = INTEGER_SET_RANGE; }
     break;
 
   case 78:
-#line 1375 "grammar.y"
+#line 1419 "grammar.y"
     {
         if ((yyvsp[(2) - (6)].expression).type != EXPRESSION_TYPE_INTEGER)
         {
@@ -3091,7 +3135,7 @@ yyreduce:
     break;
 
   case 79:
-#line 1397 "grammar.y"
+#line 1441 "grammar.y"
     {
         if ((yyvsp[(1) - (1)].expression).type != EXPRESSION_TYPE_INTEGER)
         {
@@ -3106,7 +3150,7 @@ yyreduce:
     break;
 
   case 80:
-#line 1409 "grammar.y"
+#line 1453 "grammar.y"
     {
         if ((yyvsp[(3) - (3)].expression).type != EXPRESSION_TYPE_INTEGER)
         {
@@ -3120,23 +3164,23 @@ yyreduce:
     break;
 
   case 81:
-#line 1424 "grammar.y"
+#line 1468 "grammar.y"
     {
         // Push end-of-list marker
-        yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL);
+        yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
       }
     break;
 
   case 83:
-#line 1430 "grammar.y"
+#line 1474 "grammar.y"
     {
-        yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL);
+        yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
         yr_parser_emit_pushes_for_strings(yyscanner, "$*");
       }
     break;
 
   case 86:
-#line 1445 "grammar.y"
+#line 1489 "grammar.y"
     {
         yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[(1) - (1)].c_string));
         yr_free((yyvsp[(1) - (1)].c_string));
@@ -3144,7 +3188,7 @@ yyreduce:
     break;
 
   case 87:
-#line 1450 "grammar.y"
+#line 1494 "grammar.y"
     {
         yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[(1) - (1)].c_string));
         yr_free((yyvsp[(1) - (1)].c_string));
@@ -3152,28 +3196,28 @@ yyreduce:
     break;
 
   case 89:
-#line 1460 "grammar.y"
+#line 1504 "grammar.y"
     {
-        yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL);
+        yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
       }
     break;
 
   case 90:
-#line 1464 "grammar.y"
+#line 1508 "grammar.y"
     {
-        yr_parser_emit_with_arg(yyscanner, OP_PUSH, 1, NULL);
+        yr_parser_emit_with_arg(yyscanner, OP_PUSH, 1, NULL, NULL);
       }
     break;
 
   case 91:
-#line 1472 "grammar.y"
+#line 1516 "grammar.y"
     {
         (yyval.expression) = (yyvsp[(2) - (3)].expression);
       }
     break;
 
   case 92:
-#line 1476 "grammar.y"
+#line 1520 "grammar.y"
     {
         compiler->last_result = yr_parser_emit(
             yyscanner, OP_FILESIZE, NULL);
@@ -3186,7 +3230,7 @@ yyreduce:
     break;
 
   case 93:
-#line 1486 "grammar.y"
+#line 1530 "grammar.y"
     {
         yywarning(yyscanner,
             "Using deprecated \"entrypoint\" keyword. Use the \"entry_point\" "
@@ -3203,7 +3247,7 @@ yyreduce:
     break;
 
   case 94:
-#line 1500 "grammar.y"
+#line 1544 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(3) - (4)].expression), EXPRESSION_TYPE_INTEGER, "intXXXX or uintXXXX");
 
@@ -3222,10 +3266,10 @@ yyreduce:
     break;
 
   case 95:
-#line 1516 "grammar.y"
+#line 1560 "grammar.y"
     {
         compiler->last_result = yr_parser_emit_with_arg(
-            yyscanner, OP_PUSH, (yyvsp[(1) - (1)].integer), NULL);
+            yyscanner, OP_PUSH, (yyvsp[(1) - (1)].integer), NULL, NULL);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
@@ -3235,10 +3279,10 @@ yyreduce:
     break;
 
   case 96:
-#line 1526 "grammar.y"
+#line 1570 "grammar.y"
     {
         compiler->last_result = yr_parser_emit_with_arg_double(
-            yyscanner, OP_PUSH, (yyvsp[(1) - (1)].double_), NULL);
+            yyscanner, OP_PUSH, (yyvsp[(1) - (1)].double_), NULL, NULL);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
@@ -3247,7 +3291,7 @@ yyreduce:
     break;
 
   case 97:
-#line 1535 "grammar.y"
+#line 1579 "grammar.y"
     {
         SIZED_STRING* sized_string;
 
@@ -3263,7 +3307,8 @@ yyreduce:
           compiler->last_result = yr_parser_emit_with_arg_reloc(
               yyscanner,
               OP_PUSH,
-              PTR_TO_UINT64(sized_string),
+              PTR_TO_INT64(sized_string),
+              NULL,
               NULL);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
@@ -3273,7 +3318,7 @@ yyreduce:
     break;
 
   case 98:
-#line 1558 "grammar.y"
+#line 1603 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner,
@@ -3291,7 +3336,7 @@ yyreduce:
     break;
 
   case 99:
-#line 1573 "grammar.y"
+#line 1618 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner,
@@ -3309,12 +3354,13 @@ yyreduce:
     break;
 
   case 100:
-#line 1588 "grammar.y"
+#line 1633 "grammar.y"
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner,
             OP_PUSH,
             1,
+            NULL,
             NULL);
 
         if (compiler->last_result == ERROR_SUCCESS)
@@ -3334,7 +3380,7 @@ yyreduce:
     break;
 
   case 101:
-#line 1610 "grammar.y"
+#line 1656 "grammar.y"
     {
         if ((yyvsp[(1) - (1)].expression).type == EXPRESSION_TYPE_INTEGER)  // loop identifier
         {
@@ -3381,7 +3427,7 @@ yyreduce:
     break;
 
   case 102:
-#line 1654 "grammar.y"
+#line 1700 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(2) - (2)].expression), EXPRESSION_TYPE_INTEGER | EXPRESSION_TYPE_FLOAT, "-");
 
@@ -3403,7 +3449,7 @@ yyreduce:
     break;
 
   case 103:
-#line 1673 "grammar.y"
+#line 1719 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "+", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -3424,7 +3470,7 @@ yyreduce:
     break;
 
   case 104:
-#line 1691 "grammar.y"
+#line 1737 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "-", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -3445,7 +3491,7 @@ yyreduce:
     break;
 
   case 105:
-#line 1709 "grammar.y"
+#line 1755 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "*", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -3466,7 +3512,7 @@ yyreduce:
     break;
 
   case 106:
-#line 1727 "grammar.y"
+#line 1773 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "\\", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -3487,7 +3533,7 @@ yyreduce:
     break;
 
   case 107:
-#line 1745 "grammar.y"
+#line 1791 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "%");
         CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "%");
@@ -3500,7 +3546,7 @@ yyreduce:
     break;
 
   case 108:
-#line 1755 "grammar.y"
+#line 1801 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "^");
         CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "^");
@@ -3513,7 +3559,7 @@ yyreduce:
     break;
 
   case 109:
-#line 1765 "grammar.y"
+#line 1811 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "^");
         CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "^");
@@ -3526,7 +3572,7 @@ yyreduce:
     break;
 
   case 110:
-#line 1775 "grammar.y"
+#line 1821 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "|");
         CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "|");
@@ -3539,7 +3585,7 @@ yyreduce:
     break;
 
   case 111:
-#line 1785 "grammar.y"
+#line 1831 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(2) - (2)].expression), EXPRESSION_TYPE_INTEGER, "~");
 
@@ -3552,7 +3598,7 @@ yyreduce:
     break;
 
   case 112:
-#line 1795 "grammar.y"
+#line 1841 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "<<");
         CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "<<");
@@ -3565,7 +3611,7 @@ yyreduce:
     break;
 
   case 113:
-#line 1805 "grammar.y"
+#line 1851 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, ">>");
         CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, ">>");
@@ -3578,7 +3624,7 @@ yyreduce:
     break;
 
   case 114:
-#line 1815 "grammar.y"
+#line 1861 "grammar.y"
     {
         (yyval.expression) = (yyvsp[(1) - (1)].expression);
       }
@@ -3586,7 +3632,7 @@ yyreduce:
 
 
 /* Line 1267 of yacc.c.  */
-#line 3590 "grammar.c"
+#line 3636 "grammar.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -3800,6 +3846,6 @@ yyreturn:
 }
 
 
-#line 1820 "grammar.y"
+#line 1866 "grammar.y"
 
 
diff --git a/libyara/grammar.y b/libyara/grammar.y
index 977d377..eaf9c7c 100644
--- a/libyara/grammar.y
+++ b/libyara/grammar.y
@@ -526,6 +526,7 @@ identifier
               yyscanner,
               OP_PUSH_M,
               LOOP_LOCAL_VARS * var_index,
+              NULL,
               NULL);
 
           $$.type = EXPRESSION_TYPE_INTEGER;
@@ -566,7 +567,8 @@ identifier
               compiler->last_result = yr_parser_emit_with_arg_reloc(
                   yyscanner,
                   OP_OBJ_LOAD,
-                  PTR_TO_UINT64(id),
+                  PTR_TO_INT64(id),
+                  NULL,
                   NULL);
 
             $$.type = EXPRESSION_TYPE_OBJECT;
@@ -585,7 +587,8 @@ identifier
               compiler->last_result = yr_parser_emit_with_arg_reloc(
                   yyscanner,
                   OP_PUSH_RULE,
-                  PTR_TO_UINT64(rule),
+                  PTR_TO_INT64(rule),
+                  NULL,
                   NULL);
 
               $$.type = EXPRESSION_TYPE_BOOLEAN;
@@ -626,7 +629,8 @@ identifier
               compiler->last_result = yr_parser_emit_with_arg_reloc(
                   yyscanner,
                   OP_OBJ_FIELD,
-                  PTR_TO_UINT64(ident),
+                  PTR_TO_INT64(ident),
+                  NULL,
                   NULL);
 
             $$.type = EXPRESSION_TYPE_OBJECT;
@@ -732,7 +736,8 @@ identifier
             compiler->last_result = yr_parser_emit_with_arg_reloc(
                 yyscanner,
                 OP_CALL,
-                PTR_TO_UINT64(args_fmt),
+                PTR_TO_INT64(args_fmt),
+                NULL,
                 NULL);
 
           YR_OBJECT_FUNCTION* function = (YR_OBJECT_FUNCTION*) $1.value.object;
@@ -855,7 +860,8 @@ regexp
           compiler->last_result = yr_parser_emit_with_arg_reloc(
               yyscanner,
               OP_PUSH,
-              PTR_TO_UINT64(re->root_node->forward_code),
+              PTR_TO_INT64(re->root_node->forward_code),
+              NULL,
               NULL);
 
         yr_re_destroy(re);
@@ -888,7 +894,7 @@ expression
     : _TRUE_
       {
         compiler->last_result = yr_parser_emit_with_arg(
-            yyscanner, OP_PUSH, 1, NULL);
+            yyscanner, OP_PUSH, 1, NULL, NULL);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
@@ -897,7 +903,7 @@ expression
     | _FALSE_
       {
         compiler->last_result = yr_parser_emit_with_arg(
-            yyscanner, OP_PUSH, 0, NULL);
+            yyscanner, OP_PUSH, 0, NULL, NULL);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
@@ -1007,6 +1013,7 @@ expression
             yyscanner,
             OP_PUSH,
             UNDEFINED,
+            NULL,
             NULL);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
@@ -1019,27 +1026,27 @@ expression
         // Clear counter for number of expressions evaluating
         // to TRUE.
         yr_parser_emit_with_arg(
-            yyscanner, OP_CLEAR_M, mem_offset + 1, NULL);
+            yyscanner, OP_CLEAR_M, mem_offset + 1, NULL, NULL);
 
         // Clear iterations counter
         yr_parser_emit_with_arg(
-            yyscanner, OP_CLEAR_M, mem_offset + 2, NULL);
+            yyscanner, OP_CLEAR_M, mem_offset + 2, NULL, NULL);
 
         if ($6 == INTEGER_SET_ENUMERATION)
         {
           // Pop the first integer
           yr_parser_emit_with_arg(
-              yyscanner, OP_POP_M, mem_offset, &addr);
+              yyscanner, OP_POP_M, mem_offset, &addr, NULL);
         }
         else // INTEGER_SET_RANGE
         {
           // Pop higher bound of set range
           yr_parser_emit_with_arg(
-              yyscanner, OP_POP_M, mem_offset + 3, &addr);
+              yyscanner, OP_POP_M, mem_offset + 3, &addr, NULL);
 
           // Pop lower bound of set range
           yr_parser_emit_with_arg(
-              yyscanner, OP_POP_M, mem_offset, NULL);
+              yyscanner, OP_POP_M, mem_offset, NULL, NULL);
         }
 
         compiler->loop_address[compiler->loop_depth] = addr;
@@ -1061,42 +1068,44 @@ expression
         // does nothing.
 
         yr_parser_emit_with_arg(
-            yyscanner, OP_ADD_M, mem_offset + 1, NULL);
+            yyscanner, OP_ADD_M, mem_offset + 1, NULL, NULL);
 
         // Increment iterations counter
         yr_parser_emit_with_arg(
-            yyscanner, OP_INCR_M, mem_offset + 2, NULL);
+            yyscanner, OP_INCR_M, mem_offset + 2, NULL, NULL);
 
         if ($6 == INTEGER_SET_ENUMERATION)
         {
           yr_parser_emit_with_arg_reloc(
               yyscanner,
               OP_JNUNDEF,
-              PTR_TO_UINT64(
+              PTR_TO_INT64(
                   compiler->loop_address[compiler->loop_depth]),
+              NULL,
               NULL);
         }
         else // INTEGER_SET_RANGE
         {
           // Increment lower bound of integer set
           yr_parser_emit_with_arg(
-              yyscanner, OP_INCR_M, mem_offset, NULL);
+              yyscanner, OP_INCR_M, mem_offset, NULL, NULL);
 
           // Push lower bound of integer set
           yr_parser_emit_with_arg(
-              yyscanner, OP_PUSH_M, mem_offset, NULL);
+              yyscanner, OP_PUSH_M, mem_offset, NULL, NULL);
 
           // Push higher bound of integer set
           yr_parser_emit_with_arg(
-              yyscanner, OP_PUSH_M, mem_offset + 3, NULL);
+              yyscanner, OP_PUSH_M, mem_offset + 3, NULL, NULL);
 
           // Compare higher bound with lower bound, do loop again
           // if lower bound is still lower or equal than higher bound
           yr_parser_emit_with_arg_reloc(
               yyscanner,
               OP_JLE,
-              PTR_TO_UINT64(
+              PTR_TO_INT64(
                 compiler->loop_address[compiler->loop_depth]),
+              NULL,
               NULL);
 
           yr_parser_emit(yyscanner, OP_POP, NULL);
@@ -1111,12 +1120,12 @@ expression
         // is undefined (meaning "all") and replace it with the
         // iterations counter in that case.
         yr_parser_emit_with_arg(
-            yyscanner, OP_SWAPUNDEF, mem_offset + 2, NULL);
+            yyscanner, OP_SWAPUNDEF, mem_offset + 2, NULL, NULL);
 
         // Compare the loop quantifier with the number of
         // expressions evaluating to TRUE.
         yr_parser_emit_with_arg(
-            yyscanner, OP_PUSH_M, mem_offset + 1, NULL);
+            yyscanner, OP_PUSH_M, mem_offset + 1, NULL, NULL);
 
         yr_parser_emit(yyscanner, OP_INT_LE, NULL);
 
@@ -1141,14 +1150,14 @@ expression
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
         yr_parser_emit_with_arg(
-            yyscanner, OP_CLEAR_M, mem_offset + 1, NULL);
+            yyscanner, OP_CLEAR_M, mem_offset + 1, NULL, NULL);
 
         yr_parser_emit_with_arg(
-            yyscanner, OP_CLEAR_M, mem_offset + 2, NULL);
+            yyscanner, OP_CLEAR_M, mem_offset + 2, NULL, NULL);
 
         // Pop the first string.
         yr_parser_emit_with_arg(
-            yyscanner, OP_POP_M, mem_offset, &addr);
+            yyscanner, OP_POP_M, mem_offset, &addr, NULL);
 
         compiler->loop_for_of_mem_offset = mem_offset;
         compiler->loop_address[compiler->loop_depth] = addr;
@@ -1169,19 +1178,20 @@ expression
         // returned UNDEFINED the OP_ADD_M won't do anything.
 
         yr_parser_emit_with_arg(
-            yyscanner, OP_ADD_M, mem_offset + 1, NULL);
+            yyscanner, OP_ADD_M, mem_offset + 1, NULL, NULL);
 
         // Increment iterations counter.
         yr_parser_emit_with_arg(
-            yyscanner, OP_INCR_M, mem_offset + 2, NULL);
+            yyscanner, OP_INCR_M, mem_offset + 2, NULL, NULL);
 
         // If next string is not undefined, go back to the
         // begining of the loop.
         yr_parser_emit_with_arg_reloc(
             yyscanner,
             OP_JNUNDEF,
-            PTR_TO_UINT64(
+            PTR_TO_INT64(
                 compiler->loop_address[compiler->loop_depth]),
+            NULL,
             NULL);
 
         // Pop end-of-list marker.
@@ -1192,12 +1202,12 @@ expression
         // undefined (meaning "all") and replace it with the
         // iterations counter in that case.
         yr_parser_emit_with_arg(
-            yyscanner, OP_SWAPUNDEF, mem_offset + 2, NULL);
+            yyscanner, OP_SWAPUNDEF, mem_offset + 2, NULL, NULL);
 
         // Compare the loop quantifier with the number of
         // expressions evaluating to TRUE.
         yr_parser_emit_with_arg(
-            yyscanner, OP_PUSH_M, mem_offset + 1, NULL);
+            yyscanner, OP_PUSH_M, mem_offset + 1, NULL, NULL);
 
         yr_parser_emit(yyscanner, OP_INT_LE, NULL);
 
@@ -1218,13 +1228,14 @@ expression
       }
     | boolean_expression _AND_
       {
-        uint8_t* jmp_addr;
+        int64_t* jmp_destination_addr;
 
         compiler->last_result = yr_parser_emit_with_arg_reloc(
             yyscanner,
             OP_JFALSE,
             0,          // still don't know the jump destination
-            &jmp_addr);
+            NULL,
+            &jmp_destination_addr);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
@@ -1236,7 +1247,7 @@ expression
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
-        fixup->address = (uint64_t*) (jmp_addr + 1);
+        fixup->address = jmp_destination_addr;
         fixup->next = compiler->fixup_stack_head;
         compiler->fixup_stack_head = fixup;
       }
@@ -1244,29 +1255,47 @@ expression
       {
         uint8_t* and_addr;
 
+        // Ensure that we have at least two consecutive bytes in the arena's 
+        // current page, one for the AND opcode and one for opcode following the
+        // AND. This is necessary because we need to compute the address for the
+        // opcode following the AND, and we don't want the AND in one page and
+        // the following opcode in another page.
+
+        compiler->last_result = yr_arena_reserve_memory(
+            compiler->code_arena, 2);
+
+        ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+
         compiler->last_result = yr_parser_emit(yyscanner, OP_AND, &and_addr);
 
+        ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+
         // Now we know the jump destination, which is the address of the
-        // instruction following the OP_AND. Let's fixup the jump address.
+        // instruction following the AND. Let's fixup the jump address.
 
         YR_FIXUP* fixup = compiler->fixup_stack_head;
-        *(fixup->address) = PTR_TO_UINT64(and_addr + 1);
+
+        // We know that the AND opcode and the following one are within the same
+        // page, so we can compute the address for the opcode following the AND
+        // by simply adding one to its address.
+        
+        *(fixup->address) = PTR_TO_INT64(and_addr + 1);
+        
         compiler->fixup_stack_head = fixup->next;
         yr_free(fixup);
 
-        ERROR_IF(compiler->last_result != ERROR_SUCCESS);
-
         $$.type = EXPRESSION_TYPE_BOOLEAN;
       }
     | boolean_expression _OR_
       {
-        uint8_t* jmp_addr;
+        int64_t* jmp_destination_addr;
 
         compiler->last_result = yr_parser_emit_with_arg_reloc(
             yyscanner,
             OP_JTRUE,
             0,         // still don't know the jump destination
-            &jmp_addr);
+            NULL,
+            &jmp_destination_addr);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
@@ -1277,7 +1306,7 @@ expression
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
-        fixup->address = (uint64_t*) (jmp_addr + 1);
+        fixup->address = jmp_destination_addr;
         fixup->next = compiler->fixup_stack_head;
         compiler->fixup_stack_head = fixup;
       }
@@ -1285,18 +1314,35 @@ expression
       {
         uint8_t* or_addr;
 
+        // Ensure that we have at least two consecutive bytes in the arena's 
+        // current page, one for the OR opcode and one for opcode following the
+        // OR. This is necessary because we need to compute the address for the
+        // opcode following the OR, and we don't want the OR in one page and
+        // the following opcode in another page.
+
+        compiler->last_result = yr_arena_reserve_memory(
+            compiler->code_arena, 2);
+
+        ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+
         compiler->last_result = yr_parser_emit(yyscanner, OP_OR, &or_addr);
 
+        ERROR_IF(compiler->last_result != ERROR_SUCCESS);
+
         // Now we know the jump destination, which is the address of the
         // instruction following the OP_OR. Let's fixup the jump address.
 
         YR_FIXUP* fixup = compiler->fixup_stack_head;
-        *(fixup->address) = PTR_TO_UINT64(or_addr + 1);
+
+        // We know that the OR opcode and the following one are within the same
+        // page, so we can compute the address for the opcode following the OR
+        // by simply adding one to its address.
+
+        *(fixup->address) = PTR_TO_INT64(or_addr + 1);
+
         compiler->fixup_stack_head = fixup->next;
         yr_free(fixup);
 
-        ERROR_IF(compiler->last_result != ERROR_SUCCESS);
-
         $$.type = EXPRESSION_TYPE_BOOLEAN;
       }
     | primary_expression _LT_ primary_expression
@@ -1423,12 +1469,12 @@ string_set
     : '('
       {
         // Push end-of-list marker
-        yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL);
+        yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
       }
       string_enumeration ')'
     | _THEM_
       {
-        yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL);
+        yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
         yr_parser_emit_pushes_for_strings(yyscanner, "$*");
       }
     ;
@@ -1458,11 +1504,11 @@ for_expression
     : primary_expression
     | _ALL_
       {
-        yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL);
+        yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
       }
     | _ANY_
       {
-        yr_parser_emit_with_arg(yyscanner, OP_PUSH, 1, NULL);
+        yr_parser_emit_with_arg(yyscanner, OP_PUSH, 1, NULL, NULL);
       }
     ;
 
@@ -1515,7 +1561,7 @@ primary_expression
     | _NUMBER_
       {
         compiler->last_result = yr_parser_emit_with_arg(
-            yyscanner, OP_PUSH, $1, NULL);
+            yyscanner, OP_PUSH, $1, NULL, NULL);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
@@ -1525,7 +1571,7 @@ primary_expression
     | _DOUBLE_
       {
         compiler->last_result = yr_parser_emit_with_arg_double(
-            yyscanner, OP_PUSH, $1, NULL);
+            yyscanner, OP_PUSH, $1, NULL, NULL);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
@@ -1547,7 +1593,8 @@ primary_expression
           compiler->last_result = yr_parser_emit_with_arg_reloc(
               yyscanner,
               OP_PUSH,
-              PTR_TO_UINT64(sized_string),
+              PTR_TO_INT64(sized_string),
+              NULL,
               NULL);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
@@ -1590,6 +1637,7 @@ primary_expression
             yyscanner,
             OP_PUSH,
             1,
+            NULL,
             NULL);
 
         if (compiler->last_result == ERROR_SUCCESS)
diff --git a/libyara/include/yara/compiler.h b/libyara/include/yara/compiler.h
index bff718c..797d172 100644
--- a/libyara/include/yara/compiler.h
+++ b/libyara/include/yara/compiler.h
@@ -40,7 +40,7 @@ typedef void (*YR_COMPILER_CALLBACK_FUNC)(
 
 typedef struct _YR_FIXUP
 {
-  uint64_t* address;
+  int64_t* address;
   struct _YR_FIXUP* next;
 
 } YR_FIXUP;
diff --git a/libyara/include/yara/parser.h b/libyara/include/yara/parser.h
index d2322d9..460e206 100644
--- a/libyara/include/yara/parser.h
+++ b/libyara/include/yara/parser.h
@@ -31,21 +31,24 @@ int yr_parser_emit_with_arg(
     yyscan_t yyscanner,
     uint8_t instruction,
     int64_t argument,
-    uint8_t** instruction_address);
+    uint8_t** instruction_address,
+    int64_t** argument_address);
 
 
 int yr_parser_emit_with_arg_double(
     yyscan_t yyscanner,
     uint8_t instruction,
     double argument,
-    uint8_t** instruction_address);
+    uint8_t** instruction_address,
+    double** argument_address);
 
 
 int yr_parser_emit_with_arg_reloc(
     yyscan_t yyscanner,
     uint8_t instruction,
     int64_t argument,
-    uint8_t** instruction_address);
+    uint8_t** instruction_address,
+    int64_t** argument_address);
 
 
 int yr_parser_check_types(
diff --git a/libyara/include/yara/utils.h b/libyara/include/yara/utils.h
index 9b5adc1..2205cd8 100644
--- a/libyara/include/yara/utils.h
+++ b/libyara/include/yara/utils.h
@@ -45,7 +45,7 @@ limitations under the License.
 #endif
 
 
-#define PTR_TO_UINT64(x)  ((uint64_t) (size_t) x)
+#define PTR_TO_INT64(x)  ((int64_t) (size_t) x)
 
 
 #ifdef NDEBUG
diff --git a/libyara/parser.c b/libyara/parser.c
index 097fa5c..31b45b6 100644
--- a/libyara/parser.c
+++ b/libyara/parser.c
@@ -51,7 +51,8 @@ int yr_parser_emit_with_arg_double(
     yyscan_t yyscanner,
     uint8_t instruction,
     double argument,
-    uint8_t** instruction_address)
+    uint8_t** instruction_address,
+    double** argument_address)
 {
   int result = yr_arena_write_data(
       yyget_extra(yyscanner)->code_arena,
@@ -64,7 +65,7 @@ int yr_parser_emit_with_arg_double(
         yyget_extra(yyscanner)->code_arena,
         &argument,
         sizeof(double),
-        NULL);
+        (void**) argument_address);
 
   return result;
 }
@@ -74,7 +75,8 @@ int yr_parser_emit_with_arg(
     yyscan_t yyscanner,
     uint8_t instruction,
     int64_t argument,
-    uint8_t** instruction_address)
+    uint8_t** instruction_address,
+    int64_t** argument_address)
 {
   int result = yr_arena_write_data(
       yyget_extra(yyscanner)->code_arena,
@@ -87,7 +89,7 @@ int yr_parser_emit_with_arg(
         yyget_extra(yyscanner)->code_arena,
         &argument,
         sizeof(int64_t),
-        NULL);
+        (void**) argument_address);
 
   return result;
 }
@@ -97,9 +99,10 @@ int yr_parser_emit_with_arg_reloc(
     yyscan_t yyscanner,
     uint8_t instruction,
     int64_t argument,
-    uint8_t** instruction_address)
+    uint8_t** instruction_address,
+    int64_t** argument_address)
 {
-  void* ptr;
+  int64_t* ptr;
 
   int result = yr_arena_write_data(
       yyget_extra(yyscanner)->code_arena,
@@ -112,7 +115,7 @@ int yr_parser_emit_with_arg_reloc(
         yyget_extra(yyscanner)->code_arena,
         &argument,
         sizeof(int64_t),
-        &ptr);
+        (void**) &ptr);
 
   if (result == ERROR_SUCCESS)
     result = yr_arena_make_relocatable(
@@ -121,6 +124,9 @@ int yr_parser_emit_with_arg_reloc(
         0,
         EOL);
 
+  if (argument_address != NULL)
+    *argument_address = ptr;
+
   return result;
 }
 
@@ -161,7 +167,8 @@ int yr_parser_emit_pushes_for_strings(
         yr_parser_emit_with_arg_reloc(
             yyscanner,
             OP_PUSH,
-            PTR_TO_UINT64(string),
+            PTR_TO_INT64(string),
+            NULL,
             NULL);
 
         string->g_flags |= STRING_GFLAGS_REFERENCED;
@@ -726,7 +733,8 @@ int yr_parser_reduce_rule_declaration(
   FAIL_ON_COMPILER_ERROR(yr_parser_emit_with_arg_reloc(
       yyscanner,
       OP_MATCH_RULE,
-      PTR_TO_UINT64(rule),
+      PTR_TO_INT64(rule),
+      NULL,
       NULL));
 
   FAIL_ON_COMPILER_ERROR(yr_hash_table_add(
@@ -759,6 +767,7 @@ int yr_parser_reduce_string_identifier(
           yyscanner,
           OP_PUSH_M,
           compiler->loop_for_of_mem_offset,
+          NULL,
           NULL);
 
       yr_parser_emit(yyscanner, instruction, NULL);
@@ -810,7 +819,8 @@ int yr_parser_reduce_string_identifier(
       yr_parser_emit_with_arg_reloc(
           yyscanner,
           OP_PUSH,
-          PTR_TO_UINT64(string),
+          PTR_TO_INT64(string),
+          NULL,
           NULL);
 
       if (instruction != OP_FOUND)
@@ -947,7 +957,8 @@ int yr_parser_reduce_import(
     compiler->last_result = yr_parser_emit_with_arg_reloc(
         yyscanner,
         OP_IMPORT,
-        PTR_TO_UINT64(name),
+        PTR_TO_INT64(name),
+        NULL,
         NULL);
 
   return compiler->last_result;
@@ -1044,6 +1055,7 @@ int yr_parser_reduce_operation(
           yyscanner,
           OP_INT_TO_DBL,
           (left_operand.type == EXPRESSION_TYPE_INTEGER) ? 2 : 1,
+          NULL,
           NULL);
     }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/forensics/yara.git



More information about the forensics-changes mailing list