Blob Blame History Raw
From a07b8943aff6d1daa2af404ba086d7c45fcd76c7 Mon Sep 17 00:00:00 2001
From: Hilko Bengen <bengen@debian.org>
Date: Sun, 26 Mar 2017 15:27:30 +0200
Subject: [PATCH 01/36] Reorganize pe / pe_utils

cherry-picked from

- 7f1596d5b802567a0b81d95ddd0f6b3ebb234d6a: "Add support for CLI
  parsing"
- 94249fc2e2436e66c680446df4bac021929f3a45, "Other minor fixes in
  pe_utils.c"
- 04578d76555284d9cc8d0d902f408593e311fb7a, "Add pe_utils.c to Visual
  Studio 2015 project"
- 798d37a45822bc3c86dee67899b980c7a2870755, "Fix conditionals"
---
 libyara/Makefile.am                    |   3 +
 libyara/include/yara/pe.h              |  61 ++++++++-
 libyara/include/yara/pe_utils.h        |  30 +++++
 libyara/modules/pe.c                   | 239 +--------------------------------
 libyara/modules/pe_utils.c             | 219 +++++++++++++++++++++++++++++-
 windows/vs2015/libyara/libyara.vcxproj |   1 +
 6 files changed, 303 insertions(+), 250 deletions(-)
 create mode 100644 libyara/include/yara/pe_utils.h

diff --git a/libyara/Makefile.am b/libyara/Makefile.am
index be389a2..20dbe4a 100644
--- a/libyara/Makefile.am
+++ b/libyara/Makefile.am
@@ -16,6 +16,9 @@ if HASH_MODULE
 MODULES += modules/hash.c
 endif
 
+# This isn't really a module, but needs to be compiled with them.
+MODULES += modules/pe_utils.c
+
 #
 # Add your modules here:
 #
diff --git a/libyara/include/yara/pe.h b/libyara/include/yara/pe.h
index 9afa314..d03e91a 100644
--- a/libyara/include/yara/pe.h
+++ b/libyara/include/yara/pe.h
@@ -27,6 +27,11 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
+#ifndef YR_PE_H
+#define YR_PE_H
+
+#include <yara/types.h>
+
 #pragma pack(push, 1)
 
 #if defined(_WIN32) || defined(__CYGWIN__)
@@ -285,6 +290,11 @@ typedef struct _IMAGE_OPTIONAL_HEADER64 {
 #define IMAGE_NT_OPTIONAL_HDR32_MAGIC      0x10b
 #define IMAGE_NT_OPTIONAL_HDR64_MAGIC      0x20b
 
+#define OptionalHeader(pe,field)                \
+  (IS_64BITS_PE(pe) ?                           \
+   pe->header64->OptionalHeader.field :         \
+   pe->header->OptionalHeader.field)
+
 
 typedef struct _IMAGE_NT_HEADERS32 {
     DWORD Signature;
@@ -302,6 +312,50 @@ typedef struct _IMAGE_NT_HEADERS64 {
 } IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;
 
 
+//
+// Imports are stored in a linked list. Each node (IMPORTED_DLL) contains the
+// name of the DLL and a pointer to another linked list of IMPORTED_FUNCTION
+// structures containing the names of imported functions.
+//
+
+typedef struct _IMPORTED_DLL
+{
+  char *name;
+
+  struct _IMPORTED_FUNCTION *functions;
+  struct _IMPORTED_DLL *next;
+
+} IMPORTED_DLL, *PIMPORTED_DLL;
+
+
+typedef struct _IMPORTED_FUNCTION
+{
+  char *name;
+  uint8_t has_ordinal;
+  uint16_t ordinal;
+
+  struct _IMPORTED_FUNCTION *next;
+
+} IMPORTED_FUNCTION, *PIMPORTED_FUNCTION;
+
+
+typedef struct _PE
+{
+  uint8_t* data;
+  size_t data_size;
+
+  union {
+    PIMAGE_NT_HEADERS32 header;
+    PIMAGE_NT_HEADERS64 header64;
+  };
+
+  YR_OBJECT* object;
+  IMPORTED_DLL* imported_dlls;
+  uint32_t resources;
+
+} PE;
+
+
 // IMAGE_FIRST_SECTION doesn't need 32/64 versions since the file header is
 // the same either way.
 
@@ -481,10 +535,5 @@ typedef struct _RICH_SIGNATURE {
 #define RICH_DANS 0x536e6144 // "DanS"
 #define RICH_RICH 0x68636952 // "Rich"
 
-typedef struct _RICH_DATA {
-    size_t len;
-    BYTE* raw_data;
-    BYTE* clear_data;
-} RICH_DATA, *PRICH_DATA;
-
 #pragma pack(pop)
+#endif
diff --git a/libyara/include/yara/pe_utils.h b/libyara/include/yara/pe_utils.h
new file mode 100644
index 0000000..945d843
--- /dev/null
+++ b/libyara/include/yara/pe_utils.h
@@ -0,0 +1,30 @@
+#ifndef YR_PE_UTILS_H
+#define YR_PE_UTILS_H
+
+#include <yara/pe.h>
+
+#define MAX_PE_SECTIONS              96
+
+#define IS_64BITS_PE(pe) \
+    (pe->header64->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
+
+#define fits_in_pe(pe, pointer, size) \
+    ((size_t) size <= pe->data_size && \
+     (uint8_t*) (pointer) >= pe->data && \
+     (uint8_t*) (pointer) <= pe->data + pe->data_size - size)
+
+#define struct_fits_in_pe(pe, pointer, struct_type) \
+    fits_in_pe(pe, pointer, sizeof(struct_type))
+
+PIMAGE_NT_HEADERS32 pe_get_header(uint8_t* data, size_t data_size);
+PIMAGE_DATA_DIRECTORY pe_get_directory_entry(PE* pe, int entry);
+PIMAGE_DATA_DIRECTORY pe_get_directory_entry(PE* pe, int entry);
+int64_t pe_rva_to_offset(PE* pe, uint64_t rva);
+char *ord_lookup(char *dll, uint16_t ord);
+
+#if HAVE_LIBCRYPTO
+#include <openssl/asn1.h>
+time_t ASN1_get_time_t(ASN1_TIME* time);
+#endif
+
+#endif
diff --git a/libyara/modules/pe.c b/libyara/modules/pe.c
index 1af5562..8c4cb12 100644
--- a/libyara/modules/pe.c
+++ b/libyara/modules/pe.c
@@ -52,7 +52,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <yara/mem.h>
 #include <yara/strutils.h>
 
-#include "pe_utils.c"
+#include <yara/pe_utils.h>
 
 #define MODULE_NAME pe
 
@@ -88,7 +88,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define RESOURCE_ITERATOR_ABORTED    1
 
 
-#define MAX_PE_SECTIONS              96
 #define MAX_PE_IMPORTS               16384
 #define MAX_PE_EXPORTS               65535
 
@@ -101,24 +100,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     ((entry)->OffsetToData & 0x7FFFFFFF)
 
 
-#define IS_64BITS_PE(pe) \
-    (pe->header64->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
-
-
 #define available_space(pe, pointer) \
     (pe->data + pe->data_size - (uint8_t*)(pointer))
 
 
-#define fits_in_pe(pe, pointer, size) \
-    ((size_t) size <= pe->data_size && \
-     (uint8_t*) (pointer) >= pe->data && \
-     (uint8_t*) (pointer) <= pe->data + pe->data_size - size)
-
-
-#define struct_fits_in_pe(pe, pointer, struct_type) \
-    fits_in_pe(pe, pointer, sizeof(struct_type))
-
-
 typedef int (*RESOURCE_CALLBACK_FUNC) ( \
      PIMAGE_RESOURCE_DATA_ENTRY rsrc_data, \
      int rsrc_type, \
@@ -130,50 +115,6 @@ typedef int (*RESOURCE_CALLBACK_FUNC) ( \
      void* cb_data);
 
 
-//
-// Imports are stored in a linked list. Each node (IMPORTED_DLL) contains the
-// name of the DLL and a pointer to another linked list of IMPORTED_FUNCTION
-// structures containing the names of imported functions.
-//
-
-typedef struct _IMPORTED_DLL
-{
-  char *name;
-
-  struct _IMPORTED_FUNCTION *functions;
-  struct _IMPORTED_DLL *next;
-
-} IMPORTED_DLL, *PIMPORTED_DLL;
-
-
-typedef struct _IMPORTED_FUNCTION
-{
-  char *name;
-  uint8_t has_ordinal;
-  uint16_t ordinal;
-
-  struct _IMPORTED_FUNCTION *next;
-
-} IMPORTED_FUNCTION, *PIMPORTED_FUNCTION;
-
-
-typedef struct _PE
-{
-  uint8_t* data;
-  size_t data_size;
-
-  union {
-    PIMAGE_NT_HEADERS32 header;
-    PIMAGE_NT_HEADERS64 header64;
-  };
-
-  YR_OBJECT* object;
-  IMPORTED_DLL* imported_dlls;
-  uint32_t resources;
-
-} PE;
-
-
 int wide_string_fits_in_pe(
     PE* pe,
     char* data)
@@ -193,71 +134,6 @@ int wide_string_fits_in_pe(
 }
 
 
-PIMAGE_NT_HEADERS32 pe_get_header(
-    uint8_t* data,
-    size_t data_size)
-{
-  PIMAGE_DOS_HEADER mz_header;
-  PIMAGE_NT_HEADERS32 pe_header;
-
-  size_t headers_size = 0;
-
-  if (data_size < sizeof(IMAGE_DOS_HEADER))
-    return NULL;
-
-  mz_header = (PIMAGE_DOS_HEADER) data;
-
-  if (mz_header->e_magic != IMAGE_DOS_SIGNATURE)
-    return NULL;
-
-  if (mz_header->e_lfanew < 0)
-    return NULL;
-
-  headers_size = mz_header->e_lfanew + \
-                 sizeof(pe_header->Signature) + \
-                 sizeof(IMAGE_FILE_HEADER);
-
-  if (data_size < headers_size)
-    return NULL;
-
-  pe_header = (PIMAGE_NT_HEADERS32) (data + mz_header->e_lfanew);
-
-  headers_size += pe_header->FileHeader.SizeOfOptionalHeader;
-
-  if (pe_header->Signature == IMAGE_NT_SIGNATURE &&
-      (pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_UNKNOWN ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_AM33 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_ARM ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_ARMNT ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_ARM64 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_EBC ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_M32R ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_MIPS16 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_MIPSFPU ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_MIPSFPU16 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_POWERPC ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_POWERPCFP ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_R4000 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_SH3 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_SH3DSP ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_SH4 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_SH5 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_THUMB ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_WCEMIPSV2) &&
-      data_size > headers_size)
-  {
-    return pe_header;
-  }
-  else
-  {
-    return NULL;
-  }
-}
-
-
 // Parse the rich signature.
 // http://www.ntcore.com/files/richsign.htm
 
@@ -372,119 +248,6 @@ void pe_parse_rich_signature(
 }
 
 
-PIMAGE_DATA_DIRECTORY pe_get_directory_entry(
-    PE* pe,
-    int entry)
-{
-  PIMAGE_DATA_DIRECTORY result;
-
-  if (IS_64BITS_PE(pe))
-    result = &pe->header64->OptionalHeader.DataDirectory[entry];
-  else
-    result = &pe->header->OptionalHeader.DataDirectory[entry];
-
-  return result;
-}
-
-
-#define OptionalHeader(pe,field)                \
-  (IS_64BITS_PE(pe) ?                           \
-   pe->header64->OptionalHeader.field :         \
-   pe->header->OptionalHeader.field)
-
-
-int64_t pe_rva_to_offset(
-    PE* pe,
-    uint64_t rva)
-{
-  PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pe->header);
-
-  DWORD lowest_section_rva = 0xffffffff;
-  DWORD section_rva = 0;
-  DWORD section_offset = 0;
-  DWORD section_raw_size = 0;
-
-  int64_t result;
-
-  int i = 0;
-
-  int alignment = 0;
-  int rest = 0;
-
-  while(i < yr_min(pe->header->FileHeader.NumberOfSections, MAX_PE_SECTIONS))
-  {
-    if (struct_fits_in_pe(pe, section, IMAGE_SECTION_HEADER))
-    {
-      if (lowest_section_rva > section->VirtualAddress)
-      {
-        lowest_section_rva = section->VirtualAddress;
-      }
-
-      if (rva >= section->VirtualAddress &&
-          section_rva <= section->VirtualAddress)
-      {
-        // Round section_offset
-        //
-        // Rounding everything less than 0x200 to 0 as discussed in
-        // https://code.google.com/archive/p/corkami/wikis/PE.wiki#PointerToRawData
-        // does not work for PE32_FILE from the test suite and for
-        // some tinype samples where File Alignment = 4
-        // (http://www.phreedom.org/research/tinype/).
-        //
-        // If FileAlignment is >= 0x200, it is apparently ignored (see
-        // Ero Carreras's pefile.py, PE.adjust_FileAlignment).
-
-        alignment = yr_min(OptionalHeader(pe, FileAlignment), 0x200);
-
-        section_rva = section->VirtualAddress;
-        section_offset = section->PointerToRawData;
-        section_raw_size = section->SizeOfRawData;
-
-        if (alignment)
-        {
-          rest = section_offset % alignment;
-
-          if (rest)
-            section_offset -= rest;
-        }
-      }
-
-      section++;
-      i++;
-    }
-    else
-    {
-      return -1;
-    }
-  }
-
-  // Everything before the first section seems to get mapped straight
-  // relative to ImageBase.
-
-  if (rva < lowest_section_rva)
-  {
-    section_rva = 0;
-    section_offset = 0;
-    section_raw_size = (DWORD) pe->data_size;
-  }
-
-  // Many sections, have a raw (on disk) size smaller than their in-memory size.
-  // Check for rva's that map to this sparse space, and therefore have no valid
-  // associated file offset.
-
-  if ((rva - section_rva) >= section_raw_size)
-    return -1;
-
-  result = section_offset + (rva - section_rva);
-
-  // Check that the offset fits within the file.
-  if (result >= pe->data_size)
-    return -1;
-
-  return result;
-}
-
-
 // Return a pointer to the resource directory string or NULL.
 // The callback function will parse this and call set_sized_string().
 // The pointer is guranteed to have enough space to contain the entire string.
diff --git a/libyara/modules/pe_utils.c b/libyara/modules/pe_utils.c
index 81a7ae4..ed69b80 100644
--- a/libyara/modules/pe_utils.c
+++ b/libyara/modules/pe_utils.c
@@ -1,16 +1,223 @@
+/*
+Copyright (c) 2014-2015. The YARA Authors. All Rights Reserved.
 
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its contributors
+may be used to endorse or promote products derived from this software without
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
 
 #include <stdio.h>
 
+#if defined(_WIN32)
+#define timegm _mkgmtime
+#endif
+
+#include <string.h>
+
+#include <yara/utils.h>
+#include <yara/strutils.h>
 #include <yara/mem.h>
 #include <yara/integers.h>
+#include <yara/pe_utils.h>
+#include <yara/pe.h>
 
-#if defined(WIN32)
-#include <string.h>
-#define strncasecmp _strnicmp
-#define timegm _mkgmtime
+#if HAVE_LIBCRYPTO
+#include <openssl/asn1.h>
 #endif
 
+PIMAGE_NT_HEADERS32 pe_get_header(
+    uint8_t* data,
+    size_t data_size)
+{
+  PIMAGE_DOS_HEADER mz_header;
+  PIMAGE_NT_HEADERS32 pe_header;
+
+  size_t headers_size = 0;
+
+  if (data_size < sizeof(IMAGE_DOS_HEADER))
+    return NULL;
+
+  mz_header = (PIMAGE_DOS_HEADER) data;
+
+  if (mz_header->e_magic != IMAGE_DOS_SIGNATURE)
+    return NULL;
+
+  if (mz_header->e_lfanew < 0)
+    return NULL;
+
+  headers_size = mz_header->e_lfanew + \
+                 sizeof(pe_header->Signature) + \
+                 sizeof(IMAGE_FILE_HEADER);
+
+  if (data_size < headers_size)
+    return NULL;
+
+  pe_header = (PIMAGE_NT_HEADERS32) (data + mz_header->e_lfanew);
+
+  headers_size += pe_header->FileHeader.SizeOfOptionalHeader;
+
+  if (pe_header->Signature == IMAGE_NT_SIGNATURE &&
+      (pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_UNKNOWN ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_AM33 ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_ARM ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_ARMNT ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_ARM64 ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_EBC ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_M32R ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_MIPS16 ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_MIPSFPU ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_MIPSFPU16 ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_POWERPC ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_POWERPCFP ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_R4000 ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_SH3 ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_SH3DSP ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_SH4 ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_SH5 ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_THUMB ||
+       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_WCEMIPSV2) &&
+      data_size > headers_size)
+  {
+    return pe_header;
+  }
+  else
+  {
+    return NULL;
+  }
+}
+
+
+PIMAGE_DATA_DIRECTORY pe_get_directory_entry(
+    PE* pe,
+    int entry)
+{
+  PIMAGE_DATA_DIRECTORY result;
+
+  if (IS_64BITS_PE(pe))
+    result = &pe->header64->OptionalHeader.DataDirectory[entry];
+  else
+    result = &pe->header->OptionalHeader.DataDirectory[entry];
+
+  return result;
+}
+
+
+int64_t pe_rva_to_offset(
+    PE* pe,
+    uint64_t rva)
+{
+  PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pe->header);
+
+  DWORD lowest_section_rva = 0xffffffff;
+  DWORD section_rva = 0;
+  DWORD section_offset = 0;
+  DWORD section_raw_size = 0;
+
+  int64_t result;
+
+  int i = 0;
+
+  int alignment = 0;
+  int rest = 0;
+
+  while(i < yr_min(pe->header->FileHeader.NumberOfSections, MAX_PE_SECTIONS))
+  {
+    if (struct_fits_in_pe(pe, section, IMAGE_SECTION_HEADER))
+    {
+      if (lowest_section_rva > section->VirtualAddress)
+      {
+        lowest_section_rva = section->VirtualAddress;
+      }
+
+      if (rva >= section->VirtualAddress &&
+          section_rva <= section->VirtualAddress)
+      {
+        // Round section_offset
+        //
+        // Rounding everything less than 0x200 to 0 as discussed in
+        // https://code.google.com/archive/p/corkami/wikis/PE.wiki#PointerToRawData
+        // does not work for PE32_FILE from the test suite and for
+        // some tinype samples where File Alignment = 4
+        // (http://www.phreedom.org/research/tinype/).
+        //
+        // If FileAlignment is >= 0x200, it is apparently ignored (see
+        // Ero Carreras's pefile.py, PE.adjust_FileAlignment).
+
+        alignment = yr_min(OptionalHeader(pe, FileAlignment), 0x200);
+
+        section_rva = section->VirtualAddress;
+        section_offset = section->PointerToRawData;
+        section_raw_size = section->SizeOfRawData;
+
+        if (alignment)
+        {
+          rest = section_offset % alignment;
+
+          if (rest)
+            section_offset -= rest;
+        }
+      }
+
+      section++;
+      i++;
+    }
+    else
+    {
+      return -1;
+    }
+  }
+
+  // Everything before the first section seems to get mapped straight
+  // relative to ImageBase.
+
+  if (rva < lowest_section_rva)
+  {
+    section_rva = 0;
+    section_offset = 0;
+    section_raw_size = (DWORD) pe->data_size;
+  }
+
+  // Many sections, have a raw (on disk) size smaller than their in-memory size.
+  // Check for rva's that map to this sparse space, and therefore have no valid
+  // associated file offset.
+
+  if ((rva - section_rva) >= section_raw_size)
+    return -1;
+
+  result = section_offset + (rva - section_rva);
+
+  // Check that the offset fits within the file.
+  if (result >= pe->data_size)
+    return -1;
+
+  return result;
+}
+
+
 #if !HAVE_TIMEGM && !defined(WIN32)
 
 #include <time.h>
@@ -57,7 +264,7 @@ time_t timegm(
 // Taken from http://stackoverflow.com/questions/10975542/asn1-time-conversion
 // and cleaned up. Also uses timegm(3) instead of mktime(3).
 
-static time_t ASN1_get_time_t(
+time_t ASN1_get_time_t(
   	ASN1_TIME* time)
 {
   struct tm t;
@@ -105,7 +312,7 @@ static time_t ASN1_get_time_t(
 // "ordN" and if that fails, return NULL. The caller is responsible for freeing
 // the returned string.
 
-static char *ord_lookup(
+char *ord_lookup(
     char *dll,
     uint16_t ord)
 {
diff --git a/windows/vs2015/libyara/libyara.vcxproj b/windows/vs2015/libyara/libyara.vcxproj
index c7e31f7..dc3c59f 100644
--- a/windows/vs2015/libyara/libyara.vcxproj
+++ b/windows/vs2015/libyara/libyara.vcxproj
@@ -189,6 +189,7 @@
     <ClCompile Include="..\..\..\libyara\modules\hash.c" />
     <ClCompile Include="..\..\..\libyara\modules\math.c" />
     <ClCompile Include="..\..\..\libyara\modules\pe.c" />
+    <ClCompile Include="..\..\..\libyara\modules\pe_utils.c" />
     <ClCompile Include="..\..\..\libyara\modules\tests.c" />
     <ClCompile Include="..\..\..\libyara\object.c" />
     <ClCompile Include="..\..\..\libyara\parser.c" />

From 89dbf689408399d34f160a916c9cc428dc7a66a2 Mon Sep 17 00:00:00 2001
From: "Victor M. Alvarez" <plusvic@gmail.com>
Date: Tue, 9 Aug 2016 10:28:57 +0200
Subject: [PATCH 02/36] Change modules macro names in VS 2010 project

(cherry picked from commit 0216b3a7dfa9f9c0ecabbea2517964a3b2242a9f)
---
 windows/vs2010/libyara/libyara.vcxproj |  8 ++++----
 windows/vs2010/yara.sln                | 22 +++++++++++-----------
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/windows/vs2010/libyara/libyara.vcxproj b/windows/vs2010/libyara/libyara.vcxproj
index 10d1688..f61145a 100644
--- a/windows/vs2010/libyara/libyara.vcxproj
+++ b/windows/vs2010/libyara/libyara.vcxproj
@@ -74,7 +74,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;CUCKOO;HASH;HAVE_LIBCRYPTO</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;CUCKOO_MODULE;HASH_MODULE;HAVE_LIBCRYPTO</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>..\..\..;..\..\..\libyara;..\..\..\libyara\include;..\..\..\windows\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
       <DisableSpecificWarnings>4005;4273;4090;</DisableSpecificWarnings>
@@ -98,7 +98,7 @@
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
-      <PreprocessorDefinitions>CUCKOO;HASH;HAVE_LIBCRYPTO</PreprocessorDefinitions>
+      <PreprocessorDefinitions>CUCKOO_MODULE;HASH_MODULE;HAVE_LIBCRYPTO</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>..\..\..;..\..\..\libyara;..\..\..\libyara\include;..\..\..\windows\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DisableSpecificWarnings>4005;4273;4090;</DisableSpecificWarnings>
       <CompileAs>CompileAsCpp</CompileAs>
@@ -120,7 +120,7 @@
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;CUCKOO;HASH;HAVE_LIBCRYPTO</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;CUCKOO_MODULE;HASH_MODULE;HAVE_LIBCRYPTO</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>..\..\..;..\..\..\libyara;..\..\..\libyara\include;..\..\..\windows\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <DisableSpecificWarnings>4005;4273;4090;%(DisableSpecificWarnings)</DisableSpecificWarnings>
@@ -140,7 +140,7 @@
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
-      <PreprocessorDefinitions>CUCKOO;HASH;HAVE_LIBCRYPTO</PreprocessorDefinitions>
+      <PreprocessorDefinitions>CUCKOO_MODULE;HASH_MODULE;HAVE_LIBCRYPTO</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>..\..\..;..\..\..\libyara;..\..\..\libyara\include;..\..\..\windows\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DisableSpecificWarnings>4005;4273;4090;%(DisableSpecificWarnings)</DisableSpecificWarnings>
       <CompileAs>CompileAsCpp</CompileAs>
diff --git a/windows/vs2010/yara.sln b/windows/vs2010/yara.sln
index 53a4058..054f60c 100644
--- a/windows/vs2010/yara.sln
+++ b/windows/vs2010/yara.sln
@@ -1,16 +1,16 @@
 
 Microsoft Visual Studio Solution File, Format Version 11.00
 # Visual Studio 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libyara", "libyara\libyara.vcxproj", "{B90417B6-5132-DA5C-DBA8-E8A830BE8172}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libyara", "libyara\libyara.vcxproj", "{5E18111F-0F7D-08E0-195A-C60C1C0DD239}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yara", "yara\yara.vcxproj", "{E203D7BB-29B9-4152-9208-BB410983CE8C}"
 	ProjectSection(ProjectDependencies) = postProject
-		{B90417B6-5132-DA5C-DBA8-E8A830BE8172} = {B90417B6-5132-DA5C-DBA8-E8A830BE8172}
+		{5E18111F-0F7D-08E0-195A-C60C1C0DD239} = {5E18111F-0F7D-08E0-195A-C60C1C0DD239}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yarac", "yarac\yarac.vcxproj", "{C2EE445F-2BA5-4E2D-A9E5-44ADE8CAF8E4}"
 	ProjectSection(ProjectDependencies) = postProject
-		{B90417B6-5132-DA5C-DBA8-E8A830BE8172} = {B90417B6-5132-DA5C-DBA8-E8A830BE8172}
+		{5E18111F-0F7D-08E0-195A-C60C1C0DD239} = {5E18111F-0F7D-08E0-195A-C60C1C0DD239}
 	EndProjectSection
 EndProject
 Global
@@ -21,14 +21,14 @@ Global
 		Release|x64 = Release|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{B90417B6-5132-DA5C-DBA8-E8A830BE8172}.Debug|Win32.ActiveCfg = Debug|Win32
-		{B90417B6-5132-DA5C-DBA8-E8A830BE8172}.Debug|Win32.Build.0 = Debug|Win32
-		{B90417B6-5132-DA5C-DBA8-E8A830BE8172}.Debug|x64.ActiveCfg = Debug|x64
-		{B90417B6-5132-DA5C-DBA8-E8A830BE8172}.Debug|x64.Build.0 = Debug|x64
-		{B90417B6-5132-DA5C-DBA8-E8A830BE8172}.Release|Win32.ActiveCfg = Release|Win32
-		{B90417B6-5132-DA5C-DBA8-E8A830BE8172}.Release|Win32.Build.0 = Release|Win32
-		{B90417B6-5132-DA5C-DBA8-E8A830BE8172}.Release|x64.ActiveCfg = Release|x64
-		{B90417B6-5132-DA5C-DBA8-E8A830BE8172}.Release|x64.Build.0 = Release|x64
+		{5E18111F-0F7D-08E0-195A-C60C1C0DD239}.Debug|Win32.ActiveCfg = Debug|Win32
+		{5E18111F-0F7D-08E0-195A-C60C1C0DD239}.Debug|Win32.Build.0 = Debug|Win32
+		{5E18111F-0F7D-08E0-195A-C60C1C0DD239}.Debug|x64.ActiveCfg = Debug|x64
+		{5E18111F-0F7D-08E0-195A-C60C1C0DD239}.Debug|x64.Build.0 = Debug|x64
+		{5E18111F-0F7D-08E0-195A-C60C1C0DD239}.Release|Win32.ActiveCfg = Release|Win32
+		{5E18111F-0F7D-08E0-195A-C60C1C0DD239}.Release|Win32.Build.0 = Release|Win32
+		{5E18111F-0F7D-08E0-195A-C60C1C0DD239}.Release|x64.ActiveCfg = Release|x64
+		{5E18111F-0F7D-08E0-195A-C60C1C0DD239}.Release|x64.Build.0 = Release|x64
 		{E203D7BB-29B9-4152-9208-BB410983CE8C}.Debug|Win32.ActiveCfg = Debug|Win32
 		{E203D7BB-29B9-4152-9208-BB410983CE8C}.Debug|Win32.Build.0 = Debug|Win32
 		{E203D7BB-29B9-4152-9208-BB410983CE8C}.Debug|x64.ActiveCfg = Debug|x64

From ef0f55912f40180a8ab35eeb576f6f087c9a90a3 Mon Sep 17 00:00:00 2001
From: ejectck <ejectck@users.noreply.github.com>
Date: Wed, 10 Aug 2016 18:46:10 +0200
Subject: [PATCH 03/36] Added missing apt-get command "install" (#500)

(cherry picked from commit c9d0819fe2c1f330823c541f118de45f0aad3406)
---
 docs/gettingstarted.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/docs/gettingstarted.rst b/docs/gettingstarted.rst
index 90f14a5..4a518da 100644
--- a/docs/gettingstarted.rst
+++ b/docs/gettingstarted.rst
@@ -19,12 +19,12 @@ Download the source tarball and get prepared for compiling it::
 Make sure you have ``automake``, ``libtool``, ``make``  and ``gcc`` installed
 in your system. Ubuntu and Debian users can use::
 
-    sudo apt-get automake libtool make gcc
+    sudo apt-get install automake libtool make gcc
 
 If you plan to modify YARA's source code you may also need ``flex`` and
 ``bison`` for generating lexers and parsers::
 
-   sudo apt-get flex bison
+   sudo apt-get install flex bison
 
 Compile and install YARA in the standard way::
 

From 06391f0853aeea3bf4582291bea540767a88678b Mon Sep 17 00:00:00 2001
From: plusvic <plusvic@gmail.com>
Date: Fri, 19 Aug 2016 17:25:14 +0200
Subject: [PATCH 04/36] Fix issue #506

(cherry picked from commit f4b535fa2b8adb73a0494b8f96d16af0c920180d)
---
 libyara/lexer.c    | 319 ++++++++++++++++++++++++++---------------------------
 libyara/lexer.l    |   2 +-
 tests/test-rules.c |  10 +-
 3 files changed, 168 insertions(+), 163 deletions(-)

diff --git a/libyara/lexer.c b/libyara/lexer.c
index d0f3688..64c3fea 100644
--- a/libyara/lexer.c
+++ b/libyara/lexer.c
@@ -243,7 +243,7 @@ struct yy_buffer_state
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
 	 */
-	yy_size_t yy_n_chars;
+	int yy_n_chars;
 
 	/* Whether we "own" the buffer - i.e., we know we created it,
 	 * and can realloc() it to grow it, and should free() it to
@@ -455,7 +455,7 @@ static yyconst YY_CHAR yy_ec[256] =
 
 static yyconst YY_CHAR yy_meta[56] =
     {   0,
-        1,    2,    3,    1,    1,    4,    1,    1,    2,    5,
+        1,    2,    3,    2,    1,    4,    1,    1,    2,    5,
         6,    7,    8,    8,    8,    8,    8,    8,    8,    1,
         9,    1,    1,   10,   10,   11,   12,   12,   13,   11,
        10,   10,   10,   10,   10,   10,   11,   11,   11,   11,
@@ -465,32 +465,32 @@ static yyconst YY_CHAR yy_meta[56] =
 
 static yyconst flex_uint16_t yy_base[266] =
     {   0,
-        0,    0,   53,   54,   55,   58,  343,  342,  337,  330,
-      339,  640,  640,  640,  317,  640,    0,  327,  325,   52,
-       52,   58,   45,  312,   50,    0,    0,   48,  289,  289,
-       50,  290,   32,   61,  278,   32,  273,  269,  269,   59,
-      276,  275,  298,    0,  640,  640,   70,    0,  640,   61,
-      297,    0,  640,  640,  296,  286,  640,    0,  640,  296,
-      640,  640,    0,  109,    0,  280,  279,    0,  640,  640,
-      640,  640,  640,    0,    0,  263,   67,  269,    0,  259,
-      253,  259,  258,  252,  256,  252,  250,   58,  246,  239,
-       69,    0,    0,  246,  244,  238,  247,  231,  236,  243,
+        0,    0,   53,   54,   55,   58,  347,  346,  341,  340,
+      349,  640,  640,  640,  327,  640,    0,  337,  329,   52,
+       52,   58,   45,  318,   50,    0,    0,   48,  295,  295,
+       50,  296,   32,   61,  290,   32,  287,  283,  283,   59,
+      282,  279,  305,    0,  640,  640,   70,    0,  640,   61,
+      304,    0,  640,  640,  303,  289,  640,    0,  640,  299,
+      640,  640,    0,  109,    0,  283,  282,    0,  640,  640,
+      640,  640,  640,    0,    0,  266,   67,  272,    0,  262,
+      256,  262,  261,  255,  259,  255,  253,   58,  249,  248,
+       69,    0,    0,  255,  253,  241,  250,  236,  241,  248,
 
        63,   96,    0,  640,  640,  640,  640,  640,    0,    0,
-      230,  640,  640,  640,    0,  640,    0,  116,  640,    0,
-        0,    0,    0,  228,  102,  219,  217,  227,    0,  221,
-      228,  213,  215,  123,  221,  222,  221,    0,  202,  215,
-      210,  207,  212,  199,  210,  640,  234,  148,    0,  204,
-      203,  210,  188,  204,  186,  181,  199,  184,  180,  207,
-      209,  191,  184,    0,  167,  181,    0,  168,    0,    0,
-        0,  199,  196,  202,    0,  101,    0,  640,    0,  160,
-      167,  158,    0,  162,  157,  159,  151,  163,  161,  160,
-      159,  146,  155,  256,  128,  152,  148,  146,  135,  142,
-
-        0,    0,  151,    0,  139,    0,  143,  131,  310,    0,
-      364,  164,  131,    0,  132,  128,  132,  135,  135,  166,
-        0,    0,    0,  134,  149,  135,  136,  142,   78,    0,
-       73,    0,    0,  108,  143,    0,  146,    0,   31,  640,
+      233,  640,  640,  640,    0,  640,    0,  116,  640,    0,
+        0,    0,    0,  239,  102,  232,  230,  232,    0,  224,
+      231,  219,  221,  123,  223,  224,  223,    0,  204,  217,
+      212,  209,  214,  201,  212,  640,  236,  148,    0,  206,
+      205,  212,  190,  206,  194,  189,  201,  186,  182,  211,
+      213,  193,  186,    0,  177,  191,    0,  171,    0,    0,
+        0,  202,  198,  202,    0,  101,    0,  640,    0,  162,
+      169,  163,    0,  163,  158,  160,  152,  164,  162,  161,
+      160,  147,  156,  256,  128,  153,  149,  147,  136,  143,
+
+        0,    0,  152,    0,  140,    0,  150,  132,  310,    0,
+      364,  165,  131,    0,  133,  129,  135,  136,  135,  157,
+        0,    0,    0,  134,  148,  135,  136,  143,   78,    0,
+       73,    0,    0,  108,  144,    0,  158,    0,   31,  640,
         0,  640,  419,  432,  445,  458,  464,  469,  477,  484,
       489,  494,  505,  515,  527,  540,  552,  565,  578,  584,
       587,  597,  610,  616,  626
@@ -547,30 +547,30 @@ static yyconst flex_uint16_t yy_nxt[696] =
       109,  118,  118,  118,  118,  118,  118,  118,  118,  118,
       118,  118,  118,  118,  118,  151,  160,  194,  161,  195,
       227,  162,  228,  235,  194,  236,  195,  237,  152,  175,
-      101,  227,  173,  228,  211,  227,  175,  228,  173,  176,
-      175,  175,  175,  175,  175,  175,  175,  234,  233,  232,
-      231,  175,  175,  230,  229,  226,  223,  222,  175,  175,
-      175,  175,  175,  175,  221,  220,  219,  218,  217,  216,
-      215,  208,  207,  206,  205,  204,  203,  202,  201,  200,
-
-      199,  198,  177,  175,  101,  197,  196,  101,  173,  193,
-      175,  192,  191,  176,  175,  175,  175,  175,  175,  175,
-      175,  190,  189,  162,  162,  175,  175,  188,  187,  186,
-      185,  184,  175,  175,  175,  175,  175,  175,  183,  182,
-      181,  180,  179,  173,  171,  134,  170,  169,  168,  167,
-      166,  165,  164,  163,  159,  158,  177,  210,  211,  157,
-      156,  155,  154,  153,  210,  212,  150,  213,  210,  210,
-      210,  210,  210,  210,  210,  112,  145,  144,  143,  210,
-      210,  142,  141,  140,  139,  136,  210,  210,  210,  210,
-      210,  210,  135,  132,  131,  130,  129,  128,  127,  126,
-
-      125,  124,  121,  119,  119,   59,  242,  116,  114,  102,
-      214,  210,  211,  100,   99,   96,   95,   94,  210,  212,
-       91,  213,  210,  210,  210,  210,  210,  210,  210,   86,
-       81,   80,   71,  210,  210,   61,   59,   57,  242,   55,
-      210,  210,  210,  210,  210,  210,   55,   53,   53,  242,
-      242,  242,  242,  242,  242,  242,  242,  242,  242,  242,
-      242,  242,  242,  242,  214,  211,  211,  242,  242,  242,
+      101,  175,  227,  173,  228,  211,  175,  173,  234,  176,
+      175,  175,  175,  175,  175,  175,  175,  227,  233,  228,
+      232,  175,  175,  231,  230,  229,  226,  223,  175,  175,
+      175,  175,  175,  175,  222,  221,  220,  219,  218,  217,
+      216,  215,  208,  207,  206,  205,  204,  203,  202,  201,
+
+      200,  199,  177,  175,  101,  175,  198,  197,  196,  101,
+      175,  173,  193,  176,  175,  175,  175,  175,  175,  175,
+      175,  192,  191,  190,  189,  175,  175,  162,  162,  188,
+      187,  186,  175,  175,  175,  175,  175,  175,  185,  184,
+      183,  182,  181,  180,  179,  173,  171,  134,  170,  169,
+      168,  167,  166,  165,  164,  163,  177,  210,  211,  210,
+      159,  158,  157,  156,  210,  212,  155,  213,  210,  210,
+      210,  210,  210,  210,  210,  154,  153,  150,  112,  210,
+      210,  145,  144,  143,  142,  141,  210,  210,  210,  210,
+      210,  210,  140,  139,  136,  135,  132,  131,  130,  129,
+
+      128,  127,  126,  125,  124,  121,  119,  119,   59,  242,
+      214,  210,  211,  210,  116,  114,  102,  100,  210,  212,
+       99,  213,  210,  210,  210,  210,  210,  210,  210,   96,
+       95,   94,   91,  210,  210,   86,   81,   80,   71,   61,
+      210,  210,  210,  210,  210,  210,   59,   57,  242,   55,
+       55,   53,   53,  242,  242,  242,  242,  242,  242,  242,
+      242,  242,  242,  242,  214,  211,  211,  211,  242,  242,
       242,  242,  211,  173,  242,  224,  211,  211,  211,  211,
       211,  211,  211,  242,  242,  242,  242,  211,  211,  242,
       242,  242,  242,  242,  211,  211,  211,  211,  211,  211,
@@ -628,30 +628,30 @@ static yyconst flex_int16_t yy_chk[696] =
        47,   64,   64,   64,   64,   64,   64,   64,  118,  118,
       118,  118,  118,  118,  118,  125,  134,  195,  134,  195,
       213,  134,  213,  224,  226,  224,  226,  227,  125,  148,
-      148,  228,  235,  228,  235,  237,  148,  237,  225,  148,
-      148,  148,  148,  148,  148,  148,  148,  220,  219,  218,
-      217,  148,  148,  216,  215,  212,  208,  207,  148,  148,
-      148,  148,  148,  148,  205,  203,  200,  199,  198,  197,
-      196,  193,  192,  191,  190,  189,  188,  187,  186,  185,
-
-      184,  182,  148,  174,  174,  181,  180,  173,  172,  168,
-      174,  166,  165,  174,  174,  174,  174,  174,  174,  174,
-      174,  163,  162,  161,  160,  174,  174,  159,  158,  157,
-      156,  155,  174,  174,  174,  174,  174,  174,  154,  153,
-      152,  151,  150,  147,  145,  144,  143,  142,  141,  140,
-      139,  137,  136,  135,  133,  132,  174,  194,  194,  131,
-      130,  128,  127,  126,  194,  194,  124,  194,  194,  194,
-      194,  194,  194,  194,  194,  111,  100,   99,   98,  194,
-      194,   97,   96,   95,   94,   90,  194,  194,  194,  194,
-      194,  194,   89,   87,   86,   85,   84,   83,   82,   81,
-
-       80,   78,   76,   67,   66,   60,   56,   55,   51,   43,
-      194,  209,  209,   42,   41,   39,   38,   37,  209,  209,
-       35,  209,  209,  209,  209,  209,  209,  209,  209,   32,
-       30,   29,   24,  209,  209,   19,   18,   15,   11,   10,
-      209,  209,  209,  209,  209,  209,    9,    8,    7,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,  209,  211,  211,    0,    0,    0,
+      148,  148,  228,  235,  228,  235,  148,  225,  220,  148,
+      148,  148,  148,  148,  148,  148,  148,  237,  219,  237,
+      218,  148,  148,  217,  216,  215,  212,  208,  148,  148,
+      148,  148,  148,  148,  207,  205,  203,  200,  199,  198,
+      197,  196,  193,  192,  191,  190,  189,  188,  187,  186,
+
+      185,  184,  148,  174,  174,  174,  182,  181,  180,  173,
+      174,  172,  168,  174,  174,  174,  174,  174,  174,  174,
+      174,  166,  165,  163,  162,  174,  174,  161,  160,  159,
+      158,  157,  174,  174,  174,  174,  174,  174,  156,  155,
+      154,  153,  152,  151,  150,  147,  145,  144,  143,  142,
+      141,  140,  139,  137,  136,  135,  174,  194,  194,  194,
+      133,  132,  131,  130,  194,  194,  128,  194,  194,  194,
+      194,  194,  194,  194,  194,  127,  126,  124,  111,  194,
+      194,  100,   99,   98,   97,   96,  194,  194,  194,  194,
+      194,  194,   95,   94,   90,   89,   87,   86,   85,   84,
+
+       83,   82,   81,   80,   78,   76,   67,   66,   60,   56,
+      194,  209,  209,  209,   55,   51,   43,   42,  209,  209,
+       41,  209,  209,  209,  209,  209,  209,  209,  209,   39,
+       38,   37,   35,  209,  209,   32,   30,   29,   24,   19,
+      209,  209,  209,  209,  209,  209,   18,   15,   11,   10,
+        9,    8,    7,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,  209,  211,  211,  211,    0,    0,
         0,    0,  211,  211,    0,  211,  211,  211,  211,  211,
       211,  211,  211,    0,    0,    0,    0,  211,  211,    0,
         0,    0,    0,    0,  211,  211,  211,  211,  211,  211,
@@ -736,7 +736,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 /* Lexical analyzer for YARA */
-#line 20 "lexer.l"
+#line 33 "lexer.l"
 
 /* Disable warnings for unused functions in this file.
 
@@ -754,11 +754,10 @@ with noyywrap then we can remove this pragma.
 #include <math.h>
 #include <stdarg.h>
 #include <stdio.h>
-#include <stdint.h>
 #include <string.h>
 #include <setjmp.h>
 
-
+#include <yara/integers.h>
 #include <yara/lexer.h>
 #include <yara/sizedstr.h>
 #include <yara/error.h>
@@ -810,7 +809,7 @@ with noyywrap then we can remove this pragma.
 
 
 
-#line 801 "lexer.c"
+#line 813 "lexer.c"
 
 #define INITIAL 0
 #define str 1
@@ -843,7 +842,7 @@ struct yyguts_t
     size_t yy_buffer_stack_max; /**< capacity of stack. */
     YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
     char yy_hold_char;
-    yy_size_t yy_n_chars;
+    int yy_n_chars;
     yy_size_t yyleng_r;
     char *yy_c_buf_p;
     int yy_init;
@@ -1087,10 +1086,10 @@ YY_DECL
 		}
 
 	{
-#line 111 "lexer.l"
+#line 123 "lexer.l"
 
 
-#line 1081 "lexer.c"
+#line 1093 "lexer.c"
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
@@ -1157,208 +1156,208 @@ YY_DECL
 
 case 1:
 YY_RULE_SETUP
-#line 113 "lexer.l"
+#line 125 "lexer.l"
 { return _DOT_DOT_;     }
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 114 "lexer.l"
+#line 126 "lexer.l"
 { return _LT_;          }
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 115 "lexer.l"
+#line 127 "lexer.l"
 { return _GT_;          }
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 116 "lexer.l"
+#line 128 "lexer.l"
 { return _LE_;          }
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 117 "lexer.l"
+#line 129 "lexer.l"
 { return _GE_;          }
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 118 "lexer.l"
+#line 130 "lexer.l"
 { return _EQ_;          }
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 119 "lexer.l"
+#line 131 "lexer.l"
 { return _NEQ_;         }
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 120 "lexer.l"
+#line 132 "lexer.l"
 { return _SHIFT_LEFT_;  }
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 121 "lexer.l"
+#line 133 "lexer.l"
 { return _SHIFT_RIGHT_; }
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 122 "lexer.l"
+#line 134 "lexer.l"
 { return _PRIVATE_;     }
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 123 "lexer.l"
+#line 135 "lexer.l"
 { return _GLOBAL_;      }
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 124 "lexer.l"
+#line 136 "lexer.l"
 { return _RULE_;        }
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 125 "lexer.l"
+#line 137 "lexer.l"
 { return _META_;        }
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 126 "lexer.l"
+#line 138 "lexer.l"
 { return _STRINGS_;     }
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 127 "lexer.l"
+#line 139 "lexer.l"
 { return _ASCII_;       }
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 128 "lexer.l"
+#line 140 "lexer.l"
 { return _WIDE_;        }
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 129 "lexer.l"
+#line 141 "lexer.l"
 { return _FULLWORD_;    }
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 130 "lexer.l"
+#line 142 "lexer.l"
 { return _NOCASE_;      }
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 131 "lexer.l"
+#line 143 "lexer.l"
 { return _CONDITION_;   }
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 132 "lexer.l"
+#line 144 "lexer.l"
 { return _TRUE_;        }
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 133 "lexer.l"
+#line 145 "lexer.l"
 { return _FALSE_;       }
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 134 "lexer.l"
+#line 146 "lexer.l"
 { return _NOT_;         }
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 135 "lexer.l"
+#line 147 "lexer.l"
 { return _AND_;         }
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 136 "lexer.l"
+#line 148 "lexer.l"
 { return _OR_;          }
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 137 "lexer.l"
+#line 149 "lexer.l"
 { return _AT_;          }
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 138 "lexer.l"
+#line 150 "lexer.l"
 { return _IN_;          }
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 139 "lexer.l"
+#line 151 "lexer.l"
 { return _OF_;          }
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 140 "lexer.l"
+#line 152 "lexer.l"
 { return _THEM_;        }
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 141 "lexer.l"
+#line 153 "lexer.l"
 { return _FOR_;         }
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 142 "lexer.l"
+#line 154 "lexer.l"
 { return _ALL_;         }
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 143 "lexer.l"
+#line 155 "lexer.l"
 { return _ANY_;         }
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 144 "lexer.l"
+#line 156 "lexer.l"
 { return _ENTRYPOINT_;  }
 	YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 145 "lexer.l"
+#line 157 "lexer.l"
 { return _FILESIZE_;    }
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 146 "lexer.l"
+#line 158 "lexer.l"
 { return _MATCHES_;     }
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 147 "lexer.l"
+#line 159 "lexer.l"
 { return _CONTAINS_;    }
 	YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 148 "lexer.l"
+#line 160 "lexer.l"
 { return _IMPORT_;      }
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 151 "lexer.l"
+#line 163 "lexer.l"
 { BEGIN(comment);       }
 	YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 152 "lexer.l"
+#line 164 "lexer.l"
 { BEGIN(INITIAL);       }
 	YY_BREAK
 case 39:
 /* rule 39 can match eol */
 YY_RULE_SETUP
-#line 153 "lexer.l"
+#line 165 "lexer.l"
 { /* skip comments */   }
 	YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 156 "lexer.l"
+#line 168 "lexer.l"
 { /* skip single-line comments */ }
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 159 "lexer.l"
+#line 171 "lexer.l"
 {
                           yyextra->lex_buf_ptr = yyextra->lex_buf;
                           yyextra->lex_buf_len = 0;
@@ -1368,12 +1367,12 @@ YY_RULE_SETUP
 case 42:
 /* rule 42 can match eol */
 YY_RULE_SETUP
-#line 166 "lexer.l"
+#line 178 "lexer.l"
 { YYTEXT_TO_BUFFER; }
 	YY_BREAK
 case 43:
 YY_RULE_SETUP
-#line 169 "lexer.l"
+#line 181 "lexer.l"
 {
 
   char            buffer[1024];
@@ -1489,7 +1488,7 @@ case YY_STATE_EOF(str):
 case YY_STATE_EOF(regexp):
 case YY_STATE_EOF(include):
 case YY_STATE_EOF(comment):
-#line 281 "lexer.l"
+#line 293 "lexer.l"
 {
 
   YR_COMPILER* compiler = yara_yyget_extra(yyscanner);
@@ -1511,7 +1510,7 @@ case YY_STATE_EOF(comment):
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 301 "lexer.l"
+#line 313 "lexer.l"
 {
 
   yylval->c_string = yr_strdup(yytext);
@@ -1527,7 +1526,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 315 "lexer.l"
+#line 327 "lexer.l"
 {
 
   yylval->c_string = yr_strdup(yytext);
@@ -1543,7 +1542,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 329 "lexer.l"
+#line 341 "lexer.l"
 {
 
   yylval->c_string = yr_strdup(yytext);
@@ -1560,7 +1559,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
-#line 344 "lexer.l"
+#line 356 "lexer.l"
 {
 
   yylval->c_string = yr_strdup(yytext);
@@ -1577,7 +1576,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
-#line 359 "lexer.l"
+#line 371 "lexer.l"
 {
 
   yylval->c_string = yr_strdup(yytext);
@@ -1594,7 +1593,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
-#line 374 "lexer.l"
+#line 386 "lexer.l"
 {
 
   char* text = yytext;
@@ -1635,7 +1634,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
-#line 413 "lexer.l"
+#line 425 "lexer.l"
 {
 
   if (strlen(yytext) > 128)
@@ -1656,7 +1655,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 51:
 YY_RULE_SETUP
-#line 432 "lexer.l"
+#line 444 "lexer.l"
 {
 
   #ifdef _MSC_VER
@@ -1678,7 +1677,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 52:
 YY_RULE_SETUP
-#line 451 "lexer.l"
+#line 463 "lexer.l"
 {
   yylval->double_ = atof(yytext);
   return _DOUBLE_;
@@ -1686,7 +1685,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 53:
 YY_RULE_SETUP
-#line 456 "lexer.l"
+#line 468 "lexer.l"
 {
 
   yylval->integer = xtoi(yytext + 2);
@@ -1695,7 +1694,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 54:
 YY_RULE_SETUP
-#line 463 "lexer.l"
+#line 475 "lexer.l"
 {     /* saw closing quote - all done */
 
   ALLOC_SIZED_STRING(s, yyextra->lex_buf_len);
@@ -1711,7 +1710,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 55:
 YY_RULE_SETUP
-#line 477 "lexer.l"
+#line 489 "lexer.l"
 {
 
   LEX_CHECK_SPACE_OK("\t", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -1721,7 +1720,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 56:
 YY_RULE_SETUP
-#line 485 "lexer.l"
+#line 497 "lexer.l"
 {
 
   LEX_CHECK_SPACE_OK("\n", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -1731,7 +1730,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 57:
 YY_RULE_SETUP
-#line 493 "lexer.l"
+#line 505 "lexer.l"
 {
 
   LEX_CHECK_SPACE_OK("\"", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -1741,7 +1740,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 58:
 YY_RULE_SETUP
-#line 501 "lexer.l"
+#line 513 "lexer.l"
 {
 
   LEX_CHECK_SPACE_OK("\\", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -1751,7 +1750,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 59:
 YY_RULE_SETUP
-#line 509 "lexer.l"
+#line 521 "lexer.l"
 {
 
    int result;
@@ -1764,13 +1763,13 @@ YY_RULE_SETUP
 	YY_BREAK
 case 60:
 YY_RULE_SETUP
-#line 520 "lexer.l"
+#line 532 "lexer.l"
 { YYTEXT_TO_BUFFER; }
 	YY_BREAK
 case 61:
 /* rule 61 can match eol */
 YY_RULE_SETUP
-#line 523 "lexer.l"
+#line 535 "lexer.l"
 {
 
   yyerror(yyscanner, compiler, "unterminated string");
@@ -1780,7 +1779,7 @@ YY_RULE_SETUP
 case 62:
 /* rule 62 can match eol */
 YY_RULE_SETUP
-#line 529 "lexer.l"
+#line 541 "lexer.l"
 {
 
   yyerror(yyscanner, compiler, "illegal escape sequence");
@@ -1788,7 +1787,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 63:
 YY_RULE_SETUP
-#line 535 "lexer.l"
+#line 547 "lexer.l"
 {
 
   if (yyextra->lex_buf_len > 0)
@@ -1816,7 +1815,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 64:
 YY_RULE_SETUP
-#line 561 "lexer.l"
+#line 573 "lexer.l"
 {
 
   LEX_CHECK_SPACE_OK("/", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -1826,7 +1825,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 65:
 YY_RULE_SETUP
-#line 569 "lexer.l"
+#line 581 "lexer.l"
 {
 
   LEX_CHECK_SPACE_OK("\\.", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -1837,13 +1836,13 @@ YY_RULE_SETUP
 	YY_BREAK
 case 66:
 YY_RULE_SETUP
-#line 578 "lexer.l"
+#line 590 "lexer.l"
 { YYTEXT_TO_BUFFER; }
 	YY_BREAK
 case 67:
 /* rule 67 can match eol */
 YY_RULE_SETUP
-#line 581 "lexer.l"
+#line 593 "lexer.l"
 {
 
   yyerror(yyscanner, compiler, "unterminated regular expression");
@@ -1852,7 +1851,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 68:
 YY_RULE_SETUP
-#line 588 "lexer.l"
+#line 600 "lexer.l"
 {
 
   yyextra->lex_buf_ptr = yyextra->lex_buf;
@@ -1862,7 +1861,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 69:
 YY_RULE_SETUP
-#line 596 "lexer.l"
+#line 608 "lexer.l"
 {
 
   yyextra->lex_buf_ptr = yyextra->lex_buf;
@@ -1873,7 +1872,7 @@ YY_RULE_SETUP
 case 70:
 /* rule 70 can match eol */
 YY_RULE_SETUP
-#line 604 "lexer.l"
+#line 616 "lexer.l"
 {
   // Match hex-digits with whitespace or comments. The latter are stripped
   // out by hex_lexer.l
@@ -1889,12 +1888,12 @@ YY_RULE_SETUP
 case 71:
 /* rule 71 can match eol */
 YY_RULE_SETUP
-#line 617 "lexer.l"
+#line 629 "lexer.l"
 /* skip whitespace */
 	YY_BREAK
 case 72:
 YY_RULE_SETUP
-#line 619 "lexer.l"
+#line 631 "lexer.l"
 {
 
   if (yytext[0] >= 32 && yytext[0] < 127)
@@ -1910,10 +1909,10 @@ YY_RULE_SETUP
 	YY_BREAK
 case 73:
 YY_RULE_SETUP
-#line 632 "lexer.l"
+#line 644 "lexer.l"
 ECHO;
 	YY_BREAK
-#line 1904 "lexer.c"
+#line 1916 "lexer.c"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -2169,9 +2168,9 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 	else
 		ret_val = EOB_ACT_CONTINUE_SCAN;
 
-	if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+	if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
 		/* Extend the array by 50%, plus the number we really need. */
-		yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+		int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
 		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yara_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
 		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
 			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
@@ -2571,7 +2570,7 @@ static void yara_yyensure_buffer_stack (yyscan_t yyscanner)
 		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
 		 * immediate realloc on the next call.
          */
-		num_to_alloc = 1; // After all that talk, this was set to 1 anyways...
+		num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
 		yyg->yy_buffer_stack = (struct yy_buffer_state**)yara_yyalloc
 								(num_to_alloc * sizeof(struct yy_buffer_state*)
 								, yyscanner);
@@ -3062,7 +3061,7 @@ void yara_yyfree (void * ptr , yyscan_t yyscanner)
 
 #define YYTABLES_NAME "yytables"
 
-#line 632 "lexer.l"
+#line 644 "lexer.l"
 
 
 
diff --git a/libyara/lexer.l b/libyara/lexer.l
index 640304a..b22af75 100644
--- a/libyara/lexer.l
+++ b/libyara/lexer.l
@@ -613,7 +613,7 @@ u?int(8|16|32)(be)? {
 }
 
 
-\{(({hexdigit}|[ \-|\?\[\]\(\)\n\t]|\/\*[^*]*\*\/)+|\/\/.*)+\}  {
+\{(({hexdigit}|[ \-|\?\[\]\(\)\n\r\t]|\/\*[^*]*\*\/)+|\/\/.*)+\}  {
   // Match hex-digits with whitespace or comments. The latter are stripped
   // out by hex_lexer.l
 
diff --git a/tests/test-rules.c b/tests/test-rules.c
index 8aa3058..a305f06 100644
--- a/tests/test-rules.c
+++ b/tests/test-rules.c
@@ -463,7 +463,7 @@ static void test_hex_strings()
 
   assert_true_rule(
       "rule test { \
-        strings: $a = { 31 32 [-] // Inline comment\n\
+        strings: $a = { 31 32 [-] // Inline comment\n\r \
           38 39 } \
         condition: $a }",
       "1234567890");
@@ -476,13 +476,19 @@ static void test_hex_strings()
 
   assert_true_rule(
       "rule test { \
-        strings: $a = { 31 32 /* Inline multi-line\n\
+        strings: $a = { 31 32 /* Inline multi-line\n\r \
                                  comment */ [-] 38 39 } \
         condition: $a }",
       "1234567890");
 
   assert_true_rule(
       "rule test { \
+        strings: $a = {\n 31 32 [-] 38 39 \n\r} \
+        condition: $a }",
+      "1234567890");
+
+  assert_true_rule(
+      "rule test { \
         strings: $a = { 31 32 [-] 33 34 [-] 38 39 } \
         condition: $a }",
       "1234567890");

From 755b51fac03638c689bc6652e97fdc7f12ee9d2a Mon Sep 17 00:00:00 2001
From: plusvic <plusvic@gmail.com>
Date: Fri, 19 Aug 2016 18:10:45 +0200
Subject: [PATCH 05/36] Fix issue #507

(cherry picked from commit 64930a6ea2678e7ce2d1374c984a661eb0d388fa)
---
 libyara/parser.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/libyara/parser.c b/libyara/parser.c
index 1123869..0ced96e 100644
--- a/libyara/parser.c
+++ b/libyara/parser.c
@@ -970,6 +970,14 @@ int yr_parser_reduce_import(
 
   char* name;
 
+  if (module_name->length == 0)
+  {
+    compiler->last_result = ERROR_UNKNOWN_MODULE;
+    yr_compiler_set_error_extra_info(compiler, "");
+
+    return ERROR_UNKNOWN_MODULE;
+  }
+
   module_structure = (YR_OBJECT*) yr_hash_table_lookup(
       compiler->objects_table,
       module_name->c_string,

From 64711f99a6666f0cdcefd382560f84ad0e6b9014 Mon Sep 17 00:00:00 2001
From: plusvic <plusvic@gmail.com>
Date: Thu, 25 Aug 2016 21:47:54 +0200
Subject: [PATCH 06/36] Check error codes returned by json_unpack

This avoid segfaults with JSON files not conforming the expected format.

(cherry picked from commit be8ed5ff51013fc8e9a5d9b80f2ee5e884e95c49)
---
 libyara/modules/cuckoo.c | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/libyara/modules/cuckoo.c b/libyara/modules/cuckoo.c
index 53d30f4..2351889 100644
--- a/libyara/modules/cuckoo.c
+++ b/libyara/modules/cuckoo.c
@@ -57,12 +57,13 @@ define_function(network_dns_lookup)
 
   json_array_foreach(dns_json, index, value)
   {
-    json_unpack(value, "{s:s, s:s}", "ip", &ip, "hostname", &hostname);
-
-    if (yr_re_match(regexp_argument(1), hostname) > 0)
+    if (json_unpack(value, "{s:s, s:s}", "ip", &ip, "hostname", &hostname) == 0)
     {
-      result = 1;
-      break;
+      if (yr_re_match(regexp_argument(1), hostname) > 0)
+      {
+        result = 1;
+        break;
+      }
     }
   }
 
@@ -91,14 +92,15 @@ uint64_t http_request(
 
   json_array_foreach(http_json, index, value)
   {
-    json_unpack(value, "{s:s, s:s}", "uri", &uri, "method", &method);
-
-    if (((methods & METHOD_GET && strcasecmp(method, "get") == 0) ||
-         (methods & METHOD_POST && strcasecmp(method, "post") == 0)) &&
-         yr_re_match(uri_regexp, uri) > 0)
+    if (json_unpack(value, "{s:s, s:s}", "uri", &uri, "method", &method) == 0)
     {
-      result = 1;
-      break;
+      if (((methods & METHOD_GET && strcasecmp(method, "get") == 0) ||
+           (methods & METHOD_POST && strcasecmp(method, "post") == 0)) &&
+           yr_re_match(uri_regexp, uri) > 0)
+      {
+        result = 1;
+        break;
+      }
     }
   }
 

From d7420a1eec1cef1f6ee0182b49ff5b37423b226f Mon Sep 17 00:00:00 2001
From: plusvic <plusvic@gmail.com>
Date: Fri, 26 Aug 2016 10:43:54 +0200
Subject: [PATCH 07/36] Better error reporting for regexps exceeding
 RE_MAX_SPLIT_ID

(cherry picked from commit 5122eb96201b07cd9643bbbc51c625112b3f455e)
---
 libyara/compiler.c           | 5 +++++
 libyara/include/yara/error.h | 1 +
 libyara/re.c                 | 2 +-
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/libyara/compiler.c b/libyara/compiler.c
index dd4c251..4c0fdeb 100644
--- a/libyara/compiler.c
+++ b/libyara/compiler.c
@@ -959,6 +959,11 @@ YR_API char* yr_compiler_get_error_message(
           buffer_size,
           "regular expression is too large");
       break;
+    case ERROR_REGULAR_EXPRESSION_TOO_COMPLEX:
+      snprintf(
+          buffer,
+          buffer_size,
+          "regular expression is too complex");
 
   }
 
diff --git a/libyara/include/yara/error.h b/libyara/include/yara/error.h
index 75d56ed..a5476b0 100644
--- a/libyara/include/yara/error.h
+++ b/libyara/include/yara/error.h
@@ -87,6 +87,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define ERROR_TOO_MANY_RE_FIBERS                46
 #define ERROR_COULD_NOT_READ_PROCESS_MEMORY     47
 #define ERROR_INVALID_EXTERNAL_VARIABLE_TYPE    48
+#define ERROR_REGULAR_EXPRESSION_TOO_COMPLEX    49
 
 
 #define FAIL_ON_ERROR(x) { \
diff --git a/libyara/re.c b/libyara/re.c
index a33d989..a0cf4f9 100644
--- a/libyara/re.c
+++ b/libyara/re.c
@@ -650,7 +650,7 @@ int _yr_emit_split(
   assert(opcode == RE_OPCODE_SPLIT_A || opcode == RE_OPCODE_SPLIT_B);
 
   if (emit_context->next_split_id == RE_MAX_SPLIT_ID)
-    return ERROR_INTERNAL_FATAL_ERROR;
+    return ERROR_REGULAR_EXPRESSION_TOO_COMPLEX;
 
   FAIL_ON_ERROR(yr_arena_write_data(
       emit_context->arena,

From 94faf4c6b398503f9c1d06ba2403e3bbc3cb3609 Mon Sep 17 00:00:00 2001
From: plusvic <plusvic@gmail.com>
Date: Wed, 14 Sep 2016 16:35:59 +0200
Subject: [PATCH 08/36] Fix issue #517

Double free caused by regexps starting with a null character.

(cherry picked from commit 658aec6227a61b848f66b004ebd16fadcf24b5e7)
---
 libyara/lexer.c | 28 +++++++++++++++-------------
 libyara/lexer.l |  2 ++
 2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/libyara/lexer.c b/libyara/lexer.c
index 64c3fea..03f0465 100644
--- a/libyara/lexer.c
+++ b/libyara/lexer.c
@@ -1783,11 +1783,12 @@ YY_RULE_SETUP
 {
 
   yyerror(yyscanner, compiler, "illegal escape sequence");
+  yyterminate();
 }
 	YY_BREAK
 case 63:
 YY_RULE_SETUP
-#line 547 "lexer.l"
+#line 548 "lexer.l"
 {
 
   if (yyextra->lex_buf_len > 0)
@@ -1807,6 +1808,7 @@ YY_RULE_SETUP
   else
   {
     yyerror(yyscanner, compiler, "empty regular expression");
+    yyterminate();
   }
 
   BEGIN(INITIAL);
@@ -1815,7 +1817,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 64:
 YY_RULE_SETUP
-#line 573 "lexer.l"
+#line 575 "lexer.l"
 {
 
   LEX_CHECK_SPACE_OK("/", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -1825,7 +1827,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 65:
 YY_RULE_SETUP
-#line 581 "lexer.l"
+#line 583 "lexer.l"
 {
 
   LEX_CHECK_SPACE_OK("\\.", yyextra->lex_buf_len, LEX_BUF_SIZE);
@@ -1836,13 +1838,13 @@ YY_RULE_SETUP
 	YY_BREAK
 case 66:
 YY_RULE_SETUP
-#line 590 "lexer.l"
+#line 592 "lexer.l"
 { YYTEXT_TO_BUFFER; }
 	YY_BREAK
 case 67:
 /* rule 67 can match eol */
 YY_RULE_SETUP
-#line 593 "lexer.l"
+#line 595 "lexer.l"
 {
 
   yyerror(yyscanner, compiler, "unterminated regular expression");
@@ -1851,7 +1853,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 68:
 YY_RULE_SETUP
-#line 600 "lexer.l"
+#line 602 "lexer.l"
 {
 
   yyextra->lex_buf_ptr = yyextra->lex_buf;
@@ -1861,7 +1863,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 69:
 YY_RULE_SETUP
-#line 608 "lexer.l"
+#line 610 "lexer.l"
 {
 
   yyextra->lex_buf_ptr = yyextra->lex_buf;
@@ -1872,7 +1874,7 @@ YY_RULE_SETUP
 case 70:
 /* rule 70 can match eol */
 YY_RULE_SETUP
-#line 616 "lexer.l"
+#line 618 "lexer.l"
 {
   // Match hex-digits with whitespace or comments. The latter are stripped
   // out by hex_lexer.l
@@ -1888,12 +1890,12 @@ YY_RULE_SETUP
 case 71:
 /* rule 71 can match eol */
 YY_RULE_SETUP
-#line 629 "lexer.l"
+#line 631 "lexer.l"
 /* skip whitespace */
 	YY_BREAK
 case 72:
 YY_RULE_SETUP
-#line 631 "lexer.l"
+#line 633 "lexer.l"
 {
 
   if (yytext[0] >= 32 && yytext[0] < 127)
@@ -1909,10 +1911,10 @@ YY_RULE_SETUP
 	YY_BREAK
 case 73:
 YY_RULE_SETUP
-#line 644 "lexer.l"
+#line 646 "lexer.l"
 ECHO;
 	YY_BREAK
-#line 1916 "lexer.c"
+#line 1918 "lexer.c"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -3061,7 +3063,7 @@ void yara_yyfree (void * ptr , yyscan_t yyscanner)
 
 #define YYTABLES_NAME "yytables"
 
-#line 644 "lexer.l"
+#line 646 "lexer.l"
 
 
 
diff --git a/libyara/lexer.l b/libyara/lexer.l
index b22af75..a184606 100644
--- a/libyara/lexer.l
+++ b/libyara/lexer.l
@@ -541,6 +541,7 @@ u?int(8|16|32)(be)? {
 <str>\\(.|\n) {
 
   yyerror(yyscanner, compiler, "illegal escape sequence");
+  yyterminate();
 }
 
 
@@ -563,6 +564,7 @@ u?int(8|16|32)(be)? {
   else
   {
     yyerror(yyscanner, compiler, "empty regular expression");
+    yyterminate();
   }
 
   BEGIN(INITIAL);

From 95e2ff2ccf2dba1df88030ed363dc4acdaa404d1 Mon Sep 17 00:00:00 2001
From: plusvic <plusvic@gmail.com>
Date: Wed, 21 Sep 2016 09:53:51 +0200
Subject: [PATCH 09/36] Fix issue #524

(cherry picked from commit f99a26ce5e0dd4be7206a9e490293403aeecf111)
---
 libyara/include/yara/pe.h       | 51 +------------------------
 libyara/include/yara/pe_utils.h | 82 ++++++++++++++++++++++++++++++++++++++---
 2 files changed, 78 insertions(+), 55 deletions(-)

diff --git a/libyara/include/yara/pe.h b/libyara/include/yara/pe.h
index d03e91a..001da4d 100644
--- a/libyara/include/yara/pe.h
+++ b/libyara/include/yara/pe.h
@@ -290,11 +290,6 @@ typedef struct _IMAGE_OPTIONAL_HEADER64 {
 #define IMAGE_NT_OPTIONAL_HDR32_MAGIC      0x10b
 #define IMAGE_NT_OPTIONAL_HDR64_MAGIC      0x20b
 
-#define OptionalHeader(pe,field)                \
-  (IS_64BITS_PE(pe) ?                           \
-   pe->header64->OptionalHeader.field :         \
-   pe->header->OptionalHeader.field)
-
 
 typedef struct _IMAGE_NT_HEADERS32 {
     DWORD Signature;
@@ -311,51 +306,6 @@ typedef struct _IMAGE_NT_HEADERS64 {
 
 } IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;
 
-
-//
-// Imports are stored in a linked list. Each node (IMPORTED_DLL) contains the
-// name of the DLL and a pointer to another linked list of IMPORTED_FUNCTION
-// structures containing the names of imported functions.
-//
-
-typedef struct _IMPORTED_DLL
-{
-  char *name;
-
-  struct _IMPORTED_FUNCTION *functions;
-  struct _IMPORTED_DLL *next;
-
-} IMPORTED_DLL, *PIMPORTED_DLL;
-
-
-typedef struct _IMPORTED_FUNCTION
-{
-  char *name;
-  uint8_t has_ordinal;
-  uint16_t ordinal;
-
-  struct _IMPORTED_FUNCTION *next;
-
-} IMPORTED_FUNCTION, *PIMPORTED_FUNCTION;
-
-
-typedef struct _PE
-{
-  uint8_t* data;
-  size_t data_size;
-
-  union {
-    PIMAGE_NT_HEADERS32 header;
-    PIMAGE_NT_HEADERS64 header64;
-  };
-
-  YR_OBJECT* object;
-  IMPORTED_DLL* imported_dlls;
-  uint32_t resources;
-
-} PE;
-
-
 // IMAGE_FIRST_SECTION doesn't need 32/64 versions since the file header is
 // the same either way.
 
@@ -535,5 +485,6 @@ typedef struct _RICH_SIGNATURE {
 #define RICH_DANS 0x536e6144 // "DanS"
 #define RICH_RICH 0x68636952 // "Rich"
 
+
 #pragma pack(pop)
 #endif
diff --git a/libyara/include/yara/pe_utils.h b/libyara/include/yara/pe_utils.h
index 945d843..88e5a61 100644
--- a/libyara/include/yara/pe_utils.h
+++ b/libyara/include/yara/pe_utils.h
@@ -5,9 +5,61 @@
 
 #define MAX_PE_SECTIONS              96
 
+
 #define IS_64BITS_PE(pe) \
     (pe->header64->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
 
+
+#define OptionalHeader(pe,field)                \
+  (IS_64BITS_PE(pe) ?                           \
+   pe->header64->OptionalHeader.field :         \
+   pe->header->OptionalHeader.field)
+
+
+//
+// Imports are stored in a linked list. Each node (IMPORTED_DLL) contains the
+// name of the DLL and a pointer to another linked list of IMPORTED_FUNCTION
+// structures containing the names of imported functions.
+//
+
+typedef struct _IMPORTED_DLL
+{
+  char *name;
+
+  struct _IMPORTED_FUNCTION *functions;
+  struct _IMPORTED_DLL *next;
+
+} IMPORTED_DLL, *PIMPORTED_DLL;
+
+
+typedef struct _IMPORTED_FUNCTION
+{
+  char *name;
+  uint8_t has_ordinal;
+  uint16_t ordinal;
+
+  struct _IMPORTED_FUNCTION *next;
+
+} IMPORTED_FUNCTION, *PIMPORTED_FUNCTION;
+
+
+typedef struct _PE
+{
+  uint8_t* data;
+  size_t data_size;
+
+  union {
+    PIMAGE_NT_HEADERS32 header;
+    PIMAGE_NT_HEADERS64 header64;
+  };
+
+  YR_OBJECT* object;
+  IMPORTED_DLL* imported_dlls;
+  uint32_t resources;
+
+} PE;
+
+
 #define fits_in_pe(pe, pointer, size) \
     ((size_t) size <= pe->data_size && \
      (uint8_t*) (pointer) >= pe->data && \
@@ -16,11 +68,31 @@
 #define struct_fits_in_pe(pe, pointer, struct_type) \
     fits_in_pe(pe, pointer, sizeof(struct_type))
 
-PIMAGE_NT_HEADERS32 pe_get_header(uint8_t* data, size_t data_size);
-PIMAGE_DATA_DIRECTORY pe_get_directory_entry(PE* pe, int entry);
-PIMAGE_DATA_DIRECTORY pe_get_directory_entry(PE* pe, int entry);
-int64_t pe_rva_to_offset(PE* pe, uint64_t rva);
-char *ord_lookup(char *dll, uint16_t ord);
+
+PIMAGE_NT_HEADERS32 pe_get_header(
+    uint8_t* data,
+    size_t data_size);
+
+
+PIMAGE_DATA_DIRECTORY pe_get_directory_entry(
+    PE* pe,
+    int entry);
+
+
+PIMAGE_DATA_DIRECTORY pe_get_directory_entry(
+    PE* pe,
+    int entry);
+
+
+int64_t pe_rva_to_offset(
+    PE* pe,
+    uint64_t rva);
+
+
+char *ord_lookup(
+    char *dll,
+    uint16_t ord);
+
 
 #if HAVE_LIBCRYPTO
 #include <openssl/asn1.h>

From 86c141654fc4d35e5b76edf5a66e2c72e0ce0307 Mon Sep 17 00:00:00 2001
From: plusvic <plusvic@gmail.com>
Date: Fri, 23 Sep 2016 11:47:38 +0200
Subject: [PATCH 10/36] Fix warning caused by uninitalized array

(cherry-picked from commit 542eff653586ab62088f612845edcd9005719ad2)
---
 libyara/re_lexer.c | 76 +++++++++++++++++++++++++++---------------------------
 libyara/re_lexer.l |  2 +-
 2 files changed, 39 insertions(+), 39 deletions(-)

diff --git a/libyara/re_lexer.c b/libyara/re_lexer.c
index 7707178..6d784e6 100644
--- a/libyara/re_lexer.c
+++ b/libyara/re_lexer.c
@@ -533,7 +533,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 /* Lexical analyzer for regular expressions */
-#line 20 "re_lexer.l"
+#line 33 "re_lexer.l"
 
 /* Disable warnings for unused functions in this file.
 
@@ -582,7 +582,7 @@ int read_escaped_char(
 
 #define YY_NO_UNISTD_H 1
 
-#line 573 "re_lexer.c"
+#line 586 "re_lexer.c"
 
 #define INITIAL 0
 #define char_class 1
@@ -856,10 +856,10 @@ YY_DECL
 		}
 
 	{
-#line 86 "re_lexer.l"
+#line 99 "re_lexer.l"
 
 
-#line 850 "re_lexer.c"
+#line 863 "re_lexer.c"
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
@@ -926,7 +926,7 @@ YY_DECL
 
 case 1:
 YY_RULE_SETUP
-#line 88 "re_lexer.l"
+#line 101 "re_lexer.l"
 {
 
   // Examples: {3,8} {0,5} {,5} {7,}
@@ -962,7 +962,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 122 "re_lexer.l"
+#line 135 "re_lexer.l"
 {
 
   // Example: {10}
@@ -982,7 +982,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 140 "re_lexer.l"
+#line 153 "re_lexer.l"
 {
 
   // Start of a negated character class. Example: [^abcd]
@@ -994,7 +994,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 149 "re_lexer.l"
+#line 162 "re_lexer.l"
 {
 
   // Start of character negated class containing a ].
@@ -1009,7 +1009,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 162 "re_lexer.l"
+#line 175 "re_lexer.l"
 {
 
   // Start of character class containing a ].
@@ -1024,7 +1024,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 175 "re_lexer.l"
+#line 188 "re_lexer.l"
 {
 
   // Start of character class. Example: [abcd]
@@ -1037,7 +1037,7 @@ YY_RULE_SETUP
 case 7:
 /* rule 7 can match eol */
 YY_RULE_SETUP
-#line 185 "re_lexer.l"
+#line 198 "re_lexer.l"
 {
 
   // Any non-special character is passed as a CHAR token to the scanner.
@@ -1048,63 +1048,63 @@ YY_RULE_SETUP
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 194 "re_lexer.l"
+#line 207 "re_lexer.l"
 {
   return _WORD_CHAR_;
 }
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 199 "re_lexer.l"
+#line 212 "re_lexer.l"
 {
   return _NON_WORD_CHAR_;
 }
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 204 "re_lexer.l"
+#line 217 "re_lexer.l"
 {
   return _SPACE_;
 }
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 209 "re_lexer.l"
+#line 222 "re_lexer.l"
 {
   return _NON_SPACE_;
 }
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 214 "re_lexer.l"
+#line 227 "re_lexer.l"
 {
   return _DIGIT_;
 }
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 219 "re_lexer.l"
+#line 232 "re_lexer.l"
 {
   return _NON_DIGIT_;
 }
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 224 "re_lexer.l"
+#line 237 "re_lexer.l"
 {
   return _WORD_BOUNDARY_;
 }
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 228 "re_lexer.l"
+#line 241 "re_lexer.l"
 {
   return _NON_WORD_BOUNDARY_;
 }
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 233 "re_lexer.l"
+#line 246 "re_lexer.l"
 {
 
   yyerror(yyscanner, lex_env, "backreferences are not allowed");
@@ -1113,7 +1113,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 240 "re_lexer.l"
+#line 253 "re_lexer.l"
 {
 
   uint8_t c;
@@ -1132,7 +1132,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 257 "re_lexer.l"
+#line 270 "re_lexer.l"
 {
 
   // End of character class.
@@ -1155,7 +1155,7 @@ YY_RULE_SETUP
 case 19:
 /* rule 19 can match eol */
 YY_RULE_SETUP
-#line 278 "re_lexer.l"
+#line 291 "re_lexer.l"
 {
 
   // A range inside a character class.
@@ -1199,7 +1199,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 320 "re_lexer.l"
+#line 333 "re_lexer.l"
 {
 
   int i;
@@ -1210,7 +1210,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 329 "re_lexer.l"
+#line 342 "re_lexer.l"
 {
 
   int i;
@@ -1221,7 +1221,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 338 "re_lexer.l"
+#line 351 "re_lexer.l"
 {
 
   LEX_ENV->class_vector[' ' / 8] |= 1 << ' ' % 8;
@@ -1230,7 +1230,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 345 "re_lexer.l"
+#line 358 "re_lexer.l"
 {
 
   int i;
@@ -1248,7 +1248,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 361 "re_lexer.l"
+#line 374 "re_lexer.l"
 {
 
   char c;
@@ -1259,7 +1259,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 370 "re_lexer.l"
+#line 383 "re_lexer.l"
 {
 
   int i;
@@ -1281,7 +1281,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 390 "re_lexer.l"
+#line 403 "re_lexer.l"
 {
 
   uint8_t c;
@@ -1299,7 +1299,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 406 "re_lexer.l"
+#line 419 "re_lexer.l"
 {
 
   if (yytext[0] >= 32 && yytext[0] < 127)
@@ -1317,7 +1317,7 @@ YY_RULE_SETUP
 }
 	YY_BREAK
 case YY_STATE_EOF(char_class):
-#line 423 "re_lexer.l"
+#line 436 "re_lexer.l"
 {
 
   // End of regexp reached while scanning a character class.
@@ -1328,7 +1328,7 @@ case YY_STATE_EOF(char_class):
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 432 "re_lexer.l"
+#line 445 "re_lexer.l"
 {
 
   if (yytext[0] >= 32 && yytext[0] < 127)
@@ -1343,7 +1343,7 @@ YY_RULE_SETUP
 }
 	YY_BREAK
 case YY_STATE_EOF(INITIAL):
-#line 446 "re_lexer.l"
+#line 459 "re_lexer.l"
 {
 
   yyterminate();
@@ -1351,10 +1351,10 @@ case YY_STATE_EOF(INITIAL):
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 451 "re_lexer.l"
+#line 464 "re_lexer.l"
 ECHO;
 	YY_BREAK
-#line 1345 "re_lexer.c"
+#line 1358 "re_lexer.c"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -2503,7 +2503,7 @@ void re_yyfree (void * ptr , yyscan_t yyscanner)
 
 #define YYTABLES_NAME "yytables"
 
-#line 451 "re_lexer.l"
+#line 464 "re_lexer.l"
 
 
 
@@ -2563,7 +2563,7 @@ int read_escaped_char(
     yyscan_t yyscanner,
     uint8_t* escaped_char)
 {
-  char text[4];
+  char text[4] = {0, 0, 0, 0};
 
   text[0] = '\\';
   text[1] = RE_YY_INPUT(yyscanner);
diff --git a/libyara/re_lexer.l b/libyara/re_lexer.l
index f1108e5..b3744a3 100644
--- a/libyara/re_lexer.l
+++ b/libyara/re_lexer.l
@@ -519,7 +519,7 @@ int read_escaped_char(
     yyscan_t yyscanner,
     uint8_t* escaped_char)
 {
-  char text[4];
+  char text[4] = {0, 0, 0, 0};
 
   text[0] = '\\';
   text[1] = RE_YY_INPUT(yyscanner);

From aca4e81f18cc3d05cca882531ecc8f90f0f1949b Mon Sep 17 00:00:00 2001
From: plusvic <plusvic@gmail.com>
Date: Fri, 23 Sep 2016 11:50:47 +0200
Subject: [PATCH 11/36] Fix issue with mingw not recognising %llx and %lld
 printf formats

(cherry-picked from commit 197477632635e99ff3a1234eaebc4be101dde168)
---
 yara.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/yara.c b/yara.c
index a8503b7..7a7981f 100644
--- a/yara.c
+++ b/yara.c
@@ -38,8 +38,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <windows.h>
 
-#define PRIx64 "llx"
-#define PRId64 "lld"
+#define PRIx64 "I64x"
+#define PRId64 "I64d"
 
 #endif
 

From a250447234b3d9ffce382c08a5c77106a77e8883 Mon Sep 17 00:00:00 2001
From: Hilko Bengen <hillu@users.noreply.github.com>
Date: Thu, 13 Oct 2016 22:48:38 +0200
Subject: [PATCH 12/36] Big endian fixes (#535)

* Use union instead of PTR_TO_INT64 when emitting bytecode

On big-endian architectures, this fixes pointer dereference problems

* Fix interpretation of SIZED_STRING in module function argument list

* Add macros for mapping BE/LE encoded integers to host byte order

Chaange int16, uint32be etc. and legacy entrypoint operations to use
those macros -- this fixes YARA's behavior on big-endian architectures.

* Change tests related to PE files

The pe module is not suitable for big-endian architectures yet.

* Rebuild lexer, parser

(cherry picked from commit a9a1105d923912a27546e5a8940ec1ddc19cd1be)
---
 configure.ac                    |   2 +
 libyara/exec.c                  |  31 ++-
 libyara/exefiles.c              |  83 ++++----
 libyara/grammar.c               | 409 ++++++++++++++++++++--------------------
 libyara/grammar.h               |   2 +-
 libyara/grammar.y               |  29 ++-
 libyara/include/yara/compiler.h |   2 +-
 libyara/include/yara/modules.h  |   2 +-
 libyara/include/yara/parser.h   |   4 +-
 libyara/include/yara/pe.h       |   3 +-
 libyara/include/yara/utils.h    |  30 ++-
 libyara/parser.c                |  20 +-
 tests/test-pe.c                 |   7 +
 tests/test-rules.c              |   5 +-
 14 files changed, 327 insertions(+), 302 deletions(-)

diff --git a/configure.ac b/configure.ac
index e9e27ee..6d821c8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -32,6 +32,8 @@ case $host_os in
     darwin*) CFLAGS="$CFLAGS -I/opt/local/include" ;;
 esac
 
+AC_C_BIGENDIAN
+
 ACX_PTHREAD(
     [LIBS="$PTHREAD_LIBS $LIBS"
      CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
diff --git a/libyara/exec.c b/libyara/exec.c
index b0a79b6..3facabd 100644
--- a/libyara/exec.c
+++ b/libyara/exec.c
@@ -88,27 +88,18 @@ typedef union _STACK_ITEM {
 
 
 #define little_endian_uint8_t(x)     (x)
-#define little_endian_uint16_t(x)    (x)
-#define little_endian_uint32_t(x)    (x)
 #define little_endian_int8_t(x)      (x)
-#define little_endian_int16_t(x)     (x)
-#define little_endian_int32_t(x)     (x)
-
-#define big_endian_uint8_t(x)         (x)
-
-#define big_endian_uint16_t(x) \
-    (((((uint16_t)(x) & 0xFF)) << 8) | \
-     ((((uint16_t)(x) & 0xFF00)) >> 8))
-
-#define big_endian_uint32_t(x) \
-    (((((uint32_t)(x) & 0xFF)) << 24) | \
-     ((((uint32_t)(x) & 0xFF00)) << 8) | \
-     ((((uint32_t)(x) & 0xFF0000)) >> 8) | \
-     ((((uint32_t)(x) & 0xFF000000)) >> 24))
-
-#define big_endian_int8_t(x)   big_endian_uint8_t(x)
-#define big_endian_int16_t(x)  big_endian_uint16_t(x)
-#define big_endian_int32_t(x)  big_endian_uint32_t(x)
+#define little_endian_uint16_t(x)    yr_le16toh(x)
+#define little_endian_int16_t(x)     yr_le16toh(x)
+#define little_endian_uint32_t(x)    yr_le32toh(x)
+#define little_endian_int32_t(x)     yr_le32toh(x)
+
+#define big_endian_uint8_t(x)        (x)
+#define big_endian_int8_t(x)         (x)
+#define big_endian_uint16_t(x)       yr_be16toh(x)
+#define big_endian_int16_t(x)        yr_be16toh(x)
+#define big_endian_uint32_t(x)       yr_be32toh(x)
+#define big_endian_int32_t(x)        yr_be32toh(x)
 
 
 #define function_read(type, endianess) \
diff --git a/libyara/exefiles.c b/libyara/exefiles.c
index f8d455a..599e397 100644
--- a/libyara/exefiles.c
+++ b/libyara/exefiles.c
@@ -32,6 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <yara/pe.h>
 #include <yara/elf.h>
 #include <yara/exec.h>
+#include <yara/utils.h>
 
 #ifndef NULL
 #define NULL 0
@@ -56,26 +57,26 @@ PIMAGE_NT_HEADERS32 yr_get_pe_header(
 
   mz_header = (PIMAGE_DOS_HEADER) buffer;
 
-  if (mz_header->e_magic != IMAGE_DOS_SIGNATURE)
+  if (yr_le16toh(mz_header->e_magic) != IMAGE_DOS_SIGNATURE)
     return NULL;
 
-  if (mz_header->e_lfanew < 0)
+  if ((int32_t)yr_le32toh(mz_header->e_lfanew) < 0)
     return NULL;
 
-  headers_size = mz_header->e_lfanew + \
+  headers_size = yr_le32toh(mz_header->e_lfanew) +  \
                  sizeof(pe_header->Signature) + \
                  sizeof(IMAGE_FILE_HEADER);
 
   if (buffer_length < headers_size)
     return NULL;
 
-  pe_header = (PIMAGE_NT_HEADERS32) (buffer + mz_header->e_lfanew);
+  pe_header = (PIMAGE_NT_HEADERS32) (buffer + yr_le32toh(mz_header->e_lfanew));
 
-  headers_size += pe_header->FileHeader.SizeOfOptionalHeader;
+  headers_size += yr_le16toh(pe_header->FileHeader.SizeOfOptionalHeader);
 
-  if (pe_header->Signature == IMAGE_NT_SIGNATURE &&
-      (pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) &&
+  if (yr_le32toh(pe_header->Signature) == IMAGE_NT_SIGNATURE &&
+      (yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_I386 ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_AMD64) &&
       buffer_length > headers_size)
   {
     return pe_header;
@@ -101,16 +102,16 @@ uint64_t yr_pe_rva_to_offset(
   section_rva = 0;
   section_offset = 0;
 
-  while(i < MIN(pe_header->FileHeader.NumberOfSections, 60))
+  while(i < MIN(yr_le16toh(pe_header->FileHeader.NumberOfSections), 60))
   {
     if ((uint8_t*) section - \
         (uint8_t*) pe_header + sizeof(IMAGE_SECTION_HEADER) < buffer_length)
     {
       if (rva >= section->VirtualAddress &&
-          section_rva <= section->VirtualAddress)
+          section_rva <= yr_le32toh(section->VirtualAddress))
       {
-        section_rva = section->VirtualAddress;
-        section_offset = section->PointerToRawData;
+        section_rva = yr_le32toh(section->VirtualAddress);
+        section_offset = yr_le32toh(section->PointerToRawData);
       }
 
       section++;
@@ -137,7 +138,7 @@ int yr_get_elf_type(
 
   elf_ident = (elf_ident_t*) buffer;
 
-  if (elf_ident->magic == ELF_MAGIC)
+  if (yr_le32toh(elf_ident->magic) == ELF_MAGIC)
   {
     return elf_ident->_class;
   }
@@ -161,38 +162,38 @@ uint64_t yr_elf_rva_to_offset_32(
 
   // check to prevent integer wraps
 
-  if (ULONG_MAX - elf_header->sh_entry_count <
-      sizeof(elf32_section_header_t) * elf_header->sh_entry_count)
+  if (ULONG_MAX - yr_le16toh(elf_header->sh_entry_count) <
+      sizeof(elf32_section_header_t) * yr_le16toh(elf_header->sh_entry_count))
     return 0;
 
   // check that 'sh_offset' doesn't wrap when added to the
   // size of entries.
 
-  if (ULONG_MAX - elf_header->sh_offset <
-      sizeof(elf32_section_header_t) * elf_header->sh_entry_count)
+  if (ULONG_MAX - yr_le32toh(elf_header->sh_offset) <
+      sizeof(elf32_section_header_t) * yr_le16toh(elf_header->sh_entry_count))
     return 0;
 
-  if (elf_header->sh_offset + \
+  if (yr_le32toh(elf_header->sh_offset) + \
       sizeof(elf32_section_header_t) * \
-      elf_header->sh_entry_count > buffer_length)
+      yr_le16toh(elf_header->sh_entry_count) > buffer_length)
     return 0;
 
   section = (elf32_section_header_t*) \
-      ((unsigned char*) elf_header + elf_header->sh_offset);
+      ((unsigned char*) elf_header + yr_le32toh(elf_header->sh_offset));
 
-  for (i = 0; i < elf_header->sh_entry_count; i++)
+  for (i = 0; i < yr_le16toh(elf_header->sh_entry_count); i++)
   {
-    if (section->type != ELF_SHT_NULL &&
-        section->type != ELF_SHT_NOBITS &&
-        rva >= section->addr &&
-        rva <  section->addr + section->size)
+    if (yr_le32toh(section->type) != ELF_SHT_NULL &&
+        yr_le32toh(section->type) != ELF_SHT_NOBITS &&
+        rva >= yr_le32toh(section->addr) &&
+        rva <  yr_le32toh(section->addr) + yr_le32toh(section->size))
     {
       // prevent integer wrapping with the return value
 
-      if (ULONG_MAX - section->offset < (rva - section->addr))
+      if (ULONG_MAX - yr_le32toh(section->offset) < (rva - yr_le32toh(section->addr)))
         return 0;
       else
-        return section->offset + (rva - section->addr);
+        return yr_le32toh(section->offset) + (rva - yr_le32toh(section->addr));
     }
 
     section++;
@@ -216,26 +217,26 @@ uint64_t yr_elf_rva_to_offset_64(
 
   // check that 'sh_offset' doesn't wrap when added to the
   // size of entries.
-  if(ULONG_MAX - elf_header->sh_offset <
-     sizeof(elf64_section_header_t) * elf_header->sh_entry_count)
+  if(ULONG_MAX - yr_le64toh(elf_header->sh_offset) <
+     sizeof(elf64_section_header_t) * yr_le16toh(elf_header->sh_entry_count))
     return 0;
 
-  if (elf_header->sh_offset + \
+  if (yr_le64toh(elf_header->sh_offset) + \
       sizeof(elf64_section_header_t) * \
-      elf_header->sh_entry_count > buffer_length)
+      yr_le16toh(elf_header->sh_entry_count) > buffer_length)
     return 0;
 
   section = (elf64_section_header_t*) \
-      ((uint8_t*) elf_header + elf_header->sh_offset);
+    ((uint8_t*) elf_header + yr_le64toh(elf_header->sh_offset));
 
-  for (i = 0; i < elf_header->sh_entry_count; i++)
+  for (i = 0; i < yr_le16toh(elf_header->sh_entry_count); i++)
   {
-    if (section->type != ELF_SHT_NULL &&
-        section->type != ELF_SHT_NOBITS &&
-        rva >= section->addr &&
-        rva <  section->addr + section->size)
+    if (yr_le32toh(section->type) != ELF_SHT_NULL &&
+        yr_le32toh(section->type) != ELF_SHT_NOBITS &&
+        rva >= yr_le64toh(section->addr) &&
+        rva <  yr_le64toh(section->addr) + yr_le64toh(section->size))
     {
-      return section->offset + (rva - section->addr);
+      return yr_le64toh(section->offset) + (rva - yr_le64toh(section->addr));
     }
 
     section++;
@@ -259,7 +260,7 @@ uint64_t yr_get_entry_point_offset(
   {
     return yr_pe_rva_to_offset(
         pe_header,
-        pe_header->OptionalHeader.AddressOfEntryPoint,
+        yr_le32toh(pe_header->OptionalHeader.AddressOfEntryPoint),
         buffer_length - ((uint8_t*) pe_header - buffer));
   }
 
@@ -269,14 +270,14 @@ uint64_t yr_get_entry_point_offset(
       elf_header32 = (elf32_header_t*) buffer;
       return yr_elf_rva_to_offset_32(
           elf_header32,
-          elf_header32->entry,
+          yr_le32toh(elf_header32->entry),
           buffer_length);
 
     case ELF_CLASS_64:
       elf_header64 = (elf64_header_t*) buffer;
       return yr_elf_rva_to_offset_64(
           elf_header64,
-          elf_header64->entry,
+          yr_le64toh(elf_header64->entry),
           buffer_length);
   }
 
diff --git a/libyara/grammar.c b/libyara/grammar.c
index 0f803df..0ce27b2 100644
--- a/libyara/grammar.c
+++ b/libyara/grammar.c
@@ -68,18 +68,18 @@
 
 
 /* Copy the first part of user declarations.  */
-#line 17 "grammar.y" /* yacc.c:339  */
+#line 30 "grammar.y" /* yacc.c:339  */
 
 
 
 #include <assert.h>
 #include <stdio.h>
-#include <stdint.h>
 #include <string.h>
 #include <limits.h>
 #include <stddef.h>
 
 
+#include <yara/integers.h>
 #include <yara/utils.h>
 #include <yara/strutils.h>
 #include <yara/compiler.h>
@@ -277,7 +277,7 @@ extern int yara_yydebug;
 
 union YYSTYPE
 {
-#line 191 "grammar.y" /* yacc.c:355  */
+#line 204 "grammar.y" /* yacc.c:355  */
 
   EXPRESSION      expression;
   SIZED_STRING*   sized_string;
@@ -606,19 +606,19 @@ static const yytype_uint8 yytranslate[] =
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   205,   205,   207,   208,   209,   210,   211,   216,   229,
-     238,   228,   261,   264,   292,   295,   322,   327,   328,   333,
-     334,   340,   343,   361,   374,   411,   412,   417,   433,   446,
-     459,   472,   489,   490,   496,   495,   511,   510,   526,   540,
-     541,   546,   547,   548,   549,   554,   639,   685,   743,   788,
-     789,   793,   818,   854,   900,   922,   931,   940,   955,   967,
-     981,   994,  1006,  1036,  1005,  1152,  1151,  1231,  1237,  1244,
-    1243,  1306,  1305,  1366,  1375,  1384,  1393,  1402,  1411,  1420,
-    1424,  1432,  1433,  1438,  1460,  1472,  1488,  1487,  1493,  1504,
-    1505,  1510,  1517,  1528,  1529,  1533,  1541,  1545,  1555,  1569,
-    1585,  1595,  1604,  1629,  1641,  1653,  1669,  1681,  1697,  1742,
-    1761,  1779,  1797,  1815,  1841,  1859,  1869,  1879,  1889,  1899,
-    1909,  1919
+       0,   218,   218,   220,   221,   222,   223,   224,   229,   242,
+     251,   241,   274,   277,   305,   308,   335,   340,   341,   346,
+     347,   353,   356,   374,   387,   424,   425,   430,   446,   459,
+     472,   485,   502,   503,   509,   508,   524,   523,   539,   553,
+     554,   559,   560,   561,   562,   567,   652,   698,   756,   801,
+     802,   806,   831,   867,   913,   935,   944,   953,   968,   980,
+     994,  1007,  1019,  1049,  1018,  1163,  1162,  1241,  1247,  1254,
+    1253,  1316,  1315,  1376,  1385,  1394,  1403,  1412,  1421,  1430,
+    1434,  1442,  1443,  1448,  1470,  1482,  1498,  1497,  1503,  1514,
+    1515,  1520,  1527,  1538,  1539,  1543,  1551,  1555,  1565,  1579,
+    1595,  1605,  1614,  1639,  1651,  1663,  1679,  1691,  1707,  1752,
+    1771,  1789,  1807,  1825,  1851,  1869,  1879,  1889,  1899,  1909,
+    1919,  1929
 };
 #endif
 
@@ -1333,55 +1333,55 @@ yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, void *yyscanner, Y
   switch (yytype)
     {
           case 10: /* _IDENTIFIER_  */
-#line 181 "grammar.y" /* yacc.c:1257  */
+#line 194 "grammar.y" /* yacc.c:1257  */
       { yr_free(((*yyvaluep).c_string)); }
 #line 1339 "grammar.c" /* yacc.c:1257  */
         break;
 
     case 11: /* _STRING_IDENTIFIER_  */
-#line 185 "grammar.y" /* yacc.c:1257  */
+#line 198 "grammar.y" /* yacc.c:1257  */
       { yr_free(((*yyvaluep).c_string)); }
 #line 1345 "grammar.c" /* yacc.c:1257  */
         break;
 
     case 12: /* _STRING_COUNT_  */
-#line 182 "grammar.y" /* yacc.c:1257  */
+#line 195 "grammar.y" /* yacc.c:1257  */
       { yr_free(((*yyvaluep).c_string)); }
 #line 1351 "grammar.c" /* yacc.c:1257  */
         break;
 
     case 13: /* _STRING_OFFSET_  */
-#line 183 "grammar.y" /* yacc.c:1257  */
+#line 196 "grammar.y" /* yacc.c:1257  */
       { yr_free(((*yyvaluep).c_string)); }
 #line 1357 "grammar.c" /* yacc.c:1257  */
         break;
 
     case 14: /* _STRING_LENGTH_  */
-#line 184 "grammar.y" /* yacc.c:1257  */
+#line 197 "grammar.y" /* yacc.c:1257  */
       { yr_free(((*yyvaluep).c_string)); }
 #line 1363 "grammar.c" /* yacc.c:1257  */
         break;
 
     case 15: /* _STRING_IDENTIFIER_WITH_WILDCARD_  */
-#line 186 "grammar.y" /* yacc.c:1257  */
+#line 199 "grammar.y" /* yacc.c:1257  */
       { yr_free(((*yyvaluep).c_string)); }
 #line 1369 "grammar.c" /* yacc.c:1257  */
         break;
 
     case 19: /* _TEXT_STRING_  */
-#line 187 "grammar.y" /* yacc.c:1257  */
+#line 200 "grammar.y" /* yacc.c:1257  */
       { yr_free(((*yyvaluep).sized_string)); }
 #line 1375 "grammar.c" /* yacc.c:1257  */
         break;
 
     case 20: /* _HEX_STRING_  */
-#line 188 "grammar.y" /* yacc.c:1257  */
+#line 201 "grammar.y" /* yacc.c:1257  */
       { yr_free(((*yyvaluep).sized_string)); }
 #line 1381 "grammar.c" /* yacc.c:1257  */
         break;
 
     case 21: /* _REGEXP_  */
-#line 189 "grammar.y" /* yacc.c:1257  */
+#line 202 "grammar.y" /* yacc.c:1257  */
       { yr_free(((*yyvaluep).sized_string)); }
 #line 1387 "grammar.c" /* yacc.c:1257  */
         break;
@@ -1649,7 +1649,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
   switch (yyn)
     {
         case 8:
-#line 217 "grammar.y" /* yacc.c:1646  */
+#line 230 "grammar.y" /* yacc.c:1646  */
     {
         int result = yr_parser_reduce_import(yyscanner, (yyvsp[0].sized_string));
 
@@ -1661,7 +1661,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 9:
-#line 229 "grammar.y" /* yacc.c:1646  */
+#line 242 "grammar.y" /* yacc.c:1646  */
     {
         YR_RULE* rule = yr_parser_reduce_rule_declaration_phase_1(
             yyscanner, (int32_t) (yyvsp[-2].integer), (yyvsp[0].c_string));
@@ -1674,7 +1674,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 10:
-#line 238 "grammar.y" /* yacc.c:1646  */
+#line 251 "grammar.y" /* yacc.c:1646  */
     {
         YR_RULE* rule = (yyvsp[-4].rule); // rule created in phase 1
 
@@ -1686,7 +1686,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 11:
-#line 246 "grammar.y" /* yacc.c:1646  */
+#line 259 "grammar.y" /* yacc.c:1646  */
     {
         YR_RULE* rule = (yyvsp[-7].rule); // rule created in phase 1
 
@@ -1701,7 +1701,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 12:
-#line 261 "grammar.y" /* yacc.c:1646  */
+#line 274 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.meta) = NULL;
       }
@@ -1709,7 +1709,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 13:
-#line 265 "grammar.y" /* yacc.c:1646  */
+#line 278 "grammar.y" /* yacc.c:1646  */
     {
         // Each rule have a list of meta-data info, consisting in a
         // sequence of YR_META structures. The last YR_META structure does
@@ -1736,7 +1736,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 14:
-#line 292 "grammar.y" /* yacc.c:1646  */
+#line 305 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.string) = NULL;
       }
@@ -1744,7 +1744,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 15:
-#line 296 "grammar.y" /* yacc.c:1646  */
+#line 309 "grammar.y" /* yacc.c:1646  */
     {
         // Each rule have a list of strings, consisting in a sequence
         // of YR_STRING structures. The last YR_STRING structure does not
@@ -1771,31 +1771,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 17:
-#line 327 "grammar.y" /* yacc.c:1646  */
+#line 340 "grammar.y" /* yacc.c:1646  */
     { (yyval.integer) = 0;  }
 #line 1777 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 18:
-#line 328 "grammar.y" /* yacc.c:1646  */
+#line 341 "grammar.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-1].integer) | (yyvsp[0].integer); }
 #line 1783 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 19:
-#line 333 "grammar.y" /* yacc.c:1646  */
+#line 346 "grammar.y" /* yacc.c:1646  */
     { (yyval.integer) = RULE_GFLAGS_PRIVATE; }
 #line 1789 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 20:
-#line 334 "grammar.y" /* yacc.c:1646  */
+#line 347 "grammar.y" /* yacc.c:1646  */
     { (yyval.integer) = RULE_GFLAGS_GLOBAL; }
 #line 1795 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 21:
-#line 340 "grammar.y" /* yacc.c:1646  */
+#line 353 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.c_string) = NULL;
       }
@@ -1803,7 +1803,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 22:
-#line 344 "grammar.y" /* yacc.c:1646  */
+#line 357 "grammar.y" /* yacc.c:1646  */
     {
         // Tags list is represented in the arena as a sequence
         // of null-terminated strings, the sequence ends with an
@@ -1821,7 +1821,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 23:
-#line 362 "grammar.y" /* yacc.c:1646  */
+#line 375 "grammar.y" /* yacc.c:1646  */
     {
         char* identifier;
 
@@ -1838,7 +1838,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 24:
-#line 375 "grammar.y" /* yacc.c:1646  */
+#line 388 "grammar.y" /* yacc.c:1646  */
     {
         char* tag_name = (yyvsp[-1].c_string);
         size_t tag_length = tag_name != NULL ? strlen(tag_name) : 0;
@@ -1874,19 +1874,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 25:
-#line 411 "grammar.y" /* yacc.c:1646  */
+#line 424 "grammar.y" /* yacc.c:1646  */
     {  (yyval.meta) = (yyvsp[0].meta); }
 #line 1880 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 26:
-#line 412 "grammar.y" /* yacc.c:1646  */
+#line 425 "grammar.y" /* yacc.c:1646  */
     {  (yyval.meta) = (yyvsp[-1].meta); }
 #line 1886 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 27:
-#line 418 "grammar.y" /* yacc.c:1646  */
+#line 431 "grammar.y" /* yacc.c:1646  */
     {
         SIZED_STRING* sized_string = (yyvsp[0].sized_string);
 
@@ -1906,7 +1906,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 28:
-#line 434 "grammar.y" /* yacc.c:1646  */
+#line 447 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.meta) = yr_parser_reduce_meta_declaration(
             yyscanner,
@@ -1923,7 +1923,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 29:
-#line 447 "grammar.y" /* yacc.c:1646  */
+#line 460 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.meta) = yr_parser_reduce_meta_declaration(
             yyscanner,
@@ -1940,7 +1940,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 30:
-#line 460 "grammar.y" /* yacc.c:1646  */
+#line 473 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.meta) = yr_parser_reduce_meta_declaration(
             yyscanner,
@@ -1957,7 +1957,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 31:
-#line 473 "grammar.y" /* yacc.c:1646  */
+#line 486 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.meta) = yr_parser_reduce_meta_declaration(
             yyscanner,
@@ -1974,19 +1974,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 32:
-#line 489 "grammar.y" /* yacc.c:1646  */
+#line 502 "grammar.y" /* yacc.c:1646  */
     { (yyval.string) = (yyvsp[0].string); }
 #line 1980 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 33:
-#line 490 "grammar.y" /* yacc.c:1646  */
+#line 503 "grammar.y" /* yacc.c:1646  */
     { (yyval.string) = (yyvsp[-1].string); }
 #line 1986 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 34:
-#line 496 "grammar.y" /* yacc.c:1646  */
+#line 509 "grammar.y" /* yacc.c:1646  */
     {
         compiler->error_line = yyget_lineno(yyscanner);
       }
@@ -1994,7 +1994,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 35:
-#line 500 "grammar.y" /* yacc.c:1646  */
+#line 513 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.string) = yr_parser_reduce_string_declaration(
             yyscanner, (int32_t) (yyvsp[0].integer), (yyvsp[-4].c_string), (yyvsp[-1].sized_string));
@@ -2009,7 +2009,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 36:
-#line 511 "grammar.y" /* yacc.c:1646  */
+#line 524 "grammar.y" /* yacc.c:1646  */
     {
         compiler->error_line = yyget_lineno(yyscanner);
       }
@@ -2017,7 +2017,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 37:
-#line 515 "grammar.y" /* yacc.c:1646  */
+#line 528 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.string) = yr_parser_reduce_string_declaration(
             yyscanner, (int32_t) (yyvsp[0].integer) | STRING_GFLAGS_REGEXP, (yyvsp[-4].c_string), (yyvsp[-1].sized_string));
@@ -2033,7 +2033,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 38:
-#line 527 "grammar.y" /* yacc.c:1646  */
+#line 540 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.string) = yr_parser_reduce_string_declaration(
             yyscanner, STRING_GFLAGS_HEXADECIMAL, (yyvsp[-2].c_string), (yyvsp[0].sized_string));
@@ -2047,43 +2047,43 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 39:
-#line 540 "grammar.y" /* yacc.c:1646  */
+#line 553 "grammar.y" /* yacc.c:1646  */
     { (yyval.integer) = 0; }
 #line 2053 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 40:
-#line 541 "grammar.y" /* yacc.c:1646  */
+#line 554 "grammar.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-1].integer) | (yyvsp[0].integer); }
 #line 2059 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 41:
-#line 546 "grammar.y" /* yacc.c:1646  */
+#line 559 "grammar.y" /* yacc.c:1646  */
     { (yyval.integer) = STRING_GFLAGS_WIDE; }
 #line 2065 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 42:
-#line 547 "grammar.y" /* yacc.c:1646  */
+#line 560 "grammar.y" /* yacc.c:1646  */
     { (yyval.integer) = STRING_GFLAGS_ASCII; }
 #line 2071 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 43:
-#line 548 "grammar.y" /* yacc.c:1646  */
+#line 561 "grammar.y" /* yacc.c:1646  */
     { (yyval.integer) = STRING_GFLAGS_NO_CASE; }
 #line 2077 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 44:
-#line 549 "grammar.y" /* yacc.c:1646  */
+#line 562 "grammar.y" /* yacc.c:1646  */
     { (yyval.integer) = STRING_GFLAGS_FULL_WORD; }
 #line 2083 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 45:
-#line 555 "grammar.y" /* yacc.c:1646  */
+#line 568 "grammar.y" /* yacc.c:1646  */
     {
         int var_index = yr_parser_lookup_loop_variable(yyscanner, (yyvsp[0].c_string));
 
@@ -2128,7 +2128,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
               compiler->last_result = yr_parser_emit_with_arg_reloc(
                   yyscanner,
                   OP_OBJ_LOAD,
-                  PTR_TO_INT64(id),
+                  id,
                   NULL,
                   NULL);
 
@@ -2148,7 +2148,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
               compiler->last_result = yr_parser_emit_with_arg_reloc(
                   yyscanner,
                   OP_PUSH_RULE,
-                  PTR_TO_INT64(rule),
+                  rule,
                   NULL,
                   NULL);
 
@@ -2172,7 +2172,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 46:
-#line 640 "grammar.y" /* yacc.c:1646  */
+#line 653 "grammar.y" /* yacc.c:1646  */
     {
         YR_OBJECT* field = NULL;
 
@@ -2192,7 +2192,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
               compiler->last_result = yr_parser_emit_with_arg_reloc(
                   yyscanner,
                   OP_OBJ_FIELD,
-                  PTR_TO_INT64(ident),
+                  ident,
                   NULL,
                   NULL);
 
@@ -2222,7 +2222,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 47:
-#line 686 "grammar.y" /* yacc.c:1646  */
+#line 699 "grammar.y" /* yacc.c:1646  */
     {
         YR_OBJECT_ARRAY* array;
         YR_OBJECT_DICTIONARY* dict;
@@ -2283,7 +2283,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 48:
-#line 744 "grammar.y" /* yacc.c:1646  */
+#line 757 "grammar.y" /* yacc.c:1646  */
     {
         YR_OBJECT_FUNCTION* function;
         char* args_fmt;
@@ -2302,7 +2302,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
             compiler->last_result = yr_parser_emit_with_arg_reloc(
                 yyscanner,
                 OP_CALL,
-                PTR_TO_INT64(args_fmt),
+                args_fmt,
                 NULL,
                 NULL);
 
@@ -2328,19 +2328,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 49:
-#line 788 "grammar.y" /* yacc.c:1646  */
+#line 801 "grammar.y" /* yacc.c:1646  */
     { (yyval.c_string) = yr_strdup(""); }
 #line 2334 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 50:
-#line 789 "grammar.y" /* yacc.c:1646  */
+#line 802 "grammar.y" /* yacc.c:1646  */
     { (yyval.c_string) = (yyvsp[0].c_string); }
 #line 2340 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 51:
-#line 794 "grammar.y" /* yacc.c:1646  */
+#line 807 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.c_string) = (char*) yr_malloc(MAX_FUNCTION_ARGS + 1);
 
@@ -2369,7 +2369,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 52:
-#line 819 "grammar.y" /* yacc.c:1646  */
+#line 832 "grammar.y" /* yacc.c:1646  */
     {
         if (strlen((yyvsp[-2].c_string)) == MAX_FUNCTION_ARGS)
         {
@@ -2405,7 +2405,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 53:
-#line 855 "grammar.y" /* yacc.c:1646  */
+#line 868 "grammar.y" /* yacc.c:1646  */
     {
         SIZED_STRING* sized_string = (yyvsp[0].sized_string);
         RE* re;
@@ -2437,7 +2437,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           compiler->last_result = yr_parser_emit_with_arg_reloc(
               yyscanner,
               OP_PUSH,
-              PTR_TO_INT64(re->root_node->forward_code),
+              re->root_node->forward_code,
               NULL,
               NULL);
 
@@ -2451,7 +2451,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 54:
-#line 901 "grammar.y" /* yacc.c:1646  */
+#line 914 "grammar.y" /* yacc.c:1646  */
     {
         if ((yyvsp[0].expression).type == EXPRESSION_TYPE_STRING)
         {
@@ -2474,7 +2474,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 55:
-#line 923 "grammar.y" /* yacc.c:1646  */
+#line 936 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, 1, NULL, NULL);
@@ -2487,7 +2487,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 56:
-#line 932 "grammar.y" /* yacc.c:1646  */
+#line 945 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, 0, NULL, NULL);
@@ -2500,7 +2500,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 57:
-#line 941 "grammar.y" /* yacc.c:1646  */
+#line 954 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_STRING, "matches");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_REGEXP, "matches");
@@ -2519,7 +2519,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 58:
-#line 956 "grammar.y" /* yacc.c:1646  */
+#line 969 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_STRING, "contains");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_STRING, "contains");
@@ -2535,7 +2535,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 59:
-#line 968 "grammar.y" /* yacc.c:1646  */
+#line 981 "grammar.y" /* yacc.c:1646  */
     {
         int result = yr_parser_reduce_string_identifier(
             yyscanner,
@@ -2553,7 +2553,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 60:
-#line 982 "grammar.y" /* yacc.c:1646  */
+#line 995 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "at");
 
@@ -2570,7 +2570,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 61:
-#line 995 "grammar.y" /* yacc.c:1646  */
+#line 1008 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner, (yyvsp[-2].c_string), OP_FOUND_IN, UNDEFINED);
@@ -2585,7 +2585,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 62:
-#line 1006 "grammar.y" /* yacc.c:1646  */
+#line 1019 "grammar.y" /* yacc.c:1646  */
     {
         int var_index;
 
@@ -2619,7 +2619,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 63:
-#line 1036 "grammar.y" /* yacc.c:1646  */
+#line 1049 "grammar.y" /* yacc.c:1646  */
     {
         int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth;
         uint8_t* addr;
@@ -2658,7 +2658,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
     break;
 
   case 64:
-#line 1071 "grammar.y" /* yacc.c:1646  */
+#line 1084 "grammar.y" /* yacc.c:1646  */
     {
         int mem_offset;
 
@@ -2684,8 +2684,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           yr_parser_emit_with_arg_reloc(
               yyscanner,
               OP_JNUNDEF,
-              PTR_TO_INT64(
-                  compiler->loop_address[compiler->loop_depth]),
+              compiler->loop_address[compiler->loop_depth],
               NULL,
               NULL);
         }
@@ -2708,8 +2707,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           yr_parser_emit_with_arg_reloc(
               yyscanner,
               OP_JLE,
-              PTR_TO_INT64(
-                compiler->loop_address[compiler->loop_depth]),
+              compiler->loop_address[compiler->loop_depth],
               NULL,
               NULL);
 
@@ -2739,11 +2737,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2743 "grammar.c" /* yacc.c:1646  */
+#line 2741 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 65:
-#line 1152 "grammar.y" /* yacc.c:1646  */
+#line 1163 "grammar.y" /* yacc.c:1646  */
     {
         int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth;
         uint8_t* addr;
@@ -2773,11 +2771,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         compiler->loop_identifier[compiler->loop_depth] = NULL;
         compiler->loop_depth++;
       }
-#line 2777 "grammar.c" /* yacc.c:1646  */
+#line 2775 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 66:
-#line 1182 "grammar.y" /* yacc.c:1646  */
+#line 1193 "grammar.y" /* yacc.c:1646  */
     {
         int mem_offset;
 
@@ -2802,8 +2800,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         yr_parser_emit_with_arg_reloc(
             yyscanner,
             OP_JNUNDEF,
-            PTR_TO_INT64(
-                compiler->loop_address[compiler->loop_depth]),
+            compiler->loop_address[compiler->loop_depth],
             NULL,
             NULL);
 
@@ -2827,34 +2824,34 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
 
       }
-#line 2831 "grammar.c" /* yacc.c:1646  */
+#line 2828 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 67:
-#line 1232 "grammar.y" /* yacc.c:1646  */
+#line 1242 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit(yyscanner, OP_OF, NULL);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2841 "grammar.c" /* yacc.c:1646  */
+#line 2838 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 68:
-#line 1238 "grammar.y" /* yacc.c:1646  */
+#line 1248 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit(yyscanner, OP_NOT, NULL);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2851 "grammar.c" /* yacc.c:1646  */
+#line 2848 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 69:
-#line 1244 "grammar.y" /* yacc.c:1646  */
+#line 1254 "grammar.y" /* yacc.c:1646  */
     {
         YR_FIXUP* fixup;
-        int64_t* jmp_destination_addr;
+        void* jmp_destination_addr;
 
         compiler->last_result = yr_parser_emit_with_arg_reloc(
             yyscanner,
@@ -2877,11 +2874,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         fixup->next = compiler->fixup_stack_head;
         compiler->fixup_stack_head = fixup;
       }
-#line 2881 "grammar.c" /* yacc.c:1646  */
+#line 2878 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 70:
-#line 1270 "grammar.y" /* yacc.c:1646  */
+#line 1280 "grammar.y" /* yacc.c:1646  */
     {
         YR_FIXUP* fixup;
         uint8_t* and_addr;
@@ -2910,21 +2907,21 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         // 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);
+        *(void**)(fixup->address) = (void*)(and_addr + 1);
 
         compiler->fixup_stack_head = fixup->next;
         yr_free(fixup);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2921 "grammar.c" /* yacc.c:1646  */
+#line 2918 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 71:
-#line 1306 "grammar.y" /* yacc.c:1646  */
+#line 1316 "grammar.y" /* yacc.c:1646  */
     {
         YR_FIXUP* fixup;
-        int64_t* jmp_destination_addr;
+        void* jmp_destination_addr;
 
         compiler->last_result = yr_parser_emit_with_arg_reloc(
             yyscanner,
@@ -2946,11 +2943,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         fixup->next = compiler->fixup_stack_head;
         compiler->fixup_stack_head = fixup;
       }
-#line 2950 "grammar.c" /* yacc.c:1646  */
+#line 2947 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 72:
-#line 1331 "grammar.y" /* yacc.c:1646  */
+#line 1341 "grammar.y" /* yacc.c:1646  */
     {
         YR_FIXUP* fixup;
         uint8_t* or_addr;
@@ -2979,18 +2976,18 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         // 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);
+        *(void**)(fixup->address) = (void*)(or_addr + 1);
 
         compiler->fixup_stack_head = fixup->next;
         yr_free(fixup);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2990 "grammar.c" /* yacc.c:1646  */
+#line 2987 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 73:
-#line 1367 "grammar.y" /* yacc.c:1646  */
+#line 1377 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "<", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -2999,11 +2996,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3003 "grammar.c" /* yacc.c:1646  */
+#line 3000 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 74:
-#line 1376 "grammar.y" /* yacc.c:1646  */
+#line 1386 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, ">", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3012,11 +3009,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3016 "grammar.c" /* yacc.c:1646  */
+#line 3013 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 75:
-#line 1385 "grammar.y" /* yacc.c:1646  */
+#line 1395 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "<=", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3025,11 +3022,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3029 "grammar.c" /* yacc.c:1646  */
+#line 3026 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 76:
-#line 1394 "grammar.y" /* yacc.c:1646  */
+#line 1404 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, ">=", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3038,11 +3035,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3042 "grammar.c" /* yacc.c:1646  */
+#line 3039 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 77:
-#line 1403 "grammar.y" /* yacc.c:1646  */
+#line 1413 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "==", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3051,11 +3048,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3055 "grammar.c" /* yacc.c:1646  */
+#line 3052 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 78:
-#line 1412 "grammar.y" /* yacc.c:1646  */
+#line 1422 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "!=", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3064,39 +3061,39 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3068 "grammar.c" /* yacc.c:1646  */
+#line 3065 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 79:
-#line 1421 "grammar.y" /* yacc.c:1646  */
+#line 1431 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.expression) = (yyvsp[0].expression);
       }
-#line 3076 "grammar.c" /* yacc.c:1646  */
+#line 3073 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 80:
-#line 1425 "grammar.y" /* yacc.c:1646  */
+#line 1435 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.expression) = (yyvsp[-1].expression);
       }
-#line 3084 "grammar.c" /* yacc.c:1646  */
+#line 3081 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 81:
-#line 1432 "grammar.y" /* yacc.c:1646  */
+#line 1442 "grammar.y" /* yacc.c:1646  */
     { (yyval.integer) = INTEGER_SET_ENUMERATION; }
-#line 3090 "grammar.c" /* yacc.c:1646  */
+#line 3087 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 82:
-#line 1433 "grammar.y" /* yacc.c:1646  */
+#line 1443 "grammar.y" /* yacc.c:1646  */
     { (yyval.integer) = INTEGER_SET_RANGE; }
-#line 3096 "grammar.c" /* yacc.c:1646  */
+#line 3093 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 83:
-#line 1439 "grammar.y" /* yacc.c:1646  */
+#line 1449 "grammar.y" /* yacc.c:1646  */
     {
         if ((yyvsp[-3].expression).type != EXPRESSION_TYPE_INTEGER)
         {
@@ -3114,11 +3111,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3118 "grammar.c" /* yacc.c:1646  */
+#line 3115 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 84:
-#line 1461 "grammar.y" /* yacc.c:1646  */
+#line 1471 "grammar.y" /* yacc.c:1646  */
     {
         if ((yyvsp[0].expression).type != EXPRESSION_TYPE_INTEGER)
         {
@@ -3130,11 +3127,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3134 "grammar.c" /* yacc.c:1646  */
+#line 3131 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 85:
-#line 1473 "grammar.y" /* yacc.c:1646  */
+#line 1483 "grammar.y" /* yacc.c:1646  */
     {
         if ((yyvsp[0].expression).type != EXPRESSION_TYPE_INTEGER)
         {
@@ -3145,77 +3142,77 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3149 "grammar.c" /* yacc.c:1646  */
+#line 3146 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 86:
-#line 1488 "grammar.y" /* yacc.c:1646  */
+#line 1498 "grammar.y" /* yacc.c:1646  */
     {
         // Push end-of-list marker
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
       }
-#line 3158 "grammar.c" /* yacc.c:1646  */
+#line 3155 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 88:
-#line 1494 "grammar.y" /* yacc.c:1646  */
+#line 1504 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
         yr_parser_emit_pushes_for_strings(yyscanner, "$*");
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3169 "grammar.c" /* yacc.c:1646  */
+#line 3166 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 91:
-#line 1511 "grammar.y" /* yacc.c:1646  */
+#line 1521 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[0].c_string));
         yr_free((yyvsp[0].c_string));
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3180 "grammar.c" /* yacc.c:1646  */
+#line 3177 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 92:
-#line 1518 "grammar.y" /* yacc.c:1646  */
+#line 1528 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[0].c_string));
         yr_free((yyvsp[0].c_string));
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3191 "grammar.c" /* yacc.c:1646  */
+#line 3188 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 94:
-#line 1530 "grammar.y" /* yacc.c:1646  */
+#line 1540 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
       }
-#line 3199 "grammar.c" /* yacc.c:1646  */
+#line 3196 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 95:
-#line 1534 "grammar.y" /* yacc.c:1646  */
+#line 1544 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, 1, NULL, NULL);
       }
-#line 3207 "grammar.c" /* yacc.c:1646  */
+#line 3204 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 96:
-#line 1542 "grammar.y" /* yacc.c:1646  */
+#line 1552 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.expression) = (yyvsp[-1].expression);
       }
-#line 3215 "grammar.c" /* yacc.c:1646  */
+#line 3212 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 97:
-#line 1546 "grammar.y" /* yacc.c:1646  */
+#line 1556 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit(
             yyscanner, OP_FILESIZE, NULL);
@@ -3225,11 +3222,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3229 "grammar.c" /* yacc.c:1646  */
+#line 3226 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 98:
-#line 1556 "grammar.y" /* yacc.c:1646  */
+#line 1566 "grammar.y" /* yacc.c:1646  */
     {
         yywarning(yyscanner,
             "Using deprecated \"entrypoint\" keyword. Use the \"entry_point\" "
@@ -3243,11 +3240,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3247 "grammar.c" /* yacc.c:1646  */
+#line 3244 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 99:
-#line 1570 "grammar.y" /* yacc.c:1646  */
+#line 1580 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-1].expression), EXPRESSION_TYPE_INTEGER, "intXXXX or uintXXXX");
 
@@ -3263,11 +3260,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3267 "grammar.c" /* yacc.c:1646  */
+#line 3264 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 100:
-#line 1586 "grammar.y" /* yacc.c:1646  */
+#line 1596 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, (yyvsp[0].integer), NULL, NULL);
@@ -3277,11 +3274,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = (yyvsp[0].integer);
       }
-#line 3281 "grammar.c" /* yacc.c:1646  */
+#line 3278 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 101:
-#line 1596 "grammar.y" /* yacc.c:1646  */
+#line 1606 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg_double(
             yyscanner, OP_PUSH, (yyvsp[0].double_), NULL, NULL);
@@ -3290,11 +3287,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
       }
-#line 3294 "grammar.c" /* yacc.c:1646  */
+#line 3291 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 102:
-#line 1605 "grammar.y" /* yacc.c:1646  */
+#line 1615 "grammar.y" /* yacc.c:1646  */
     {
         SIZED_STRING* sized_string;
 
@@ -3310,7 +3307,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           compiler->last_result = yr_parser_emit_with_arg_reloc(
               yyscanner,
               OP_PUSH,
-              PTR_TO_INT64(sized_string),
+              sized_string,
               NULL,
               NULL);
 
@@ -3319,11 +3316,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_STRING;
         (yyval.expression).value.sized_string = sized_string;
       }
-#line 3323 "grammar.c" /* yacc.c:1646  */
+#line 3320 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 103:
-#line 1630 "grammar.y" /* yacc.c:1646  */
+#line 1640 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner, (yyvsp[0].c_string), OP_COUNT, UNDEFINED);
@@ -3335,11 +3332,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3339 "grammar.c" /* yacc.c:1646  */
+#line 3336 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 104:
-#line 1642 "grammar.y" /* yacc.c:1646  */
+#line 1652 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner, (yyvsp[-3].c_string), OP_OFFSET, UNDEFINED);
@@ -3351,11 +3348,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3355 "grammar.c" /* yacc.c:1646  */
+#line 3352 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 105:
-#line 1654 "grammar.y" /* yacc.c:1646  */
+#line 1664 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, 1, NULL, NULL);
@@ -3371,11 +3368,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3375 "grammar.c" /* yacc.c:1646  */
+#line 3372 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 106:
-#line 1670 "grammar.y" /* yacc.c:1646  */
+#line 1680 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner, (yyvsp[-3].c_string), OP_LENGTH, UNDEFINED);
@@ -3387,11 +3384,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3391 "grammar.c" /* yacc.c:1646  */
+#line 3388 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 107:
-#line 1682 "grammar.y" /* yacc.c:1646  */
+#line 1692 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, 1, NULL, NULL);
@@ -3407,11 +3404,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3411 "grammar.c" /* yacc.c:1646  */
+#line 3408 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 108:
-#line 1698 "grammar.y" /* yacc.c:1646  */
+#line 1708 "grammar.y" /* yacc.c:1646  */
     {
         if ((yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER)  // loop identifier
         {
@@ -3456,11 +3453,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3460 "grammar.c" /* yacc.c:1646  */
+#line 3457 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 109:
-#line 1743 "grammar.y" /* yacc.c:1646  */
+#line 1753 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER | EXPRESSION_TYPE_FLOAT, "-");
 
@@ -3479,11 +3476,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3483 "grammar.c" /* yacc.c:1646  */
+#line 3480 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 110:
-#line 1762 "grammar.y" /* yacc.c:1646  */
+#line 1772 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "+", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3501,11 +3498,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
         }
       }
-#line 3505 "grammar.c" /* yacc.c:1646  */
+#line 3502 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 111:
-#line 1780 "grammar.y" /* yacc.c:1646  */
+#line 1790 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "-", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3523,11 +3520,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
         }
       }
-#line 3527 "grammar.c" /* yacc.c:1646  */
+#line 3524 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 112:
-#line 1798 "grammar.y" /* yacc.c:1646  */
+#line 1808 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "*", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3545,11 +3542,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
         }
       }
-#line 3549 "grammar.c" /* yacc.c:1646  */
+#line 3546 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 113:
-#line 1816 "grammar.y" /* yacc.c:1646  */
+#line 1826 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "\\", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3575,11 +3572,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
         }
       }
-#line 3579 "grammar.c" /* yacc.c:1646  */
+#line 3576 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 114:
-#line 1842 "grammar.y" /* yacc.c:1646  */
+#line 1852 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "%");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "%");
@@ -3597,11 +3594,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           ERROR_IF(compiler->last_result != ERROR_SUCCESS);
         }
       }
-#line 3601 "grammar.c" /* yacc.c:1646  */
+#line 3598 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 115:
-#line 1860 "grammar.y" /* yacc.c:1646  */
+#line 1870 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^");
@@ -3611,11 +3608,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(^, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3615 "grammar.c" /* yacc.c:1646  */
+#line 3612 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 116:
-#line 1870 "grammar.y" /* yacc.c:1646  */
+#line 1880 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^");
@@ -3625,11 +3622,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(&, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3629 "grammar.c" /* yacc.c:1646  */
+#line 3626 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 117:
-#line 1880 "grammar.y" /* yacc.c:1646  */
+#line 1890 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "|");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "|");
@@ -3639,11 +3636,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(|, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3643 "grammar.c" /* yacc.c:1646  */
+#line 3640 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 118:
-#line 1890 "grammar.y" /* yacc.c:1646  */
+#line 1900 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "~");
 
@@ -3653,11 +3650,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).value.integer = ((yyvsp[0].expression).value.integer == UNDEFINED) ?
             UNDEFINED : ~((yyvsp[0].expression).value.integer);
       }
-#line 3657 "grammar.c" /* yacc.c:1646  */
+#line 3654 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 119:
-#line 1900 "grammar.y" /* yacc.c:1646  */
+#line 1910 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "<<");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "<<");
@@ -3667,11 +3664,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(<<, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3671 "grammar.c" /* yacc.c:1646  */
+#line 3668 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 120:
-#line 1910 "grammar.y" /* yacc.c:1646  */
+#line 1920 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, ">>");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, ">>");
@@ -3681,19 +3678,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(>>, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3685 "grammar.c" /* yacc.c:1646  */
+#line 3682 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 121:
-#line 1920 "grammar.y" /* yacc.c:1646  */
+#line 1930 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.expression) = (yyvsp[0].expression);
       }
-#line 3693 "grammar.c" /* yacc.c:1646  */
+#line 3690 "grammar.c" /* yacc.c:1646  */
     break;
 
 
-#line 3697 "grammar.c" /* yacc.c:1646  */
+#line 3694 "grammar.c" /* yacc.c:1646  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -3921,5 +3918,5 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 #endif
   return yyresult;
 }
-#line 1925 "grammar.y" /* yacc.c:1906  */
+#line 1935 "grammar.y" /* yacc.c:1906  */
 
diff --git a/libyara/grammar.h b/libyara/grammar.h
index 06b3cbd..0e35f37 100644
--- a/libyara/grammar.h
+++ b/libyara/grammar.h
@@ -152,7 +152,7 @@ extern int yara_yydebug;
 
 union YYSTYPE
 {
-#line 191 "grammar.y" /* yacc.c:1909  */
+#line 204 "grammar.y" /* yacc.c:1909  */
 
   EXPRESSION      expression;
   SIZED_STRING*   sized_string;
diff --git a/libyara/grammar.y b/libyara/grammar.y
index 0090d73..56bae40 100644
--- a/libyara/grammar.y
+++ b/libyara/grammar.y
@@ -609,7 +609,7 @@ identifier
               compiler->last_result = yr_parser_emit_with_arg_reloc(
                   yyscanner,
                   OP_OBJ_LOAD,
-                  PTR_TO_INT64(id),
+                  id,
                   NULL,
                   NULL);
 
@@ -629,7 +629,7 @@ identifier
               compiler->last_result = yr_parser_emit_with_arg_reloc(
                   yyscanner,
                   OP_PUSH_RULE,
-                  PTR_TO_INT64(rule),
+                  rule,
                   NULL,
                   NULL);
 
@@ -669,7 +669,7 @@ identifier
               compiler->last_result = yr_parser_emit_with_arg_reloc(
                   yyscanner,
                   OP_OBJ_FIELD,
-                  PTR_TO_INT64(ident),
+                  ident,
                   NULL,
                   NULL);
 
@@ -772,7 +772,7 @@ identifier
             compiler->last_result = yr_parser_emit_with_arg_reloc(
                 yyscanner,
                 OP_CALL,
-                PTR_TO_INT64(args_fmt),
+                args_fmt,
                 NULL,
                 NULL);
 
@@ -896,7 +896,7 @@ regexp
           compiler->last_result = yr_parser_emit_with_arg_reloc(
               yyscanner,
               OP_PUSH,
-              PTR_TO_INT64(re->root_node->forward_code),
+              re->root_node->forward_code,
               NULL,
               NULL);
 
@@ -1106,8 +1106,7 @@ expression
           yr_parser_emit_with_arg_reloc(
               yyscanner,
               OP_JNUNDEF,
-              PTR_TO_INT64(
-                  compiler->loop_address[compiler->loop_depth]),
+              compiler->loop_address[compiler->loop_depth],
               NULL,
               NULL);
         }
@@ -1130,8 +1129,7 @@ expression
           yr_parser_emit_with_arg_reloc(
               yyscanner,
               OP_JLE,
-              PTR_TO_INT64(
-                compiler->loop_address[compiler->loop_depth]),
+              compiler->loop_address[compiler->loop_depth],
               NULL,
               NULL);
 
@@ -1216,8 +1214,7 @@ expression
         yr_parser_emit_with_arg_reloc(
             yyscanner,
             OP_JNUNDEF,
-            PTR_TO_INT64(
-                compiler->loop_address[compiler->loop_depth]),
+            compiler->loop_address[compiler->loop_depth],
             NULL,
             NULL);
 
@@ -1256,7 +1253,7 @@ expression
     | boolean_expression _AND_
       {
         YR_FIXUP* fixup;
-        int64_t* jmp_destination_addr;
+        void* jmp_destination_addr;
 
         compiler->last_result = yr_parser_emit_with_arg_reloc(
             yyscanner,
@@ -1308,7 +1305,7 @@ expression
         // 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);
+        *(void**)(fixup->address) = (void*)(and_addr + 1);
 
         compiler->fixup_stack_head = fixup->next;
         yr_free(fixup);
@@ -1318,7 +1315,7 @@ expression
     | boolean_expression _OR_
       {
         YR_FIXUP* fixup;
-        int64_t* jmp_destination_addr;
+        void* jmp_destination_addr;
 
         compiler->last_result = yr_parser_emit_with_arg_reloc(
             yyscanner,
@@ -1369,7 +1366,7 @@ expression
         // 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);
+        *(void**)(fixup->address) = (void*)(or_addr + 1);
 
         compiler->fixup_stack_head = fixup->next;
         yr_free(fixup);
@@ -1630,7 +1627,7 @@ primary_expression
           compiler->last_result = yr_parser_emit_with_arg_reloc(
               yyscanner,
               OP_PUSH,
-              PTR_TO_INT64(sized_string),
+              sized_string,
               NULL,
               NULL);
 
diff --git a/libyara/include/yara/compiler.h b/libyara/include/yara/compiler.h
index f111373..440b777 100644
--- a/libyara/include/yara/compiler.h
+++ b/libyara/include/yara/compiler.h
@@ -53,7 +53,7 @@ typedef void (*YR_COMPILER_CALLBACK_FUNC)(
 
 typedef struct _YR_FIXUP
 {
-  int64_t* address;
+  void* address;
   struct _YR_FIXUP* next;
 
 } YR_FIXUP;
diff --git a/libyara/include/yara/modules.h b/libyara/include/yara/modules.h
index 3b5b058..38e1bcd 100644
--- a/libyara/include/yara/modules.h
+++ b/libyara/include/yara/modules.h
@@ -272,7 +272,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 #define sized_string_argument(n) \
-    ((SIZED_STRING*)(size_t)((int64_t*) __args)[n-1])
+    (*(SIZED_STRING**) &(((int64_t*) __args)[n-1]))
 
 #define string_argument(n) \
     (sized_string_argument(n)->c_string)
diff --git a/libyara/include/yara/parser.h b/libyara/include/yara/parser.h
index 8fff40e..77c26b6 100644
--- a/libyara/include/yara/parser.h
+++ b/libyara/include/yara/parser.h
@@ -59,9 +59,9 @@ int yr_parser_emit_with_arg_double(
 int yr_parser_emit_with_arg_reloc(
     yyscan_t yyscanner,
     uint8_t instruction,
-    int64_t argument,
+    void* argument,
     uint8_t** instruction_address,
-    int64_t** argument_address);
+    void** argument_address);
 
 
 int yr_parser_check_types(
diff --git a/libyara/include/yara/pe.h b/libyara/include/yara/pe.h
index 001da4d..0291cb0 100644
--- a/libyara/include/yara/pe.h
+++ b/libyara/include/yara/pe.h
@@ -31,6 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define YR_PE_H
 
 #include <yara/types.h>
+#include <yara/utils.h>
 
 #pragma pack(push, 1)
 
@@ -312,7 +313,7 @@ typedef struct _IMAGE_NT_HEADERS64 {
 #define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \
     ((BYTE*)ntheader + \
      FIELD_OFFSET( IMAGE_NT_HEADERS32, OptionalHeader ) + \
-     ((PIMAGE_NT_HEADERS32)(ntheader))->FileHeader.SizeOfOptionalHeader \
+     yr_le16toh(((PIMAGE_NT_HEADERS32)(ntheader))->FileHeader.SizeOfOptionalHeader) \
     ))
 
 // Subsystem Values
diff --git a/libyara/include/yara/utils.h b/libyara/include/yara/utils.h
index 104d9ee..da0fb88 100644
--- a/libyara/include/yara/utils.h
+++ b/libyara/include/yara/utils.h
@@ -31,6 +31,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef YR_UTILS_H
 #define YR_UTILS_H
 
+#include <config.h>
+
 #ifndef TRUE
 #define TRUE 1
 #endif
@@ -68,7 +70,33 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define yr_min(x, y) ((x < y) ? (x) : (y))
 #define yr_max(x, y) ((x > y) ? (x) : (y))
 
-#define PTR_TO_INT64(x)  ((int64_t) (size_t) x)
+#if defined(__GNUC__)
+#define yr_bswap16(x) __builtin_bswap16(x)
+#define yr_bswap32(x) __builtin_bswap32(x)
+#define yr_bswap64(x) __builtin_bswap64(x)
+#elif defined(_MSC_VER)
+#define yr_bswap16(x) _byteswap_ushort(x)
+#define yr_bswap32(x) _byteswap_ulong(x)
+#define yr_bswap64(x) _byteswap_uint64(x)
+#else
+#error Unknown compiler: Add yr_bswap* definitions
+#endif
+
+#if defined(WORDS_BIGENDIAN)
+#define yr_le16toh(x) yr_bswap16(x)
+#define yr_le32toh(x) yr_bswap32(x)
+#define yr_le64toh(x) yr_bswap64(x)
+#define yr_be16toh(x) (x)
+#define yr_be32toh(x) (x)
+#define yr_be64toh(x) (x)
+#else
+#define yr_le16toh(x) (x)
+#define yr_le32toh(x) (x)
+#define yr_le64toh(x) (x)
+#define yr_be16toh(x) yr_bswap16(x)
+#define yr_be32toh(x) yr_bswap32(x)
+#define yr_be64toh(x) yr_bswap64(x)
+#endif
 
 
 #ifdef NDEBUG
diff --git a/libyara/parser.c b/libyara/parser.c
index 0ced96e..9c99e17 100644
--- a/libyara/parser.c
+++ b/libyara/parser.c
@@ -111,11 +111,13 @@ int yr_parser_emit_with_arg(
 int yr_parser_emit_with_arg_reloc(
     yyscan_t yyscanner,
     uint8_t instruction,
-    int64_t argument,
+    void* argument,
     uint8_t** instruction_address,
-    int64_t** argument_address)
+    void** argument_address)
 {
   int64_t* ptr = NULL;
+  DECLARE_REFERENCE(void*, argument) a;
+  a.argument = argument;
 
   int result = yr_arena_write_data(
       yyget_extra(yyscanner)->code_arena,
@@ -126,7 +128,7 @@ int yr_parser_emit_with_arg_reloc(
   if (result == ERROR_SUCCESS)
     result = yr_arena_write_data(
         yyget_extra(yyscanner)->code_arena,
-        &argument,
+        &a,
         sizeof(int64_t),
         (void**) &ptr);
 
@@ -138,7 +140,7 @@ int yr_parser_emit_with_arg_reloc(
         EOL);
 
   if (argument_address != NULL)
-    *argument_address = ptr;
+    *argument_address = (void*)ptr;
 
   return result;
 }
@@ -180,7 +182,7 @@ int yr_parser_emit_pushes_for_strings(
         yr_parser_emit_with_arg_reloc(
             yyscanner,
             OP_PUSH,
-            PTR_TO_INT64(string),
+            string,
             NULL,
             NULL);
 
@@ -747,7 +749,7 @@ YR_RULE* yr_parser_reduce_rule_declaration_phase_1(
   compiler->last_result = yr_parser_emit_with_arg_reloc(
       yyscanner,
       OP_INIT_RULE,
-      PTR_TO_INT64(rule),
+      rule,
       NULL,
       NULL);
 
@@ -798,7 +800,7 @@ int yr_parser_reduce_rule_declaration_phase_2(
   compiler->last_result = yr_parser_emit_with_arg_reloc(
       yyscanner,
       OP_MATCH_RULE,
-      PTR_TO_INT64(rule),
+      rule,
       NULL,
       NULL);
 
@@ -875,7 +877,7 @@ int yr_parser_reduce_string_identifier(
       yr_parser_emit_with_arg_reloc(
           yyscanner,
           OP_PUSH,
-          PTR_TO_INT64(string),
+          string,
           NULL,
           NULL);
 
@@ -1021,7 +1023,7 @@ int yr_parser_reduce_import(
     compiler->last_result = yr_parser_emit_with_arg_reloc(
         yyscanner,
         OP_IMPORT,
-        PTR_TO_INT64(name),
+        name,
         NULL,
         NULL);
 
diff --git a/tests/test-pe.c b/tests/test-pe.c
index c2c6270..93cb06e 100644
--- a/tests/test-pe.c
+++ b/tests/test-pe.c
@@ -1,8 +1,11 @@
 #include <yara.h>
+#include <config.h>
+#include <stdio.h>
 #include "util.h"
 
 int main(int argc, char** argv)
 {
+#if (defined(HAVE_ENDIAN_H) && BYTE_ORDER == LITTLE_ENDIAN) || defined(_MSC)
   yr_initialize();
 
   assert_true_rule_file("import \"pe\" rule test { condition: pe.imports(\"KERNEL32.dll\", \"DeleteCriticalSection\") }",
@@ -15,5 +18,9 @@ int main(int argc, char** argv)
       "tests/data/tiny-idata-5200");
 
   yr_finalize();
+#else
+  puts("Not testing pe module on big-endian architectures ... yet");
+  exit(77);
+#endif
   return 0;
 }
diff --git a/tests/test-rules.c b/tests/test-rules.c
index a305f06..19a0902 100644
--- a/tests/test-rules.c
+++ b/tests/test-rules.c
@@ -613,10 +613,9 @@ static void test_at()
 static void test_in()
 {
   assert_true_rule_blob(
-      "import \"pe\" \
-       rule test { \
+      "rule test { \
         strings: $a = { 6a 2a 58 c3 } \
-        condition: $a in (pe.entry_point .. pe.entry_point + 1) }",
+        condition: $a in (entrypoint .. entrypoint + 1) }",
       PE32_FILE);
 }
 

From 00b7e34c42407051dfcb4f6e48c35820416123dd Mon Sep 17 00:00:00 2001
From: Hilko Bengen <hillu@users.noreply.github.com>
Date: Sun, 16 Oct 2016 13:01:31 +0200
Subject: [PATCH 13/36] Fix pe, elf module for big-endian architectures
 (related to #493) (#538)

* Fix pe module for big-endian architectures

* No longer skip pe test on big-endian architectures

(The ifdef was wrong anyhow.)

* Add tests for elf module

* Fix elf module for big-endian architectures

(cherry picked from commit d272b9c742e15d6767f20a7f1c01579b468cceee)
---
 Makefile.am                     |   4 +-
 libyara/include/yara/pe_utils.h |   2 +-
 libyara/modules/elf.c           | 135 ++++++++++++++++-------------
 libyara/modules/pe.c            | 187 +++++++++++++++++++++-------------------
 libyara/modules/pe_utils.c      |  78 ++++++++---------
 tests/test-elf.c                |  29 +++++++
 tests/test-pe.c                 |   5 --
 7 files changed, 244 insertions(+), 196 deletions(-)
 create mode 100644 tests/test-elf.c

diff --git a/Makefile.am b/Makefile.am
index 4d4f7fa..8c1652a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -15,12 +15,14 @@ yarac_SOURCES = args.c args.h yarac.c
 yarac_LDADD = libyara/.libs/libyara.a
 
 TESTS = $(check_PROGRAMS)
-check_PROGRAMS = test-alignment test-rules test-pe
+check_PROGRAMS = test-alignment test-rules test-pe test-elf
 test_alignment_SOURCES = tests/test-alignment.c
 test_rules_SOURCES = tests/test-rules.c tests/util.c
 test_rules_LDADD = libyara/.libs/libyara.a
 test_pe_SOURCES = tests/test-pe.c tests/util.c
 test_pe_LDADD = libyara/.libs/libyara.a
+test_elf_SOURCES = tests/test-elf.c tests/util.c
+test_elf_LDADD = libyara/.libs/libyara.a
 
 # man pages
 man1_MANS = yara.man yarac.man
diff --git a/libyara/include/yara/pe_utils.h b/libyara/include/yara/pe_utils.h
index 88e5a61..86571c5 100644
--- a/libyara/include/yara/pe_utils.h
+++ b/libyara/include/yara/pe_utils.h
@@ -7,7 +7,7 @@
 
 
 #define IS_64BITS_PE(pe) \
-    (pe->header64->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
+    (yr_le16toh(pe->header64->OptionalHeader.Magic) == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
 
 
 #define OptionalHeader(pe,field)                \
diff --git a/libyara/modules/elf.c b/libyara/modules/elf.c
index ed4ccd1..08c3ce4 100644
--- a/libyara/modules/elf.c
+++ b/libyara/modules/elf.c
@@ -48,7 +48,7 @@ int get_elf_type(
 
   elf_ident = (elf_ident_t*) buffer;
 
-  if (elf_ident->magic == ELF_MAGIC)
+  if (yr_le32toh(elf_ident->magic) == ELF_MAGIC)
   {
     return elf_ident->_class;
   }
@@ -58,11 +58,11 @@ int get_elf_type(
   }
 }
 
-#define SIZE_OF_SECTION_TABLE_32 \
-    (sizeof(elf32_section_header_t) * elf_header->sh_entry_count)
+#define SIZE_OF_SECTION_TABLE_32(h) \
+    (sizeof(elf32_section_header_t) * yr_le16toh(h->sh_entry_count))
 
-#define SIZE_OF_SECTION_TABLE_64 \
-    (sizeof(elf64_section_header_t) * elf_header->sh_entry_count)
+#define SIZE_OF_SECTION_TABLE_64(h) \
+    (sizeof(elf64_section_header_t) * yr_le16toh(h->sh_entry_count))
 
 
 #define ELF_RVA_TO_OFFSET(bits)                                                \
@@ -77,30 +77,34 @@ uint64_t elf_rva_to_offset_##bits(                                             \
                                                                                \
   /* check that sh_offset doesn't wrap when added to SIZE_OF_SECTION_TABLE */  \
                                                                                \
-  if(ULONG_MAX - elf_header->sh_offset < SIZE_OF_SECTION_TABLE_##bits)         \
+  if(ULONG_MAX - yr_le##bits##toh(elf_header->sh_offset) <                     \
+     SIZE_OF_SECTION_TABLE_##bits(elf_header))                                 \
   {                                                                            \
     return UNDEFINED;                                                          \
   }                                                                            \
                                                                                \
-  if (elf_header->sh_offset == 0 ||                                            \
-      elf_header->sh_offset > elf_size ||                                      \
-      elf_header->sh_offset + SIZE_OF_SECTION_TABLE_##bits > elf_size ||       \
-      elf_header->sh_entry_count == 0)                                         \
+  if (yr_le##bits##toh(elf_header->sh_offset) == 0 ||                          \
+      yr_le##bits##toh(elf_header->sh_offset) > elf_size ||                    \
+      yr_le##bits##toh(elf_header->sh_offset) +                                \
+      SIZE_OF_SECTION_TABLE_##bits(elf_header) > elf_size ||                   \
+      yr_le16toh(elf_header->sh_entry_count) == 0)                             \
   {                                                                            \
     return UNDEFINED;                                                          \
   }                                                                            \
                                                                                \
   section = (elf##bits##_section_header_t*)                                    \
-      ((uint8_t*) elf_header + elf_header->sh_offset);                         \
+      ((uint8_t*) elf_header + yr_le##bits##toh(elf_header->sh_offset));       \
                                                                                \
-  for (i = 0; i < elf_header->sh_entry_count; i++)                             \
+  for (i = 0; i < yr_le16toh(elf_header->sh_entry_count); i++)                 \
   {                                                                            \
-    if (section->type != ELF_SHT_NULL &&                                       \
-        section->type != ELF_SHT_NOBITS &&                                     \
-        rva >= section->addr &&                                                \
-        rva < section->addr + section->size)                                   \
+    if (yr_le32toh(section->type) != ELF_SHT_NULL &&                           \
+        yr_le32toh(section->type) != ELF_SHT_NOBITS &&                         \
+        rva >= yr_le##bits##toh(section->addr) &&                              \
+        rva < yr_le##bits##toh(section->addr) +                                \
+        yr_le##bits##toh(section->size))                                       \
     {                                                                          \
-      return section->offset + (rva - section->addr);                          \
+      return yr_le##bits##toh(section->offset) +                               \
+        (rva - yr_le##bits##toh(section->addr));                               \
     }                                                                          \
                                                                                \
     section++;                                                                 \
@@ -122,83 +126,96 @@ void parse_elf_header_##bits(                                                  \
   elf##bits##_section_header_t* section;                                       \
   elf##bits##_program_header_t* segment;                                       \
                                                                                \
-  set_integer(elf->type, elf_obj, "type");                                     \
-  set_integer(elf->machine, elf_obj, "machine");                               \
-  set_integer(elf->sh_offset, elf_obj, "sh_offset");                           \
-  set_integer(elf->sh_entry_size, elf_obj, "sh_entry_size");                   \
-  set_integer(elf->sh_entry_count, elf_obj, "number_of_sections");             \
-  set_integer(elf->ph_offset, elf_obj, "ph_offset");                           \
-  set_integer(elf->ph_entry_size, elf_obj, "ph_entry_size");                   \
-  set_integer(elf->ph_entry_count, elf_obj, "number_of_segments");             \
+  set_integer(yr_le16toh(elf->type), elf_obj, "type");                         \
+  set_integer(yr_le16toh(elf->machine), elf_obj, "machine");                   \
+  set_integer(yr_le##bits##toh(elf->sh_offset), elf_obj, "sh_offset");         \
+  set_integer(yr_le16toh(elf->sh_entry_size), elf_obj, "sh_entry_size");       \
+  set_integer(yr_le16toh(elf->sh_entry_count), elf_obj, "number_of_sections"); \
+  set_integer(yr_le##bits##toh(elf->ph_offset), elf_obj, "ph_offset");         \
+  set_integer(yr_le16toh(elf->ph_entry_size), elf_obj, "ph_entry_size");       \
+  set_integer(yr_le16toh(elf->ph_entry_count), elf_obj, "number_of_segments"); \
                                                                                \
-  if (elf->entry != 0)                                                         \
+  if (yr_le##bits##toh(elf->entry) != 0)                                       \
   {                                                                            \
     set_integer(                                                               \
         flags & SCAN_FLAGS_PROCESS_MEMORY ?                                    \
-          base_address + elf->entry :                                          \
-          elf_rva_to_offset_##bits(elf, elf->entry, elf_size),                 \
+        base_address + yr_le##bits##toh(elf->entry) :                          \
+        elf_rva_to_offset_##bits(elf, yr_le##bits##toh(elf->entry), elf_size), \
         elf_obj, "entry_point");                                               \
   }                                                                            \
                                                                                \
-  if (elf->sh_entry_count < ELF_SHN_LORESERVE &&                               \
-      elf->sh_str_table_index < elf->sh_entry_count &&                         \
-      elf->sh_offset < elf_size &&                                             \
-      elf->sh_offset + elf->sh_entry_count *                                   \
+  if (yr_le16toh(elf->sh_entry_count) < ELF_SHN_LORESERVE &&                   \
+      yr_le16toh(elf->sh_str_table_index) < yr_le16toh(elf->sh_entry_count) && \
+      yr_le##bits##toh(elf->sh_offset) < elf_size &&                           \
+      yr_le##bits##toh(elf->sh_offset) + yr_le16toh(elf->sh_entry_count) *     \
          sizeof(elf##bits##_section_header_t) <= elf_size)                     \
   {                                                                            \
     char* str_table = NULL;                                                    \
                                                                                \
     section = (elf##bits##_section_header_t*)                                  \
-       ((uint8_t*) elf + elf->sh_offset);                                      \
+      ((uint8_t*) elf + yr_le##bits##toh(elf->sh_offset));                     \
                                                                                \
-    if (section[elf->sh_str_table_index].offset < elf_size)                    \
-      str_table = (char*) elf + section[elf->sh_str_table_index].offset;       \
+    if (section[yr_le16toh(elf->sh_str_table_index)].offset < elf_size)        \
+      str_table = (char*) elf +                                                \
+        yr_le##bits##toh(section[yr_le16toh(elf->sh_str_table_index)].offset); \
                                                                                \
-    for (i = 0; i < elf->sh_entry_count; i++)                                  \
+    for (i = 0; i < yr_le16toh(elf->sh_entry_count); i++)                      \
     {                                                                          \
-      set_integer(section->type, elf_obj, "sections[%i].type", i);             \
-      set_integer(section->flags, elf_obj, "sections[%i].flags", i);           \
-      set_integer(section->size, elf_obj, "sections[%i].size", i);             \
-      set_integer(section->offset, elf_obj, "sections[%i].offset", i);         \
+      set_integer(yr_le32toh(section->type), elf_obj,                          \
+                  "sections[%i].type", i);                                     \
+      set_integer(yr_le32toh(section->flags), elf_obj,                         \
+                  "sections[%i].flags", i);                                    \
+      set_integer(yr_le##bits##toh(section->size), elf_obj,                    \
+                  "sections[%i].size", i);                                     \
+      set_integer(yr_le##bits##toh(section->offset), elf_obj,                  \
+                  "sections[%i].offset", i);                                   \
                                                                                \
-      if (section->name < elf_size &&                                          \
+      if (yr_le##bits##toh(section->name) < elf_size &&                        \
           str_table > (char*) elf &&                                           \
-          str_table + section->name < (char*) elf + elf_size)                  \
+          str_table + yr_le##bits##toh(section->name) <                        \
+          (char*) elf + elf_size)                                              \
       {                                                                        \
-        set_string(str_table + section->name, elf_obj, "sections[%i].name", i);\
+        set_string(str_table + yr_le##bits##toh(section->name), elf_obj,       \
+                   "sections[%i].name", i);                                    \
       }                                                                        \
                                                                                \
       section++;                                                               \
     }                                                                          \
   }                                                                            \
                                                                                \
-  if (elf->ph_entry_count > 0 &&                                               \
-      elf->ph_entry_count < ELF_PN_XNUM &&                                     \
-      elf->ph_offset < elf_size &&                                             \
-      elf->ph_offset + elf->ph_entry_count *                                   \
+  if (yr_le16toh(elf->ph_entry_count) > 0 &&                                   \
+      yr_le16toh(elf->ph_entry_count) < ELF_PN_XNUM &&                         \
+      yr_le##bits##toh(elf->ph_offset) < elf_size &&                           \
+      yr_le##bits##toh(elf->ph_offset) + yr_le16toh(elf->ph_entry_count) *     \
         sizeof(elf##bits##_program_header_t) <= elf_size)                      \
   {                                                                            \
     segment = (elf##bits##_program_header_t*)                                  \
-        ((uint8_t*) elf + elf->ph_offset);                                     \
+      ((uint8_t*) elf + yr_le##bits##toh(elf->ph_offset));                     \
                                                                                \
-    for (i = 0; i < elf->ph_entry_count; i++)                                  \
+    for (i = 0; i < yr_le16toh(elf->ph_entry_count); i++)                      \
     {                                                                          \
       set_integer(                                                             \
-          segment->type, elf_obj, "segments[%i].type", i);                     \
+          yr_le32toh(segment->type), elf_obj, "segments[%i].type", i);         \
       set_integer(                                                             \
-          segment->flags, elf_obj, "segments[%i].flags", i);                   \
+          yr_le32toh(segment->flags), elf_obj, "segments[%i].flags", i);       \
       set_integer(                                                             \
-          segment->offset, elf_obj, "segments[%i].offset", i);                 \
+          yr_le##bits##toh(segment->offset), elf_obj,                          \
+          "segments[%i].offset", i);                                           \
       set_integer(                                                             \
-          segment->virt_addr, elf_obj, "segments[%i].virtual_address", i);     \
+          yr_le##bits##toh(segment->virt_addr), elf_obj,                       \
+          "segments[%i].virtual_address", i);                                  \
       set_integer(                                                             \
-          segment->phys_addr, elf_obj, "segments[%i].physical_address", i);    \
+          yr_le##bits##toh(segment->phys_addr), elf_obj,                       \
+          "segments[%i].physical_address", i);                                 \
       set_integer(                                                             \
-          segment->file_size, elf_obj, "segments[%i].file_size", i);           \
+          yr_le##bits##toh(segment->file_size), elf_obj,                       \
+          "segments[%i].file_size", i);                                        \
       set_integer(                                                             \
-          segment->mem_size, elf_obj, "segments[%i].memory_size", i);          \
+          yr_le##bits##toh(segment->mem_size), elf_obj,                        \
+          "segments[%i].memory_size", i);                                      \
       set_integer(                                                             \
-          segment->alignment, elf_obj, "segments[%i].alignment", i);           \
+          yr_le##bits##toh(segment->alignment), elf_obj,                       \
+          "segments[%i].alignment", i);                                        \
                                                                                \
       segment++;                                                               \
     }                                                                          \
@@ -398,7 +415,7 @@ int module_load(
           elf_header32 = (elf32_header_t*) block_data;
 
           if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
-              elf_header32->type == ELF_ET_EXEC)
+              yr_le16toh(elf_header32->type) == ELF_ET_EXEC)
           {
             parse_elf_header_32(
                 elf_header32,
@@ -418,7 +435,7 @@ int module_load(
           elf_header64 = (elf64_header_t*) block_data;
 
           if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
-              elf_header64->type == ELF_ET_EXEC)
+              yr_le16toh(elf_header64->type) == ELF_ET_EXEC)
           {
             parse_elf_header_64(
                 elf_header64,
diff --git a/libyara/modules/pe.c b/libyara/modules/pe.c
index 8c4cb12..7c32daf 100644
--- a/libyara/modules/pe.c
+++ b/libyara/modules/pe.c
@@ -156,13 +156,13 @@ void pe_parse_rich_signature(
 
   mz_header = (PIMAGE_DOS_HEADER) pe->data;
 
-  if (mz_header->e_magic != IMAGE_DOS_SIGNATURE)
+  if (yr_le16toh(mz_header->e_magic) != IMAGE_DOS_SIGNATURE)
     return;
 
-  if (mz_header->e_lfanew < 0)
+  if (yr_le32toh(mz_header->e_lfanew) < 0)
     return;
 
-  headers_size = mz_header->e_lfanew + \
+  headers_size = yr_le32toh(mz_header->e_lfanew) + \
                  sizeof(pe_header->Signature) + \
                  sizeof(IMAGE_FILE_HEADER);
 
@@ -177,9 +177,9 @@ void pe_parse_rich_signature(
 
   rich_signature = (PRICH_SIGNATURE) (pe->data + 0x80);
 
-  if (rich_signature->key1 != rich_signature->key2 ||
-      rich_signature->key2 != rich_signature->key3 ||
-      (rich_signature->dans ^ rich_signature->key1) != RICH_DANS)
+  if (yr_le32toh(rich_signature->key1) != yr_le32toh(rich_signature->key2) ||
+      yr_le32toh(rich_signature->key2) != yr_le32toh(rich_signature->key3) ||
+      (yr_le32toh(rich_signature->dans) ^ yr_le32toh(rich_signature->key1)) != RICH_DANS)
   {
     return;
   }
@@ -188,7 +188,7 @@ void pe_parse_rich_signature(
        rich_ptr <= (DWORD*) (pe->data + headers_size);
        rich_ptr++)
   {
-    if (*rich_ptr == RICH_RICH)
+    if (yr_le32toh(*rich_ptr) == RICH_RICH)
     {
       // Multiple by 4 because we are counting in DWORDs.
       rich_len = (rich_ptr - (DWORD*) rich_signature) * 4;
@@ -261,11 +261,11 @@ uint8_t* parse_resource_name(
   // If high bit is set it is an offset relative to rsrc_data, which contains
   // a resource directory string.
 
-  if (entry->Name & 0x80000000)
+  if (yr_le32toh(entry->Name) & 0x80000000)
   {
     DWORD length;
 
-    uint8_t* rsrc_str_ptr = rsrc_data + (entry->Name & 0x7FFFFFFF);
+    uint8_t* rsrc_str_ptr = rsrc_data + (yr_le32toh(entry->Name) & 0x7FFFFFFF);
 
     // A resource directory string is 2 bytes for a string and then a variable
     // length Unicode string. Make sure we at least have two bytes.
@@ -307,15 +307,15 @@ int _pe_iterate_resources(
 
   // A few sanity checks to avoid corrupt files
 
-  if (resource_dir->Characteristics != 0 ||
-      resource_dir->NumberOfNamedEntries > 32768 ||
-      resource_dir->NumberOfIdEntries > 32768)
+  if (yr_le32toh(resource_dir->Characteristics) != 0 ||
+      yr_le16toh(resource_dir->NumberOfNamedEntries) > 32768 ||
+      yr_le16toh(resource_dir->NumberOfIdEntries) > 32768)
   {
     return result;
   }
 
-  total_entries = resource_dir->NumberOfNamedEntries +
-                  resource_dir->NumberOfIdEntries;
+  total_entries = yr_le16toh(resource_dir->NumberOfNamedEntries) +
+                  yr_le16toh(resource_dir->NumberOfIdEntries);
 
   // The first directory entry is just after the resource directory,
   // by incrementing resource_dir we skip sizeof(resource_dir) bytes
@@ -333,15 +333,15 @@ int _pe_iterate_resources(
     switch(rsrc_tree_level)
     {
       case 0:
-        *type = entry->Name;
+        *type = yr_le32toh(entry->Name);
         type_string = parse_resource_name(pe, rsrc_data, entry);
         break;
       case 1:
-        *id = entry->Name;
+        *id = yr_le32toh(entry->Name);
         name_string = parse_resource_name(pe, rsrc_data, entry);
         break;
       case 2:
-        *language = entry->Name;
+        *language = yr_le32toh(entry->Name);
         lang_string = parse_resource_name(pe, rsrc_data, entry);
         break;
     }
@@ -425,11 +425,11 @@ int pe_iterate_resources(
   PIMAGE_DATA_DIRECTORY directory = pe_get_directory_entry(
       pe, IMAGE_DIRECTORY_ENTRY_RESOURCE);
 
-  if (directory->VirtualAddress != 0)
+  if (yr_le32toh(directory->VirtualAddress) != 0)
   {
     PIMAGE_RESOURCE_DIRECTORY rsrc_dir;
 
-    offset = pe_rva_to_offset(pe, directory->VirtualAddress);
+    offset = pe_rva_to_offset(pe, yr_le32toh(directory->VirtualAddress));
 
     if (offset < 0)
       return 0;
@@ -438,14 +438,14 @@ int pe_iterate_resources(
 
     if (struct_fits_in_pe(pe, rsrc_dir, IMAGE_RESOURCE_DIRECTORY))
     {
-      set_integer(rsrc_dir->TimeDateStamp,
+      set_integer(yr_le32toh(rsrc_dir->TimeDateStamp),
           pe->object,
           "resource_timestamp");
 
-      set_integer(rsrc_dir->MajorVersion,
+      set_integer(yr_le16toh(rsrc_dir->MajorVersion),
                   pe->object,
                   "resource_version.major");
-      set_integer(rsrc_dir->MinorVersion,
+      set_integer(yr_le16toh(rsrc_dir->MinorVersion),
                   pe->object,
                   "resource_version.minor");
 
@@ -483,7 +483,7 @@ void pe_parse_version_info(
 {
   PVERSION_INFO version_info;
 
-  int64_t version_info_offset = pe_rva_to_offset(pe, rsrc_data->OffsetToData);
+  int64_t version_info_offset = pe_rva_to_offset(pe, yr_le32toh(rsrc_data->OffsetToData));
 
   if (version_info_offset < 0)
     return;
@@ -504,16 +504,16 @@ void pe_parse_version_info(
 
   while(fits_in_pe(pe, version_info->Key, sizeof("VarFileInfo") * 2) &&
         strcmp_w(version_info->Key, "VarFileInfo") == 0 &&
-        version_info->Length != 0)
+        yr_le16toh(version_info->Length) != 0)
   {
     version_info = ADD_OFFSET(
         version_info,
-        version_info->Length);
+        yr_le16toh(version_info->Length));
   }
 
   while(fits_in_pe(pe, version_info->Key, sizeof("StringFileInfo") * 2) &&
         strcmp_w(version_info->Key, "StringFileInfo") == 0 &&
-        version_info->Length != 0)
+        yr_le16toh(version_info->Length) != 0)
   {
     PVERSION_INFO string_table = ADD_OFFSET(
         version_info,
@@ -521,11 +521,11 @@ void pe_parse_version_info(
 
     version_info = ADD_OFFSET(
         version_info,
-        version_info->Length);
+        yr_le16toh(version_info->Length));
 
     while (struct_fits_in_pe(pe, string_table, VERSION_INFO) &&
            wide_string_fits_in_pe(pe, string_table->Key) &&
-           string_table->Length != 0 &&
+           yr_le16toh(string_table->Length) != 0 &&
            string_table < version_info)
     {
       PVERSION_INFO string = ADD_OFFSET(
@@ -534,11 +534,11 @@ void pe_parse_version_info(
 
       string_table = ADD_OFFSET(
           string_table,
-          string_table->Length);
+          yr_le16toh(string_table->Length));
 
       while (struct_fits_in_pe(pe, string, VERSION_INFO) &&
              wide_string_fits_in_pe(pe, string->Key) &&
-             string->Length != 0 &&
+             yr_le16toh(string->Length) != 0 &&
              string < string_table)
       {
         if (string->ValueLength > 0)
@@ -577,9 +577,9 @@ int pe_collect_resources(
 {
   DWORD length;
 
-  int64_t offset = pe_rva_to_offset(pe, rsrc_data->OffsetToData);
+  int64_t offset = pe_rva_to_offset(pe, yr_le32toh(rsrc_data->OffsetToData));
 
-  if (offset < 0 || !fits_in_pe(pe, pe->data + offset, rsrc_data->Size))
+  if (offset < 0 || !fits_in_pe(pe, pe->data + offset, yr_le32toh(rsrc_data->Size)))
     return RESOURCE_CALLBACK_CONTINUE;
 
   set_integer(
@@ -589,7 +589,7 @@ int pe_collect_resources(
         pe->resources);
 
   set_integer(
-        rsrc_data->Size,
+        yr_le32toh(rsrc_data->Size),
         pe->object,
         "resources[%i].length",
         pe->resources);
@@ -669,13 +669,13 @@ IMPORTED_FUNCTION* pe_parse_import_descriptor(
   int num_functions = 0;
 
   int64_t offset = pe_rva_to_offset(
-      pe, import_descriptor->OriginalFirstThunk);
+      pe, yr_le32toh(import_descriptor->OriginalFirstThunk));
 
   // I've seen binaries where OriginalFirstThunk is zero. In this case
   // use FirstThunk.
 
   if (offset <= 0)
-    offset = pe_rva_to_offset(pe, import_descriptor->FirstThunk);
+    offset = pe_rva_to_offset(pe, yr_le32toh(import_descriptor->FirstThunk));
 
   if (offset < 0)
     return NULL;
@@ -685,16 +685,16 @@ IMPORTED_FUNCTION* pe_parse_import_descriptor(
     PIMAGE_THUNK_DATA64 thunks64 = (PIMAGE_THUNK_DATA64)(pe->data + offset);
 
     while (struct_fits_in_pe(pe, thunks64, IMAGE_THUNK_DATA64) &&
-           thunks64->u1.Ordinal != 0 && num_functions < MAX_PE_IMPORTS)
+           yr_le64toh(thunks64->u1.Ordinal) != 0 && num_functions < MAX_PE_IMPORTS)
     {
       char* name = NULL;
       uint16_t ordinal = 0;
       uint8_t has_ordinal = 0;
 
-      if (!(thunks64->u1.Ordinal & IMAGE_ORDINAL_FLAG64))
+      if (!(yr_le64toh(thunks64->u1.Ordinal) & IMAGE_ORDINAL_FLAG64))
       {
         // If imported by name
-        offset = pe_rva_to_offset(pe, thunks64->u1.Function);
+        offset = pe_rva_to_offset(pe, yr_le64toh(thunks64->u1.Function));
 
         if (offset >= 0)
         {
@@ -712,9 +712,9 @@ IMPORTED_FUNCTION* pe_parse_import_descriptor(
       else
       {
         // If imported by ordinal. Lookup the ordinal.
-        name = ord_lookup(dll_name, thunks64->u1.Ordinal & 0xFFFF);
+        name = ord_lookup(dll_name, yr_le64toh(thunks64->u1.Ordinal) & 0xFFFF);
         // Also store the ordinal.
-        ordinal = thunks64->u1.Ordinal & 0xFFFF;
+        ordinal = yr_le64toh(thunks64->u1.Ordinal) & 0xFFFF;
         has_ordinal = 1;
       }
 
@@ -752,16 +752,16 @@ IMPORTED_FUNCTION* pe_parse_import_descriptor(
     PIMAGE_THUNK_DATA32 thunks32 = (PIMAGE_THUNK_DATA32)(pe->data + offset);
 
     while (struct_fits_in_pe(pe, thunks32, IMAGE_THUNK_DATA32) &&
-           thunks32->u1.Ordinal != 0 && num_functions < MAX_PE_IMPORTS)
+           yr_le32toh(thunks32->u1.Ordinal) != 0 && num_functions < MAX_PE_IMPORTS)
     {
       char* name = NULL;
       uint16_t ordinal = 0;
       uint8_t has_ordinal = 0;
 
-      if (!(thunks32->u1.Ordinal & IMAGE_ORDINAL_FLAG32))
+      if (!(yr_le32toh(thunks32->u1.Ordinal) & IMAGE_ORDINAL_FLAG32))
       {
         // If imported by name
-        offset = pe_rva_to_offset(pe, thunks32->u1.Function);
+        offset = pe_rva_to_offset(pe, yr_le32toh(thunks32->u1.Function));
 
         if (offset >= 0)
         {
@@ -779,9 +779,9 @@ IMPORTED_FUNCTION* pe_parse_import_descriptor(
       else
       {
         // If imported by ordinal. Lookup the ordinal.
-        name = ord_lookup(dll_name, thunks32->u1.Ordinal & 0xFFFF);
+        name = ord_lookup(dll_name, yr_le32toh(thunks32->u1.Ordinal) & 0xFFFF);
         // Also store the ordinal.
-        ordinal = thunks32->u1.Ordinal & 0xFFFF;
+        ordinal = yr_le32toh(thunks32->u1.Ordinal) & 0xFFFF;
         has_ordinal = 1;
       }
 
@@ -865,10 +865,10 @@ IMPORTED_DLL* pe_parse_imports(
   PIMAGE_DATA_DIRECTORY directory = pe_get_directory_entry(
       pe, IMAGE_DIRECTORY_ENTRY_IMPORT);
 
-  if (directory->VirtualAddress == 0)
+  if (yr_le32toh(directory->VirtualAddress) == 0)
     return NULL;
 
-  offset = pe_rva_to_offset(pe, directory->VirtualAddress);
+  offset = pe_rva_to_offset(pe, yr_le32toh(directory->VirtualAddress));
 
   if (offset < 0)
     return NULL;
@@ -877,9 +877,9 @@ IMPORTED_DLL* pe_parse_imports(
       (pe->data + offset);
 
   while (struct_fits_in_pe(pe, imports, IMAGE_IMPORT_DESCRIPTOR) &&
-         imports->Name != 0 && num_imports < MAX_PE_IMPORTS)
+         yr_le32toh(imports->Name) != 0 && num_imports < MAX_PE_IMPORTS)
   {
-    int64_t offset = pe_rva_to_offset(pe, imports->Name);
+    int64_t offset = pe_rva_to_offset(pe, yr_le32toh(imports->Name));
 
     if (offset >= 0)
     {
@@ -943,19 +943,19 @@ void pe_parse_certificates(
   set_integer(0, pe->object, "number_of_signatures");
 
   // directory->VirtualAddress is a file offset. Don't call pe_rva_to_offset().
-  if (directory->VirtualAddress == 0 ||
-      directory->VirtualAddress > pe->data_size ||
-      directory->Size > pe->data_size ||
-      directory->VirtualAddress + directory->Size > pe->data_size)
+  if (yr_le32toh(directory->VirtualAddress) == 0 ||
+      yr_le32toh(directory->VirtualAddress) > pe->data_size ||
+      yr_le32toh(directory->Size) > pe->data_size ||
+      yr_le32toh(directory->VirtualAddress) + yr_le32toh(directory->Size) > pe->data_size)
   {
     return;
   }
 
   // Store the end of directory, making comparisons easier.
-  eod = pe->data + directory->VirtualAddress + directory->Size;
+  eod = pe->data + yr_le32toh(directory->VirtualAddress) + directory->Size;
 
   win_cert = (PWIN_CERTIFICATE) \
-      (pe->data + directory->VirtualAddress);
+    (pe->data + yr_le32toh(directory->VirtualAddress));
 
   //
   // Walk the directory, pulling out certificates.
@@ -969,10 +969,10 @@ void pe_parse_certificates(
   //
 
   while (struct_fits_in_pe(pe, win_cert, WIN_CERTIFICATE) &&
-         win_cert->Length > sizeof(WIN_CERTIFICATE) &&
-         fits_in_pe(pe, win_cert, win_cert->Length) &&
+         yr_le32toh(win_cert->Length) > sizeof(WIN_CERTIFICATE) &&
+         fits_in_pe(pe, win_cert, yr_le32toh(win_cert->Length)) &&
          (uint8_t*) win_cert + sizeof(WIN_CERTIFICATE) < eod &&
-         (uint8_t*) win_cert + win_cert->Length <= eod)
+         (uint8_t*) win_cert + yr_le32toh(win_cert->Length) <= eod)
   {
     BIO* cert_bio;
     PKCS7* pkcs7;
@@ -980,9 +980,9 @@ void pe_parse_certificates(
 
     // Some sanity checks
 
-    if (win_cert->Length == 0 ||
-        (win_cert->Revision != WIN_CERT_REVISION_1_0 &&
-         win_cert->Revision != WIN_CERT_REVISION_2_0))
+    if (yr_le32toh(win_cert->Length) == 0 ||
+        (yr_le16toh(win_cert->Revision) != WIN_CERT_REVISION_1_0 &&
+         yr_le16toh(win_cert->Revision) != WIN_CERT_REVISION_2_0))
     {
       break;
     }
@@ -990,16 +990,16 @@ void pe_parse_certificates(
     // Don't support legacy revision for now.
     // Make sure type is PKCS#7 too.
 
-    if (win_cert->Revision != WIN_CERT_REVISION_2_0 ||
-        win_cert->CertificateType != WIN_CERT_TYPE_PKCS_SIGNED_DATA)
+    if (yr_le16toh(win_cert->Revision) != WIN_CERT_REVISION_2_0 ||
+        yr_le16toh(win_cert->CertificateType) != WIN_CERT_TYPE_PKCS_SIGNED_DATA)
     {
-      uintptr_t end = (uintptr_t) ((uint8_t *) win_cert) + win_cert->Length;
+      uintptr_t end = (uintptr_t) ((uint8_t *) win_cert) + yr_le32toh(win_cert->Length);
       win_cert = (PWIN_CERTIFICATE) (end + (end % 8));
 
       continue;
     }
 
-    cert_bio = BIO_new_mem_buf(win_cert->Certificate, win_cert->Length);
+    cert_bio = BIO_new_mem_buf(win_cert->Certificate, yr_le32toh(win_cert->Length));
 
     if (!cert_bio)
       break;
@@ -1161,29 +1161,31 @@ void pe_parse_header(
   int i, scount;
 
   set_integer(
-      pe->header->FileHeader.Machine,
+      yr_le16toh(pe->header->FileHeader.Machine),
       pe->object, "machine");
 
   set_integer(
-      pe->header->FileHeader.NumberOfSections,
+      yr_le16toh(pe->header->FileHeader.NumberOfSections),
       pe->object, "number_of_sections");
 
   set_integer(
-      pe->header->FileHeader.TimeDateStamp,
+      yr_le32toh(pe->header->FileHeader.TimeDateStamp),
       pe->object, "timestamp");
 
   set_integer(
-      pe->header->FileHeader.Characteristics,
+      yr_le16toh(pe->header->FileHeader.Characteristics),
       pe->object, "characteristics");
 
   set_integer(
       flags & SCAN_FLAGS_PROCESS_MEMORY ?
-        base_address + OptionalHeader(pe, AddressOfEntryPoint) :
-        pe_rva_to_offset(pe, OptionalHeader(pe, AddressOfEntryPoint)),
+      base_address + yr_le32toh(OptionalHeader(pe, AddressOfEntryPoint)) :
+      pe_rva_to_offset(pe, yr_le32toh(OptionalHeader(pe, AddressOfEntryPoint))),
       pe->object, "entry_point");
 
   set_integer(
-      OptionalHeader(pe, ImageBase),
+      IS_64BITS_PE(pe) ?
+      yr_le64toh(OptionalHeader(pe, ImageBase)) :
+      yr_le32toh(OptionalHeader(pe, ImageBase)),
       pe->object, "image_base");
 
   set_integer(
@@ -1195,31 +1197,31 @@ void pe_parse_header(
       pe->object, "linker_version.minor");
 
   set_integer(
-      OptionalHeader(pe, MajorOperatingSystemVersion),
+      yr_le16toh(OptionalHeader(pe, MajorOperatingSystemVersion)),
       pe->object, "os_version.major");
 
   set_integer(
-      OptionalHeader(pe, MinorOperatingSystemVersion),
+      yr_le16toh(OptionalHeader(pe, MinorOperatingSystemVersion)),
       pe->object, "os_version.minor");
 
   set_integer(
-      OptionalHeader(pe, MajorImageVersion),
+      yr_le16toh(OptionalHeader(pe, MajorImageVersion)),
       pe->object, "image_version.major");
 
   set_integer(
-      OptionalHeader(pe, MinorImageVersion),
+      yr_le16toh(OptionalHeader(pe, MinorImageVersion)),
       pe->object, "image_version.minor");
 
   set_integer(
-      OptionalHeader(pe, MajorSubsystemVersion),
+      yr_le16toh(OptionalHeader(pe, MajorSubsystemVersion)),
       pe->object, "subsystem_version.major");
 
   set_integer(
-      OptionalHeader(pe, MinorSubsystemVersion),
+      yr_le16toh(OptionalHeader(pe, MinorSubsystemVersion)),
       pe->object, "subsystem_version.minor");
 
   set_integer(
-      OptionalHeader(pe, Subsystem),
+      yr_le16toh(OptionalHeader(pe, Subsystem)),
       pe->object, "subsystem");
 
   pe_iterate_resources(
@@ -1231,7 +1233,7 @@ void pe_parse_header(
 
   section = IMAGE_FIRST_SECTION(pe->header);
 
-  scount = yr_min(pe->header->FileHeader.NumberOfSections, MAX_PE_SECTIONS);
+  scount = yr_min(yr_le16toh(pe->header->FileHeader.NumberOfSections), MAX_PE_SECTIONS);
 
   for (i = 0; i < scount; i++)
   {
@@ -1246,20 +1248,23 @@ void pe_parse_header(
         pe->object, "sections[%i].name", i);
 
     set_integer(
-        section->Characteristics,
+        yr_le32toh(section->Characteristics),
         pe->object, "sections[%i].characteristics", i);
 
-    set_integer(section->SizeOfRawData,
+    set_integer(
+        yr_le32toh(section->SizeOfRawData),
         pe->object, "sections[%i].raw_data_size", i);
 
-    set_integer(section->PointerToRawData,
+    set_integer(
+        yr_le32toh(section->PointerToRawData),
         pe->object, "sections[%i].raw_data_offset", i);
 
-    set_integer(section->VirtualAddress,
+    set_integer(
+        yr_le32toh(section->VirtualAddress),
         pe->object, "sections[%i].virtual_address", i);
 
     set_integer(
-        section->Misc.VirtualSize,
+        yr_le32toh(section->Misc.VirtualSize),
         pe->object, "sections[%i].virtual_size", i);
 
     section++;
@@ -1377,7 +1382,7 @@ define_function(exports)
 
   // If the PE doesn't export any functions, return FALSE
 
-  if (directory->VirtualAddress == 0)
+  if (yr_le32toh(directory->VirtualAddress) == 0)
     return_integer(0);
 
   offset = pe_rva_to_offset(pe, directory->VirtualAddress);
@@ -1391,18 +1396,18 @@ define_function(exports)
   if (!struct_fits_in_pe(pe, exports, IMAGE_EXPORT_DIRECTORY))
     return_integer(0);
 
-  offset = pe_rva_to_offset(pe, exports->AddressOfNames);
+  offset = pe_rva_to_offset(pe, yr_le32toh(exports->AddressOfNames));
 
   if (offset < 0)
     return_integer(0);
 
-  if (exports->NumberOfNames > MAX_PE_EXPORTS ||
-      exports->NumberOfNames * sizeof(DWORD) > pe->data_size - offset)
+  if (yr_le32toh(exports->NumberOfNames) > MAX_PE_EXPORTS ||
+      yr_le32toh(exports->NumberOfNames) * sizeof(DWORD) > pe->data_size - offset)
     return_integer(0);
 
   names = (DWORD*)(pe->data + offset);
 
-  for (i = 0; i < exports->NumberOfNames; i++)
+  for (i = 0; i < yr_le32toh(exports->NumberOfNames); i++)
   {
     char* name;
     offset = pe_rva_to_offset(pe, names[i]);
@@ -2299,7 +2304,7 @@ int module_load(
       // Ignore DLLs while scanning a process
 
       if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
-          !(pe_header->FileHeader.Characteristics & IMAGE_FILE_DLL))
+          !(yr_le16toh(pe_header->FileHeader.Characteristics) & IMAGE_FILE_DLL))
       {
         pe = (PE*) yr_malloc(sizeof(PE));
 
diff --git a/libyara/modules/pe_utils.c b/libyara/modules/pe_utils.c
index ed69b80..9b80286 100644
--- a/libyara/modules/pe_utils.c
+++ b/libyara/modules/pe_utils.c
@@ -60,46 +60,46 @@ PIMAGE_NT_HEADERS32 pe_get_header(
 
   mz_header = (PIMAGE_DOS_HEADER) data;
 
-  if (mz_header->e_magic != IMAGE_DOS_SIGNATURE)
+  if (yr_le16toh(mz_header->e_magic) != IMAGE_DOS_SIGNATURE)
     return NULL;
 
-  if (mz_header->e_lfanew < 0)
+  if (yr_le32toh(mz_header->e_lfanew) < 0)
     return NULL;
 
-  headers_size = mz_header->e_lfanew + \
+  headers_size = yr_le32toh(mz_header->e_lfanew) +      \
                  sizeof(pe_header->Signature) + \
                  sizeof(IMAGE_FILE_HEADER);
 
   if (data_size < headers_size)
     return NULL;
 
-  pe_header = (PIMAGE_NT_HEADERS32) (data + mz_header->e_lfanew);
-
-  headers_size += pe_header->FileHeader.SizeOfOptionalHeader;
-
-  if (pe_header->Signature == IMAGE_NT_SIGNATURE &&
-      (pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_UNKNOWN ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_AM33 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_ARM ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_ARMNT ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_ARM64 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_EBC ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_M32R ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_MIPS16 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_MIPSFPU ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_MIPSFPU16 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_POWERPC ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_POWERPCFP ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_R4000 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_SH3 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_SH3DSP ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_SH4 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_SH5 ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_THUMB ||
-       pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_WCEMIPSV2) &&
+  pe_header = (PIMAGE_NT_HEADERS32) (data + yr_le32toh(mz_header->e_lfanew));
+
+  headers_size += yr_le16toh(pe_header->FileHeader.SizeOfOptionalHeader);
+
+  if (yr_le32toh(pe_header->Signature) == IMAGE_NT_SIGNATURE &&
+      (yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_UNKNOWN ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_AM33 ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_AMD64 ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_ARM ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_ARMNT ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_ARM64 ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_EBC ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_I386 ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_IA64 ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_M32R ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_MIPS16 ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_MIPSFPU ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_MIPSFPU16 ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_POWERPC ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_POWERPCFP ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_R4000 ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_SH3 ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_SH3DSP ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_SH4 ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_SH5 ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_THUMB ||
+       yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_WCEMIPSV2) &&
       data_size > headers_size)
   {
     return pe_header;
@@ -144,17 +144,17 @@ int64_t pe_rva_to_offset(
   int alignment = 0;
   int rest = 0;
 
-  while(i < yr_min(pe->header->FileHeader.NumberOfSections, MAX_PE_SECTIONS))
+  while(i < yr_min(yr_le16toh(pe->header->FileHeader.NumberOfSections), MAX_PE_SECTIONS))
   {
     if (struct_fits_in_pe(pe, section, IMAGE_SECTION_HEADER))
     {
-      if (lowest_section_rva > section->VirtualAddress)
+      if (lowest_section_rva > yr_le32toh(section->VirtualAddress))
       {
-        lowest_section_rva = section->VirtualAddress;
+        lowest_section_rva = yr_le32toh(section->VirtualAddress);
       }
 
-      if (rva >= section->VirtualAddress &&
-          section_rva <= section->VirtualAddress)
+      if (rva >= yr_le32toh(section->VirtualAddress) &&
+          section_rva <= yr_le32toh(section->VirtualAddress))
       {
         // Round section_offset
         //
@@ -167,11 +167,11 @@ int64_t pe_rva_to_offset(
         // If FileAlignment is >= 0x200, it is apparently ignored (see
         // Ero Carreras's pefile.py, PE.adjust_FileAlignment).
 
-        alignment = yr_min(OptionalHeader(pe, FileAlignment), 0x200);
+        alignment = yr_min(yr_le32toh(OptionalHeader(pe, FileAlignment)), 0x200);
 
-        section_rva = section->VirtualAddress;
-        section_offset = section->PointerToRawData;
-        section_raw_size = section->SizeOfRawData;
+        section_rva = yr_le32toh(section->VirtualAddress);
+        section_offset = yr_le32toh(section->PointerToRawData);
+        section_raw_size = yr_le32toh(section->SizeOfRawData);
 
         if (alignment)
         {
diff --git a/tests/test-elf.c b/tests/test-elf.c
new file mode 100644
index 0000000..8d13b47
--- /dev/null
+++ b/tests/test-elf.c
@@ -0,0 +1,29 @@
+#include <yara.h>
+#include "util.h"
+#include "blob.h"
+
+int main(int argc, char** argv)
+{
+  yr_initialize();
+
+  assert_true_rule_blob("import \"elf\" rule test { condition: elf.type }", ELF32_FILE);
+  assert_true_rule_blob("import \"elf\" rule test { condition: elf.type }", ELF64_FILE);
+
+  assert_true_rule_blob("import \"elf\" rule test { condition: elf.machine == elf.EM_386 }", ELF32_FILE)
+  assert_true_rule_blob("import \"elf\" rule test { condition: elf.machine == elf.EM_X86_64 }", ELF64_FILE)
+
+  assert_true_rule_blob(
+      "import \"elf\" rule test { \
+        strings: $a = { b8 01 00 00 00 bb 2a } \
+        condition: $a at elf.entry_point }",
+      ELF32_FILE);
+
+  assert_true_rule_blob(
+      "import \"elf\" rule test { \
+        strings: $a = { b8 01 00 00 00 bb 2a } \
+        condition: $a at elf.entry_point }",
+      ELF64_FILE);
+
+  yr_finalize();
+  return 0;
+}
diff --git a/tests/test-pe.c b/tests/test-pe.c
index 93cb06e..881939e 100644
--- a/tests/test-pe.c
+++ b/tests/test-pe.c
@@ -5,7 +5,6 @@
 
 int main(int argc, char** argv)
 {
-#if (defined(HAVE_ENDIAN_H) && BYTE_ORDER == LITTLE_ENDIAN) || defined(_MSC)
   yr_initialize();
 
   assert_true_rule_file("import \"pe\" rule test { condition: pe.imports(\"KERNEL32.dll\", \"DeleteCriticalSection\") }",
@@ -18,9 +17,5 @@ int main(int argc, char** argv)
       "tests/data/tiny-idata-5200");
 
   yr_finalize();
-#else
-  puts("Not testing pe module on big-endian architectures ... yet");
-  exit(77);
-#endif
   return 0;
 }

From 1cca7072d684d86fdba4a8a1f3eca63ba584befe Mon Sep 17 00:00:00 2001
From: Hilko Bengen <hillu@users.noreply.github.com>
Date: Mon, 24 Oct 2016 11:14:44 +0200
Subject: [PATCH 14/36] Move yr_*toh() macros to their own header file (#542)

See #541
(cherry picked from commit d3b77eb1e9ee4731ea11c39fceb262cf4f2b006f)
---
 libyara/exec.c                |  1 +
 libyara/exefiles.c            |  1 +
 libyara/include/yara/endian.h | 63 +++++++++++++++++++++++++++++++++++++++++++
 libyara/include/yara/pe.h     |  2 +-
 libyara/include/yara/utils.h  | 29 --------------------
 libyara/modules/elf.c         |  1 +
 libyara/modules/pe.c          |  1 +
 libyara/modules/pe_utils.c    |  1 +
 8 files changed, 69 insertions(+), 30 deletions(-)
 create mode 100644 libyara/include/yara/endian.h

diff --git a/libyara/exec.c b/libyara/exec.c
index 3facabd..1a347c0 100644
--- a/libyara/exec.c
+++ b/libyara/exec.c
@@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <time.h>
 #include <math.h>
 
+#include <yara/endian.h>
 #include <yara/exec.h>
 #include <yara/limits.h>
 #include <yara/error.h>
diff --git a/libyara/exefiles.c b/libyara/exefiles.c
index 599e397..05d1de7 100644
--- a/libyara/exefiles.c
+++ b/libyara/exefiles.c
@@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <limits.h>
 
+#include <yara/endian.h>
 #include <yara/pe.h>
 #include <yara/elf.h>
 #include <yara/exec.h>
diff --git a/libyara/include/yara/endian.h b/libyara/include/yara/endian.h
new file mode 100644
index 0000000..06d8c14
--- /dev/null
+++ b/libyara/include/yara/endian.h
@@ -0,0 +1,63 @@
+/*
+Copyright (c) 2016. The YARA Authors. All Rights Reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its contributors
+may be used to endorse or promote products derived from this software without
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef YR_ENDIAN_H
+#define YR_ENDIAN_H
+
+#include <config.h>
+
+#if defined(__GNUC__)
+#define yr_bswap16(x) __builtin_bswap16(x)
+#define yr_bswap32(x) __builtin_bswap32(x)
+#define yr_bswap64(x) __builtin_bswap64(x)
+#elif defined(_MSC_VER)
+#define yr_bswap16(x) _byteswap_ushort(x)
+#define yr_bswap32(x) _byteswap_ulong(x)
+#define yr_bswap64(x) _byteswap_uint64(x)
+#else
+#error Unknown compiler: Add yr_bswap* definitions
+#endif
+
+#if defined(WORDS_BIGENDIAN)
+#define yr_le16toh(x) yr_bswap16(x)
+#define yr_le32toh(x) yr_bswap32(x)
+#define yr_le64toh(x) yr_bswap64(x)
+#define yr_be16toh(x) (x)
+#define yr_be32toh(x) (x)
+#define yr_be64toh(x) (x)
+#else
+#define yr_le16toh(x) (x)
+#define yr_le32toh(x) (x)
+#define yr_le64toh(x) (x)
+#define yr_be16toh(x) yr_bswap16(x)
+#define yr_be32toh(x) yr_bswap32(x)
+#define yr_be64toh(x) yr_bswap64(x)
+#endif
+
+#endif
diff --git a/libyara/include/yara/pe.h b/libyara/include/yara/pe.h
index 0291cb0..c189146 100644
--- a/libyara/include/yara/pe.h
+++ b/libyara/include/yara/pe.h
@@ -30,8 +30,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef YR_PE_H
 #define YR_PE_H
 
+#include <yara/endian.h>
 #include <yara/types.h>
-#include <yara/utils.h>
 
 #pragma pack(push, 1)
 
diff --git a/libyara/include/yara/utils.h b/libyara/include/yara/utils.h
index da0fb88..58f1347 100644
--- a/libyara/include/yara/utils.h
+++ b/libyara/include/yara/utils.h
@@ -70,35 +70,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define yr_min(x, y) ((x < y) ? (x) : (y))
 #define yr_max(x, y) ((x > y) ? (x) : (y))
 
-#if defined(__GNUC__)
-#define yr_bswap16(x) __builtin_bswap16(x)
-#define yr_bswap32(x) __builtin_bswap32(x)
-#define yr_bswap64(x) __builtin_bswap64(x)
-#elif defined(_MSC_VER)
-#define yr_bswap16(x) _byteswap_ushort(x)
-#define yr_bswap32(x) _byteswap_ulong(x)
-#define yr_bswap64(x) _byteswap_uint64(x)
-#else
-#error Unknown compiler: Add yr_bswap* definitions
-#endif
-
-#if defined(WORDS_BIGENDIAN)
-#define yr_le16toh(x) yr_bswap16(x)
-#define yr_le32toh(x) yr_bswap32(x)
-#define yr_le64toh(x) yr_bswap64(x)
-#define yr_be16toh(x) (x)
-#define yr_be32toh(x) (x)
-#define yr_be64toh(x) (x)
-#else
-#define yr_le16toh(x) (x)
-#define yr_le32toh(x) (x)
-#define yr_le64toh(x) (x)
-#define yr_be16toh(x) yr_bswap16(x)
-#define yr_be32toh(x) yr_bswap32(x)
-#define yr_be64toh(x) yr_bswap64(x)
-#endif
-
-
 #ifdef NDEBUG
 
 #define assertf(expr, msg, ...)  ((void)0)
diff --git a/libyara/modules/elf.c b/libyara/modules/elf.c
index 08c3ce4..e934084 100644
--- a/libyara/modules/elf.c
+++ b/libyara/modules/elf.c
@@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <limits.h>
 
 #include <yara/elf.h>
+#include <yara/endian.h>
 #include <yara/modules.h>
 #include <yara/mem.h>
 
diff --git a/libyara/modules/pe.c b/libyara/modules/pe.c
index 7c32daf..f78a9d5 100644
--- a/libyara/modules/pe.c
+++ b/libyara/modules/pe.c
@@ -47,6 +47,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #endif
 #endif
 
+#include <yara/endian.h>
 #include <yara/pe.h>
 #include <yara/modules.h>
 #include <yara/mem.h>
diff --git a/libyara/modules/pe_utils.c b/libyara/modules/pe_utils.c
index 9b80286..dddbba3 100644
--- a/libyara/modules/pe_utils.c
+++ b/libyara/modules/pe_utils.c
@@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <string.h>
 
+#include <yara/endian.h>
 #include <yara/utils.h>
 #include <yara/strutils.h>
 #include <yara/mem.h>

From 0dafb5078bee2c880e3db5ad372c39ceb8a3a9af Mon Sep 17 00:00:00 2001
From: plusvic <plusvic@gmail.com>
Date: Mon, 24 Oct 2016 11:47:00 +0200
Subject: [PATCH 15/36] Use a union instead of a int64_t for arguments to
 module functions. This makes the code clearer, reduce typecasting and solve
 warnings.

(cherry-picked from commit fc36b064096233b959b958d7cd51a2edb2f563e7)
---
 libyara/exec.c                 | 31 ++++++++-----------------------
 libyara/include/yara/modules.h | 10 +++++-----
 libyara/include/yara/types.h   | 15 +++++++++++++--
 3 files changed, 26 insertions(+), 30 deletions(-)

diff --git a/libyara/exec.c b/libyara/exec.c
index 1a347c0..5266b9a 100644
--- a/libyara/exec.c
+++ b/libyara/exec.c
@@ -50,17 +50,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #define MEM_SIZE   MAX_LOOP_NESTING * LOOP_LOCAL_VARS
 
-typedef union _STACK_ITEM {
-
-  int64_t i;
-  double d;
-  void* p;
-  YR_OBJECT* o;
-  YR_STRING* s;
-  SIZED_STRING* ss;
-
-} STACK_ITEM;
-
 
 #define push(x)  \
     if (sp < stack_size) \
@@ -172,14 +161,14 @@ int yr_execute_code(
     time_t start_time)
 {
   int64_t mem[MEM_SIZE];
-  int64_t args[MAX_FUNCTION_ARGS];
   int32_t sp = 0;
   uint8_t* ip = rules->code_start;
 
-  STACK_ITEM *stack;
-  STACK_ITEM r1;
-  STACK_ITEM r2;
-  STACK_ITEM r3;
+  YR_VALUE args[MAX_FUNCTION_ARGS];
+  YR_VALUE *stack;
+  YR_VALUE r1;
+  YR_VALUE r2;
+  YR_VALUE r3;
 
   #ifdef PROFILING_ENABLED
   YR_RULE* current_rule = NULL;
@@ -207,7 +196,7 @@ int yr_execute_code(
 
   yr_get_configuration(YR_CONFIG_STACK_SIZE, (void*) &stack_size);
 
-  stack = (STACK_ITEM*) yr_malloc(stack_size * sizeof(STACK_ITEM));
+  stack = (YR_VALUE*) yr_malloc(stack_size * sizeof(YR_VALUE));
 
   if (stack == NULL)
     return ERROR_INSUFICIENT_MEMORY;
@@ -553,7 +542,7 @@ int yr_execute_code(
           if (is_undef(r1))  // count the number of undefined args
             count++;
 
-          args[i - 1] = r1.i;
+          args[i - 1] = r1;
           i--;
         }
 
@@ -580,11 +569,7 @@ int yr_execute_code(
 
           if (strcmp(function->prototypes[i].arguments_fmt, args_fmt) == 0)
           {
-            result = function->prototypes[i].code(
-                (void*) args,
-                context,
-                function);
-
+            result = function->prototypes[i].code(args, context, function);
             break;
           }
         }
diff --git a/libyara/include/yara/modules.h b/libyara/include/yara/modules.h
index 38e1bcd..9e9a6e3 100644
--- a/libyara/include/yara/modules.h
+++ b/libyara/include/yara/modules.h
@@ -266,25 +266,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #define define_function(func) \
     int func ( \
-        void* __args, \
+        YR_VALUE* __args, \
         YR_SCAN_CONTEXT* __context, \
         YR_OBJECT_FUNCTION* __function_obj)
 
 
 #define sized_string_argument(n) \
-    (*(SIZED_STRING**) &(((int64_t*) __args)[n-1]))
+    (__args[n-1].ss)
 
 #define string_argument(n) \
     (sized_string_argument(n)->c_string)
 
 #define integer_argument(n) \
-    (((int64_t*) __args)[n-1])
+    (__args[n-1].i)
 
 #define float_argument(n) \
-    (((double*) __args)[n-1])
+    (__args[n-1].d)
 
 #define regexp_argument(n) \
-    ((RE_CODE)((int64_t*) __args)[n-1])
+    ((RE_CODE)(__args[n-1].p))
 
 
 #define module()        yr_object_get_root((YR_OBJECT*) __function_obj)
diff --git a/libyara/include/yara/types.h b/libyara/include/yara/types.h
index bdacaa9..0fea79b 100644
--- a/libyara/include/yara/types.h
+++ b/libyara/include/yara/types.h
@@ -382,7 +382,6 @@ typedef struct _YR_RULES {
 } YR_RULES;
 
 
-
 struct _YR_MEMORY_BLOCK;
 struct _YR_MEMORY_BLOCK_ITERATOR;
 
@@ -516,11 +515,23 @@ typedef struct _YR_OBJECT_DICTIONARY
 } YR_OBJECT_DICTIONARY;
 
 
+typedef union _YR_VALUE {
+
+  int64_t i;
+  double d;
+  void* p;
+  YR_OBJECT* o;
+  YR_STRING* s;
+  SIZED_STRING* ss;
+
+} YR_VALUE;
+
+
 struct _YR_OBJECT_FUNCTION;
 
 
 typedef int (*YR_MODULE_FUNC)(
-    void* args,
+    YR_VALUE* args,
     YR_SCAN_CONTEXT* context,
     struct _YR_OBJECT_FUNCTION* function_obj);
 

From 00bcc7c6865be713bed6d2e58cb6308e055ce3cd Mon Sep 17 00:00:00 2001
From: Hilko Bengen <hillu@users.noreply.github.com>
Date: Mon, 31 Oct 2016 09:40:38 +0100
Subject: [PATCH 16/36] Don't unmask signals when setting up exception handler
 (Unix) (#546)

* YR_TRYCATCH: Remove duplicate initialization of oldmask

* Add test for handling exceptions

With

    #define YR_TRYCATCH(_try_clause_, _catch_clause_) {_try_clause_}

this will cause a bus error on Linux -- as it should.

* tests: Add assert_*_rule_blob_size, make count_matches usable from test code

* test-exception: Block and send SIGUSR1 before 2nd yr_rules_scan_mem call

This seems to reproduce something similar to the symptom described in

$ ./test-exception
Scanning for "aaaa"...
err = 4, matches = 0
Sending blocked SIGUSR1 to ourselves...
Scanning for {00 00 00 00}...
User defined signal 1

* exception (UNIX): Remove unneeded pthread_sigmask() calls

sigsetjmp() already saves the signal mask for us.

Also, setting the signal mask using the (empty) act.sa_mask was wrong
and led to the behavior described in #544.

We still want delivery of all signals to be blocked during execution of
the signal handler.

* Document test-exception

cherry-picked from:

- 8b2b6b8f82b8a8a8830bae122474b39ac2814fc6
- 0b3d9a93276d3364b2a3561995d27e8b4a137134, "Minor re-styling"
---
 Makefile.am            |   4 +-
 libyara/exception.h    |   7 +--
 tests/test-exception.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/util.c           |   2 +-
 tests/util.h           |  20 ++++++--
 5 files changed, 147 insertions(+), 12 deletions(-)
 create mode 100644 tests/test-exception.c

diff --git a/Makefile.am b/Makefile.am
index 8c1652a..8f5ab59 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -15,7 +15,7 @@ yarac_SOURCES = args.c args.h yarac.c
 yarac_LDADD = libyara/.libs/libyara.a
 
 TESTS = $(check_PROGRAMS)
-check_PROGRAMS = test-alignment test-rules test-pe test-elf
+check_PROGRAMS = test-alignment test-rules test-pe test-elf test-exception
 test_alignment_SOURCES = tests/test-alignment.c
 test_rules_SOURCES = tests/test-rules.c tests/util.c
 test_rules_LDADD = libyara/.libs/libyara.a
@@ -23,6 +23,8 @@ test_pe_SOURCES = tests/test-pe.c tests/util.c
 test_pe_LDADD = libyara/.libs/libyara.a
 test_elf_SOURCES = tests/test-elf.c tests/util.c
 test_elf_LDADD = libyara/.libs/libyara.a
+test_exception_SOURCES = tests/test-exception.c tests/util.c
+test_exception_LDADD = libyara/.libs/libyara.a
 
 # man pages
 man1_MANS = yara.man yarac.man
diff --git a/libyara/exception.h b/libyara/exception.h
index 436d006..c70ae63 100644
--- a/libyara/exception.h
+++ b/libyara/exception.h
@@ -99,13 +99,9 @@ typedef struct sigaction sa;
   {                                                             \
     struct sigaction oldact;                                    \
     struct sigaction act;                                       \
-    sigset_t oldmask;                                           \
     act.sa_handler = exception_handler;                         \
     act.sa_flags = 0; /* SA_ONSTACK? */                         \
-    sigemptyset(&oldmask);                                      \
-    sigemptyset(&act.sa_mask);                                  \
-    sigemptyset(&oldmask);                                      \
-    pthread_sigmask(SIG_SETMASK, &act.sa_mask, &oldmask);       \
+    sigfillset(&act.sa_mask);                                   \
     sigaction(SIGBUS, &act, &oldact);                           \
     int tidx = yr_get_tidx();                                   \
     assert(tidx != -1);                                         \
@@ -117,7 +113,6 @@ typedef struct sigaction sa;
       { _catch_clause_ }                                        \
     exc_jmp_buf[tidx] = NULL;                                   \
     sigaction(SIGBUS, &oldact, NULL);                           \
-    pthread_sigmask(SIG_SETMASK, &oldmask, NULL);               \
   } while (0)
 
 #endif
diff --git a/tests/test-exception.c b/tests/test-exception.c
new file mode 100644
index 0000000..8ebea58
--- /dev/null
+++ b/tests/test-exception.c
@@ -0,0 +1,126 @@
+/*
+Copyright (c) 2016. The YARA Authors. All Rights Reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its contributors
+may be used to endorse or promote products derived from this software without
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <signal.h>
+
+#include <yara.h>
+#include "util.h"
+
+int main(int argc, char **argv)
+{
+  char* filename = strdup("yara-testblob.XXXXXX");
+  int fd = mkstemp(filename);
+  char wbuf[4096];
+  int i;
+
+  if (fd <= 0)
+  {
+    perror("Create temp file");
+    return 77;
+  }
+
+  unlink(filename);
+
+  memset(wbuf, 'a', sizeof(wbuf));
+
+  for (i = 0; i <= 3; i++)
+    write(fd, wbuf, sizeof(wbuf));
+
+  uint8_t* mapped_region = mmap(
+      NULL, 4 * sizeof(wbuf), PROT_READ, MAP_SHARED, fd, 0);
+
+  ftruncate(fd, 2 * sizeof(wbuf));
+
+  /*
+    mapped_region is now only partially backed by the open file
+    referred to by fd. Accessing the memory beyond
+
+        mapped_region + 2 * sizeof(wbuf)
+
+    causes SIGBUS to be raised.
+  */
+
+  yr_initialize();
+
+  YR_RULES* rules_a = compile_rule(
+      "rule test { strings: $a = \"aaaa\" condition: all of them }");
+
+  YR_RULES* rules_0 = compile_rule(
+      "rule test { strings: $a = { 00 00 00 00 } condition: all of them }");
+
+  puts("Scanning for \"aaaa\"...");
+
+  int matches = 0;
+
+  /*
+    If YR_TRYCATCH is redefined like this
+
+        #define YR_TRYCATCH(_try_clause_,_catch_clause_) {_try_clause_}
+
+    yr_rules_scan_mem() will terminate the process.
+  */
+
+  int rc = yr_rules_scan_mem(
+      rules_a, mapped_region, 4 * sizeof(wbuf), 0, count_matches, &matches, 0);
+
+  printf("err = %d, matches = %d\n", rc, matches);
+
+  if (rc == ERROR_SUCCESS || matches != 0)
+    return 1;
+
+  puts("Sending blocked SIGUSR1 to ourselves...");
+
+  sigset_t set;
+  sigemptyset(&set);
+  sigaddset(&set, SIGUSR1);
+  sigprocmask(SIG_BLOCK, &set, NULL);
+  kill(getpid(), SIGUSR1);
+
+  puts("Scanning for {00 00 00 00}...");
+  matches = 0;
+
+  /*
+    This tests that SIGUSR1 is not delivered when setting up SIGBUS
+    signal handling -- or during SIGBUS signal handling
+  */
+
+  rc = yr_rules_scan_mem(
+      rules_0, mapped_region, 4 * sizeof(wbuf), 0, count_matches, &matches, 0);
+
+  printf("err = %d, matches = %d\n", rc, matches);
+
+  if (rc == ERROR_SUCCESS || matches != 0)
+    return 1;
+
+  return 0;
+}
diff --git a/tests/util.c b/tests/util.c
index 5597c98..59105dd 100644
--- a/tests/util.c
+++ b/tests/util.c
@@ -82,7 +82,7 @@ YR_RULES* compile_rule(
 }
 
 
-static int count_matches(
+int count_matches(
     int message,
     void* message_data,
     void* user_data)
diff --git a/tests/util.h b/tests/util.h
index 89b245b..835115f 100644
--- a/tests/util.h
+++ b/tests/util.h
@@ -36,6 +36,12 @@ YR_RULES* compile_rule(
     char* string);
 
 
+int count_matches(
+    int message,
+    void* message_data,
+    void* user_data);
+
+
 int matches_blob(
     char* rule,
     uint8_t* blob,
@@ -66,15 +72,18 @@ int read_file(
     }                                                                   \
   } while (0);
 
-#define assert_true_rule_blob(rule, blob)                               \
+#define assert_true_rule_blob_size(rule, blob, size)                    \
   do {                                                                  \
-    if (!matches_blob(rule, (uint8_t*) (blob), sizeof(blob))) {         \
+    if (!matches_blob(rule, (uint8_t*) (blob), size)) {                 \
       fprintf(stderr, "%s:%d: rule does not match (but should)\n",      \
               __FILE__, __LINE__ );                                     \
       exit(EXIT_FAILURE);                                               \
     }                                                                   \
   } while (0);
 
+#define assert_true_rule_blob(rule, blob)               \
+  assert_true_rule_blob_size(rule, blob, sizeof(blob))
+
 #define assert_true_rule_file(rule, filename)                           \
   do {                                                                  \
     char* buf;                                                          \
@@ -102,15 +111,18 @@ int read_file(
     }                                                                   \
   } while (0);
 
-#define assert_false_rule_blob(rule, blob)                              \
+#define assert_false_rule_blob_size(rule, blob, size)                   \
   do {                                                                  \
-    if (matches_blob(rule, (uint8_t*) (blob), sizeof(blob))) {          \
+    if (matches_blob(rule, (uint8_t*) (blob), size)) {                  \
       fprintf(stderr, "%s:%d: rule matches (but shouldn't)\n",          \
               __FILE__, __LINE__ );                                     \
       exit(EXIT_FAILURE);                                               \
     }                                                                   \
   } while (0);
 
+#define assert_false_rule_blob(rule, blob)              \
+  assert_false_rule_blob_size(rule, blob, sizeof(blob))
+
 #define assert_false_rule_file(rule, filename)                          \
   do {                                                                  \
     char* buf;                                                          \

From 7a71fc986f00abd29a7c332d01c45ee101ffda25 Mon Sep 17 00:00:00 2001
From: Hilko Bengen <hillu@users.noreply.github.com>
Date: Mon, 31 Oct 2016 22:31:27 +0100
Subject: [PATCH 17/36] tests: Use larger file to demonstrate SIGBUS (#549)

Apparently, PowerPC uses larger pages so the original size did not lead
to a signal.
(cherry picked from commit ddd5e975f2c36323e408e0eeedd56db59e0148a0)
---
 tests/test-exception.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/tests/test-exception.c b/tests/test-exception.c
index 8ebea58..29232b2 100644
--- a/tests/test-exception.c
+++ b/tests/test-exception.c
@@ -36,11 +36,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <yara.h>
 #include "util.h"
 
+#define COUNT 128
+char wbuf[1024];
+
 int main(int argc, char **argv)
 {
   char* filename = strdup("yara-testblob.XXXXXX");
   int fd = mkstemp(filename);
-  char wbuf[4096];
   int i;
 
   if (fd <= 0)
@@ -53,21 +55,21 @@ int main(int argc, char **argv)
 
   memset(wbuf, 'a', sizeof(wbuf));
 
-  for (i = 0; i <= 3; i++)
+  for (i = 0; i < COUNT; i++)
     write(fd, wbuf, sizeof(wbuf));
 
   uint8_t* mapped_region = mmap(
-      NULL, 4 * sizeof(wbuf), PROT_READ, MAP_SHARED, fd, 0);
+      NULL, COUNT * sizeof(wbuf), PROT_READ, MAP_SHARED, fd, 0);
 
-  ftruncate(fd, 2 * sizeof(wbuf));
+  ftruncate(fd, COUNT * sizeof(wbuf) / 2);
 
   /*
     mapped_region is now only partially backed by the open file
     referred to by fd. Accessing the memory beyond
 
-        mapped_region + 2 * sizeof(wbuf)
+        mapped_region + COUNT * sizeof(wbuf) / 2
 
-    causes SIGBUS to be raised.
+    should cause a signal (usually SIGBUS) to be raised.
   */
 
   yr_initialize();
@@ -91,7 +93,7 @@ int main(int argc, char **argv)
   */
 
   int rc = yr_rules_scan_mem(
-      rules_a, mapped_region, 4 * sizeof(wbuf), 0, count_matches, &matches, 0);
+      rules_a, mapped_region, COUNT * sizeof(wbuf), 0, count_matches, &matches, 0);
 
   printf("err = %d, matches = %d\n", rc, matches);
 
@@ -115,7 +117,7 @@ int main(int argc, char **argv)
   */
 
   rc = yr_rules_scan_mem(
-      rules_0, mapped_region, 4 * sizeof(wbuf), 0, count_matches, &matches, 0);
+      rules_0, mapped_region, COUNT * sizeof(wbuf), 0, count_matches, &matches, 0);
 
   printf("err = %d, matches = %d\n", rc, matches);
 

From 5032e9030a64ccf5bdbcda9ead7581bbd8c47229 Mon Sep 17 00:00:00 2001
From: Hilko Bengen <hillu@users.noreply.github.com>
Date: Wed, 2 Nov 2016 09:23:15 +0100
Subject: [PATCH 18/36] Exception handler (Unix): Install a handler for SIGSEGV
 (#552)

test-exception now passes on FreeBSD11/amd64, OpenBSD6/amd64.

Closes #551
(cherry picked from commit 35f01653ab162d4302faebcfa36b349b4141344a)
---
 libyara/exception.h | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/libyara/exception.h b/libyara/exception.h
index c70ae63..a9698b3 100644
--- a/libyara/exception.h
+++ b/libyara/exception.h
@@ -81,7 +81,7 @@ static LONG CALLBACK exception_handler(
 sigjmp_buf *exc_jmp_buf[MAX_THREADS];
 
 static void exception_handler(int sig) {
-  if (sig == SIGBUS)
+  if (sig == SIGBUS || sig == SIGSEGV)
   {
     int tidx = yr_get_tidx();
 
@@ -97,12 +97,14 @@ typedef struct sigaction sa;
 #define YR_TRYCATCH(_try_clause_, _catch_clause_)               \
   do                                                            \
   {                                                             \
-    struct sigaction oldact;                                    \
+    struct sigaction old_sigbus_act;                            \
+    struct sigaction old_sigsegv_act;                           \
     struct sigaction act;                                       \
     act.sa_handler = exception_handler;                         \
     act.sa_flags = 0; /* SA_ONSTACK? */                         \
     sigfillset(&act.sa_mask);                                   \
-    sigaction(SIGBUS, &act, &oldact);                           \
+    sigaction(SIGBUS, &act, &old_sigbus_act);                   \
+    sigaction(SIGSEGV, &act, &old_sigsegv_act);                 \
     int tidx = yr_get_tidx();                                   \
     assert(tidx != -1);                                         \
     sigjmp_buf jb;                                              \
@@ -112,7 +114,8 @@ typedef struct sigaction sa;
     else                                                        \
       { _catch_clause_ }                                        \
     exc_jmp_buf[tidx] = NULL;                                   \
-    sigaction(SIGBUS, &oldact, NULL);                           \
+    sigaction(SIGBUS, &old_sigbus_act, NULL);                   \
+    sigaction(SIGSEGV, &old_sigsegv_act, NULL);                 \
   } while (0)
 
 #endif

From 6ba610d91aebdc94de95802507bff71456ca2532 Mon Sep 17 00:00:00 2001
From: Hilko Bengen <bengen@hilluzination.de>
Date: Wed, 2 Nov 2016 22:43:58 +0100
Subject: [PATCH 19/36] Add scan flag for disabling exceptions

(cherry picked from commit c72536a223a3e039c147273c7cc0d43f40b77660)
---
 libyara/exception.h         | 74 +++++++++++++++++++++++++++------------------
 libyara/include/yara/scan.h |  1 +
 libyara/rules.c             | 12 ++++++--
 3 files changed, 54 insertions(+), 33 deletions(-)

diff --git a/libyara/exception.h b/libyara/exception.h
index a9698b3..edead24 100644
--- a/libyara/exception.h
+++ b/libyara/exception.h
@@ -57,20 +57,27 @@ static LONG CALLBACK exception_handler(
   return EXCEPTION_CONTINUE_SEARCH;
 }
 
-#define YR_TRYCATCH(_try_clause_, _catch_clause_)                       \
+#define YR_TRYCATCH(_do_,_try_clause_, _catch_clause_)                  \
   do                                                                    \
   {                                                                     \
-    jmp_buf jb;                                                         \
-    HANDLE exh = AddVectoredExceptionHandler(1, exception_handler);     \
-    int tidx = yr_get_tidx();                                           \
-    assert(tidx != -1);                                                 \
-    exc_jmp_buf[tidx] = &jb;                                            \
-    if (setjmp(jb) == 0)                                                \
-      { _try_clause_ }                                                  \
+    if (_do_)                                                           \
+    {                                                                   \
+      jmp_buf jb;                                                       \
+      HANDLE exh = AddVectoredExceptionHandler(1, exception_handler);   \
+      int tidx = yr_get_tidx();                                         \
+      assert(tidx != -1);                                               \
+      exc_jmp_buf[tidx] = &jb;                                          \
+      if (setjmp(jb) == 0)                                              \
+        { _try_clause_ }                                                \
+      else                                                              \
+        { _catch_clause_ }                                              \
+      exc_jmp_buf[tidx] = NULL;                                         \
+      RemoveVectoredExceptionHandler(exh);                              \
+    }                                                                   \
     else                                                                \
-      { _catch_clause_ }                                                \
-    exc_jmp_buf[tidx] = NULL;                                           \
-    RemoveVectoredExceptionHandler(exh);                                \
+    {                                                                   \
+      _try_clause_                                                      \
+    }                                                                   \
   } while(0)
 
 #else
@@ -94,28 +101,35 @@ static void exception_handler(int sig) {
 
 typedef struct sigaction sa;
 
-#define YR_TRYCATCH(_try_clause_, _catch_clause_)               \
+#define YR_TRYCATCH(_do_,_try_clause_, _catch_clause_)          \
   do                                                            \
   {                                                             \
-    struct sigaction old_sigbus_act;                            \
-    struct sigaction old_sigsegv_act;                           \
-    struct sigaction act;                                       \
-    act.sa_handler = exception_handler;                         \
-    act.sa_flags = 0; /* SA_ONSTACK? */                         \
-    sigfillset(&act.sa_mask);                                   \
-    sigaction(SIGBUS, &act, &old_sigbus_act);                   \
-    sigaction(SIGSEGV, &act, &old_sigsegv_act);                 \
-    int tidx = yr_get_tidx();                                   \
-    assert(tidx != -1);                                         \
-    sigjmp_buf jb;                                              \
-    exc_jmp_buf[tidx] = &jb;                                    \
-    if (sigsetjmp(jb, 1) == 0)                                  \
-      { _try_clause_ }                                          \
+    if (_do_)                                                   \
+    {                                                           \
+      struct sigaction old_sigbus_act;                          \
+      struct sigaction old_sigsegv_act;                         \
+      struct sigaction act;                                     \
+      act.sa_handler = exception_handler;                       \
+      act.sa_flags = 0; /* SA_ONSTACK? */                       \
+      sigfillset(&act.sa_mask);                                 \
+      sigaction(SIGBUS, &act, &old_sigbus_act);                 \
+      sigaction(SIGSEGV, &act, &old_sigsegv_act);               \
+      int tidx = yr_get_tidx();                                 \
+      assert(tidx != -1);                                       \
+      sigjmp_buf jb;                                            \
+      exc_jmp_buf[tidx] = &jb;                                  \
+      if (sigsetjmp(jb, 1) == 0)                                \
+        { _try_clause_ }                                        \
+      else                                                      \
+        { _catch_clause_ }                                      \
+      exc_jmp_buf[tidx] = NULL;                                 \
+      sigaction(SIGBUS, &old_sigbus_act, NULL);                 \
+      sigaction(SIGSEGV, &old_sigsegv_act, NULL);               \
+    }                                                           \
     else                                                        \
-      { _catch_clause_ }                                        \
-    exc_jmp_buf[tidx] = NULL;                                   \
-    sigaction(SIGBUS, &old_sigbus_act, NULL);                   \
-    sigaction(SIGSEGV, &old_sigsegv_act, NULL);                 \
+    {                                                           \
+      _try_clause_                                              \
+    }                                                           \
   } while (0)
 
 #endif
diff --git a/libyara/include/yara/scan.h b/libyara/include/yara/scan.h
index 8ea0cb8..8ef6575 100644
--- a/libyara/include/yara/scan.h
+++ b/libyara/include/yara/scan.h
@@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // Bitmasks for flags.
 #define SCAN_FLAGS_FAST_MODE         1
 #define SCAN_FLAGS_PROCESS_MEMORY    2
+#define SCAN_FLAGS_NO_TRYCATCH       4
 
 
 int yr_scan_verify_match(
diff --git a/libyara/rules.c b/libyara/rules.c
index 490c472..336ba7c 100644
--- a/libyara/rules.c
+++ b/libyara/rules.c
@@ -436,7 +436,9 @@ YR_API int yr_rules_scan_mem_blocks(
 
     if (context.entry_point == UNDEFINED)
     {
-      YR_TRYCATCH({
+      YR_TRYCATCH(
+        !(flags & SCAN_FLAGS_NO_TRYCATCH),
+        {
           if (flags & SCAN_FLAGS_PROCESS_MEMORY)
             context.entry_point = yr_get_entry_point_address(
                 data,
@@ -449,7 +451,9 @@ YR_API int yr_rules_scan_mem_blocks(
         },{});
     }
 
-    YR_TRYCATCH({
+    YR_TRYCATCH(
+      !(flags & SCAN_FLAGS_NO_TRYCATCH),
+      {
         result = _yr_rules_scan_mem_block(
             rules,
             data,
@@ -467,7 +471,9 @@ YR_API int yr_rules_scan_mem_blocks(
     block = iterator->next(iterator);
   }
 
-  YR_TRYCATCH({
+  YR_TRYCATCH(
+    !(flags & SCAN_FLAGS_NO_TRYCATCH),
+    {
       result = yr_execute_code(
           rules,
           &context,

From e7eab9a77c858ad7440810b571a3e5d0b19ca208 Mon Sep 17 00:00:00 2001
From: Rastislav Masaryk <rmasaryk@eset.sk>
Date: Fri, 11 Nov 2016 10:15:57 +0100
Subject: [PATCH 20/36] Windows mutex replaced with CriticalSection

(cherry picked from commit 245edc994b2c8c0a9753a0f690e186d2fb513dd0)
---
 threading.c | 13 +++++--------
 threading.h |  2 +-
 2 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/threading.c b/threading.c
index 5257884..5a65c2e 100644
--- a/threading.c
+++ b/threading.c
@@ -40,11 +40,8 @@ int mutex_init(
     MUTEX* mutex)
 {
   #if defined(_WIN32) || defined(__CYGWIN__)
-  *mutex = CreateMutex(NULL, FALSE, NULL);
-  if (*mutex == NULL)
-    return GetLastError();
-  else
-    return 0;
+  InitializeCriticalSection(mutex);
+  return GetLastError();
   #else
   return pthread_mutex_init(mutex, NULL);
   #endif
@@ -54,7 +51,7 @@ void mutex_destroy(
     MUTEX* mutex)
 {
   #if defined(_WIN32) || defined(__CYGWIN__)
-  CloseHandle(*mutex);
+  DeleteCriticalSection(mutex);
   #else
   pthread_mutex_destroy(mutex);
   #endif
@@ -65,7 +62,7 @@ void mutex_lock(
     MUTEX* mutex)
 {
   #if defined(_WIN32) || defined(__CYGWIN__)
-  WaitForSingleObject(*mutex, INFINITE);
+  EnterCriticalSection(mutex);
   #else
   pthread_mutex_lock(mutex);
   #endif
@@ -76,7 +73,7 @@ void mutex_unlock(
     MUTEX* mutex)
 {
   #if defined(_WIN32) || defined(__CYGWIN__)
-  ReleaseMutex(*mutex);
+  LeaveCriticalSection(mutex);
   #else
   pthread_mutex_unlock(mutex);
   #endif
diff --git a/threading.h b/threading.h
index d6bf46a..43a68b6 100644
--- a/threading.h
+++ b/threading.h
@@ -42,7 +42,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #if defined(_WIN32) || defined(__CYGWIN__)
 
 typedef HANDLE SEMAPHORE;
-typedef HANDLE MUTEX;
+typedef CRITICAL_SECTION MUTEX;
 typedef HANDLE THREAD;
 
 typedef LPTHREAD_START_ROUTINE THREAD_START_ROUTINE;

From 405a2cc32b7c3ef73c5678133bccaad327c49733 Mon Sep 17 00:00:00 2001
From: Rastislav Masaryk <rmasaryk@eset.sk>
Date: Mon, 14 Nov 2016 07:59:55 +0100
Subject: [PATCH 21/36] CritSection in try block and return value fixed

(cherry picked from commit 7e168cd2a344b206da799d1fd8344ac0dcdd4807)
---
 threading.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/threading.c b/threading.c
index 5a65c2e..5479c20 100644
--- a/threading.c
+++ b/threading.c
@@ -40,8 +40,13 @@ int mutex_init(
     MUTEX* mutex)
 {
   #if defined(_WIN32) || defined(__CYGWIN__)
-  InitializeCriticalSection(mutex);
-  return GetLastError();
+  __try {
+    InitializeCriticalSection(mutex);
+    return 0;
+  }
+  __except (STATUS_NO_MEMORY) {
+    return STATUS_NO_MEMORY;
+  }
   #else
   return pthread_mutex_init(mutex, NULL);
   #endif

From ac1057c8f8310cdaa6eeed92aa013cd9ae8f20ff Mon Sep 17 00:00:00 2001
From: Rastislav Masaryk <rmasaryk@eset.sk>
Date: Mon, 14 Nov 2016 08:57:59 +0100
Subject: [PATCH 22/36] removed __try block around CritSection

(cherry picked from commit e0c19f2bceee50787e9044d010b5ad59f11da93e)
---
 threading.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/threading.c b/threading.c
index 5479c20..07c0b88 100644
--- a/threading.c
+++ b/threading.c
@@ -40,13 +40,8 @@ int mutex_init(
     MUTEX* mutex)
 {
   #if defined(_WIN32) || defined(__CYGWIN__)
-  __try {
     InitializeCriticalSection(mutex);
     return 0;
-  }
-  __except (STATUS_NO_MEMORY) {
-    return STATUS_NO_MEMORY;
-  }
   #else
   return pthread_mutex_init(mutex, NULL);
   #endif

From 8e364afcf9e328c016c109ee2e417412e634f2e0 Mon Sep 17 00:00:00 2001
From: plusvic <plusvic@gmail.com>
Date: Wed, 4 Jan 2017 16:18:03 +0100
Subject: [PATCH 23/36] Fix issue #576

(cherry picked from commit eb491e03851a11bc811173f5e13c89cefa7257ac)
---
 libyara/lexer.c | 27 +++++++++++++++++----------
 libyara/lexer.l |  7 +++++++
 2 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/libyara/lexer.c b/libyara/lexer.c
index 03f0465..b20e0c4 100644
--- a/libyara/lexer.c
+++ b/libyara/lexer.c
@@ -1831,6 +1831,13 @@ YY_RULE_SETUP
 {
 
   LEX_CHECK_SPACE_OK("\\.", yyextra->lex_buf_len, LEX_BUF_SIZE);
+
+  if (yytext[1] == 0)
+  {
+    yyerror(yyscanner, compiler, "malformed regular expression");
+    yyterminate();
+  }
+
   *yyextra->lex_buf_ptr++ = yytext[0];
   *yyextra->lex_buf_ptr++ = yytext[1];
   yyextra->lex_buf_len += 2;
@@ -1838,13 +1845,13 @@ YY_RULE_SETUP
 	YY_BREAK
 case 66:
 YY_RULE_SETUP
-#line 592 "lexer.l"
+#line 599 "lexer.l"
 { YYTEXT_TO_BUFFER; }
 	YY_BREAK
 case 67:
 /* rule 67 can match eol */
 YY_RULE_SETUP
-#line 595 "lexer.l"
+#line 602 "lexer.l"
 {
 
   yyerror(yyscanner, compiler, "unterminated regular expression");
@@ -1853,7 +1860,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 68:
 YY_RULE_SETUP
-#line 602 "lexer.l"
+#line 609 "lexer.l"
 {
 
   yyextra->lex_buf_ptr = yyextra->lex_buf;
@@ -1863,7 +1870,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 69:
 YY_RULE_SETUP
-#line 610 "lexer.l"
+#line 617 "lexer.l"
 {
 
   yyextra->lex_buf_ptr = yyextra->lex_buf;
@@ -1874,7 +1881,7 @@ YY_RULE_SETUP
 case 70:
 /* rule 70 can match eol */
 YY_RULE_SETUP
-#line 618 "lexer.l"
+#line 625 "lexer.l"
 {
   // Match hex-digits with whitespace or comments. The latter are stripped
   // out by hex_lexer.l
@@ -1890,12 +1897,12 @@ YY_RULE_SETUP
 case 71:
 /* rule 71 can match eol */
 YY_RULE_SETUP
-#line 631 "lexer.l"
+#line 638 "lexer.l"
 /* skip whitespace */
 	YY_BREAK
 case 72:
 YY_RULE_SETUP
-#line 633 "lexer.l"
+#line 640 "lexer.l"
 {
 
   if (yytext[0] >= 32 && yytext[0] < 127)
@@ -1911,10 +1918,10 @@ YY_RULE_SETUP
 	YY_BREAK
 case 73:
 YY_RULE_SETUP
-#line 646 "lexer.l"
+#line 653 "lexer.l"
 ECHO;
 	YY_BREAK
-#line 1918 "lexer.c"
+#line 1925 "lexer.c"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -3063,7 +3070,7 @@ void yara_yyfree (void * ptr , yyscan_t yyscanner)
 
 #define YYTABLES_NAME "yytables"
 
-#line 646 "lexer.l"
+#line 653 "lexer.l"
 
 
 
diff --git a/libyara/lexer.l b/libyara/lexer.l
index a184606..e1bd98b 100644
--- a/libyara/lexer.l
+++ b/libyara/lexer.l
@@ -583,6 +583,13 @@ u?int(8|16|32)(be)? {
 <regexp>\\. {
 
   LEX_CHECK_SPACE_OK("\\.", yyextra->lex_buf_len, LEX_BUF_SIZE);
+
+  if (yytext[1] == 0)
+  {
+    yyerror(yyscanner, compiler, "malformed regular expression");
+    yyterminate();
+  }
+
   *yyextra->lex_buf_ptr++ = yytext[0];
   *yyextra->lex_buf_ptr++ = yytext[1];
   yyextra->lex_buf_len += 2;

From 3fc60e8b46cb0a0bbab433fd4c72c1ae2658f475 Mon Sep 17 00:00:00 2001
From: plusvic <plusvic@gmail.com>
Date: Wed, 4 Jan 2017 17:09:35 +0100
Subject: [PATCH 24/36] Fix issue #575

(cherry picked from commit 890c3f850293176c0e996a602ffa88b315f4e98f)
---
 libyara/grammar.c | 645 +++++++++++++++++++++++++++---------------------------
 libyara/grammar.y |   5 +
 2 files changed, 332 insertions(+), 318 deletions(-)

diff --git a/libyara/grammar.c b/libyara/grammar.c
index 0ce27b2..eb28701 100644
--- a/libyara/grammar.c
+++ b/libyara/grammar.c
@@ -546,16 +546,16 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  2
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   408
+#define YYLAST   406
 
 /* YYNTOKENS -- Number of terminals.  */
 #define YYNTOKENS  72
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  41
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  121
+#define YYNRULES  122
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  209
+#define YYNSTATES  210
 
 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
    by yylex, with out-of-bounds checking.  */
@@ -612,13 +612,13 @@ static const yytype_uint16 yyrline[] =
      472,   485,   502,   503,   509,   508,   524,   523,   539,   553,
      554,   559,   560,   561,   562,   567,   652,   698,   756,   801,
      802,   806,   831,   867,   913,   935,   944,   953,   968,   980,
-     994,  1007,  1019,  1049,  1018,  1163,  1162,  1241,  1247,  1254,
-    1253,  1316,  1315,  1376,  1385,  1394,  1403,  1412,  1421,  1430,
-    1434,  1442,  1443,  1448,  1470,  1482,  1498,  1497,  1503,  1514,
-    1515,  1520,  1527,  1538,  1539,  1543,  1551,  1555,  1565,  1579,
-    1595,  1605,  1614,  1639,  1651,  1663,  1679,  1691,  1707,  1752,
-    1771,  1789,  1807,  1825,  1851,  1869,  1879,  1889,  1899,  1909,
-    1919,  1929
+     994,  1007,  1018,  1024,  1054,  1023,  1168,  1167,  1246,  1252,
+    1259,  1258,  1321,  1320,  1381,  1390,  1399,  1408,  1417,  1426,
+    1435,  1439,  1447,  1448,  1453,  1475,  1487,  1503,  1502,  1508,
+    1519,  1520,  1525,  1532,  1543,  1544,  1548,  1556,  1560,  1570,
+    1584,  1600,  1610,  1619,  1644,  1656,  1668,  1684,  1696,  1712,
+    1757,  1776,  1794,  1812,  1830,  1856,  1874,  1884,  1894,  1904,
+    1914,  1924,  1934
 };
 #endif
 
@@ -672,7 +672,7 @@ static const yytype_uint16 yytoknum[] =
 #define yypact_value_is_default(Yystate) \
   (!!((Yystate) == (-73)))
 
-#define YYTABLE_NINF -94
+#define YYTABLE_NINF -95
 
 #define yytable_value_is_error(Yytable_value) \
   0
@@ -681,27 +681,27 @@ static const yytype_uint16 yytoknum[] =
      STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
-     -73,    79,   -73,   -32,    -4,   -73,   -73,    94,   -73,   -73,
-     -73,   -73,    13,   -73,   -73,   -73,   -73,    -8,    72,     6,
-     -73,    78,   111,   -73,    61,   122,   123,    82,   -73,    90,
-     123,   -73,   147,   150,    16,   -73,    96,   147,   -73,   101,
-      97,   -73,   -73,   -73,   -73,   151,    53,   -73,    48,   -73,
-     -73,   -73,   149,   145,   -73,    -9,   -73,   103,   107,   -73,
-     -73,   106,   -73,   -73,   -73,   -73,   -73,   -73,   110,   -73,
-     -73,   135,    48,   135,    48,   -33,   -73,    64,   -73,   144,
-     306,   -73,   -73,   135,   108,   135,   135,   135,   135,    -7,
-     322,   -73,   -73,   -73,    64,   117,   163,   168,   135,    48,
-     -73,   -73,    -6,   167,   135,   135,   135,   135,   135,   135,
-     135,   135,   135,   135,   135,   135,   135,   135,   135,   135,
-     135,    86,    86,   322,   135,   -73,   243,   261,   183,   203,
-     159,    -6,   -73,   -73,   -73,   279,   121,   125,    95,    48,
-      48,   -73,   -73,   -73,   -73,   322,   337,   351,   -43,   322,
-     322,   322,   322,   322,   322,    40,    40,    58,    58,   -73,
-     -73,   -73,   -73,   -73,   -73,   -73,   -73,   129,   -73,   -73,
-     -73,   -73,   128,   -73,   -73,    48,   152,   -73,    15,   135,
-     131,   -73,    95,   -73,   -73,    71,   -73,   223,   135,   133,
-     -73,   132,   -73,    15,   -73,    73,   129,   -73,    48,   -73,
-     -73,   135,   134,    31,   322,    48,   -73,    49,   -73
+     -73,    90,   -73,   -32,   -10,   -73,   -73,    93,   -73,   -73,
+     -73,   -73,     1,   -73,   -73,   -73,   -73,   -49,     7,   -36,
+     -73,    20,    26,   -73,   -28,    92,    46,     4,   -73,    40,
+      46,   -73,   100,   119,    16,   -73,    72,   100,   -73,    77,
+      83,   -73,   -73,   -73,   -73,   134,    59,   -73,    48,   -73,
+     -73,   -73,   133,   136,   -73,   -18,   -73,    88,    95,   -73,
+     -73,    91,   -73,   -73,   -73,   -73,   -73,   -73,   102,   -73,
+     -73,   126,    48,   126,    48,   -44,   -73,    85,   -73,   127,
+     297,   -73,   -73,   126,   110,   126,   126,   126,   126,     2,
+     313,   -73,   -73,   -73,    85,   111,   154,   172,   126,    48,
+     -73,   -73,    -6,   162,   126,   126,   126,   126,   126,   126,
+     126,   126,   126,   126,   126,   126,   126,   126,   126,   126,
+     126,    60,    60,   313,   126,   -73,   234,   252,   174,   194,
+     -73,   153,    -6,   -73,   -73,   -73,   270,   117,   120,   108,
+      48,    48,   -73,   -73,   -73,   -73,   313,   328,   342,   349,
+     313,   313,   313,   313,   313,   313,   113,   113,    53,    53,
+     -73,   -73,   -73,   -73,   -73,   -73,   -73,   -73,   121,   -73,
+     -73,   -73,   -73,   124,   -73,   -73,    48,   151,   -73,    -1,
+     126,   125,   -73,   108,   -73,   -73,    18,   -73,   214,   126,
+     129,   -73,   143,   -73,    -1,   -73,    63,   121,   -73,    48,
+     -73,   -73,   126,   144,    31,   313,    48,   -73,    33,   -73
 };
 
   /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -714,31 +714,31 @@ static const yytype_uint8 yydefact[] =
       23,    22,    12,    24,     0,    14,     0,     0,    10,     0,
       13,    25,     0,     0,     0,    26,     0,    15,    32,     0,
        0,    28,    27,    30,    31,     0,    34,    33,     0,    11,
-      29,    38,     0,     0,    45,    59,   103,   105,   107,   100,
-     101,     0,   102,    53,    97,    98,    94,    95,     0,    55,
-      56,     0,     0,     0,     0,   108,   121,    16,    54,     0,
-      79,    39,    39,     0,     0,     0,     0,     0,     0,     0,
-      93,   109,    68,   118,     0,    54,    79,     0,     0,    49,
-      71,    69,     0,     0,     0,     0,     0,     0,     0,     0,
+      29,    38,     0,     0,    45,    59,   104,   106,   108,   101,
+     102,     0,   103,    53,    98,    99,    95,    96,     0,    55,
+      56,     0,     0,     0,     0,   109,   122,    16,    54,     0,
+      80,    39,    39,     0,     0,     0,     0,     0,     0,     0,
+      94,   110,    69,   119,     0,    54,    80,     0,     0,    49,
+      72,    70,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,    35,    37,    60,     0,    61,     0,     0,     0,     0,
-       0,     0,    80,    96,    46,     0,     0,    50,    51,     0,
-       0,    88,    86,    67,    57,    58,   117,   115,   116,    77,
-      78,    73,    75,    74,    76,   119,   120,   110,   111,   112,
-     113,   114,    42,    41,    43,    44,    40,     0,   104,   106,
-      99,    62,     0,    47,    48,     0,    72,    70,     0,     0,
-       0,    65,    52,    91,    92,     0,    89,     0,     0,     0,
-      82,     0,    87,     0,    83,     0,    84,    63,     0,    90,
-      81,     0,     0,     0,    85,     0,    66,     0,    64
+      62,     0,     0,    81,    97,    46,     0,     0,    50,    51,
+       0,     0,    89,    87,    68,    57,    58,   118,   116,   117,
+      78,    79,    74,    76,    75,    77,   120,   121,   111,   112,
+     113,   114,   115,    42,    41,    43,    44,    40,     0,   105,
+     107,   100,    63,     0,    47,    48,     0,    73,    71,     0,
+       0,     0,    66,    52,    92,    93,     0,    90,     0,     0,
+       0,    83,     0,    88,     0,    84,     0,    85,    64,     0,
+      91,    82,     0,     0,     0,    86,     0,    67,     0,    65
 };
 
   /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-     -73,   -73,   199,   218,   -73,   -73,   -73,   -73,   -73,   -73,
-     -73,   -73,   -73,   -73,   192,   -73,   186,   -73,   -73,   142,
-     -73,   -73,   -73,   -73,   126,   -48,   -72,   -73,   -73,   -73,
-     -73,   -73,   -73,    50,   -73,   100,   -73,   -73,    35,   164,
+     -73,   -73,   211,   212,   -73,   -73,   -73,   -73,   -73,   -73,
+     -73,   -73,   -73,   -73,   189,   -73,   183,   -73,   -73,   139,
+     -73,   -73,   -73,   -73,   130,   -48,   -72,   -73,   -73,   -73,
+     -73,   -73,   -73,    41,   -73,   103,   -73,   -73,    29,   164,
      -67
 };
 
@@ -747,8 +747,8 @@ static const yytype_int16 yydefgoto[] =
 {
       -1,     1,     5,     6,    17,    33,    25,    28,    40,     7,
       15,    19,    21,    30,    31,    37,    38,    52,    53,   121,
-     166,    75,   136,   137,    76,    94,    78,   180,   202,   191,
-     140,   139,   189,   125,   195,   143,   178,   185,   186,    79,
+     167,    75,   137,   138,    76,    94,    78,   181,   203,   192,
+     141,   140,   190,   125,   196,   144,   179,   186,   187,    79,
       80
 };
 
@@ -757,92 +757,92 @@ static const yytype_int16 yydefgoto[] =
      number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_int16 yytable[] =
 {
-      77,    90,    95,   130,    91,     4,    93,    96,   114,   115,
-     116,   117,   118,   119,   120,    11,   123,    83,   126,   127,
-     128,   129,    84,    16,    92,   131,   183,   138,   141,     8,
-     184,   135,    41,    97,    98,    42,    99,   145,   146,   147,
-     148,   149,   150,   151,   152,   153,   154,   155,   156,   157,
-     158,   159,   160,   161,    43,    44,    18,   167,    54,    55,
-      56,    57,    58,   142,    59,    60,    61,    62,    22,    63,
-      45,   100,   101,    51,   -36,    64,    65,    66,    67,     2,
-       3,    68,    20,   -17,   -17,   -17,    69,    70,    23,   100,
-     101,   176,   177,   116,   117,   118,   119,   120,    12,    13,
-      14,   206,    71,   182,   100,   101,    72,    73,   162,   163,
-     164,   165,   187,   118,   119,   120,     4,    74,    24,   208,
-      54,   196,    56,    57,    58,    26,    59,    60,    61,    62,
-      27,    63,   179,    29,   204,   -54,   -54,    64,    65,    66,
-      67,   192,   193,   200,   201,    54,    32,    56,    57,    58,
-     203,    59,    60,    61,    62,    34,    63,   207,    36,    39,
-      49,    46,    64,    65,    71,    48,    82,    50,    81,    73,
-      85,   105,   106,   107,    86,    87,   102,   124,   134,    88,
-     114,   115,   116,   117,   118,   119,   120,   132,    63,    71,
-     171,   174,   181,   101,    73,   -93,   175,   197,   103,   104,
-     188,   198,     9,   205,    88,   105,   106,   107,   108,   109,
-     110,   111,   112,   113,   114,   115,   116,   117,   118,   119,
-     120,    10,    35,    47,   122,   105,   106,   107,   199,   144,
-     190,   172,    89,   133,   114,   115,   116,   117,   118,   119,
-     120,     0,     0,     0,     0,   105,   106,   107,     0,     0,
-       0,     0,     0,   170,   114,   115,   116,   117,   118,   119,
-     120,     0,     0,     0,     0,   105,   106,   107,     0,     0,
-       0,     0,     0,   133,   114,   115,   116,   117,   118,   119,
-     120,     0,     0,     0,     0,   105,   106,   107,     0,     0,
-       0,     0,     0,   194,   114,   115,   116,   117,   118,   119,
-     120,     0,     0,   105,   106,   107,     0,     0,     0,     0,
-       0,   168,   114,   115,   116,   117,   118,   119,   120,     0,
-       0,   105,   106,   107,     0,     0,     0,     0,     0,   169,
-     114,   115,   116,   117,   118,   119,   120,     0,   -93,     0,
-       0,   103,   104,     0,     0,     0,     0,   173,   105,   106,
-     107,   108,   109,   110,   111,   112,   113,   114,   115,   116,
-     117,   118,   119,   120,   105,   106,   107,     0,     0,     0,
+      77,    90,    95,   130,    91,     4,    93,    96,    83,    11,
+     184,    16,   131,    84,   185,    18,   123,    20,   126,   127,
+     128,   129,    97,    98,    92,    99,    22,   139,   142,     8,
+      23,   136,    41,    24,   132,    42,    26,   146,   147,   148,
+     149,   150,   151,   152,   153,   154,   155,   156,   157,   158,
+     159,   160,   161,   162,    43,    44,    29,   168,    54,    55,
+      56,    57,    58,   143,    59,    60,    61,    62,    32,    63,
+      45,   100,   101,   100,   101,    64,    65,    66,    67,    51,
+     -36,    68,   163,   164,   165,   166,    69,    70,   193,   194,
+       2,     3,   177,   178,   -17,   -17,   -17,    12,    13,    14,
+      27,   207,    71,   209,   183,    34,    72,    73,   118,   119,
+     120,    36,    54,   188,    56,    57,    58,    74,    59,    60,
+      61,    62,   197,    63,   180,   100,   101,     4,    39,    64,
+      65,    66,    67,   201,   202,   205,    54,    46,    56,    57,
+      58,    48,    59,    60,    61,    62,    49,    63,   -54,   -54,
+      50,   204,    81,    64,    65,    85,    71,    82,   208,   102,
+      87,    73,    86,   105,   106,   107,   116,   117,   118,   119,
+     120,    88,   114,   115,   116,   117,   118,   119,   120,   124,
+      71,   133,   135,    63,   172,    73,   -94,   175,   182,   103,
+     104,   176,   101,   198,   189,    88,   105,   106,   107,   108,
+     109,   110,   111,   112,   113,   114,   115,   116,   117,   118,
+     119,   120,   199,   206,     9,    10,   105,   106,   107,    35,
+      47,   122,   191,   200,   134,   114,   115,   116,   117,   118,
+     119,   120,    89,   145,     0,   173,   105,   106,   107,     0,
+       0,     0,     0,     0,   171,   114,   115,   116,   117,   118,
+     119,   120,     0,     0,     0,     0,   105,   106,   107,     0,
+       0,     0,     0,     0,   134,   114,   115,   116,   117,   118,
+     119,   120,     0,     0,     0,     0,   105,   106,   107,     0,
+       0,     0,     0,     0,   195,   114,   115,   116,   117,   118,
+     119,   120,     0,     0,   105,   106,   107,     0,     0,     0,
+       0,     0,   169,   114,   115,   116,   117,   118,   119,   120,
+       0,     0,   105,   106,   107,     0,     0,     0,     0,     0,
+     170,   114,   115,   116,   117,   118,   119,   120,     0,   -94,
+       0,     0,   103,   104,     0,     0,     0,     0,   174,   105,
+     106,   107,   108,   109,   110,   111,   112,   113,   114,   115,
+     116,   117,   118,   119,   120,   105,   106,   107,     0,     0,
+       0,     0,     0,     0,   114,   115,   116,   117,   118,   119,
+     120,   106,   107,     0,     0,     0,     0,     0,     0,   114,
+     115,   116,   117,   118,   119,   120,   107,     0,     0,     0,
        0,     0,     0,   114,   115,   116,   117,   118,   119,   120,
-     106,   107,     0,     0,     0,     0,     0,     0,   114,   115,
-     116,   117,   118,   119,   120,   107,     0,     0,     0,     0,
-       0,     0,   114,   115,   116,   117,   118,   119,   120
+     114,   115,   116,   117,   118,   119,   120
 };
 
 static const yytype_int16 yycheck[] =
 {
-      48,    68,    74,    10,    71,    37,    73,    74,    51,    52,
-      53,    54,    55,    56,    57,    19,    83,    26,    85,    86,
-      87,    88,    31,    10,    72,    32,    11,    99,    34,    61,
-      15,    98,    16,    66,    67,    19,    69,   104,   105,   106,
+      48,    68,    74,     1,    71,    37,    73,    74,    26,    19,
+      11,    10,    10,    31,    15,    64,    83,    10,    85,    86,
+      87,    88,    66,    67,    72,    69,    62,    99,    34,    61,
+      10,    98,    16,     7,    32,    19,    64,   104,   105,   106,
      107,   108,   109,   110,   111,   112,   113,   114,   115,   116,
-     117,   118,   119,   120,    38,    39,    64,   124,    10,    11,
-      12,    13,    14,    69,    16,    17,    18,    19,    62,    21,
-      54,    40,    41,    20,    21,    27,    28,    29,    30,     0,
-       1,    33,    10,     4,     5,     6,    38,    39,    10,    40,
-      41,   139,   140,    53,    54,    55,    56,    57,     4,     5,
-       6,    70,    54,   175,    40,    41,    58,    59,    22,    23,
-      24,    25,   179,    55,    56,    57,    37,    69,     7,    70,
-      10,   188,    12,    13,    14,    64,    16,    17,    18,    19,
-       8,    21,     3,    10,   201,    40,    41,    27,    28,    29,
-      30,    70,    71,    70,    71,    10,    64,    12,    13,    14,
-     198,    16,    17,    18,    19,    65,    21,   205,    11,     9,
-      63,    65,    27,    28,    54,    64,    21,    16,    19,    59,
-      67,    42,    43,    44,    67,    69,    32,    69,    10,    69,
-      51,    52,    53,    54,    55,    56,    57,    70,    21,    54,
-      31,    70,    64,    41,    59,    32,    71,    64,    35,    36,
-      69,    69,     3,    69,    69,    42,    43,    44,    45,    46,
-      47,    48,    49,    50,    51,    52,    53,    54,    55,    56,
-      57,     3,    30,    37,    82,    42,    43,    44,   193,   103,
-     180,   131,    68,    70,    51,    52,    53,    54,    55,    56,
-      57,    -1,    -1,    -1,    -1,    42,    43,    44,    -1,    -1,
-      -1,    -1,    -1,    70,    51,    52,    53,    54,    55,    56,
-      57,    -1,    -1,    -1,    -1,    42,    43,    44,    -1,    -1,
-      -1,    -1,    -1,    70,    51,    52,    53,    54,    55,    56,
-      57,    -1,    -1,    -1,    -1,    42,    43,    44,    -1,    -1,
-      -1,    -1,    -1,    70,    51,    52,    53,    54,    55,    56,
-      57,    -1,    -1,    42,    43,    44,    -1,    -1,    -1,    -1,
-      -1,    68,    51,    52,    53,    54,    55,    56,    57,    -1,
-      -1,    42,    43,    44,    -1,    -1,    -1,    -1,    -1,    68,
-      51,    52,    53,    54,    55,    56,    57,    -1,    32,    -1,
-      -1,    35,    36,    -1,    -1,    -1,    -1,    68,    42,    43,
-      44,    45,    46,    47,    48,    49,    50,    51,    52,    53,
-      54,    55,    56,    57,    42,    43,    44,    -1,    -1,    -1,
+     117,   118,   119,   120,    38,    39,    10,   124,    10,    11,
+      12,    13,    14,    69,    16,    17,    18,    19,    64,    21,
+      54,    40,    41,    40,    41,    27,    28,    29,    30,    20,
+      21,    33,    22,    23,    24,    25,    38,    39,    70,    71,
+       0,     1,   140,   141,     4,     5,     6,     4,     5,     6,
+       8,    70,    54,    70,   176,    65,    58,    59,    55,    56,
+      57,    11,    10,   180,    12,    13,    14,    69,    16,    17,
+      18,    19,   189,    21,     3,    40,    41,    37,     9,    27,
+      28,    29,    30,    70,    71,   202,    10,    65,    12,    13,
+      14,    64,    16,    17,    18,    19,    63,    21,    40,    41,
+      16,   199,    19,    27,    28,    67,    54,    21,   206,    32,
+      69,    59,    67,    42,    43,    44,    53,    54,    55,    56,
+      57,    69,    51,    52,    53,    54,    55,    56,    57,    69,
+      54,    70,    10,    21,    31,    59,    32,    70,    64,    35,
+      36,    71,    41,    64,    69,    69,    42,    43,    44,    45,
+      46,    47,    48,    49,    50,    51,    52,    53,    54,    55,
+      56,    57,    69,    69,     3,     3,    42,    43,    44,    30,
+      37,    82,   181,   194,    70,    51,    52,    53,    54,    55,
+      56,    57,    68,   103,    -1,   132,    42,    43,    44,    -1,
+      -1,    -1,    -1,    -1,    70,    51,    52,    53,    54,    55,
+      56,    57,    -1,    -1,    -1,    -1,    42,    43,    44,    -1,
+      -1,    -1,    -1,    -1,    70,    51,    52,    53,    54,    55,
+      56,    57,    -1,    -1,    -1,    -1,    42,    43,    44,    -1,
+      -1,    -1,    -1,    -1,    70,    51,    52,    53,    54,    55,
+      56,    57,    -1,    -1,    42,    43,    44,    -1,    -1,    -1,
+      -1,    -1,    68,    51,    52,    53,    54,    55,    56,    57,
+      -1,    -1,    42,    43,    44,    -1,    -1,    -1,    -1,    -1,
+      68,    51,    52,    53,    54,    55,    56,    57,    -1,    32,
+      -1,    -1,    35,    36,    -1,    -1,    -1,    -1,    68,    42,
+      43,    44,    45,    46,    47,    48,    49,    50,    51,    52,
+      53,    54,    55,    56,    57,    42,    43,    44,    -1,    -1,
+      -1,    -1,    -1,    -1,    51,    52,    53,    54,    55,    56,
+      57,    43,    44,    -1,    -1,    -1,    -1,    -1,    -1,    51,
+      52,    53,    54,    55,    56,    57,    44,    -1,    -1,    -1,
       -1,    -1,    -1,    51,    52,    53,    54,    55,    56,    57,
-      43,    44,    -1,    -1,    -1,    -1,    -1,    -1,    51,    52,
-      53,    54,    55,    56,    57,    44,    -1,    -1,    -1,    -1,
-      -1,    -1,    51,    52,    53,    54,    55,    56,    57
+      51,    52,    53,    54,    55,    56,    57
 };
 
   /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -862,14 +862,14 @@ static const yytype_uint8 yystos[] =
       40,    41,    32,    35,    36,    42,    43,    44,    45,    46,
       47,    48,    49,    50,    51,    52,    53,    54,    55,    56,
       57,    91,    91,   112,    69,   105,   112,   112,   112,   112,
-      10,    32,    70,    70,    10,   112,    94,    95,    98,   103,
-     102,    34,    69,   107,    96,   112,   112,   112,   112,   112,
+       1,    10,    32,    70,    70,    10,   112,    94,    95,    98,
+     103,   102,    34,    69,   107,    96,   112,   112,   112,   112,
      112,   112,   112,   112,   112,   112,   112,   112,   112,   112,
-     112,   112,    22,    23,    24,    25,    92,   112,    68,    68,
-      70,    31,   107,    68,    70,    71,    97,    97,   108,     3,
-      99,    64,    98,    11,    15,   109,   110,   112,    69,   104,
-     105,   101,    70,    71,    70,   106,   112,    64,    69,   110,
-      70,    71,   100,    97,   112,    69,    70,    97,    70
+     112,   112,   112,    22,    23,    24,    25,    92,   112,    68,
+      68,    70,    31,   107,    68,    70,    71,    97,    97,   108,
+       3,    99,    64,    98,    11,    15,   109,   110,   112,    69,
+     104,   105,   101,    70,    71,    70,   106,   112,    64,    69,
+     110,    70,    71,   100,    97,   112,    69,    70,    97,    70
 };
 
   /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
@@ -881,13 +881,13 @@ static const yytype_uint8 yyr1[] =
       86,    86,    87,    87,    89,    88,    90,    88,    88,    91,
       91,    92,    92,    92,    92,    93,    93,    93,    93,    94,
       94,    95,    95,    96,    97,    98,    98,    98,    98,    98,
-      98,    98,    99,   100,    98,   101,    98,    98,    98,   102,
-      98,   103,    98,    98,    98,    98,    98,    98,    98,    98,
-      98,   104,   104,   105,   106,   106,   108,   107,   107,   109,
-     109,   110,   110,   111,   111,   111,   112,   112,   112,   112,
+      98,    98,    98,    99,   100,    98,   101,    98,    98,    98,
+     102,    98,   103,    98,    98,    98,    98,    98,    98,    98,
+      98,    98,   104,   104,   105,   106,   106,   108,   107,   107,
+     109,   109,   110,   110,   111,   111,   111,   112,   112,   112,
      112,   112,   112,   112,   112,   112,   112,   112,   112,   112,
      112,   112,   112,   112,   112,   112,   112,   112,   112,   112,
-     112,   112
+     112,   112,   112
 };
 
   /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
@@ -899,13 +899,13 @@ static const yytype_uint8 yyr2[] =
        3,     3,     1,     2,     0,     5,     0,     5,     3,     0,
        2,     1,     1,     1,     1,     1,     3,     4,     4,     0,
        1,     1,     3,     1,     1,     1,     1,     3,     3,     1,
-       3,     3,     0,     0,    11,     0,     9,     3,     2,     0,
-       4,     0,     4,     3,     3,     3,     3,     3,     3,     1,
-       3,     3,     1,     5,     1,     3,     0,     4,     1,     1,
-       3,     1,     1,     1,     1,     1,     3,     1,     1,     4,
-       1,     1,     1,     1,     4,     1,     4,     1,     1,     2,
-       3,     3,     3,     3,     3,     3,     3,     3,     2,     3,
-       3,     1
+       3,     3,     3,     0,     0,    11,     0,     9,     3,     2,
+       0,     4,     0,     4,     3,     3,     3,     3,     3,     3,
+       1,     3,     3,     1,     5,     1,     3,     0,     4,     1,
+       1,     3,     1,     1,     1,     1,     1,     3,     1,     1,
+       4,     1,     1,     1,     1,     4,     1,     4,     1,     1,
+       2,     3,     3,     3,     3,     3,     3,     3,     3,     2,
+       3,     3,     1
 };
 
 
@@ -2587,6 +2587,15 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
   case 62:
 #line 1019 "grammar.y" /* yacc.c:1646  */
     {
+        compiler->loop_depth--;
+        compiler->loop_identifier[compiler->loop_depth] = NULL;
+      }
+#line 2594 "grammar.c" /* yacc.c:1646  */
+    break;
+
+  case 63:
+#line 1024 "grammar.y" /* yacc.c:1646  */
+    {
         int var_index;
 
         if (compiler->loop_depth == MAX_LOOP_NESTING)
@@ -2615,11 +2624,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 2619 "grammar.c" /* yacc.c:1646  */
+#line 2628 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 63:
-#line 1049 "grammar.y" /* yacc.c:1646  */
+  case 64:
+#line 1054 "grammar.y" /* yacc.c:1646  */
     {
         int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth;
         uint8_t* addr;
@@ -2654,11 +2663,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         compiler->loop_identifier[compiler->loop_depth] = (yyvsp[-4].c_string);
         compiler->loop_depth++;
       }
-#line 2658 "grammar.c" /* yacc.c:1646  */
+#line 2667 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 64:
-#line 1084 "grammar.y" /* yacc.c:1646  */
+  case 65:
+#line 1089 "grammar.y" /* yacc.c:1646  */
     {
         int mem_offset;
 
@@ -2737,11 +2746,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2741 "grammar.c" /* yacc.c:1646  */
+#line 2750 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 65:
-#line 1163 "grammar.y" /* yacc.c:1646  */
+  case 66:
+#line 1168 "grammar.y" /* yacc.c:1646  */
     {
         int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth;
         uint8_t* addr;
@@ -2771,11 +2780,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         compiler->loop_identifier[compiler->loop_depth] = NULL;
         compiler->loop_depth++;
       }
-#line 2775 "grammar.c" /* yacc.c:1646  */
+#line 2784 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 66:
-#line 1193 "grammar.y" /* yacc.c:1646  */
+  case 67:
+#line 1198 "grammar.y" /* yacc.c:1646  */
     {
         int mem_offset;
 
@@ -2824,31 +2833,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
 
       }
-#line 2828 "grammar.c" /* yacc.c:1646  */
+#line 2837 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 67:
-#line 1242 "grammar.y" /* yacc.c:1646  */
+  case 68:
+#line 1247 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit(yyscanner, OP_OF, NULL);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2838 "grammar.c" /* yacc.c:1646  */
+#line 2847 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 68:
-#line 1248 "grammar.y" /* yacc.c:1646  */
+  case 69:
+#line 1253 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit(yyscanner, OP_NOT, NULL);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2848 "grammar.c" /* yacc.c:1646  */
+#line 2857 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 69:
-#line 1254 "grammar.y" /* yacc.c:1646  */
+  case 70:
+#line 1259 "grammar.y" /* yacc.c:1646  */
     {
         YR_FIXUP* fixup;
         void* jmp_destination_addr;
@@ -2874,11 +2883,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         fixup->next = compiler->fixup_stack_head;
         compiler->fixup_stack_head = fixup;
       }
-#line 2878 "grammar.c" /* yacc.c:1646  */
+#line 2887 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 70:
-#line 1280 "grammar.y" /* yacc.c:1646  */
+  case 71:
+#line 1285 "grammar.y" /* yacc.c:1646  */
     {
         YR_FIXUP* fixup;
         uint8_t* and_addr;
@@ -2914,11 +2923,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2918 "grammar.c" /* yacc.c:1646  */
+#line 2927 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 71:
-#line 1316 "grammar.y" /* yacc.c:1646  */
+  case 72:
+#line 1321 "grammar.y" /* yacc.c:1646  */
     {
         YR_FIXUP* fixup;
         void* jmp_destination_addr;
@@ -2943,11 +2952,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         fixup->next = compiler->fixup_stack_head;
         compiler->fixup_stack_head = fixup;
       }
-#line 2947 "grammar.c" /* yacc.c:1646  */
+#line 2956 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 72:
-#line 1341 "grammar.y" /* yacc.c:1646  */
+  case 73:
+#line 1346 "grammar.y" /* yacc.c:1646  */
     {
         YR_FIXUP* fixup;
         uint8_t* or_addr;
@@ -2983,11 +2992,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2987 "grammar.c" /* yacc.c:1646  */
+#line 2996 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 73:
-#line 1377 "grammar.y" /* yacc.c:1646  */
+  case 74:
+#line 1382 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "<", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -2996,11 +3005,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3000 "grammar.c" /* yacc.c:1646  */
+#line 3009 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 74:
-#line 1386 "grammar.y" /* yacc.c:1646  */
+  case 75:
+#line 1391 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, ">", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3009,11 +3018,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3013 "grammar.c" /* yacc.c:1646  */
+#line 3022 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 75:
-#line 1395 "grammar.y" /* yacc.c:1646  */
+  case 76:
+#line 1400 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "<=", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3022,11 +3031,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3026 "grammar.c" /* yacc.c:1646  */
+#line 3035 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 76:
-#line 1404 "grammar.y" /* yacc.c:1646  */
+  case 77:
+#line 1409 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, ">=", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3035,11 +3044,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3039 "grammar.c" /* yacc.c:1646  */
+#line 3048 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 77:
-#line 1413 "grammar.y" /* yacc.c:1646  */
+  case 78:
+#line 1418 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "==", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3048,11 +3057,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3052 "grammar.c" /* yacc.c:1646  */
+#line 3061 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 78:
-#line 1422 "grammar.y" /* yacc.c:1646  */
+  case 79:
+#line 1427 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "!=", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3061,39 +3070,39 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3065 "grammar.c" /* yacc.c:1646  */
+#line 3074 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 79:
-#line 1431 "grammar.y" /* yacc.c:1646  */
+  case 80:
+#line 1436 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.expression) = (yyvsp[0].expression);
       }
-#line 3073 "grammar.c" /* yacc.c:1646  */
+#line 3082 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 80:
-#line 1435 "grammar.y" /* yacc.c:1646  */
+  case 81:
+#line 1440 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.expression) = (yyvsp[-1].expression);
       }
-#line 3081 "grammar.c" /* yacc.c:1646  */
+#line 3090 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 81:
-#line 1442 "grammar.y" /* yacc.c:1646  */
+  case 82:
+#line 1447 "grammar.y" /* yacc.c:1646  */
     { (yyval.integer) = INTEGER_SET_ENUMERATION; }
-#line 3087 "grammar.c" /* yacc.c:1646  */
+#line 3096 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 82:
-#line 1443 "grammar.y" /* yacc.c:1646  */
+  case 83:
+#line 1448 "grammar.y" /* yacc.c:1646  */
     { (yyval.integer) = INTEGER_SET_RANGE; }
-#line 3093 "grammar.c" /* yacc.c:1646  */
+#line 3102 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 83:
-#line 1449 "grammar.y" /* yacc.c:1646  */
+  case 84:
+#line 1454 "grammar.y" /* yacc.c:1646  */
     {
         if ((yyvsp[-3].expression).type != EXPRESSION_TYPE_INTEGER)
         {
@@ -3111,11 +3120,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3115 "grammar.c" /* yacc.c:1646  */
+#line 3124 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 84:
-#line 1471 "grammar.y" /* yacc.c:1646  */
+  case 85:
+#line 1476 "grammar.y" /* yacc.c:1646  */
     {
         if ((yyvsp[0].expression).type != EXPRESSION_TYPE_INTEGER)
         {
@@ -3127,11 +3136,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3131 "grammar.c" /* yacc.c:1646  */
+#line 3140 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 85:
-#line 1483 "grammar.y" /* yacc.c:1646  */
+  case 86:
+#line 1488 "grammar.y" /* yacc.c:1646  */
     {
         if ((yyvsp[0].expression).type != EXPRESSION_TYPE_INTEGER)
         {
@@ -3142,77 +3151,77 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3146 "grammar.c" /* yacc.c:1646  */
+#line 3155 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 86:
-#line 1498 "grammar.y" /* yacc.c:1646  */
+  case 87:
+#line 1503 "grammar.y" /* yacc.c:1646  */
     {
         // Push end-of-list marker
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
       }
-#line 3155 "grammar.c" /* yacc.c:1646  */
+#line 3164 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 88:
-#line 1504 "grammar.y" /* yacc.c:1646  */
+  case 89:
+#line 1509 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
         yr_parser_emit_pushes_for_strings(yyscanner, "$*");
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3166 "grammar.c" /* yacc.c:1646  */
+#line 3175 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 91:
-#line 1521 "grammar.y" /* yacc.c:1646  */
+  case 92:
+#line 1526 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[0].c_string));
         yr_free((yyvsp[0].c_string));
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3177 "grammar.c" /* yacc.c:1646  */
+#line 3186 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 92:
-#line 1528 "grammar.y" /* yacc.c:1646  */
+  case 93:
+#line 1533 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[0].c_string));
         yr_free((yyvsp[0].c_string));
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3188 "grammar.c" /* yacc.c:1646  */
+#line 3197 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 94:
-#line 1540 "grammar.y" /* yacc.c:1646  */
+  case 95:
+#line 1545 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
       }
-#line 3196 "grammar.c" /* yacc.c:1646  */
+#line 3205 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 95:
-#line 1544 "grammar.y" /* yacc.c:1646  */
+  case 96:
+#line 1549 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, 1, NULL, NULL);
       }
-#line 3204 "grammar.c" /* yacc.c:1646  */
+#line 3213 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 96:
-#line 1552 "grammar.y" /* yacc.c:1646  */
+  case 97:
+#line 1557 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.expression) = (yyvsp[-1].expression);
       }
-#line 3212 "grammar.c" /* yacc.c:1646  */
+#line 3221 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 97:
-#line 1556 "grammar.y" /* yacc.c:1646  */
+  case 98:
+#line 1561 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit(
             yyscanner, OP_FILESIZE, NULL);
@@ -3222,11 +3231,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3226 "grammar.c" /* yacc.c:1646  */
+#line 3235 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 98:
-#line 1566 "grammar.y" /* yacc.c:1646  */
+  case 99:
+#line 1571 "grammar.y" /* yacc.c:1646  */
     {
         yywarning(yyscanner,
             "Using deprecated \"entrypoint\" keyword. Use the \"entry_point\" "
@@ -3240,11 +3249,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3244 "grammar.c" /* yacc.c:1646  */
+#line 3253 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 99:
-#line 1580 "grammar.y" /* yacc.c:1646  */
+  case 100:
+#line 1585 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-1].expression), EXPRESSION_TYPE_INTEGER, "intXXXX or uintXXXX");
 
@@ -3260,11 +3269,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3264 "grammar.c" /* yacc.c:1646  */
+#line 3273 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 100:
-#line 1596 "grammar.y" /* yacc.c:1646  */
+  case 101:
+#line 1601 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, (yyvsp[0].integer), NULL, NULL);
@@ -3274,11 +3283,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = (yyvsp[0].integer);
       }
-#line 3278 "grammar.c" /* yacc.c:1646  */
+#line 3287 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 101:
-#line 1606 "grammar.y" /* yacc.c:1646  */
+  case 102:
+#line 1611 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg_double(
             yyscanner, OP_PUSH, (yyvsp[0].double_), NULL, NULL);
@@ -3287,11 +3296,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
       }
-#line 3291 "grammar.c" /* yacc.c:1646  */
+#line 3300 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 102:
-#line 1615 "grammar.y" /* yacc.c:1646  */
+  case 103:
+#line 1620 "grammar.y" /* yacc.c:1646  */
     {
         SIZED_STRING* sized_string;
 
@@ -3316,11 +3325,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_STRING;
         (yyval.expression).value.sized_string = sized_string;
       }
-#line 3320 "grammar.c" /* yacc.c:1646  */
+#line 3329 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 103:
-#line 1640 "grammar.y" /* yacc.c:1646  */
+  case 104:
+#line 1645 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner, (yyvsp[0].c_string), OP_COUNT, UNDEFINED);
@@ -3332,11 +3341,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3336 "grammar.c" /* yacc.c:1646  */
+#line 3345 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 104:
-#line 1652 "grammar.y" /* yacc.c:1646  */
+  case 105:
+#line 1657 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner, (yyvsp[-3].c_string), OP_OFFSET, UNDEFINED);
@@ -3348,11 +3357,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3352 "grammar.c" /* yacc.c:1646  */
+#line 3361 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 105:
-#line 1664 "grammar.y" /* yacc.c:1646  */
+  case 106:
+#line 1669 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, 1, NULL, NULL);
@@ -3368,11 +3377,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3372 "grammar.c" /* yacc.c:1646  */
+#line 3381 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 106:
-#line 1680 "grammar.y" /* yacc.c:1646  */
+  case 107:
+#line 1685 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner, (yyvsp[-3].c_string), OP_LENGTH, UNDEFINED);
@@ -3384,11 +3393,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3388 "grammar.c" /* yacc.c:1646  */
+#line 3397 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 107:
-#line 1692 "grammar.y" /* yacc.c:1646  */
+  case 108:
+#line 1697 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, 1, NULL, NULL);
@@ -3404,11 +3413,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3408 "grammar.c" /* yacc.c:1646  */
+#line 3417 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 108:
-#line 1708 "grammar.y" /* yacc.c:1646  */
+  case 109:
+#line 1713 "grammar.y" /* yacc.c:1646  */
     {
         if ((yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER)  // loop identifier
         {
@@ -3453,11 +3462,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3457 "grammar.c" /* yacc.c:1646  */
+#line 3466 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 109:
-#line 1753 "grammar.y" /* yacc.c:1646  */
+  case 110:
+#line 1758 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER | EXPRESSION_TYPE_FLOAT, "-");
 
@@ -3476,11 +3485,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3480 "grammar.c" /* yacc.c:1646  */
+#line 3489 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 110:
-#line 1772 "grammar.y" /* yacc.c:1646  */
+  case 111:
+#line 1777 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "+", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3498,11 +3507,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
         }
       }
-#line 3502 "grammar.c" /* yacc.c:1646  */
+#line 3511 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 111:
-#line 1790 "grammar.y" /* yacc.c:1646  */
+  case 112:
+#line 1795 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "-", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3520,11 +3529,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
         }
       }
-#line 3524 "grammar.c" /* yacc.c:1646  */
+#line 3533 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 112:
-#line 1808 "grammar.y" /* yacc.c:1646  */
+  case 113:
+#line 1813 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "*", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3542,11 +3551,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
         }
       }
-#line 3546 "grammar.c" /* yacc.c:1646  */
+#line 3555 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 113:
-#line 1826 "grammar.y" /* yacc.c:1646  */
+  case 114:
+#line 1831 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "\\", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3572,11 +3581,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
         }
       }
-#line 3576 "grammar.c" /* yacc.c:1646  */
+#line 3585 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 114:
-#line 1852 "grammar.y" /* yacc.c:1646  */
+  case 115:
+#line 1857 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "%");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "%");
@@ -3594,11 +3603,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           ERROR_IF(compiler->last_result != ERROR_SUCCESS);
         }
       }
-#line 3598 "grammar.c" /* yacc.c:1646  */
+#line 3607 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 115:
-#line 1870 "grammar.y" /* yacc.c:1646  */
+  case 116:
+#line 1875 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^");
@@ -3608,11 +3617,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(^, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3612 "grammar.c" /* yacc.c:1646  */
+#line 3621 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 116:
-#line 1880 "grammar.y" /* yacc.c:1646  */
+  case 117:
+#line 1885 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^");
@@ -3622,11 +3631,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(&, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3626 "grammar.c" /* yacc.c:1646  */
+#line 3635 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 117:
-#line 1890 "grammar.y" /* yacc.c:1646  */
+  case 118:
+#line 1895 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "|");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "|");
@@ -3636,11 +3645,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(|, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3640 "grammar.c" /* yacc.c:1646  */
+#line 3649 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 118:
-#line 1900 "grammar.y" /* yacc.c:1646  */
+  case 119:
+#line 1905 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "~");
 
@@ -3650,11 +3659,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).value.integer = ((yyvsp[0].expression).value.integer == UNDEFINED) ?
             UNDEFINED : ~((yyvsp[0].expression).value.integer);
       }
-#line 3654 "grammar.c" /* yacc.c:1646  */
+#line 3663 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 119:
-#line 1910 "grammar.y" /* yacc.c:1646  */
+  case 120:
+#line 1915 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "<<");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "<<");
@@ -3664,11 +3673,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(<<, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3668 "grammar.c" /* yacc.c:1646  */
+#line 3677 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 120:
-#line 1920 "grammar.y" /* yacc.c:1646  */
+  case 121:
+#line 1925 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, ">>");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, ">>");
@@ -3678,19 +3687,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(>>, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3682 "grammar.c" /* yacc.c:1646  */
+#line 3691 "grammar.c" /* yacc.c:1646  */
     break;
 
-  case 121:
-#line 1930 "grammar.y" /* yacc.c:1646  */
+  case 122:
+#line 1935 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.expression) = (yyvsp[0].expression);
       }
-#line 3690 "grammar.c" /* yacc.c:1646  */
+#line 3699 "grammar.c" /* yacc.c:1646  */
     break;
 
 
-#line 3694 "grammar.c" /* yacc.c:1646  */
+#line 3703 "grammar.c" /* yacc.c:1646  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -3918,5 +3927,5 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 #endif
   return yyresult;
 }
-#line 1935 "grammar.y" /* yacc.c:1906  */
+#line 1940 "grammar.y" /* yacc.c:1906  */
 
diff --git a/libyara/grammar.y b/libyara/grammar.y
index 56bae40..be24307 100644
--- a/libyara/grammar.y
+++ b/libyara/grammar.y
@@ -1015,6 +1015,11 @@ expression
 
         $$.type = EXPRESSION_TYPE_BOOLEAN;
       }
+    | _FOR_ for_expression error
+      {
+        compiler->loop_depth--;
+        compiler->loop_identifier[compiler->loop_depth] = NULL;
+      }
     | _FOR_ for_expression _IDENTIFIER_ _IN_
       {
         int var_index;

From 03dc5bdb2f3fa820fb6c757f502c323aacd88f35 Mon Sep 17 00:00:00 2001
From: plusvic <plusvic@gmail.com>
Date: Mon, 9 Jan 2017 13:17:39 +0100
Subject: [PATCH 25/36] Make sure that loop depth is greater than 0 before
 decrementing it.

(cherry picked from commit 7f02eca670f29c00a1d2c305e96febae6ce5d37b)
---
 libyara/grammar.c | 251 +++++++++++++++++++++++++++---------------------------
 libyara/grammar.y |   7 +-
 2 files changed, 132 insertions(+), 126 deletions(-)

diff --git a/libyara/grammar.c b/libyara/grammar.c
index eb28701..9c79512 100644
--- a/libyara/grammar.c
+++ b/libyara/grammar.c
@@ -612,13 +612,13 @@ static const yytype_uint16 yyrline[] =
      472,   485,   502,   503,   509,   508,   524,   523,   539,   553,
      554,   559,   560,   561,   562,   567,   652,   698,   756,   801,
      802,   806,   831,   867,   913,   935,   944,   953,   968,   980,
-     994,  1007,  1018,  1024,  1054,  1023,  1168,  1167,  1246,  1252,
-    1259,  1258,  1321,  1320,  1381,  1390,  1399,  1408,  1417,  1426,
-    1435,  1439,  1447,  1448,  1453,  1475,  1487,  1503,  1502,  1508,
-    1519,  1520,  1525,  1532,  1543,  1544,  1548,  1556,  1560,  1570,
-    1584,  1600,  1610,  1619,  1644,  1656,  1668,  1684,  1696,  1712,
-    1757,  1776,  1794,  1812,  1830,  1856,  1874,  1884,  1894,  1904,
-    1914,  1924,  1934
+     994,  1007,  1018,  1027,  1057,  1026,  1171,  1170,  1249,  1255,
+    1262,  1261,  1324,  1323,  1384,  1393,  1402,  1411,  1420,  1429,
+    1438,  1442,  1450,  1451,  1456,  1478,  1490,  1506,  1505,  1511,
+    1522,  1523,  1528,  1535,  1546,  1547,  1551,  1559,  1563,  1573,
+    1587,  1603,  1613,  1622,  1647,  1659,  1671,  1687,  1699,  1715,
+    1760,  1779,  1797,  1815,  1833,  1859,  1877,  1887,  1897,  1907,
+    1917,  1927,  1937
 };
 #endif
 
@@ -2587,14 +2587,17 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
   case 62:
 #line 1019 "grammar.y" /* yacc.c:1646  */
     {
-        compiler->loop_depth--;
-        compiler->loop_identifier[compiler->loop_depth] = NULL;
+        if (compiler->loop_depth > 0)
+        {
+          compiler->loop_depth--;
+          compiler->loop_identifier[compiler->loop_depth] = NULL;
+        }
       }
-#line 2594 "grammar.c" /* yacc.c:1646  */
+#line 2597 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 63:
-#line 1024 "grammar.y" /* yacc.c:1646  */
+#line 1027 "grammar.y" /* yacc.c:1646  */
     {
         int var_index;
 
@@ -2624,11 +2627,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 2628 "grammar.c" /* yacc.c:1646  */
+#line 2631 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 64:
-#line 1054 "grammar.y" /* yacc.c:1646  */
+#line 1057 "grammar.y" /* yacc.c:1646  */
     {
         int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth;
         uint8_t* addr;
@@ -2663,11 +2666,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         compiler->loop_identifier[compiler->loop_depth] = (yyvsp[-4].c_string);
         compiler->loop_depth++;
       }
-#line 2667 "grammar.c" /* yacc.c:1646  */
+#line 2670 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 65:
-#line 1089 "grammar.y" /* yacc.c:1646  */
+#line 1092 "grammar.y" /* yacc.c:1646  */
     {
         int mem_offset;
 
@@ -2746,11 +2749,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2750 "grammar.c" /* yacc.c:1646  */
+#line 2753 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 66:
-#line 1168 "grammar.y" /* yacc.c:1646  */
+#line 1171 "grammar.y" /* yacc.c:1646  */
     {
         int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth;
         uint8_t* addr;
@@ -2780,11 +2783,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         compiler->loop_identifier[compiler->loop_depth] = NULL;
         compiler->loop_depth++;
       }
-#line 2784 "grammar.c" /* yacc.c:1646  */
+#line 2787 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 67:
-#line 1198 "grammar.y" /* yacc.c:1646  */
+#line 1201 "grammar.y" /* yacc.c:1646  */
     {
         int mem_offset;
 
@@ -2833,31 +2836,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
 
       }
-#line 2837 "grammar.c" /* yacc.c:1646  */
+#line 2840 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 68:
-#line 1247 "grammar.y" /* yacc.c:1646  */
+#line 1250 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit(yyscanner, OP_OF, NULL);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2847 "grammar.c" /* yacc.c:1646  */
+#line 2850 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 69:
-#line 1253 "grammar.y" /* yacc.c:1646  */
+#line 1256 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit(yyscanner, OP_NOT, NULL);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2857 "grammar.c" /* yacc.c:1646  */
+#line 2860 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 70:
-#line 1259 "grammar.y" /* yacc.c:1646  */
+#line 1262 "grammar.y" /* yacc.c:1646  */
     {
         YR_FIXUP* fixup;
         void* jmp_destination_addr;
@@ -2883,11 +2886,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         fixup->next = compiler->fixup_stack_head;
         compiler->fixup_stack_head = fixup;
       }
-#line 2887 "grammar.c" /* yacc.c:1646  */
+#line 2890 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 71:
-#line 1285 "grammar.y" /* yacc.c:1646  */
+#line 1288 "grammar.y" /* yacc.c:1646  */
     {
         YR_FIXUP* fixup;
         uint8_t* and_addr;
@@ -2923,11 +2926,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2927 "grammar.c" /* yacc.c:1646  */
+#line 2930 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 72:
-#line 1321 "grammar.y" /* yacc.c:1646  */
+#line 1324 "grammar.y" /* yacc.c:1646  */
     {
         YR_FIXUP* fixup;
         void* jmp_destination_addr;
@@ -2952,11 +2955,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         fixup->next = compiler->fixup_stack_head;
         compiler->fixup_stack_head = fixup;
       }
-#line 2956 "grammar.c" /* yacc.c:1646  */
+#line 2959 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 73:
-#line 1346 "grammar.y" /* yacc.c:1646  */
+#line 1349 "grammar.y" /* yacc.c:1646  */
     {
         YR_FIXUP* fixup;
         uint8_t* or_addr;
@@ -2992,11 +2995,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2996 "grammar.c" /* yacc.c:1646  */
+#line 2999 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 74:
-#line 1382 "grammar.y" /* yacc.c:1646  */
+#line 1385 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "<", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3005,11 +3008,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3009 "grammar.c" /* yacc.c:1646  */
+#line 3012 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 75:
-#line 1391 "grammar.y" /* yacc.c:1646  */
+#line 1394 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, ">", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3018,11 +3021,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3022 "grammar.c" /* yacc.c:1646  */
+#line 3025 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 76:
-#line 1400 "grammar.y" /* yacc.c:1646  */
+#line 1403 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "<=", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3031,11 +3034,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3035 "grammar.c" /* yacc.c:1646  */
+#line 3038 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 77:
-#line 1409 "grammar.y" /* yacc.c:1646  */
+#line 1412 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, ">=", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3044,11 +3047,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3048 "grammar.c" /* yacc.c:1646  */
+#line 3051 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 78:
-#line 1418 "grammar.y" /* yacc.c:1646  */
+#line 1421 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "==", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3057,11 +3060,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3061 "grammar.c" /* yacc.c:1646  */
+#line 3064 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 79:
-#line 1427 "grammar.y" /* yacc.c:1646  */
+#line 1430 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "!=", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3070,39 +3073,39 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3074 "grammar.c" /* yacc.c:1646  */
+#line 3077 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 80:
-#line 1436 "grammar.y" /* yacc.c:1646  */
+#line 1439 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.expression) = (yyvsp[0].expression);
       }
-#line 3082 "grammar.c" /* yacc.c:1646  */
+#line 3085 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 81:
-#line 1440 "grammar.y" /* yacc.c:1646  */
+#line 1443 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.expression) = (yyvsp[-1].expression);
       }
-#line 3090 "grammar.c" /* yacc.c:1646  */
+#line 3093 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 82:
-#line 1447 "grammar.y" /* yacc.c:1646  */
+#line 1450 "grammar.y" /* yacc.c:1646  */
     { (yyval.integer) = INTEGER_SET_ENUMERATION; }
-#line 3096 "grammar.c" /* yacc.c:1646  */
+#line 3099 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 83:
-#line 1448 "grammar.y" /* yacc.c:1646  */
+#line 1451 "grammar.y" /* yacc.c:1646  */
     { (yyval.integer) = INTEGER_SET_RANGE; }
-#line 3102 "grammar.c" /* yacc.c:1646  */
+#line 3105 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 84:
-#line 1454 "grammar.y" /* yacc.c:1646  */
+#line 1457 "grammar.y" /* yacc.c:1646  */
     {
         if ((yyvsp[-3].expression).type != EXPRESSION_TYPE_INTEGER)
         {
@@ -3120,11 +3123,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3124 "grammar.c" /* yacc.c:1646  */
+#line 3127 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 85:
-#line 1476 "grammar.y" /* yacc.c:1646  */
+#line 1479 "grammar.y" /* yacc.c:1646  */
     {
         if ((yyvsp[0].expression).type != EXPRESSION_TYPE_INTEGER)
         {
@@ -3136,11 +3139,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3140 "grammar.c" /* yacc.c:1646  */
+#line 3143 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 86:
-#line 1488 "grammar.y" /* yacc.c:1646  */
+#line 1491 "grammar.y" /* yacc.c:1646  */
     {
         if ((yyvsp[0].expression).type != EXPRESSION_TYPE_INTEGER)
         {
@@ -3151,77 +3154,77 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3155 "grammar.c" /* yacc.c:1646  */
+#line 3158 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 87:
-#line 1503 "grammar.y" /* yacc.c:1646  */
+#line 1506 "grammar.y" /* yacc.c:1646  */
     {
         // Push end-of-list marker
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
       }
-#line 3164 "grammar.c" /* yacc.c:1646  */
+#line 3167 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 89:
-#line 1509 "grammar.y" /* yacc.c:1646  */
+#line 1512 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
         yr_parser_emit_pushes_for_strings(yyscanner, "$*");
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3175 "grammar.c" /* yacc.c:1646  */
+#line 3178 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 92:
-#line 1526 "grammar.y" /* yacc.c:1646  */
+#line 1529 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[0].c_string));
         yr_free((yyvsp[0].c_string));
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3186 "grammar.c" /* yacc.c:1646  */
+#line 3189 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 93:
-#line 1533 "grammar.y" /* yacc.c:1646  */
+#line 1536 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[0].c_string));
         yr_free((yyvsp[0].c_string));
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3197 "grammar.c" /* yacc.c:1646  */
+#line 3200 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 95:
-#line 1545 "grammar.y" /* yacc.c:1646  */
+#line 1548 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
       }
-#line 3205 "grammar.c" /* yacc.c:1646  */
+#line 3208 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 96:
-#line 1549 "grammar.y" /* yacc.c:1646  */
+#line 1552 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, 1, NULL, NULL);
       }
-#line 3213 "grammar.c" /* yacc.c:1646  */
+#line 3216 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 97:
-#line 1557 "grammar.y" /* yacc.c:1646  */
+#line 1560 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.expression) = (yyvsp[-1].expression);
       }
-#line 3221 "grammar.c" /* yacc.c:1646  */
+#line 3224 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 98:
-#line 1561 "grammar.y" /* yacc.c:1646  */
+#line 1564 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit(
             yyscanner, OP_FILESIZE, NULL);
@@ -3231,11 +3234,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3235 "grammar.c" /* yacc.c:1646  */
+#line 3238 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 99:
-#line 1571 "grammar.y" /* yacc.c:1646  */
+#line 1574 "grammar.y" /* yacc.c:1646  */
     {
         yywarning(yyscanner,
             "Using deprecated \"entrypoint\" keyword. Use the \"entry_point\" "
@@ -3249,11 +3252,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3253 "grammar.c" /* yacc.c:1646  */
+#line 3256 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 100:
-#line 1585 "grammar.y" /* yacc.c:1646  */
+#line 1588 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-1].expression), EXPRESSION_TYPE_INTEGER, "intXXXX or uintXXXX");
 
@@ -3269,11 +3272,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3273 "grammar.c" /* yacc.c:1646  */
+#line 3276 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 101:
-#line 1601 "grammar.y" /* yacc.c:1646  */
+#line 1604 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, (yyvsp[0].integer), NULL, NULL);
@@ -3283,11 +3286,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = (yyvsp[0].integer);
       }
-#line 3287 "grammar.c" /* yacc.c:1646  */
+#line 3290 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 102:
-#line 1611 "grammar.y" /* yacc.c:1646  */
+#line 1614 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg_double(
             yyscanner, OP_PUSH, (yyvsp[0].double_), NULL, NULL);
@@ -3296,11 +3299,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
       }
-#line 3300 "grammar.c" /* yacc.c:1646  */
+#line 3303 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 103:
-#line 1620 "grammar.y" /* yacc.c:1646  */
+#line 1623 "grammar.y" /* yacc.c:1646  */
     {
         SIZED_STRING* sized_string;
 
@@ -3325,11 +3328,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_STRING;
         (yyval.expression).value.sized_string = sized_string;
       }
-#line 3329 "grammar.c" /* yacc.c:1646  */
+#line 3332 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 104:
-#line 1645 "grammar.y" /* yacc.c:1646  */
+#line 1648 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner, (yyvsp[0].c_string), OP_COUNT, UNDEFINED);
@@ -3341,11 +3344,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3345 "grammar.c" /* yacc.c:1646  */
+#line 3348 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 105:
-#line 1657 "grammar.y" /* yacc.c:1646  */
+#line 1660 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner, (yyvsp[-3].c_string), OP_OFFSET, UNDEFINED);
@@ -3357,11 +3360,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3361 "grammar.c" /* yacc.c:1646  */
+#line 3364 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 106:
-#line 1669 "grammar.y" /* yacc.c:1646  */
+#line 1672 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, 1, NULL, NULL);
@@ -3377,11 +3380,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3381 "grammar.c" /* yacc.c:1646  */
+#line 3384 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 107:
-#line 1685 "grammar.y" /* yacc.c:1646  */
+#line 1688 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner, (yyvsp[-3].c_string), OP_LENGTH, UNDEFINED);
@@ -3393,11 +3396,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3397 "grammar.c" /* yacc.c:1646  */
+#line 3400 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 108:
-#line 1697 "grammar.y" /* yacc.c:1646  */
+#line 1700 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, 1, NULL, NULL);
@@ -3413,11 +3416,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3417 "grammar.c" /* yacc.c:1646  */
+#line 3420 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 109:
-#line 1713 "grammar.y" /* yacc.c:1646  */
+#line 1716 "grammar.y" /* yacc.c:1646  */
     {
         if ((yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER)  // loop identifier
         {
@@ -3462,11 +3465,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3466 "grammar.c" /* yacc.c:1646  */
+#line 3469 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 110:
-#line 1758 "grammar.y" /* yacc.c:1646  */
+#line 1761 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER | EXPRESSION_TYPE_FLOAT, "-");
 
@@ -3485,11 +3488,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3489 "grammar.c" /* yacc.c:1646  */
+#line 3492 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 111:
-#line 1777 "grammar.y" /* yacc.c:1646  */
+#line 1780 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "+", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3507,11 +3510,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
         }
       }
-#line 3511 "grammar.c" /* yacc.c:1646  */
+#line 3514 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 112:
-#line 1795 "grammar.y" /* yacc.c:1646  */
+#line 1798 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "-", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3529,11 +3532,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
         }
       }
-#line 3533 "grammar.c" /* yacc.c:1646  */
+#line 3536 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 113:
-#line 1813 "grammar.y" /* yacc.c:1646  */
+#line 1816 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "*", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3551,11 +3554,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
         }
       }
-#line 3555 "grammar.c" /* yacc.c:1646  */
+#line 3558 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 114:
-#line 1831 "grammar.y" /* yacc.c:1646  */
+#line 1834 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "\\", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3581,11 +3584,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
         }
       }
-#line 3585 "grammar.c" /* yacc.c:1646  */
+#line 3588 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 115:
-#line 1857 "grammar.y" /* yacc.c:1646  */
+#line 1860 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "%");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "%");
@@ -3603,11 +3606,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           ERROR_IF(compiler->last_result != ERROR_SUCCESS);
         }
       }
-#line 3607 "grammar.c" /* yacc.c:1646  */
+#line 3610 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 116:
-#line 1875 "grammar.y" /* yacc.c:1646  */
+#line 1878 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^");
@@ -3617,11 +3620,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(^, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3621 "grammar.c" /* yacc.c:1646  */
+#line 3624 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 117:
-#line 1885 "grammar.y" /* yacc.c:1646  */
+#line 1888 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^");
@@ -3631,11 +3634,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(&, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3635 "grammar.c" /* yacc.c:1646  */
+#line 3638 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 118:
-#line 1895 "grammar.y" /* yacc.c:1646  */
+#line 1898 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "|");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "|");
@@ -3645,11 +3648,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(|, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3649 "grammar.c" /* yacc.c:1646  */
+#line 3652 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 119:
-#line 1905 "grammar.y" /* yacc.c:1646  */
+#line 1908 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "~");
 
@@ -3659,11 +3662,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).value.integer = ((yyvsp[0].expression).value.integer == UNDEFINED) ?
             UNDEFINED : ~((yyvsp[0].expression).value.integer);
       }
-#line 3663 "grammar.c" /* yacc.c:1646  */
+#line 3666 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 120:
-#line 1915 "grammar.y" /* yacc.c:1646  */
+#line 1918 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "<<");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "<<");
@@ -3673,11 +3676,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(<<, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3677 "grammar.c" /* yacc.c:1646  */
+#line 3680 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 121:
-#line 1925 "grammar.y" /* yacc.c:1646  */
+#line 1928 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, ">>");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, ">>");
@@ -3687,19 +3690,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(>>, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3691 "grammar.c" /* yacc.c:1646  */
+#line 3694 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 122:
-#line 1935 "grammar.y" /* yacc.c:1646  */
+#line 1938 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.expression) = (yyvsp[0].expression);
       }
-#line 3699 "grammar.c" /* yacc.c:1646  */
+#line 3702 "grammar.c" /* yacc.c:1646  */
     break;
 
 
-#line 3703 "grammar.c" /* yacc.c:1646  */
+#line 3706 "grammar.c" /* yacc.c:1646  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -3927,5 +3930,5 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 #endif
   return yyresult;
 }
-#line 1940 "grammar.y" /* yacc.c:1906  */
+#line 1943 "grammar.y" /* yacc.c:1906  */
 
diff --git a/libyara/grammar.y b/libyara/grammar.y
index be24307..addb55d 100644
--- a/libyara/grammar.y
+++ b/libyara/grammar.y
@@ -1017,8 +1017,11 @@ expression
       }
     | _FOR_ for_expression error
       {
-        compiler->loop_depth--;
-        compiler->loop_identifier[compiler->loop_depth] = NULL;
+        if (compiler->loop_depth > 0)
+        {
+          compiler->loop_depth--;
+          compiler->loop_identifier[compiler->loop_depth] = NULL;
+        }
       }
     | _FOR_ for_expression _IDENTIFIER_ _IN_
       {

From b9ca16ab1c5c11461c3cdd929dacafe5d74a72f0 Mon Sep 17 00:00:00 2001
From: Hilko Bengen <bengen@hilluzination.de>
Date: Tue, 15 Nov 2016 00:17:56 +0100
Subject: [PATCH 26/36] Add support for big-endian ELF files (#560)

cherry picked from:

- c9c0dfb61ed5b27bdad3433d1e8d095f2f0c5684
- 79316a3b911b4ccfda0b3961d26523f0fd8ccfd5, "Minor re-styling"
---
 libyara/modules/elf.c | 211 +++++++++++++++++++++++++++++++-------------------
 1 file changed, 133 insertions(+), 78 deletions(-)

diff --git a/libyara/modules/elf.c b/libyara/modules/elf.c
index e934084..dff586e 100644
--- a/libyara/modules/elf.c
+++ b/libyara/modules/elf.c
@@ -37,8 +37,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #define MODULE_NAME elf
 
+#define CLASS_DATA(c,d) ((c << 8) | d)
 
-int get_elf_type(
+int get_elf_class_data(
     uint8_t* buffer,
     size_t buffer_length)
 {
@@ -51,7 +52,7 @@ int get_elf_type(
 
   if (yr_le32toh(elf_ident->magic) == ELF_MAGIC)
   {
-    return elf_ident->_class;
+    return CLASS_DATA(elf_ident->_class, elf_ident->data);
   }
   else
   {
@@ -59,15 +60,13 @@ int get_elf_type(
   }
 }
 
-#define SIZE_OF_SECTION_TABLE_32(h) \
-    (sizeof(elf32_section_header_t) * yr_le16toh(h->sh_entry_count))
+#define ELF_SIZE_OF_SECTION_TABLE(bits,bo,h)       \
+  (sizeof(elf##bits##_section_header_t) * yr_##bo##16toh(h->sh_entry_count))
 
-#define SIZE_OF_SECTION_TABLE_64(h) \
-    (sizeof(elf64_section_header_t) * yr_le16toh(h->sh_entry_count))
 
 
-#define ELF_RVA_TO_OFFSET(bits)                                                \
-uint64_t elf_rva_to_offset_##bits(                                             \
+#define ELF_RVA_TO_OFFSET(bits,bo)                                             \
+uint64_t elf_rva_to_offset_##bits##_##bo(                                      \
     elf##bits##_header_t* elf_header,                                          \
     uint64_t rva,                                                              \
     size_t elf_size)                                                           \
@@ -78,34 +77,34 @@ uint64_t elf_rva_to_offset_##bits(                                             \
                                                                                \
   /* check that sh_offset doesn't wrap when added to SIZE_OF_SECTION_TABLE */  \
                                                                                \
-  if(ULONG_MAX - yr_le##bits##toh(elf_header->sh_offset) <                     \
-     SIZE_OF_SECTION_TABLE_##bits(elf_header))                                 \
+  if(ULONG_MAX - yr_##bo##bits##toh(elf_header->sh_offset) <                   \
+     ELF_SIZE_OF_SECTION_TABLE(bits,bo,elf_header))                            \
   {                                                                            \
     return UNDEFINED;                                                          \
   }                                                                            \
                                                                                \
-  if (yr_le##bits##toh(elf_header->sh_offset) == 0 ||                          \
-      yr_le##bits##toh(elf_header->sh_offset) > elf_size ||                    \
-      yr_le##bits##toh(elf_header->sh_offset) +                                \
-      SIZE_OF_SECTION_TABLE_##bits(elf_header) > elf_size ||                   \
-      yr_le16toh(elf_header->sh_entry_count) == 0)                             \
+  if (yr_##bo##bits##toh(elf_header->sh_offset) == 0 ||                        \
+      yr_##bo##bits##toh(elf_header->sh_offset) > elf_size ||                  \
+      yr_##bo##bits##toh(elf_header->sh_offset) +                              \
+        ELF_SIZE_OF_SECTION_TABLE(bits,bo,elf_header) > elf_size ||            \
+      yr_##bo##16toh(elf_header->sh_entry_count) == 0)                         \
   {                                                                            \
     return UNDEFINED;                                                          \
   }                                                                            \
                                                                                \
   section = (elf##bits##_section_header_t*)                                    \
-      ((uint8_t*) elf_header + yr_le##bits##toh(elf_header->sh_offset));       \
+      ((uint8_t*) elf_header + yr_##bo##bits##toh(elf_header->sh_offset));     \
                                                                                \
-  for (i = 0; i < yr_le16toh(elf_header->sh_entry_count); i++)                 \
+  for (i = 0; i < yr_##bo##16toh(elf_header->sh_entry_count); i++)             \
   {                                                                            \
-    if (yr_le32toh(section->type) != ELF_SHT_NULL &&                           \
-        yr_le32toh(section->type) != ELF_SHT_NOBITS &&                         \
-        rva >= yr_le##bits##toh(section->addr) &&                              \
-        rva < yr_le##bits##toh(section->addr) +                                \
-        yr_le##bits##toh(section->size))                                       \
+    if (yr_##bo##32toh(section->type) != ELF_SHT_NULL &&                       \
+        yr_##bo##32toh(section->type) != ELF_SHT_NOBITS &&                     \
+        rva >= yr_##bo##bits##toh(section->addr) &&                            \
+        rva < yr_##bo##bits##toh(section->addr) +                              \
+          yr_##bo##bits##toh(section->size))                                   \
     {                                                                          \
-      return yr_le##bits##toh(section->offset) +                               \
-        (rva - yr_le##bits##toh(section->addr));                               \
+      return yr_##bo##bits##toh(section->offset) +                             \
+        (rva - yr_##bo##bits##toh(section->addr));                             \
     }                                                                          \
                                                                                \
     section++;                                                                 \
@@ -114,8 +113,8 @@ uint64_t elf_rva_to_offset_##bits(                                             \
   return UNDEFINED;                                                            \
 }
 
-#define PARSE_ELF_HEADER(bits)                                                 \
-void parse_elf_header_##bits(                                                  \
+#define PARSE_ELF_HEADER(bits,bo)                                              \
+void parse_elf_header_##bits##_##bo(                                           \
   elf##bits##_header_t* elf,                                                   \
   size_t base_address,                                                         \
   size_t elf_size,                                                             \
@@ -127,56 +126,67 @@ void parse_elf_header_##bits(                                                  \
   elf##bits##_section_header_t* section;                                       \
   elf##bits##_program_header_t* segment;                                       \
                                                                                \
-  set_integer(yr_le16toh(elf->type), elf_obj, "type");                         \
-  set_integer(yr_le16toh(elf->machine), elf_obj, "machine");                   \
-  set_integer(yr_le##bits##toh(elf->sh_offset), elf_obj, "sh_offset");         \
-  set_integer(yr_le16toh(elf->sh_entry_size), elf_obj, "sh_entry_size");       \
-  set_integer(yr_le16toh(elf->sh_entry_count), elf_obj, "number_of_sections"); \
-  set_integer(yr_le##bits##toh(elf->ph_offset), elf_obj, "ph_offset");         \
-  set_integer(yr_le16toh(elf->ph_entry_size), elf_obj, "ph_entry_size");       \
-  set_integer(yr_le16toh(elf->ph_entry_count), elf_obj, "number_of_segments"); \
+  set_integer(yr_##bo##16toh(elf->type), elf_obj, "type");                     \
+  set_integer(yr_##bo##16toh(elf->machine), elf_obj, "machine");               \
+  set_integer(yr_##bo##bits##toh(elf->sh_offset), elf_obj,                     \
+              "sh_offset");                                                    \
+  set_integer(yr_##bo##16toh(elf->sh_entry_size), elf_obj,                     \
+              "sh_entry_size");                                                \
+  set_integer(yr_##bo##16toh(elf->sh_entry_count), elf_obj,                    \
+              "number_of_sections");                                           \
+  set_integer(yr_##bo##bits##toh(elf->ph_offset), elf_obj,                     \
+              "ph_offset");                                                    \
+  set_integer(yr_##bo##16toh(elf->ph_entry_size), elf_obj,                     \
+              "ph_entry_size");                                                \
+  set_integer(yr_##bo##16toh(elf->ph_entry_count), elf_obj,                    \
+              "number_of_segments");                                           \
                                                                                \
-  if (yr_le##bits##toh(elf->entry) != 0)                                       \
+  if (yr_##bo##bits##toh(elf->entry) != 0)                                     \
   {                                                                            \
     set_integer(                                                               \
         flags & SCAN_FLAGS_PROCESS_MEMORY ?                                    \
-        base_address + yr_le##bits##toh(elf->entry) :                          \
-        elf_rva_to_offset_##bits(elf, yr_le##bits##toh(elf->entry), elf_size), \
+        base_address + yr_##bo##bits##toh(elf->entry) :                        \
+        elf_rva_to_offset_##bits##_##bo(                                       \
+            elf, yr_##bo##bits##toh(elf->entry), elf_size),                    \
         elf_obj, "entry_point");                                               \
   }                                                                            \
                                                                                \
-  if (yr_le16toh(elf->sh_entry_count) < ELF_SHN_LORESERVE &&                   \
-      yr_le16toh(elf->sh_str_table_index) < yr_le16toh(elf->sh_entry_count) && \
-      yr_le##bits##toh(elf->sh_offset) < elf_size &&                           \
-      yr_le##bits##toh(elf->sh_offset) + yr_le16toh(elf->sh_entry_count) *     \
-         sizeof(elf##bits##_section_header_t) <= elf_size)                     \
+  if (yr_##bo##16toh(elf->sh_entry_count) < ELF_SHN_LORESERVE &&               \
+      yr_##bo##16toh(elf->sh_str_table_index) <                                \
+        yr_##bo##16toh(elf->sh_entry_count) &&                                 \
+      yr_##bo##bits##toh(elf->sh_offset) < elf_size &&                         \
+      yr_##bo##bits##toh(elf->sh_offset) +                                     \
+        yr_##bo##16toh(elf->sh_entry_count) *                                  \
+        sizeof(elf##bits##_section_header_t) <= elf_size)                      \
   {                                                                            \
     char* str_table = NULL;                                                    \
                                                                                \
     section = (elf##bits##_section_header_t*)                                  \
-      ((uint8_t*) elf + yr_le##bits##toh(elf->sh_offset));                     \
+      ((uint8_t*) elf + yr_##bo##bits##toh(elf->sh_offset));                   \
                                                                                \
-    if (section[yr_le16toh(elf->sh_str_table_index)].offset < elf_size)        \
-      str_table = (char*) elf +                                                \
-        yr_le##bits##toh(section[yr_le16toh(elf->sh_str_table_index)].offset); \
+    if (section[yr_##bo##16toh(elf->sh_str_table_index)].offset < elf_size)    \
+    {                                                                          \
+      str_table = (char*) elf + yr_##bo##bits##toh(                            \
+          section[yr_##bo##16toh(elf->sh_str_table_index)].offset);            \
+    }                                                                          \
                                                                                \
-    for (i = 0; i < yr_le16toh(elf->sh_entry_count); i++)                      \
+    for (i = 0; i < yr_##bo##16toh(elf->sh_entry_count); i++)                  \
     {                                                                          \
-      set_integer(yr_le32toh(section->type), elf_obj,                          \
+      set_integer(yr_##bo##32toh(section->type), elf_obj,                      \
                   "sections[%i].type", i);                                     \
-      set_integer(yr_le32toh(section->flags), elf_obj,                         \
+      set_integer(yr_##bo##32toh(section->flags), elf_obj,                     \
                   "sections[%i].flags", i);                                    \
-      set_integer(yr_le##bits##toh(section->size), elf_obj,                    \
+      set_integer(yr_##bo##bits##toh(section->size), elf_obj,                  \
                   "sections[%i].size", i);                                     \
-      set_integer(yr_le##bits##toh(section->offset), elf_obj,                  \
+      set_integer(yr_##bo##bits##toh(section->offset), elf_obj,                \
                   "sections[%i].offset", i);                                   \
                                                                                \
-      if (yr_le##bits##toh(section->name) < elf_size &&                        \
+      if (yr_##bo##bits##toh(section->name) < elf_size &&                      \
           str_table > (char*) elf &&                                           \
-          str_table + yr_le##bits##toh(section->name) <                        \
-          (char*) elf + elf_size)                                              \
+          str_table + yr_##bo##bits##toh(section->name) <                      \
+            (char*) elf + elf_size)                                            \
       {                                                                        \
-        set_string(str_table + yr_le##bits##toh(section->name), elf_obj,       \
+        set_string(str_table + yr_##bo##bits##toh(section->name), elf_obj,     \
                    "sections[%i].name", i);                                    \
       }                                                                        \
                                                                                \
@@ -184,38 +194,39 @@ void parse_elf_header_##bits(                                                  \
     }                                                                          \
   }                                                                            \
                                                                                \
-  if (yr_le16toh(elf->ph_entry_count) > 0 &&                                   \
-      yr_le16toh(elf->ph_entry_count) < ELF_PN_XNUM &&                         \
-      yr_le##bits##toh(elf->ph_offset) < elf_size &&                           \
-      yr_le##bits##toh(elf->ph_offset) + yr_le16toh(elf->ph_entry_count) *     \
+  if (yr_##bo##16toh(elf->ph_entry_count) > 0 &&                               \
+      yr_##bo##16toh(elf->ph_entry_count) < ELF_PN_XNUM &&                     \
+      yr_##bo##bits##toh(elf->ph_offset) < elf_size &&                         \
+      yr_##bo##bits##toh(elf->ph_offset) +                                     \
+        yr_##bo##16toh(elf->ph_entry_count) *                                  \
         sizeof(elf##bits##_program_header_t) <= elf_size)                      \
   {                                                                            \
     segment = (elf##bits##_program_header_t*)                                  \
-      ((uint8_t*) elf + yr_le##bits##toh(elf->ph_offset));                     \
+      ((uint8_t*) elf + yr_##bo##bits##toh(elf->ph_offset));                   \
                                                                                \
-    for (i = 0; i < yr_le16toh(elf->ph_entry_count); i++)                      \
+    for (i = 0; i < yr_##bo##16toh(elf->ph_entry_count); i++)                  \
     {                                                                          \
       set_integer(                                                             \
-          yr_le32toh(segment->type), elf_obj, "segments[%i].type", i);         \
+          yr_##bo##32toh(segment->type), elf_obj, "segments[%i].type", i);     \
       set_integer(                                                             \
-          yr_le32toh(segment->flags), elf_obj, "segments[%i].flags", i);       \
+          yr_##bo##32toh(segment->flags), elf_obj, "segments[%i].flags", i);   \
       set_integer(                                                             \
-          yr_le##bits##toh(segment->offset), elf_obj,                          \
+          yr_##bo##bits##toh(segment->offset), elf_obj,                        \
           "segments[%i].offset", i);                                           \
       set_integer(                                                             \
-          yr_le##bits##toh(segment->virt_addr), elf_obj,                       \
+          yr_##bo##bits##toh(segment->virt_addr), elf_obj,                     \
           "segments[%i].virtual_address", i);                                  \
       set_integer(                                                             \
-          yr_le##bits##toh(segment->phys_addr), elf_obj,                       \
+          yr_##bo##bits##toh(segment->phys_addr), elf_obj,                     \
           "segments[%i].physical_address", i);                                 \
       set_integer(                                                             \
-          yr_le##bits##toh(segment->file_size), elf_obj,                       \
+          yr_##bo##bits##toh(segment->file_size), elf_obj,                     \
           "segments[%i].file_size", i);                                        \
       set_integer(                                                             \
-          yr_le##bits##toh(segment->mem_size), elf_obj,                        \
+          yr_##bo##bits##toh(segment->mem_size), elf_obj,                      \
           "segments[%i].memory_size", i);                                      \
       set_integer(                                                             \
-          yr_le##bits##toh(segment->alignment), elf_obj,                       \
+          yr_##bo##bits##toh(segment->alignment), elf_obj,                     \
           "segments[%i].alignment", i);                                        \
                                                                                \
       segment++;                                                               \
@@ -224,12 +235,16 @@ void parse_elf_header_##bits(                                                  \
 }
 
 
-ELF_RVA_TO_OFFSET(32);
-ELF_RVA_TO_OFFSET(64);
+ELF_RVA_TO_OFFSET(32,le);
+ELF_RVA_TO_OFFSET(64,le);
+ELF_RVA_TO_OFFSET(32,be);
+ELF_RVA_TO_OFFSET(64,be);
 
 
-PARSE_ELF_HEADER(32);
-PARSE_ELF_HEADER(64);
+PARSE_ELF_HEADER(32,le);
+PARSE_ELF_HEADER(64,le);
+PARSE_ELF_HEADER(32,be);
+PARSE_ELF_HEADER(64,be);
 
 
 begin_declarations;
@@ -407,9 +422,9 @@ int module_load(
     if (block_data == NULL)
       continue;
 
-    switch(get_elf_type(block_data, block->size))
+    switch(get_elf_class_data(block_data, block->size))
     {
-      case ELF_CLASS_32:
+      case CLASS_DATA(ELF_CLASS_32, ELF_DATA_2LSB):
 
         if (block->size > sizeof(elf32_header_t))
         {
@@ -418,7 +433,27 @@ int module_load(
           if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
               yr_le16toh(elf_header32->type) == ELF_ET_EXEC)
           {
-            parse_elf_header_32(
+            parse_elf_header_32_le(
+                elf_header32,
+                block->base,
+                block->size,
+                context->flags,
+                module_object);
+          }
+        }
+
+        break;
+
+      case CLASS_DATA(ELF_CLASS_32, ELF_DATA_2MSB):
+
+        if (block->size > sizeof(elf32_header_t))
+        {
+          elf_header32 = (elf32_header_t*) block_data;
+
+          if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
+              yr_be16toh(elf_header32->type) == ELF_ET_EXEC)
+          {
+            parse_elf_header_32_be(
                 elf_header32,
                 block->base,
                 block->size,
@@ -429,7 +464,7 @@ int module_load(
 
         break;
 
-      case ELF_CLASS_64:
+      case CLASS_DATA(ELF_CLASS_64,ELF_DATA_2LSB):
 
         if (block->size > sizeof(elf64_header_t))
         {
@@ -438,7 +473,27 @@ int module_load(
           if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
               yr_le16toh(elf_header64->type) == ELF_ET_EXEC)
           {
-            parse_elf_header_64(
+            parse_elf_header_64_le(
+                elf_header64,
+                block->base,
+                block->size,
+                context->flags,
+                module_object);
+          }
+        }
+
+        break;
+
+      case CLASS_DATA(ELF_CLASS_64,ELF_DATA_2MSB):
+
+        if (block->size > sizeof(elf64_header_t))
+        {
+          elf_header64 = (elf64_header_t*) block_data;
+
+          if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) ||
+              yr_be16toh(elf_header64->type) == ELF_ET_EXEC)
+          {
+            parse_elf_header_64_be(
                 elf_header64,
                 block->base,
                 block->size,

From c221d4bb820a6005a7b9da44499ce4829f7cf591 Mon Sep 17 00:00:00 2001
From: Hilko Bengen <hillu@users.noreply.github.com>
Date: Tue, 17 Jan 2017 17:07:02 +0100
Subject: [PATCH 27/36] re_lexer: Make reading escape sequences more robust
 (#586)

* Add test for issue #503

* re_lexer: Make reading escape sequences more robust

This commit fixes parsing incomplete escape sequences at the end of a
regular expression and parsing things like \xxy (invalid hex digits)
which before were silently turned into (char)255.

Close #503

* Update re_lexer.c

(cherry picked from commit 3119b232c9c453c98d8fa8b6ae4e37ba18117cd4)
---
 libyara/re_lexer.c | 22 +++++++++++-----------
 libyara/re_lexer.l | 12 ++++++------
 tests/test-rules.c |  6 ++++++
 3 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/libyara/re_lexer.c b/libyara/re_lexer.c
index 6d784e6..388a5c6 100644
--- a/libyara/re_lexer.c
+++ b/libyara/re_lexer.c
@@ -243,7 +243,7 @@ struct yy_buffer_state
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
 	 */
-	yy_size_t yy_n_chars;
+	int yy_n_chars;
 
 	/* Whether we "own" the buffer - i.e., we know we created it,
 	 * and can realloc() it to grow it, and should free() it to
@@ -612,7 +612,7 @@ struct yyguts_t
     size_t yy_buffer_stack_max; /**< capacity of stack. */
     YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
     char yy_hold_char;
-    yy_size_t yy_n_chars;
+    int yy_n_chars;
     yy_size_t yyleng_r;
     char *yy_c_buf_p;
     int yy_init;
@@ -1125,7 +1125,7 @@ YY_RULE_SETUP
   }
   else
   {
-    yyerror(yyscanner, lex_env, "unexpected end of buffer");
+    yyerror(yyscanner, lex_env, "illegal escape sequence");
     yyterminate();
   }
 }
@@ -1180,7 +1180,7 @@ YY_RULE_SETUP
   {
     if (!read_escaped_char(yyscanner, &end))
     {
-      yyerror(yyscanner, lex_env, "unexpected end of buffer");
+      yyerror(yyscanner, lex_env, "illegal escape sequence");
       yyterminate();
     }
   }
@@ -1292,7 +1292,7 @@ YY_RULE_SETUP
   }
   else
   {
-    yyerror(yyscanner, lex_env, "unexpected end of buffer");
+    yyerror(yyscanner, lex_env, "illegal escape sequence");
     yyterminate();
   }
 }
@@ -1610,9 +1610,9 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 	else
 		ret_val = EOB_ACT_CONTINUE_SCAN;
 
-	if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+	if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
 		/* Extend the array by 50%, plus the number we really need. */
-		yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+		int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
 		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) re_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
 		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
 			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
@@ -2012,7 +2012,7 @@ static void re_yyensure_buffer_stack (yyscan_t yyscanner)
 		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
 		 * immediate realloc on the next call.
          */
-		num_to_alloc = 1; // After all that talk, this was set to 1 anyways...
+		num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
 		yyg->yy_buffer_stack = (struct yy_buffer_state**)re_yyalloc
 								(num_to_alloc * sizeof(struct yy_buffer_state*)
 								, yyscanner);
@@ -2568,19 +2568,19 @@ int read_escaped_char(
   text[0] = '\\';
   text[1] = RE_YY_INPUT(yyscanner);
 
-  if (text[1] == EOF)
+  if (text[1] == EOF || text[1] == 0)
     return 0;
 
   if (text[1] == 'x')
   {
     text[2] = RE_YY_INPUT(yyscanner);
 
-    if (text[2] == EOF)
+    if (!isxdigit(text[2]))
       return 0;
 
     text[3] = RE_YY_INPUT(yyscanner);
 
-    if (text[3] == EOF)
+    if (!isxdigit(text[3]))
       return 0;
   }
 
diff --git a/libyara/re_lexer.l b/libyara/re_lexer.l
index b3744a3..ecb6ad4 100644
--- a/libyara/re_lexer.l
+++ b/libyara/re_lexer.l
@@ -261,7 +261,7 @@ hex_digit     [0-9a-fA-F]
   }
   else
   {
-    yyerror(yyscanner, lex_env, "unexpected end of buffer");
+    yyerror(yyscanner, lex_env, "illegal escape sequence");
     yyterminate();
   }
 }
@@ -312,7 +312,7 @@ hex_digit     [0-9a-fA-F]
   {
     if (!read_escaped_char(yyscanner, &end))
     {
-      yyerror(yyscanner, lex_env, "unexpected end of buffer");
+      yyerror(yyscanner, lex_env, "illegal escape sequence");
       yyterminate();
     }
   }
@@ -410,7 +410,7 @@ hex_digit     [0-9a-fA-F]
   }
   else
   {
-    yyerror(yyscanner, lex_env, "unexpected end of buffer");
+    yyerror(yyscanner, lex_env, "illegal escape sequence");
     yyterminate();
   }
 }
@@ -524,19 +524,19 @@ int read_escaped_char(
   text[0] = '\\';
   text[1] = RE_YY_INPUT(yyscanner);
 
-  if (text[1] == EOF)
+  if (text[1] == EOF || text[1] == 0)
     return 0;
 
   if (text[1] == 'x')
   {
     text[2] = RE_YY_INPUT(yyscanner);
 
-    if (text[2] == EOF)
+    if (!isxdigit(text[2]))
       return 0;
 
     text[3] = RE_YY_INPUT(yyscanner);
 
-    if (text[3] == EOF)
+    if (!isxdigit(text[3]))
       return 0;
   }
 
diff --git a/tests/test-rules.c b/tests/test-rules.c
index 19a0902..d4e8f1c 100644
--- a/tests/test-rules.c
+++ b/tests/test-rules.c
@@ -1013,6 +1013,12 @@ void test_re()
 
   // Test case for issue #324
   assert_true_regexp("whatever|   x.   x", "   xy   x", "   xy   x");
+
+  // test case for issue #503, \x without two following hex-digits
+  assert_regexp_syntax_error("\\x0");
+  assert_regexp_syntax_error("\\x");
+
+  assert_regexp_syntax_error("\\xxy");
 }
 
 

From c869ac16178d10ffdc3d3eeb1931dfb08262525b Mon Sep 17 00:00:00 2001
From: plusvic <plusvic@gmail.com>
Date: Mon, 23 Jan 2017 18:08:51 +0100
Subject: [PATCH 28/36] Fix issue #597

(cherry picked from commit ab906da53ff2a68c6fd6d1fa73f2b7c7bf0bc636)
---
 libyara/grammar.c | 296 ++++++++++++++++++++++++++++--------------------------
 libyara/grammar.y |   6 ++
 2 files changed, 157 insertions(+), 145 deletions(-)

diff --git a/libyara/grammar.c b/libyara/grammar.c
index 9c79512..6d4ba05 100644
--- a/libyara/grammar.c
+++ b/libyara/grammar.c
@@ -611,14 +611,14 @@ static const yytype_uint16 yyrline[] =
      347,   353,   356,   374,   387,   424,   425,   430,   446,   459,
      472,   485,   502,   503,   509,   508,   524,   523,   539,   553,
      554,   559,   560,   561,   562,   567,   652,   698,   756,   801,
-     802,   806,   831,   867,   913,   935,   944,   953,   968,   980,
-     994,  1007,  1018,  1027,  1057,  1026,  1171,  1170,  1249,  1255,
-    1262,  1261,  1324,  1323,  1384,  1393,  1402,  1411,  1420,  1429,
-    1438,  1442,  1450,  1451,  1456,  1478,  1490,  1506,  1505,  1511,
-    1522,  1523,  1528,  1535,  1546,  1547,  1551,  1559,  1563,  1573,
-    1587,  1603,  1613,  1622,  1647,  1659,  1671,  1687,  1699,  1715,
-    1760,  1779,  1797,  1815,  1833,  1859,  1877,  1887,  1897,  1907,
-    1917,  1927,  1937
+     802,   806,   833,   871,   917,   939,   948,   957,   972,   984,
+     998,  1011,  1022,  1033,  1063,  1032,  1177,  1176,  1255,  1261,
+    1268,  1267,  1330,  1329,  1390,  1399,  1408,  1417,  1426,  1435,
+    1444,  1448,  1456,  1457,  1462,  1484,  1496,  1512,  1511,  1517,
+    1528,  1529,  1534,  1541,  1552,  1553,  1557,  1565,  1569,  1579,
+    1593,  1609,  1619,  1628,  1653,  1665,  1677,  1693,  1705,  1721,
+    1766,  1785,  1803,  1821,  1839,  1865,  1883,  1893,  1903,  1913,
+    1923,  1933,  1943
 };
 #endif
 
@@ -2361,15 +2361,17 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           case EXPRESSION_TYPE_REGEXP:
             strlcpy((yyval.c_string), "r", MAX_FUNCTION_ARGS);
             break;
+          default:
+            assert(FALSE);
         }
 
         ERROR_IF((yyval.c_string) == NULL);
       }
-#line 2369 "grammar.c" /* yacc.c:1646  */
+#line 2371 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 52:
-#line 832 "grammar.y" /* yacc.c:1646  */
+#line 834 "grammar.y" /* yacc.c:1646  */
     {
         if (strlen((yyvsp[-2].c_string)) == MAX_FUNCTION_ARGS)
         {
@@ -2394,6 +2396,8 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
             case EXPRESSION_TYPE_REGEXP:
               strlcat((yyvsp[-2].c_string), "r", MAX_FUNCTION_ARGS);
               break;
+            default:
+              assert(FALSE);
           }
         }
 
@@ -2401,11 +2405,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.c_string) = (yyvsp[-2].c_string);
       }
-#line 2405 "grammar.c" /* yacc.c:1646  */
+#line 2409 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 53:
-#line 868 "grammar.y" /* yacc.c:1646  */
+#line 872 "grammar.y" /* yacc.c:1646  */
     {
         SIZED_STRING* sized_string = (yyvsp[0].sized_string);
         RE* re;
@@ -2447,11 +2451,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_REGEXP;
       }
-#line 2451 "grammar.c" /* yacc.c:1646  */
+#line 2455 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 54:
-#line 914 "grammar.y" /* yacc.c:1646  */
+#line 918 "grammar.y" /* yacc.c:1646  */
     {
         if ((yyvsp[0].expression).type == EXPRESSION_TYPE_STRING)
         {
@@ -2470,11 +2474,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2474 "grammar.c" /* yacc.c:1646  */
+#line 2478 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 55:
-#line 936 "grammar.y" /* yacc.c:1646  */
+#line 940 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, 1, NULL, NULL);
@@ -2483,11 +2487,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2487 "grammar.c" /* yacc.c:1646  */
+#line 2491 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 56:
-#line 945 "grammar.y" /* yacc.c:1646  */
+#line 949 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, 0, NULL, NULL);
@@ -2496,11 +2500,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2500 "grammar.c" /* yacc.c:1646  */
+#line 2504 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 57:
-#line 954 "grammar.y" /* yacc.c:1646  */
+#line 958 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_STRING, "matches");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_REGEXP, "matches");
@@ -2515,11 +2519,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2519 "grammar.c" /* yacc.c:1646  */
+#line 2523 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 58:
-#line 969 "grammar.y" /* yacc.c:1646  */
+#line 973 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_STRING, "contains");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_STRING, "contains");
@@ -2531,11 +2535,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2535 "grammar.c" /* yacc.c:1646  */
+#line 2539 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 59:
-#line 981 "grammar.y" /* yacc.c:1646  */
+#line 985 "grammar.y" /* yacc.c:1646  */
     {
         int result = yr_parser_reduce_string_identifier(
             yyscanner,
@@ -2549,11 +2553,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2553 "grammar.c" /* yacc.c:1646  */
+#line 2557 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 60:
-#line 995 "grammar.y" /* yacc.c:1646  */
+#line 999 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "at");
 
@@ -2566,11 +2570,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2570 "grammar.c" /* yacc.c:1646  */
+#line 2574 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 61:
-#line 1008 "grammar.y" /* yacc.c:1646  */
+#line 1012 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner, (yyvsp[-2].c_string), OP_FOUND_IN, UNDEFINED);
@@ -2581,23 +2585,25 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2585 "grammar.c" /* yacc.c:1646  */
+#line 2589 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 62:
-#line 1019 "grammar.y" /* yacc.c:1646  */
+#line 1023 "grammar.y" /* yacc.c:1646  */
     {
         if (compiler->loop_depth > 0)
         {
           compiler->loop_depth--;
           compiler->loop_identifier[compiler->loop_depth] = NULL;
         }
+
+        YYERROR;
       }
-#line 2597 "grammar.c" /* yacc.c:1646  */
+#line 2603 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 63:
-#line 1027 "grammar.y" /* yacc.c:1646  */
+#line 1033 "grammar.y" /* yacc.c:1646  */
     {
         int var_index;
 
@@ -2627,11 +2633,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 2631 "grammar.c" /* yacc.c:1646  */
+#line 2637 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 64:
-#line 1057 "grammar.y" /* yacc.c:1646  */
+#line 1063 "grammar.y" /* yacc.c:1646  */
     {
         int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth;
         uint8_t* addr;
@@ -2666,11 +2672,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         compiler->loop_identifier[compiler->loop_depth] = (yyvsp[-4].c_string);
         compiler->loop_depth++;
       }
-#line 2670 "grammar.c" /* yacc.c:1646  */
+#line 2676 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 65:
-#line 1092 "grammar.y" /* yacc.c:1646  */
+#line 1098 "grammar.y" /* yacc.c:1646  */
     {
         int mem_offset;
 
@@ -2749,11 +2755,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2753 "grammar.c" /* yacc.c:1646  */
+#line 2759 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 66:
-#line 1171 "grammar.y" /* yacc.c:1646  */
+#line 1177 "grammar.y" /* yacc.c:1646  */
     {
         int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth;
         uint8_t* addr;
@@ -2783,11 +2789,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         compiler->loop_identifier[compiler->loop_depth] = NULL;
         compiler->loop_depth++;
       }
-#line 2787 "grammar.c" /* yacc.c:1646  */
+#line 2793 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 67:
-#line 1201 "grammar.y" /* yacc.c:1646  */
+#line 1207 "grammar.y" /* yacc.c:1646  */
     {
         int mem_offset;
 
@@ -2836,31 +2842,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
 
       }
-#line 2840 "grammar.c" /* yacc.c:1646  */
+#line 2846 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 68:
-#line 1250 "grammar.y" /* yacc.c:1646  */
+#line 1256 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit(yyscanner, OP_OF, NULL);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2850 "grammar.c" /* yacc.c:1646  */
+#line 2856 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 69:
-#line 1256 "grammar.y" /* yacc.c:1646  */
+#line 1262 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit(yyscanner, OP_NOT, NULL);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2860 "grammar.c" /* yacc.c:1646  */
+#line 2866 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 70:
-#line 1262 "grammar.y" /* yacc.c:1646  */
+#line 1268 "grammar.y" /* yacc.c:1646  */
     {
         YR_FIXUP* fixup;
         void* jmp_destination_addr;
@@ -2886,11 +2892,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         fixup->next = compiler->fixup_stack_head;
         compiler->fixup_stack_head = fixup;
       }
-#line 2890 "grammar.c" /* yacc.c:1646  */
+#line 2896 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 71:
-#line 1288 "grammar.y" /* yacc.c:1646  */
+#line 1294 "grammar.y" /* yacc.c:1646  */
     {
         YR_FIXUP* fixup;
         uint8_t* and_addr;
@@ -2926,11 +2932,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2930 "grammar.c" /* yacc.c:1646  */
+#line 2936 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 72:
-#line 1324 "grammar.y" /* yacc.c:1646  */
+#line 1330 "grammar.y" /* yacc.c:1646  */
     {
         YR_FIXUP* fixup;
         void* jmp_destination_addr;
@@ -2955,11 +2961,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         fixup->next = compiler->fixup_stack_head;
         compiler->fixup_stack_head = fixup;
       }
-#line 2959 "grammar.c" /* yacc.c:1646  */
+#line 2965 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 73:
-#line 1349 "grammar.y" /* yacc.c:1646  */
+#line 1355 "grammar.y" /* yacc.c:1646  */
     {
         YR_FIXUP* fixup;
         uint8_t* or_addr;
@@ -2995,11 +3001,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 2999 "grammar.c" /* yacc.c:1646  */
+#line 3005 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 74:
-#line 1385 "grammar.y" /* yacc.c:1646  */
+#line 1391 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "<", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3008,11 +3014,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3012 "grammar.c" /* yacc.c:1646  */
+#line 3018 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 75:
-#line 1394 "grammar.y" /* yacc.c:1646  */
+#line 1400 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, ">", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3021,11 +3027,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3025 "grammar.c" /* yacc.c:1646  */
+#line 3031 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 76:
-#line 1403 "grammar.y" /* yacc.c:1646  */
+#line 1409 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "<=", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3034,11 +3040,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3038 "grammar.c" /* yacc.c:1646  */
+#line 3044 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 77:
-#line 1412 "grammar.y" /* yacc.c:1646  */
+#line 1418 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, ">=", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3047,11 +3053,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3051 "grammar.c" /* yacc.c:1646  */
+#line 3057 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 78:
-#line 1421 "grammar.y" /* yacc.c:1646  */
+#line 1427 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "==", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3060,11 +3066,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3064 "grammar.c" /* yacc.c:1646  */
+#line 3070 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 79:
-#line 1430 "grammar.y" /* yacc.c:1646  */
+#line 1436 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "!=", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3073,39 +3079,39 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN;
       }
-#line 3077 "grammar.c" /* yacc.c:1646  */
+#line 3083 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 80:
-#line 1439 "grammar.y" /* yacc.c:1646  */
+#line 1445 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.expression) = (yyvsp[0].expression);
       }
-#line 3085 "grammar.c" /* yacc.c:1646  */
+#line 3091 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 81:
-#line 1443 "grammar.y" /* yacc.c:1646  */
+#line 1449 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.expression) = (yyvsp[-1].expression);
       }
-#line 3093 "grammar.c" /* yacc.c:1646  */
+#line 3099 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 82:
-#line 1450 "grammar.y" /* yacc.c:1646  */
+#line 1456 "grammar.y" /* yacc.c:1646  */
     { (yyval.integer) = INTEGER_SET_ENUMERATION; }
-#line 3099 "grammar.c" /* yacc.c:1646  */
+#line 3105 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 83:
-#line 1451 "grammar.y" /* yacc.c:1646  */
+#line 1457 "grammar.y" /* yacc.c:1646  */
     { (yyval.integer) = INTEGER_SET_RANGE; }
-#line 3105 "grammar.c" /* yacc.c:1646  */
+#line 3111 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 84:
-#line 1457 "grammar.y" /* yacc.c:1646  */
+#line 1463 "grammar.y" /* yacc.c:1646  */
     {
         if ((yyvsp[-3].expression).type != EXPRESSION_TYPE_INTEGER)
         {
@@ -3123,11 +3129,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3127 "grammar.c" /* yacc.c:1646  */
+#line 3133 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 85:
-#line 1479 "grammar.y" /* yacc.c:1646  */
+#line 1485 "grammar.y" /* yacc.c:1646  */
     {
         if ((yyvsp[0].expression).type != EXPRESSION_TYPE_INTEGER)
         {
@@ -3139,11 +3145,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3143 "grammar.c" /* yacc.c:1646  */
+#line 3149 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 86:
-#line 1491 "grammar.y" /* yacc.c:1646  */
+#line 1497 "grammar.y" /* yacc.c:1646  */
     {
         if ((yyvsp[0].expression).type != EXPRESSION_TYPE_INTEGER)
         {
@@ -3154,77 +3160,77 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3158 "grammar.c" /* yacc.c:1646  */
+#line 3164 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 87:
-#line 1506 "grammar.y" /* yacc.c:1646  */
+#line 1512 "grammar.y" /* yacc.c:1646  */
     {
         // Push end-of-list marker
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
       }
-#line 3167 "grammar.c" /* yacc.c:1646  */
+#line 3173 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 89:
-#line 1512 "grammar.y" /* yacc.c:1646  */
+#line 1518 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
         yr_parser_emit_pushes_for_strings(yyscanner, "$*");
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3178 "grammar.c" /* yacc.c:1646  */
+#line 3184 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 92:
-#line 1529 "grammar.y" /* yacc.c:1646  */
+#line 1535 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[0].c_string));
         yr_free((yyvsp[0].c_string));
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3189 "grammar.c" /* yacc.c:1646  */
+#line 3195 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 93:
-#line 1536 "grammar.y" /* yacc.c:1646  */
+#line 1542 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[0].c_string));
         yr_free((yyvsp[0].c_string));
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3200 "grammar.c" /* yacc.c:1646  */
+#line 3206 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 95:
-#line 1548 "grammar.y" /* yacc.c:1646  */
+#line 1554 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
       }
-#line 3208 "grammar.c" /* yacc.c:1646  */
+#line 3214 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 96:
-#line 1552 "grammar.y" /* yacc.c:1646  */
+#line 1558 "grammar.y" /* yacc.c:1646  */
     {
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, 1, NULL, NULL);
       }
-#line 3216 "grammar.c" /* yacc.c:1646  */
+#line 3222 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 97:
-#line 1560 "grammar.y" /* yacc.c:1646  */
+#line 1566 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.expression) = (yyvsp[-1].expression);
       }
-#line 3224 "grammar.c" /* yacc.c:1646  */
+#line 3230 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 98:
-#line 1564 "grammar.y" /* yacc.c:1646  */
+#line 1570 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit(
             yyscanner, OP_FILESIZE, NULL);
@@ -3234,11 +3240,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3238 "grammar.c" /* yacc.c:1646  */
+#line 3244 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 99:
-#line 1574 "grammar.y" /* yacc.c:1646  */
+#line 1580 "grammar.y" /* yacc.c:1646  */
     {
         yywarning(yyscanner,
             "Using deprecated \"entrypoint\" keyword. Use the \"entry_point\" "
@@ -3252,11 +3258,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3256 "grammar.c" /* yacc.c:1646  */
+#line 3262 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 100:
-#line 1588 "grammar.y" /* yacc.c:1646  */
+#line 1594 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-1].expression), EXPRESSION_TYPE_INTEGER, "intXXXX or uintXXXX");
 
@@ -3272,11 +3278,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3276 "grammar.c" /* yacc.c:1646  */
+#line 3282 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 101:
-#line 1604 "grammar.y" /* yacc.c:1646  */
+#line 1610 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, (yyvsp[0].integer), NULL, NULL);
@@ -3286,11 +3292,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = (yyvsp[0].integer);
       }
-#line 3290 "grammar.c" /* yacc.c:1646  */
+#line 3296 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 102:
-#line 1614 "grammar.y" /* yacc.c:1646  */
+#line 1620 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg_double(
             yyscanner, OP_PUSH, (yyvsp[0].double_), NULL, NULL);
@@ -3299,11 +3305,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
       }
-#line 3303 "grammar.c" /* yacc.c:1646  */
+#line 3309 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 103:
-#line 1623 "grammar.y" /* yacc.c:1646  */
+#line 1629 "grammar.y" /* yacc.c:1646  */
     {
         SIZED_STRING* sized_string;
 
@@ -3328,11 +3334,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_STRING;
         (yyval.expression).value.sized_string = sized_string;
       }
-#line 3332 "grammar.c" /* yacc.c:1646  */
+#line 3338 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 104:
-#line 1648 "grammar.y" /* yacc.c:1646  */
+#line 1654 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner, (yyvsp[0].c_string), OP_COUNT, UNDEFINED);
@@ -3344,11 +3350,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3348 "grammar.c" /* yacc.c:1646  */
+#line 3354 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 105:
-#line 1660 "grammar.y" /* yacc.c:1646  */
+#line 1666 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner, (yyvsp[-3].c_string), OP_OFFSET, UNDEFINED);
@@ -3360,11 +3366,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3364 "grammar.c" /* yacc.c:1646  */
+#line 3370 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 106:
-#line 1672 "grammar.y" /* yacc.c:1646  */
+#line 1678 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, 1, NULL, NULL);
@@ -3380,11 +3386,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3384 "grammar.c" /* yacc.c:1646  */
+#line 3390 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 107:
-#line 1688 "grammar.y" /* yacc.c:1646  */
+#line 1694 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner, (yyvsp[-3].c_string), OP_LENGTH, UNDEFINED);
@@ -3396,11 +3402,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3400 "grammar.c" /* yacc.c:1646  */
+#line 3406 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 108:
-#line 1700 "grammar.y" /* yacc.c:1646  */
+#line 1706 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, 1, NULL, NULL);
@@ -3416,11 +3422,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = UNDEFINED;
       }
-#line 3420 "grammar.c" /* yacc.c:1646  */
+#line 3426 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 109:
-#line 1716 "grammar.y" /* yacc.c:1646  */
+#line 1722 "grammar.y" /* yacc.c:1646  */
     {
         if ((yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER)  // loop identifier
         {
@@ -3465,11 +3471,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3469 "grammar.c" /* yacc.c:1646  */
+#line 3475 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 110:
-#line 1761 "grammar.y" /* yacc.c:1646  */
+#line 1767 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER | EXPRESSION_TYPE_FLOAT, "-");
 
@@ -3488,11 +3494,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
-#line 3492 "grammar.c" /* yacc.c:1646  */
+#line 3498 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 111:
-#line 1780 "grammar.y" /* yacc.c:1646  */
+#line 1786 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "+", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3510,11 +3516,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
         }
       }
-#line 3514 "grammar.c" /* yacc.c:1646  */
+#line 3520 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 112:
-#line 1798 "grammar.y" /* yacc.c:1646  */
+#line 1804 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "-", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3532,11 +3538,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
         }
       }
-#line 3536 "grammar.c" /* yacc.c:1646  */
+#line 3542 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 113:
-#line 1816 "grammar.y" /* yacc.c:1646  */
+#line 1822 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "*", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3554,11 +3560,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
         }
       }
-#line 3558 "grammar.c" /* yacc.c:1646  */
+#line 3564 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 114:
-#line 1834 "grammar.y" /* yacc.c:1646  */
+#line 1840 "grammar.y" /* yacc.c:1646  */
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "\\", (yyvsp[-2].expression), (yyvsp[0].expression));
@@ -3584,11 +3590,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           (yyval.expression).type = EXPRESSION_TYPE_FLOAT;
         }
       }
-#line 3588 "grammar.c" /* yacc.c:1646  */
+#line 3594 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 115:
-#line 1860 "grammar.y" /* yacc.c:1646  */
+#line 1866 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "%");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "%");
@@ -3606,11 +3612,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
           ERROR_IF(compiler->last_result != ERROR_SUCCESS);
         }
       }
-#line 3610 "grammar.c" /* yacc.c:1646  */
+#line 3616 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 116:
-#line 1878 "grammar.y" /* yacc.c:1646  */
+#line 1884 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^");
@@ -3620,11 +3626,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(^, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3624 "grammar.c" /* yacc.c:1646  */
+#line 3630 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 117:
-#line 1888 "grammar.y" /* yacc.c:1646  */
+#line 1894 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^");
@@ -3634,11 +3640,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(&, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3638 "grammar.c" /* yacc.c:1646  */
+#line 3644 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 118:
-#line 1898 "grammar.y" /* yacc.c:1646  */
+#line 1904 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "|");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "|");
@@ -3648,11 +3654,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(|, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3652 "grammar.c" /* yacc.c:1646  */
+#line 3658 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 119:
-#line 1908 "grammar.y" /* yacc.c:1646  */
+#line 1914 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "~");
 
@@ -3662,11 +3668,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).value.integer = ((yyvsp[0].expression).value.integer == UNDEFINED) ?
             UNDEFINED : ~((yyvsp[0].expression).value.integer);
       }
-#line 3666 "grammar.c" /* yacc.c:1646  */
+#line 3672 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 120:
-#line 1918 "grammar.y" /* yacc.c:1646  */
+#line 1924 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "<<");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "<<");
@@ -3676,11 +3682,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(<<, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3680 "grammar.c" /* yacc.c:1646  */
+#line 3686 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 121:
-#line 1928 "grammar.y" /* yacc.c:1646  */
+#line 1934 "grammar.y" /* yacc.c:1646  */
     {
         CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, ">>");
         CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, ">>");
@@ -3690,19 +3696,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
         (yyval.expression).type = EXPRESSION_TYPE_INTEGER;
         (yyval.expression).value.integer = OPERATION(>>, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer);
       }
-#line 3694 "grammar.c" /* yacc.c:1646  */
+#line 3700 "grammar.c" /* yacc.c:1646  */
     break;
 
   case 122:
-#line 1938 "grammar.y" /* yacc.c:1646  */
+#line 1944 "grammar.y" /* yacc.c:1646  */
     {
         (yyval.expression) = (yyvsp[0].expression);
       }
-#line 3702 "grammar.c" /* yacc.c:1646  */
+#line 3708 "grammar.c" /* yacc.c:1646  */
     break;
 
 
-#line 3706 "grammar.c" /* yacc.c:1646  */
+#line 3712 "grammar.c" /* yacc.c:1646  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -3930,5 +3936,5 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
 #endif
   return yyresult;
 }
-#line 1943 "grammar.y" /* yacc.c:1906  */
+#line 1949 "grammar.y" /* yacc.c:1906  */
 
diff --git a/libyara/grammar.y b/libyara/grammar.y
index addb55d..9cb4be7 100644
--- a/libyara/grammar.y
+++ b/libyara/grammar.y
@@ -824,6 +824,8 @@ arguments_list
           case EXPRESSION_TYPE_REGEXP:
             strlcpy($$, "r", MAX_FUNCTION_ARGS);
             break;
+          default:
+            assert(FALSE);
         }
 
         ERROR_IF($$ == NULL);
@@ -853,6 +855,8 @@ arguments_list
             case EXPRESSION_TYPE_REGEXP:
               strlcat($1, "r", MAX_FUNCTION_ARGS);
               break;
+            default:
+              assert(FALSE);
           }
         }
 
@@ -1022,6 +1026,8 @@ expression
           compiler->loop_depth--;
           compiler->loop_identifier[compiler->loop_depth] = NULL;
         }
+
+        YYERROR;
       }
     | _FOR_ for_expression _IDENTIFIER_ _IN_
       {

From e91ceb150bd55d3249b0b523a3ce454f8dec5e81 Mon Sep 17 00:00:00 2001
From: plusvic <plusvic@gmail.com>
Date: Tue, 7 Feb 2017 11:34:49 +0100
Subject: [PATCH 29/36] Fix detection of bswap compiler features in endian.h

Cherry picked from commits

- 764f33dd04135f8d3f9428c8f9bed213494d538f
- 16c3dd1215ea013bf472820878e22aaaab0fd8cd
- ca3927fcebb85c429231087ef796753a37d5b079
- 0541a7932517364f5ec042af710ce48f92f6e5bd
---
 libyara/Makefile.am           |  1 +
 libyara/endian.c              | 53 +++++++++++++++++++++++++++++++++++++++
 libyara/include/yara/endian.h | 58 +++++++++++++++++++++++++++++++++++--------
 3 files changed, 102 insertions(+), 10 deletions(-)
 create mode 100644 libyara/endian.c

diff --git a/libyara/Makefile.am b/libyara/Makefile.am
index 20dbe4a..6861843 100644
--- a/libyara/Makefile.am
+++ b/libyara/Makefile.am
@@ -73,6 +73,7 @@ libyara_la_SOURCES = \
   arena.c \
   atoms.c \
   compiler.c \
+  endian.c \
   exec.c \
   exefiles.c \
   exefiles.h \
diff --git a/libyara/endian.c b/libyara/endian.c
new file mode 100644
index 0000000..02fff63
--- /dev/null
+++ b/libyara/endian.c
@@ -0,0 +1,53 @@
+/*
+Copyright (c) 2017. The YARA Authors. All Rights Reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its contributors
+may be used to endorse or promote products derived from this software without
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <yara/endian.h>
+
+uint16_t _yr_bswap16(uint16_t x)
+{
+  return (x >> 8 | x << 8);
+}
+
+uint32_t _yr_bswap32(uint32_t x)
+{
+  return ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |
+          (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24));
+}
+
+uint64_t _yr_bswap64(uint64_t x)
+{
+  return ((((x) & 0xff00000000000000ull) >> 56)
+        | (((x) & 0x00ff000000000000ull) >> 40)
+        | (((x) & 0x0000ff0000000000ull) >> 24)
+        | (((x) & 0x000000ff00000000ull) >> 8)
+        | (((x) & 0x00000000ff000000ull) << 8)
+        | (((x) & 0x0000000000ff0000ull) << 24)
+        | (((x) & 0x000000000000ff00ull) << 40)
+        | (((x) & 0x00000000000000ffull) << 56));
+}
diff --git a/libyara/include/yara/endian.h b/libyara/include/yara/endian.h
index 06d8c14..8d75012 100644
--- a/libyara/include/yara/endian.h
+++ b/libyara/include/yara/endian.h
@@ -30,20 +30,58 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef YR_ENDIAN_H
 #define YR_ENDIAN_H
 
+#include <stdint.h>
 #include <config.h>
 
-#if defined(__GNUC__)
-#define yr_bswap16(x) __builtin_bswap16(x)
-#define yr_bswap32(x) __builtin_bswap32(x)
-#define yr_bswap64(x) __builtin_bswap64(x)
-#elif defined(_MSC_VER)
-#define yr_bswap16(x) _byteswap_ushort(x)
-#define yr_bswap32(x) _byteswap_ulong(x)
-#define yr_bswap64(x) _byteswap_uint64(x)
-#else
-#error Unknown compiler: Add yr_bswap* definitions
+
+#if defined(__has_builtin)
+#  if __has_builtin(__builtin_bswap16)
+#    define yr_bswap16(x) __builtin_bswap16(x)
+#  endif
+#endif
+
+#if !defined(yr_bswap16) && defined(_MSC_VER)
+#  define yr_bswap16(x) _byteswap_ushort(x)
+#endif
+
+#if !defined(yr_bswap16)
+uint16_t _yr_bswap16(uint16_t x);
+# define yr_bswap16(x) _yr_bswap16(x)
+#endif
+
+
+#if defined(__has_builtin)
+#  if __has_builtin(__builtin_bswap32)
+#    define yr_bswap32(x) __builtin_bswap32(x)
+#  endif
+#endif
+
+#if !defined(yr_bswap32) && defined(_MSC_VER)
+#  define yr_bswap32(x) _byteswap_ulong(x)
 #endif
 
+#if !defined(yr_bswap32)
+uint32_t _yr_bswap32(uint32_t x);
+#define yr_bswap32(x) _yr_bswap32(x)
+#endif
+
+
+#if defined(__has_builtin)
+#  if __has_builtin(__builtin_bswap64)
+#    define yr_bswap64(x) __builtin_bswap64(x)
+#  endif
+#endif
+
+#if !defined(yr_bswap64) && defined(_MSC_VER)
+#  define yr_bswap64(x) _byteswap_uint64(x)
+#endif
+
+#if !defined(yr_bswap64)
+uint64_t _yr_bswap64(uint64_t x);
+#define yr_bswap64(x) _yr_bswap64(x)
+#endif
+
+
 #if defined(WORDS_BIGENDIAN)
 #define yr_le16toh(x) yr_bswap16(x)
 #define yr_le32toh(x) yr_bswap32(x)

From ac82bbe68bf640658eb0d558dfc929c5fb54dfa3 Mon Sep 17 00:00:00 2001
From: Jacob Baines <baines.jacob@gmail.com>
Date: Wed, 15 Feb 2017 03:36:45 -0500
Subject: [PATCH 30/36] Fix endian issues with section name extraction (#607)

(cherry picked from commit 0e2c3a7cf35639a369e4e86d82227de67668bdae)
---
 libyara/modules/elf.c |   3 +-
 tests/blob.h          | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/test-elf.c      |  21 +++++++
 3 files changed, 178 insertions(+), 1 deletion(-)

diff --git a/libyara/modules/elf.c b/libyara/modules/elf.c
index dff586e..c6ee384 100644
--- a/libyara/modules/elf.c
+++ b/libyara/modules/elf.c
@@ -164,7 +164,8 @@ void parse_elf_header_##bits##_##bo(                                           \
     section = (elf##bits##_section_header_t*)                                  \
       ((uint8_t*) elf + yr_##bo##bits##toh(elf->sh_offset));                   \
                                                                                \
-    if (section[yr_##bo##16toh(elf->sh_str_table_index)].offset < elf_size)    \
+    if (yr_##bo##bits##toh(                                                    \
+      section[yr_##bo##16toh(elf->sh_str_table_index)].offset) < elf_size)     \
     {                                                                          \
       str_table = (char*) elf + yr_##bo##bits##toh(                            \
           section[yr_##bo##16toh(elf->sh_str_table_index)].offset);            \
diff --git a/tests/blob.h b/tests/blob.h
index 08bf5b6..1659a91 100644
--- a/tests/blob.h
+++ b/tests/blob.h
@@ -178,3 +178,158 @@ uint8_t ELF64_FILE[] = {
   0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 };
+
+uint8_t ELF32_MIPS_FILE[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x02, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x40, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x34,
+  0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x10, 0x07,
+  0x00, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x28,
+  0x00, 0x0b, 0x00, 0x08, 0x70, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x98, 0x00, 0x40, 0x00, 0x98,
+  0x00, 0x40, 0x00, 0x98, 0x00, 0x00, 0x00, 0x18,
+  0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xb0, 0x00, 0x40, 0x00, 0xb0,
+  0x00, 0x40, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x18,
+  0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x05,
+  0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x80, 0xd0,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x03, 0xe0, 0x00, 0x08, 0x24, 0x02, 0x00, 0x2a,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x47, 0x43, 0x43, 0x3a, 0x20, 0x28, 0x47, 0x4e,
+  0x55, 0x29, 0x20, 0x35, 0x2e, 0x33, 0x2e, 0x30,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0xd0,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d,
+  0x00, 0x00, 0x00, 0x1f, 0x41, 0x00, 0x00, 0x00,
+  0x0f, 0x67, 0x6e, 0x75, 0x00, 0x01, 0x00, 0x00,
+  0x00, 0x07, 0x04, 0x01, 0x00, 0x2e, 0x73, 0x79,
+  0x6d, 0x74, 0x61, 0x62, 0x00, 0x2e, 0x73, 0x74,
+  0x72, 0x74, 0x61, 0x62, 0x00, 0x2e, 0x73, 0x68,
+  0x73, 0x74, 0x72, 0x74, 0x61, 0x62, 0x00, 0x2e,
+  0x4d, 0x49, 0x50, 0x53, 0x2e, 0x61, 0x62, 0x69,
+  0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x2e, 0x72,
+  0x65, 0x67, 0x69, 0x6e, 0x66, 0x6f, 0x00, 0x2e,
+  0x74, 0x65, 0x78, 0x74, 0x00, 0x2e, 0x63, 0x6f,
+  0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x2e, 0x70,
+  0x64, 0x72, 0x00, 0x2e, 0x67, 0x6e, 0x75, 0x2e,
+  0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
+  0x65, 0x73, 0x00, 0x2e, 0x6d, 0x64, 0x65, 0x62,
+  0x75, 0x67, 0x2e, 0x61, 0x62, 0x69, 0x33, 0x32,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x40, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x40, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x40, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x41, 0x80, 0xd0, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x0c,
+  0x00, 0x41, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
+  0x00, 0x40, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x22,
+  0x00, 0x41, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2e,
+  0x00, 0x40, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x08,
+  0x12, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x33,
+  0x00, 0x41, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a,
+  0x00, 0x41, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3f,
+  0x00, 0x41, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x03, 0x00, 0x6d, 0x61, 0x69,
+  0x6e, 0x2e, 0x63, 0x00, 0x5f, 0x67, 0x70, 0x00,
+  0x5f, 0x66, 0x64, 0x61, 0x74, 0x61, 0x00, 0x5f,
+  0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x5f,
+  0x66, 0x74, 0x65, 0x78, 0x74, 0x00, 0x5f, 0x5f,
+  0x62, 0x73, 0x73, 0x5f, 0x73, 0x74, 0x61, 0x72,
+  0x74, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x5f,
+  0x65, 0x64, 0x61, 0x74, 0x61, 0x00, 0x5f, 0x65,
+  0x6e, 0x64, 0x00, 0x5f, 0x66, 0x62, 0x73, 0x73,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
+  0x70, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0x40, 0x00, 0x98, 0x00, 0x00, 0x00, 0x98,
+  0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x2a,
+  0x70, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0x40, 0x00, 0xb0, 0x00, 0x00, 0x00, 0xb0,
+  0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x33,
+  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06,
+  0x00, 0x40, 0x00, 0xd0, 0x00, 0x00, 0x00, 0xd0,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39,
+  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x42,
+  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4,
+  0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+  0x6f, 0xff, 0xff, 0xf5, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x14,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57,
+  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x24,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x24,
+  0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8c,
+  0x00, 0x00, 0x01, 0x30, 0x00, 0x00, 0x00, 0x0a,
+  0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x09,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xbc,
+  0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x00
+};
\ No newline at end of file
diff --git a/tests/test-elf.c b/tests/test-elf.c
index 8d13b47..6415933 100644
--- a/tests/test-elf.c
+++ b/tests/test-elf.c
@@ -24,6 +24,27 @@ int main(int argc, char** argv)
         condition: $a at elf.entry_point }",
       ELF64_FILE);
 
+  assert_true_rule_blob("import \"elf\" rule test { \
+    condition: elf.sections[2].name == \".comment\" }", ELF64_FILE);
+
+  assert_true_rule_blob("import \"elf\" rule test { \
+    condition: elf.machine == elf.EM_MIPS }", ELF32_MIPS_FILE);
+
+  assert_true_rule_blob("import \"elf\" rule test { \
+    condition: elf.number_of_sections == 11 and \
+    elf.number_of_segments == 3 }", ELF32_MIPS_FILE);
+
+  assert_true_rule_blob("import \"elf\" rule test { \
+    condition: for any i in (0..elf.number_of_sections): ( \
+    elf.sections[i].type == elf.SHT_PROGBITS and \
+    elf.sections[i].name == \".text\")}", ELF32_MIPS_FILE);
+
+  assert_true_rule_blob("import \"elf\" rule test { \
+    condition: for any i in (0..elf.number_of_segments): ( \
+    elf.segments[i].type == elf.PT_LOAD and \
+    elf.segments[i].virtual_address == 0x00400000 and \
+    elf.segments[i].file_size == 0xe0)}", ELF32_MIPS_FILE);
+
   yr_finalize();
   return 0;
 }

From 5daf58f4f5b98f4aeb33c60a70b7abec4f13f9b8 Mon Sep 17 00:00:00 2001
From: Jacob Baines <baines.jacob@gmail.com>
Date: Wed, 15 Feb 2017 03:50:18 -0500
Subject: [PATCH 31/36] Use the program headers to determine the physical
 offset of the ELF entry point (#606)

(cherry picked from commit 8fc561b50121227b78baa85fd0d56482655c290d)
---
 libyara/exefiles.c    | 189 ++++++++++-----
 libyara/modules/elf.c | 100 +++++---
 tests/blob.h          | 625 +++++++++++++++++++++++++++++++++++++++++++++++++-
 tests/test-elf.c      |   7 +-
 4 files changed, 834 insertions(+), 87 deletions(-)

diff --git a/libyara/exefiles.c b/libyara/exefiles.c
index 05d1de7..293b905 100644
--- a/libyara/exefiles.c
+++ b/libyara/exefiles.c
@@ -150,54 +150,95 @@ int yr_get_elf_type(
 }
 
 
-uint64_t yr_elf_rva_to_offset_32(
+static uint64_t yr_elf_rva_to_offset_32(
     elf32_header_t* elf_header,
     uint64_t rva,
     size_t buffer_length)
 {
-  int i;
-  elf32_section_header_t* section;
+  // if the binary is an executable then prefer the program headers to resolve
+  // the offset
+  if (elf_header->type == ELF_ET_EXEC)
+  {
+    int i;
+    elf32_program_header_t* program;
+    if (elf_header->ph_offset == 0 || elf_header->ph_entry_count == 0)
+      return 0;
 
-  if (elf_header->sh_offset == 0 || elf_header->sh_entry_count == 0)
-    return 0;
+    // check to prevent integer wraps
+    if (ULONG_MAX - yr_le16toh(elf_header->ph_entry_count) <
+     sizeof(elf32_program_header_t) * yr_le16toh(elf_header->ph_entry_count))
+      return 0;
 
-  // check to prevent integer wraps
+    // check that 'ph_offset' doesn't wrap when added to the
+    // size of entries.
+    if(ULONG_MAX - yr_le32toh(elf_header->ph_offset) <
+     sizeof(elf32_program_header_t) * yr_le16toh(elf_header->ph_entry_count))
+      return 0;
 
-  if (ULONG_MAX - yr_le16toh(elf_header->sh_entry_count) <
-      sizeof(elf32_section_header_t) * yr_le16toh(elf_header->sh_entry_count))
-    return 0;
+    // ensure we don't exceed the buffer size
+    if (yr_le32toh(elf_header->ph_offset) + sizeof(elf32_program_header_t) *
+        yr_le16toh(elf_header->ph_entry_count) > buffer_length)
+      return 0;
 
-  // check that 'sh_offset' doesn't wrap when added to the
-  // size of entries.
+    program = (elf32_program_header_t*)
+      ((uint8_t*) elf_header + yr_le32toh(elf_header->ph_offset));
 
-  if (ULONG_MAX - yr_le32toh(elf_header->sh_offset) <
-      sizeof(elf32_section_header_t) * yr_le16toh(elf_header->sh_entry_count))
-    return 0;
+    for (i = 0; i < yr_le16toh(elf_header->ph_entry_count); i++)
+    {
+      if (rva >= yr_le32toh(program->virt_addr) &&
+          rva <  yr_le32toh(program->virt_addr) + yr_le32toh(program->mem_size))
+      {
+        return yr_le32toh(program->offset) + (rva - yr_le32toh(program->virt_addr));
+      }
 
-  if (yr_le32toh(elf_header->sh_offset) + \
-      sizeof(elf32_section_header_t) * \
-      yr_le16toh(elf_header->sh_entry_count) > buffer_length)
-    return 0;
+      program++;
+    }
+  }
+  else
+  {
+    int i;
+    elf32_section_header_t* section;
+
+    if (elf_header->sh_offset == 0 || elf_header->sh_entry_count == 0)
+      return 0;
+
+    // check to prevent integer wraps
 
-  section = (elf32_section_header_t*) \
+    if (ULONG_MAX - yr_le16toh(elf_header->sh_entry_count) <
+     sizeof(elf32_section_header_t) * yr_le16toh(elf_header->sh_entry_count))
+      return 0;
+
+    // check that 'sh_offset' doesn't wrap when added to the
+    // size of entries.
+
+    if (ULONG_MAX - yr_le32toh(elf_header->sh_offset) <
+     sizeof(elf32_section_header_t) * yr_le16toh(elf_header->sh_entry_count))
+      return 0;
+
+    if (yr_le32toh(elf_header->sh_offset) + sizeof(elf32_section_header_t) *
+     yr_le16toh(elf_header->sh_entry_count) > buffer_length)
+      return 0;
+
+    section = (elf32_section_header_t*)
       ((unsigned char*) elf_header + yr_le32toh(elf_header->sh_offset));
 
-  for (i = 0; i < yr_le16toh(elf_header->sh_entry_count); i++)
-  {
-    if (yr_le32toh(section->type) != ELF_SHT_NULL &&
-        yr_le32toh(section->type) != ELF_SHT_NOBITS &&
-        rva >= yr_le32toh(section->addr) &&
-        rva <  yr_le32toh(section->addr) + yr_le32toh(section->size))
+    for (i = 0; i < yr_le16toh(elf_header->sh_entry_count); i++)
     {
-      // prevent integer wrapping with the return value
+      if (yr_le32toh(section->type) != ELF_SHT_NULL &&
+          yr_le32toh(section->type) != ELF_SHT_NOBITS &&
+          rva >= yr_le32toh(section->addr) &&
+          rva <  yr_le32toh(section->addr) + yr_le32toh(section->size))
+      {
+        // prevent integer wrapping with the return value
 
-      if (ULONG_MAX - yr_le32toh(section->offset) < (rva - yr_le32toh(section->addr)))
-        return 0;
-      else
-        return yr_le32toh(section->offset) + (rva - yr_le32toh(section->addr));
-    }
+        if (ULONG_MAX - yr_le32toh(section->offset) < (rva - yr_le32toh(section->addr)))
+          return 0;
+        else
+          return yr_le32toh(section->offset) + (rva - yr_le32toh(section->addr));
+      }
 
-    section++;
+      section++;
+    }
   }
 
   return 0;
@@ -205,42 +246,78 @@ uint64_t yr_elf_rva_to_offset_32(
 }
 
 
-uint64_t yr_elf_rva_to_offset_64(
+static uint64_t yr_elf_rva_to_offset_64(
     elf64_header_t* elf_header,
     uint64_t rva,
     size_t buffer_length)
 {
-  int i;
-  elf64_section_header_t* section;
+  // if the binary is an executable then prefer the program headers to resolve
+  // the offset
+  if (elf_header->type == ELF_ET_EXEC)
+  {
+    int i;
+    elf64_program_header_t* program;
+    if (elf_header->ph_offset == 0 || elf_header->ph_entry_count == 0)
+      return 0;
 
-  if (elf_header->sh_offset == 0 || elf_header->sh_entry_count == 0)
-    return 0;
+    // check that 'ph_offset' doesn't wrap when added to the
+    // size of entries.
+    if(ULONG_MAX - yr_le64toh(elf_header->ph_offset) <
+     sizeof(elf64_program_header_t) * yr_le16toh(elf_header->ph_entry_count))
+      return 0;
 
-  // check that 'sh_offset' doesn't wrap when added to the
-  // size of entries.
-  if(ULONG_MAX - yr_le64toh(elf_header->sh_offset) <
-     sizeof(elf64_section_header_t) * yr_le16toh(elf_header->sh_entry_count))
-    return 0;
+    // ensure we don't exceed the buffer size
+    if (yr_le64toh(elf_header->ph_offset) + sizeof(elf64_program_header_t) *
+        yr_le16toh(elf_header->ph_entry_count) > buffer_length)
+      return 0;
 
-  if (yr_le64toh(elf_header->sh_offset) + \
-      sizeof(elf64_section_header_t) * \
-      yr_le16toh(elf_header->sh_entry_count) > buffer_length)
-    return 0;
+    program = (elf64_program_header_t*)
+      ((uint8_t*) elf_header + yr_le64toh(elf_header->ph_offset));
 
-  section = (elf64_section_header_t*) \
-    ((uint8_t*) elf_header + yr_le64toh(elf_header->sh_offset));
+    for (i = 0; i < yr_le16toh(elf_header->ph_entry_count); i++)
+    {
+      if (rva >= yr_le64toh(program->virt_addr) &&
+          rva <  yr_le64toh(program->virt_addr) + yr_le64toh(program->mem_size))
+      {
+        return yr_le64toh(program->offset) + (rva - yr_le64toh(program->virt_addr));
+      }
 
-  for (i = 0; i < yr_le16toh(elf_header->sh_entry_count); i++)
+      program++;
+    }
+  }
+  else
   {
-    if (yr_le32toh(section->type) != ELF_SHT_NULL &&
-        yr_le32toh(section->type) != ELF_SHT_NOBITS &&
-        rva >= yr_le64toh(section->addr) &&
-        rva <  yr_le64toh(section->addr) + yr_le64toh(section->size))
+    int i;
+    elf64_section_header_t* section;
+
+    if (elf_header->sh_offset == 0 || elf_header->sh_entry_count == 0)
+      return 0;
+
+    // check that 'sh_offset' doesn't wrap when added to the
+    // size of entries.
+    if(ULONG_MAX - yr_le64toh(elf_header->sh_offset) <
+     sizeof(elf64_section_header_t) * yr_le16toh(elf_header->sh_entry_count))
+      return 0;
+
+    if (yr_le64toh(elf_header->sh_offset) + sizeof(elf64_section_header_t) *
+        yr_le16toh(elf_header->sh_entry_count) > buffer_length)
+      return 0;
+
+    section = (elf64_section_header_t*)
+      ((uint8_t*) elf_header + yr_le64toh(elf_header->sh_offset));
+
+    for (i = 0; i < yr_le16toh(elf_header->sh_entry_count); i++)
     {
-      return yr_le64toh(section->offset) + (rva - yr_le64toh(section->addr));
-    }
+      if (yr_le32toh(section->type) != ELF_SHT_NULL &&
+          yr_le32toh(section->type) != ELF_SHT_NOBITS &&
+          rva >= yr_le64toh(section->addr) &&
+          rva <  yr_le64toh(section->addr) + yr_le64toh(section->size))
+      {
+        return yr_le64toh(section->offset) + (rva - yr_le64toh(section->addr));
+      }
 
-    section++;
+      section++;
+    }
   }
 
   return 0;
diff --git a/libyara/modules/elf.c b/libyara/modules/elf.c
index c6ee384..8ea6c94 100644
--- a/libyara/modules/elf.c
+++ b/libyara/modules/elf.c
@@ -63,7 +63,8 @@ int get_elf_class_data(
 #define ELF_SIZE_OF_SECTION_TABLE(bits,bo,h)       \
   (sizeof(elf##bits##_section_header_t) * yr_##bo##16toh(h->sh_entry_count))
 
-
+#define ELF_SIZE_OF_PROGRAM_TABLE(bits,bo,h)       \
+  (sizeof(elf##bits##_program_header_t) * yr_##bo##16toh(h->ph_entry_count))
 
 #define ELF_RVA_TO_OFFSET(bits,bo)                                             \
 uint64_t elf_rva_to_offset_##bits##_##bo(                                      \
@@ -71,45 +72,86 @@ uint64_t elf_rva_to_offset_##bits##_##bo(                                      \
     uint64_t rva,                                                              \
     size_t elf_size)                                                           \
 {                                                                              \
-  int i;                                                                       \
+  if (elf_header->type == ELF_ET_EXEC)                                         \
+  {                                                                            \
+    int i;                                                                     \
                                                                                \
-  elf##bits##_section_header_t* section;                                       \
+    elf##bits##_program_header_t* program;                                     \
                                                                                \
-  /* check that sh_offset doesn't wrap when added to SIZE_OF_SECTION_TABLE */  \
+    /* check that ph_offset doesn't wrap when added to SIZE_OF_PROGRAM_TABLE */\
                                                                                \
-  if(ULONG_MAX - yr_##bo##bits##toh(elf_header->sh_offset) <                   \
-     ELF_SIZE_OF_SECTION_TABLE(bits,bo,elf_header))                            \
-  {                                                                            \
-    return UNDEFINED;                                                          \
-  }                                                                            \
+    if(ULONG_MAX - yr_##bo##bits##toh(elf_header->ph_offset) <                 \
+       ELF_SIZE_OF_PROGRAM_TABLE(bits,bo,elf_header))                          \
+    {                                                                          \
+      return UNDEFINED;                                                        \
+    }                                                                          \
                                                                                \
-  if (yr_##bo##bits##toh(elf_header->sh_offset) == 0 ||                        \
-      yr_##bo##bits##toh(elf_header->sh_offset) > elf_size ||                  \
-      yr_##bo##bits##toh(elf_header->sh_offset) +                              \
-        ELF_SIZE_OF_SECTION_TABLE(bits,bo,elf_header) > elf_size ||            \
-      yr_##bo##16toh(elf_header->sh_entry_count) == 0)                         \
-  {                                                                            \
-    return UNDEFINED;                                                          \
-  }                                                                            \
+    if (yr_##bo##bits##toh(elf_header->ph_offset) == 0 ||                      \
+        yr_##bo##bits##toh(elf_header->ph_offset) > elf_size ||                \
+        yr_##bo##bits##toh(elf_header->ph_offset) +                            \
+         ELF_SIZE_OF_PROGRAM_TABLE(bits,bo,elf_header) > elf_size ||           \
+        yr_##bo##16toh(elf_header->ph_entry_count) == 0)                       \
+    {                                                                          \
+      return UNDEFINED;                                                        \
+    }                                                                          \
                                                                                \
-  section = (elf##bits##_section_header_t*)                                    \
-      ((uint8_t*) elf_header + yr_##bo##bits##toh(elf_header->sh_offset));     \
+    program = (elf##bits##_program_header_t*)                                  \
+        ((uint8_t*) elf_header + yr_##bo##bits##toh(elf_header->ph_offset));   \
                                                                                \
-  for (i = 0; i < yr_##bo##16toh(elf_header->sh_entry_count); i++)             \
+    for (i = 0; i < yr_##bo##16toh(elf_header->ph_entry_count); i++)           \
+    {                                                                          \
+      if (rva >= yr_##bo##bits##toh(program->virt_addr) &&                     \
+          rva < yr_##bo##bits##toh(program->virt_addr) +                       \
+          yr_##bo##bits##toh(program->mem_size))                               \
+      {                                                                        \
+        return yr_##bo##bits##toh(program->offset) +                           \
+          (rva - yr_##bo##bits##toh(program->virt_addr));                      \
+      }                                                                        \
+                                                                               \
+      program++;                                                               \
+    }                                                                          \
+  }                                                                            \
+  else                                                                         \
   {                                                                            \
-    if (yr_##bo##32toh(section->type) != ELF_SHT_NULL &&                       \
-        yr_##bo##32toh(section->type) != ELF_SHT_NOBITS &&                     \
-        rva >= yr_##bo##bits##toh(section->addr) &&                            \
-        rva < yr_##bo##bits##toh(section->addr) +                              \
-          yr_##bo##bits##toh(section->size))                                   \
+    int i;                                                                     \
+                                                                               \
+    elf##bits##_section_header_t* section;                                     \
+                                                                               \
+    /* check that sh_offset doesn't wrap when added to SIZE_OF_SECTION_TABLE */\
+                                                                               \
+    if(ULONG_MAX - yr_##bo##bits##toh(elf_header->sh_offset) <                 \
+       ELF_SIZE_OF_SECTION_TABLE(bits,bo,elf_header))                          \
     {                                                                          \
-      return yr_##bo##bits##toh(section->offset) +                             \
-        (rva - yr_##bo##bits##toh(section->addr));                             \
+      return UNDEFINED;                                                        \
     }                                                                          \
                                                                                \
-    section++;                                                                 \
-  }                                                                            \
+    if (yr_##bo##bits##toh(elf_header->sh_offset) == 0 ||                      \
+        yr_##bo##bits##toh(elf_header->sh_offset) > elf_size ||                \
+        yr_##bo##bits##toh(elf_header->sh_offset) +                            \
+         ELF_SIZE_OF_SECTION_TABLE(bits,bo,elf_header) > elf_size ||           \
+        yr_##bo##16toh(elf_header->sh_entry_count) == 0)                       \
+    {                                                                          \
+      return UNDEFINED;                                                        \
+    }                                                                          \
+                                                                               \
+    section = (elf##bits##_section_header_t*)                                  \
+        ((uint8_t*) elf_header + yr_##bo##bits##toh(elf_header->sh_offset));   \
                                                                                \
+    for (i = 0; i < yr_##bo##16toh(elf_header->sh_entry_count); i++)           \
+    {                                                                          \
+      if (yr_##bo##32toh(section->type) != ELF_SHT_NULL &&                     \
+          yr_##bo##32toh(section->type) != ELF_SHT_NOBITS &&                   \
+          rva >= yr_##bo##bits##toh(section->addr) &&                          \
+          rva < yr_##bo##bits##toh(section->addr) +                            \
+          yr_##bo##bits##toh(section->size))                                   \
+      {                                                                        \
+        return yr_##bo##bits##toh(section->offset) +                           \
+          (rva - yr_##bo##bits##toh(section->addr));                           \
+      }                                                                        \
+                                                                               \
+      section++;                                                               \
+    }                                                                          \
+  }                                                                            \
   return UNDEFINED;                                                            \
 }
 
diff --git a/tests/blob.h b/tests/blob.h
index 1659a91..d7a617a 100644
--- a/tests/blob.h
+++ b/tests/blob.h
@@ -179,6 +179,628 @@ uint8_t ELF64_FILE[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 };
 
+
+uint8_t ELF32_NOSECTIONS[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0xa0, 0x80, 0x04, 0x08, 0x34, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x34, 0x00, 0x20, 0x00, 0x02, 0x00, 0x28, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x08,
+  0x00, 0x80, 0x04, 0x08, 0xac, 0x00, 0x00, 0x00,
+  0xac, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x74, 0x00, 0x00, 0x00, 0x74, 0x80, 0x04, 0x08,
+  0x74, 0x80, 0x04, 0x08, 0x24, 0x00, 0x00, 0x00,
+  0x24, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x47, 0x4e, 0x55, 0x00, 0x72, 0x5c, 0x33, 0xa6,
+  0xcd, 0xed, 0x46, 0xf2, 0xc7, 0xa2, 0x8c, 0x1f,
+  0xbd, 0x65, 0x7a, 0xd1, 0x9f, 0x0f, 0x51, 0x80,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xb8, 0x01, 0x00, 0x00, 0x00, 0xbb, 0x2a, 0x00,
+  0x00, 0x00, 0xcd, 0x80, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+uint8_t ELF32_SHAREDOBJ[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0xa0, 0x01, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+  0x54, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x34, 0x00, 0x20, 0x00, 0x05, 0x00, 0x28, 0x00,
+  0x09, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xac, 0x01, 0x00, 0x00,
+  0xac, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0xa8, 0x0f, 0x00, 0x00, 0xa8, 0x1f, 0x00, 0x00,
+  0xa8, 0x1f, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
+  0x58, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xa8, 0x0f, 0x00, 0x00, 0xa8, 0x1f, 0x00, 0x00,
+  0xa8, 0x1f, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
+  0x58, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0xd4, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
+  0xd4, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+  0x24, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x52, 0xe5, 0x74, 0x64,
+  0xa8, 0x0f, 0x00, 0x00, 0xa8, 0x1f, 0x00, 0x00,
+  0xa8, 0x1f, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
+  0x58, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x47, 0x4e, 0x55, 0x00, 0x6e, 0x96, 0x9b, 0xbc,
+  0x8b, 0x0c, 0x9d, 0x95, 0x29, 0xfc, 0x07, 0x04,
+  0x15, 0x95, 0xc5, 0xf0, 0xb9, 0xd5, 0xcd, 0xae,
+  0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+  0x08, 0x44, 0x06, 0x29, 0x01, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x42, 0x45, 0xd5, 0xec, 0xbb, 0xe3, 0x92, 0x7c,
+  0x32, 0x62, 0xdb, 0xed, 0xd9, 0x71, 0x58, 0x1c,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x07, 0x00,
+  0x14, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x07, 0x00,
+  0x0d, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x05, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x07, 0x00,
+  0x00, 0x5f, 0x65, 0x64, 0x61, 0x74, 0x61, 0x00,
+  0x5f, 0x5f, 0x62, 0x73, 0x73, 0x5f, 0x73, 0x74,
+  0x61, 0x72, 0x74, 0x00, 0x5f, 0x65, 0x6e, 0x64,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xb8, 0x01, 0x00, 0x00, 0x00, 0xbb, 0x2a, 0x00,
+  0x00, 0x00, 0xcd, 0x80, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf5, 0xfe, 0xff, 0x6f, 0xf8, 0x00, 0x00, 0x00,
+  0x05, 0x00, 0x00, 0x00, 0x78, 0x01, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00,
+  0x0a, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
+  0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x2e, 0x73, 0x68, 0x73, 0x74, 0x72, 0x74,
+  0x61, 0x62, 0x00, 0x2e, 0x6e, 0x6f, 0x74, 0x65,
+  0x2e, 0x67, 0x6e, 0x75, 0x2e, 0x62, 0x75, 0x69,
+  0x6c, 0x64, 0x2d, 0x69, 0x64, 0x00, 0x2e, 0x67,
+  0x6e, 0x75, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x00,
+  0x2e, 0x64, 0x79, 0x6e, 0x73, 0x79, 0x6d, 0x00,
+  0x2e, 0x64, 0x79, 0x6e, 0x73, 0x74, 0x72, 0x00,
+  0x2e, 0x74, 0x65, 0x78, 0x74, 0x00, 0x2e, 0x65,
+  0x68, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x00,
+  0x2e, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
+  0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xd4, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
+  0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
+  0xf6, 0xff, 0xff, 0x6f, 0x02, 0x00, 0x00, 0x00,
+  0xf8, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
+  0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+  0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x28, 0x01, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00,
+  0x50, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x78, 0x01, 0x00, 0x00, 0x78, 0x01, 0x00, 0x00,
+  0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0xa0, 0x01, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00,
+  0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xac, 0x01, 0x00, 0x00, 0xac, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0xa8, 0x1f, 0x00, 0x00, 0xa8, 0x0f, 0x00, 0x00,
+  0x58, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+  0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+
 uint8_t ELF32_MIPS_FILE[] = {
   0x7f, 0x45, 0x4c, 0x46, 0x01, 0x02, 0x01, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -332,4 +954,5 @@ uint8_t ELF32_MIPS_FILE[] = {
   0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
   0x00, 0x00, 0x00, 0x00
-};
\ No newline at end of file
+};
+
diff --git a/tests/test-elf.c b/tests/test-elf.c
index 6415933..062f417 100644
--- a/tests/test-elf.c
+++ b/tests/test-elf.c
@@ -24,6 +24,12 @@ int main(int argc, char** argv)
         condition: $a at elf.entry_point }",
       ELF64_FILE);
 
+  assert_true_rule_blob(
+      "import \"elf\" rule test { condition: elf.entry_point == 0xa0 }", ELF32_NOSECTIONS);
+
+  assert_true_rule_blob(
+      "import \"elf\" rule test { condition: elf.entry_point == 0x1a0 }", ELF32_SHAREDOBJ);
+
   assert_true_rule_blob("import \"elf\" rule test { \
     condition: elf.sections[2].name == \".comment\" }", ELF64_FILE);
 
@@ -46,5 +52,4 @@ int main(int argc, char** argv)
     elf.segments[i].file_size == 0xe0)}", ELF32_MIPS_FILE);
 
   yr_finalize();
-  return 0;
 }

From a2d40e616b831fbd81628479de7b62de306c8db1 Mon Sep 17 00:00:00 2001
From: plusvic <plusvic@gmail.com>
Date: Wed, 8 Mar 2017 16:56:17 +0100
Subject: [PATCH 32/36] Fix issue  #516

(cherry-picked from commit 2a36c168bb2097c0831d4ddf24a6c04bafe28dca)
---
 libyara/compiler.c           |  7 +++++++
 libyara/hash.c               |  3 +++
 libyara/include/yara/error.h |  1 +
 libyara/parser.c             | 21 +++++++++++++++++----
 4 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/libyara/compiler.c b/libyara/compiler.c
index 4c0fdeb..9bbaa51 100644
--- a/libyara/compiler.c
+++ b/libyara/compiler.c
@@ -914,6 +914,13 @@ YR_API char* yr_compiler_get_error_message(
           "unknown module \"%s\"",
           compiler->last_error_extra_info);
       break;
+    case ERROR_INVALID_MODULE_NAME:
+      snprintf(
+          buffer,
+          buffer_size,
+          "invalid module name \"%s\"",
+          compiler->last_error_extra_info);
+      break;
     case ERROR_DUPLICATED_STRUCTURE_MEMBER:
       snprintf(buffer,
           buffer_size,
diff --git a/libyara/hash.c b/libyara/hash.c
index 1ce2a53..5e5d8e9 100644
--- a/libyara/hash.c
+++ b/libyara/hash.c
@@ -27,6 +27,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
+#include <assert.h>
 #include <string.h>
 
 #include <yara/integers.h>
@@ -90,6 +91,8 @@ uint32_t hash(
   uint32_t result = seed;
   size_t i;
 
+  assert(len > 0);
+
   for (i = len - 1; i > 0; i--)
   {
     result ^= ROTATE_INT32(byte_to_int32[*b], i);
diff --git a/libyara/include/yara/error.h b/libyara/include/yara/error.h
index a5476b0..67e4bdb 100644
--- a/libyara/include/yara/error.h
+++ b/libyara/include/yara/error.h
@@ -88,6 +88,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define ERROR_COULD_NOT_READ_PROCESS_MEMORY     47
 #define ERROR_INVALID_EXTERNAL_VARIABLE_TYPE    48
 #define ERROR_REGULAR_EXPRESSION_TOO_COMPLEX    49
+#define ERROR_INVALID_MODULE_NAME               50
 
 
 #define FAIL_ON_ERROR(x) { \
diff --git a/libyara/parser.c b/libyara/parser.c
index 9c99e17..95f5b37 100644
--- a/libyara/parser.c
+++ b/libyara/parser.c
@@ -963,6 +963,19 @@ YR_META* yr_parser_reduce_meta_declaration(
 }
 
 
+int _yr_parser_valid_module_name(
+    SIZED_STRING* module_name)
+{
+  if (module_name->length == 0)
+    return FALSE;
+
+  if (strlen(module_name->c_string) != module_name->length)
+    return FALSE;
+
+  return TRUE;
+}
+
+
 int yr_parser_reduce_import(
     yyscan_t yyscanner,
     SIZED_STRING* module_name)
@@ -972,12 +985,12 @@ int yr_parser_reduce_import(
 
   char* name;
 
-  if (module_name->length == 0)
+  if (!_yr_parser_valid_module_name(module_name))
   {
-    compiler->last_result = ERROR_UNKNOWN_MODULE;
-    yr_compiler_set_error_extra_info(compiler, "");
+    compiler->last_result = ERROR_INVALID_MODULE_NAME;
+    yr_compiler_set_error_extra_info(compiler, module_name->c_string);
 
-    return ERROR_UNKNOWN_MODULE;
+    return ERROR_INVALID_MODULE_NAME;
   }
 
   module_structure = (YR_OBJECT*) yr_hash_table_lookup(

From f4003355bf05daf84cface923d9a21d399a1a9d5 Mon Sep 17 00:00:00 2001
From: Jacob Baines <baines.jacob@gmail.com>
Date: Thu, 16 Mar 2017 08:38:51 -0700
Subject: [PATCH 33/36] Fix ELF module issues on big endian system (#618)

(cherry picked from commit 75dba10e60313d5dd44548b6f60f1386320556c7)
---
 libyara/exefiles.c    | 16 ++++++++++------
 libyara/modules/elf.c |  8 ++++----
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/libyara/exefiles.c b/libyara/exefiles.c
index 293b905..5cac047 100644
--- a/libyara/exefiles.c
+++ b/libyara/exefiles.c
@@ -157,11 +157,12 @@ static uint64_t yr_elf_rva_to_offset_32(
 {
   // if the binary is an executable then prefer the program headers to resolve
   // the offset
-  if (elf_header->type == ELF_ET_EXEC)
+  if (yr_le16toh(elf_header->type) == ELF_ET_EXEC)
   {
     int i;
     elf32_program_header_t* program;
-    if (elf_header->ph_offset == 0 || elf_header->ph_entry_count == 0)
+    if (yr_le32toh(elf_header->ph_offset) == 0 ||
+        yr_le16toh(elf_header->ph_entry_count == 0))
       return 0;
 
     // check to prevent integer wraps
@@ -199,7 +200,8 @@ static uint64_t yr_elf_rva_to_offset_32(
     int i;
     elf32_section_header_t* section;
 
-    if (elf_header->sh_offset == 0 || elf_header->sh_entry_count == 0)
+    if (yr_le32toh(elf_header->sh_offset) == 0 ||
+        yr_le16toh(elf_header->sh_entry_count == 0))
       return 0;
 
     // check to prevent integer wraps
@@ -253,11 +255,12 @@ static uint64_t yr_elf_rva_to_offset_64(
 {
   // if the binary is an executable then prefer the program headers to resolve
   // the offset
-  if (elf_header->type == ELF_ET_EXEC)
+  if (yr_le16toh(elf_header->type) == ELF_ET_EXEC)
   {
     int i;
     elf64_program_header_t* program;
-    if (elf_header->ph_offset == 0 || elf_header->ph_entry_count == 0)
+    if (yr_le64toh(elf_header->ph_offset) == 0 ||
+        yr_le16toh(elf_header->ph_entry_count == 0))
       return 0;
 
     // check that 'ph_offset' doesn't wrap when added to the
@@ -290,7 +293,8 @@ static uint64_t yr_elf_rva_to_offset_64(
     int i;
     elf64_section_header_t* section;
 
-    if (elf_header->sh_offset == 0 || elf_header->sh_entry_count == 0)
+    if (yr_le64toh(elf_header->sh_offset) == 0 ||
+        yr_le16toh(elf_header->sh_entry_count) == 0)
       return 0;
 
     // check that 'sh_offset' doesn't wrap when added to the
diff --git a/libyara/modules/elf.c b/libyara/modules/elf.c
index 8ea6c94..a4f7568 100644
--- a/libyara/modules/elf.c
+++ b/libyara/modules/elf.c
@@ -72,7 +72,7 @@ uint64_t elf_rva_to_offset_##bits##_##bo(                                      \
     uint64_t rva,                                                              \
     size_t elf_size)                                                           \
 {                                                                              \
-  if (elf_header->type == ELF_ET_EXEC)                                         \
+  if (yr_##bo##16toh(elf_header->type) == ELF_ET_EXEC)                         \
   {                                                                            \
     int i;                                                                     \
                                                                                \
@@ -224,12 +224,12 @@ void parse_elf_header_##bits##_##bo(                                           \
       set_integer(yr_##bo##bits##toh(section->offset), elf_obj,                \
                   "sections[%i].offset", i);                                   \
                                                                                \
-      if (yr_##bo##bits##toh(section->name) < elf_size &&                      \
+      if (yr_##bo##32toh(section->name) < elf_size &&                          \
           str_table > (char*) elf &&                                           \
-          str_table + yr_##bo##bits##toh(section->name) <                      \
+          str_table + yr_##bo##32toh(section->name) <                          \
             (char*) elf + elf_size)                                            \
       {                                                                        \
-        set_string(str_table + yr_##bo##bits##toh(section->name), elf_obj,     \
+        set_string(str_table + yr_##bo##32toh(section->name), elf_obj,         \
                    "sections[%i].name", i);                                    \
       }                                                                        \
                                                                                \

From 3aa1d8ae08a07bdbde992f03edb8322d6cf6ad2c Mon Sep 17 00:00:00 2001
From: plusvic <plusvic@gmail.com>
Date: Thu, 16 Mar 2017 16:38:16 +0100
Subject: [PATCH 34/36] Add missing endianness conversions

(cherry picked from commit b6851ea05bfcc7938101aff26f48094cba3e07f5)
---
 libyara/modules/pe.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/libyara/modules/pe.c b/libyara/modules/pe.c
index f78a9d5..1c90a6a 100644
--- a/libyara/modules/pe.c
+++ b/libyara/modules/pe.c
@@ -542,7 +542,7 @@ void pe_parse_version_info(
              yr_le16toh(string->Length) != 0 &&
              string < string_table)
       {
-        if (string->ValueLength > 0)
+        if (yr_le16toh(string->ValueLength) > 0)
         {
           char* string_value = (char*) ADD_OFFSET(string,
               sizeof(VERSION_INFO) + 2 * (strnlen_w(string->Key) + 1));
@@ -559,7 +559,7 @@ void pe_parse_version_info(
           }
         }
 
-        string = ADD_OFFSET(string, string->Length);
+        string = ADD_OFFSET(string, yr_le16toh(string->Length));
       }
     }
   }
@@ -953,7 +953,9 @@ void pe_parse_certificates(
   }
 
   // Store the end of directory, making comparisons easier.
-  eod = pe->data + yr_le32toh(directory->VirtualAddress) + directory->Size;
+  eod = pe->data + \
+        yr_le32toh(directory->VirtualAddress) + \
+        yr_le32toh(directory->Size);
 
   win_cert = (PWIN_CERTIFICATE) \
     (pe->data + yr_le32toh(directory->VirtualAddress));
@@ -1137,7 +1139,10 @@ void pe_parse_certificates(
       counter++;
     }
 
-    uintptr_t end = (uintptr_t)((uint8_t *) win_cert) + win_cert->Length;
+    uintptr_t end = \
+        (uintptr_t)((uint8_t *) win_cert) + \
+        yr_le32toh(win_cert->Length);
+
     win_cert = (PWIN_CERTIFICATE)(end + (end % 8));
 
     BIO_free(cert_bio);
@@ -1777,7 +1782,7 @@ static uint64_t rich_internal(
 
   for (i = 0; i < rich_count; i++)
   {
-    DWORD id_version = clear_rich_signature->versions[i].id_version;
+    DWORD id_version = yr_le32toh(clear_rich_signature->versions[i].id_version);
 
     int match_version = (version == RICH_VERSION_VERSION(id_version));
     int match_toolid = (toolid == RICH_VERSION_ID(id_version));

From f6553648f19ed33d9a1bbdcf9f458215e50d35a8 Mon Sep 17 00:00:00 2001
From: Jacob Baines <baines.jacob@gmail.com>
Date: Mon, 20 Mar 2017 02:17:24 -0700
Subject: [PATCH 35/36] Linux Memory Scan Can Leave Process In Stopped State
 (#622)

* Wait for process to stop

* Specify which process to wait for

(cherry picked from commit 68ffbbcdc992e3f1969d0aa37d3d0b1568b5514b)
---
 libyara/proc.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/libyara/proc.c b/libyara/proc.c
index 21c21cb..5879b44 100644
--- a/libyara/proc.c
+++ b/libyara/proc.c
@@ -352,6 +352,7 @@ int _yr_process_attach(
     int pid,
     YR_PROC_ITERATOR_CTX* context)
 {
+  int status;
   char buffer[256];
 
   context->pid = pid;
@@ -386,6 +387,22 @@ int _yr_process_attach(
     return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
   }
 
+  status = 0;
+  if (waitpid(pid, &status, 0) == -1)
+  {
+    // this is a strange error state where we attached but the proc didn't
+    // stop. Try to detach and clean up.
+    ptrace(PTRACE_DETACH, context->pid, NULL, 0);
+
+    fclose(context->maps);
+    context->maps = NULL;
+
+    close(context->mem_fd);
+    context->mem_fd = -1;
+
+    return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
+  }
+
   return ERROR_SUCCESS;
 }
 

From 62ad5a701b04d0fa955ef5593bcd7ec789d1241e Mon Sep 17 00:00:00 2001
From: plusvic <plusvic@gmail.com>
Date: Fri, 23 Sep 2016 12:03:30 +0200
Subject: [PATCH 36/36] Add appveyor config file

(cherry picked from commit b254eeef98a7042b6df28b3432c065860583e8cc)
---
 appveyor.yml | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
 create mode 100644 appveyor.yml

diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..2ba177b
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,15 @@
+# AppVeyor CI for Windows
+
+version: 3.5.{build}
+pull_requests:
+  do_not_increment_build_number: true
+configuration: Release
+platform:
+- x64
+- x86
+before_build:
+- ps: nuget restore windows/vs2015/yara.sln
+build:
+  project: windows/vs2015/yara.sln
+  verbosity: minimal
+test: off