From a07b8943aff6d1daa2af404ba086d7c45fcd76c7 Mon Sep 17 00:00:00 2001 From: Hilko Bengen 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 be389a261c..20dbe4abb3 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 9afa314db4..d03e91ac5a 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 + #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 0000000000..945d8439f3 --- /dev/null +++ b/libyara/include/yara/pe_utils.h @@ -0,0 +1,30 @@ +#ifndef YR_PE_UTILS_H +#define YR_PE_UTILS_H + +#include + +#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 +time_t ASN1_get_time_t(ASN1_TIME* time); +#endif + +#endif diff --git a/libyara/modules/pe.c b/libyara/modules/pe.c index 1af5562cec..8c4cb12448 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 #include -#include "pe_utils.c" +#include #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 81a7ae4a53..ed69b8097d 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 +#if defined(_WIN32) +#define timegm _mkgmtime +#endif + +#include + +#include +#include #include #include +#include +#include -#if defined(WIN32) -#include -#define strncasecmp _strnicmp -#define timegm _mkgmtime +#if HAVE_LIBCRYPTO +#include #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 @@ -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 c7e31f7cfd..dc3c59f4ab 100644 --- a/windows/vs2015/libyara/libyara.vcxproj +++ b/windows/vs2015/libyara/libyara.vcxproj @@ -189,6 +189,7 @@ + From 89dbf689408399d34f160a916c9cc428dc7a66a2 Mon Sep 17 00:00:00 2001 From: "Victor M. Alvarez" 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 10d1688bf3..f61145a638 100644 --- a/windows/vs2010/libyara/libyara.vcxproj +++ b/windows/vs2010/libyara/libyara.vcxproj @@ -74,7 +74,7 @@ - _CRT_SECURE_NO_WARNINGS;CUCKOO;HASH;HAVE_LIBCRYPTO + _CRT_SECURE_NO_WARNINGS;CUCKOO_MODULE;HASH_MODULE;HAVE_LIBCRYPTO ..\..\..;..\..\..\libyara;..\..\..\libyara\include;..\..\..\windows\include;%(AdditionalIncludeDirectories) MultiThreadedDebugDLL 4005;4273;4090; @@ -98,7 +98,7 @@ - CUCKOO;HASH;HAVE_LIBCRYPTO + CUCKOO_MODULE;HASH_MODULE;HAVE_LIBCRYPTO ..\..\..;..\..\..\libyara;..\..\..\libyara\include;..\..\..\windows\include;%(AdditionalIncludeDirectories) 4005;4273;4090; CompileAsCpp @@ -120,7 +120,7 @@ - _CRT_SECURE_NO_WARNINGS;CUCKOO;HASH;HAVE_LIBCRYPTO + _CRT_SECURE_NO_WARNINGS;CUCKOO_MODULE;HASH_MODULE;HAVE_LIBCRYPTO ..\..\..;..\..\..\libyara;..\..\..\libyara\include;..\..\..\windows\include;%(AdditionalIncludeDirectories) MultiThreadedDLL 4005;4273;4090;%(DisableSpecificWarnings) @@ -140,7 +140,7 @@ - CUCKOO;HASH;HAVE_LIBCRYPTO + CUCKOO_MODULE;HASH_MODULE;HAVE_LIBCRYPTO ..\..\..;..\..\..\libyara;..\..\..\libyara\include;..\..\..\windows\include;%(AdditionalIncludeDirectories) 4005;4273;4090;%(DisableSpecificWarnings) CompileAsCpp diff --git a/windows/vs2010/yara.sln b/windows/vs2010/yara.sln index 53a4058edf..054f60c15b 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 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 90f14a5f80..4a518da7c5 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 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 d0f368803f..64c3feabff 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 #include #include -#include #include #include - +#include #include #include #include @@ -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 640304a718..b22af75214 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 8aa3058681..a305f067d1 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,11 +476,17 @@ 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 } \ From 755b51fac03638c689bc6652e97fdc7f12ee9d2a Mon Sep 17 00:00:00 2001 From: plusvic 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 1123869007..0ced96e081 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 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 53d30f47e3..2351889092 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 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 dd4c251790..4c0fdeb855 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 75d56ed777..a5476b0e9f 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 a33d98970f..a0cf4f9da8 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 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 64c3feabff..03f0465a70 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 b22af75214..a1846064a2 100644 --- a/libyara/lexer.l +++ b/libyara/lexer.l @@ -541,6 +541,7 @@ u?int(8|16|32)(be)? { \\(.|\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 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 d03e91ac5a..001da4da4b 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 945d8439f3..88e5a61910 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 From 86c141654fc4d35e5b76edf5a66e2c72e0ce0307 Mon Sep 17 00:00:00 2001 From: plusvic 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 7707178792..6d784e698f 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 f1108e5924..b3744a39eb 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 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 a8503b79d4..7a7981fdf8 100644 --- a/yara.c +++ b/yara.c @@ -38,8 +38,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#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 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 e9e27eea92..6d821c881a 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 b0a79b6d98..3facabda1b 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 f8d455a002..599e3979ed 100644 --- a/libyara/exefiles.c +++ b/libyara/exefiles.c @@ -32,6 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #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 0f803df6fc..0ce27b2587 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 #include -#include #include #include #include +#include #include #include #include @@ -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 06b3cbd2a8..0e35f375b1 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 0090d73e1f..56bae40910 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 f111373ec2..440b7777fd 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 3b5b058e79..38e1bcd45e 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 8fff40e5c5..77c26b6130 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 001da4da4b..0291cb0d46 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 +#include #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 104d9eeaf2..da0fb8879b 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 + #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 0ced96e081..9c99e171a9 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 c2c6270cc7..93cb06e32c 100644 --- a/tests/test-pe.c +++ b/tests/test-pe.c @@ -1,8 +1,11 @@ #include +#include +#include #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 a305f067d1..19a0902bee 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 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 4d4f7fa0f1..8c1652a7f8 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 88e5a61910..86571c5adb 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 ed4ccd1a63..08c3ce4360 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 8c4cb12448..7c32daf93d 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 ed69b8097d..9b802868df 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 0000000000..8d13b47d0c --- /dev/null +++ b/tests/test-elf.c @@ -0,0 +1,29 @@ +#include +#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 93cb06e32c..881939e15a 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 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 3facabda1b..1a347c0e24 100644 --- a/libyara/exec.c +++ b/libyara/exec.c @@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include #include #include #include diff --git a/libyara/exefiles.c b/libyara/exefiles.c index 599e3979ed..05d1de711a 100644 --- a/libyara/exefiles.c +++ b/libyara/exefiles.c @@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include #include #include #include diff --git a/libyara/include/yara/endian.h b/libyara/include/yara/endian.h new file mode 100644 index 0000000000..06d8c14c0e --- /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 + +#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 0291cb0d46..c189146a59 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 #include -#include #pragma pack(push, 1) diff --git a/libyara/include/yara/utils.h b/libyara/include/yara/utils.h index da0fb8879b..58f13476d1 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 08c3ce4360..e934084f79 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 #include +#include #include #include diff --git a/libyara/modules/pe.c b/libyara/modules/pe.c index 7c32daf93d..f78a9d5970 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 #include #include #include diff --git a/libyara/modules/pe_utils.c b/libyara/modules/pe_utils.c index 9b802868df..dddbba39c8 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 +#include #include #include #include From 0dafb5078bee2c880e3db5ad372c39ceb8a3a9af Mon Sep 17 00:00:00 2001 From: plusvic 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 1a347c0e24..5266b9acc6 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 38e1bcd45e..9e9a6e3e3b 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 bdacaa9a23..0fea79b1fd 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 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 8c1652a7f8..8f5ab597c5 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 436d0063ae..c70ae63e36 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 0000000000..8ebea58da6 --- /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 +#include +#include +#include +#include + +#include +#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 5597c9802d..59105dda67 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 89b245b528..835115ff62 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 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 8ebea58da6..29232b23d9 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 #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 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 c70ae63e36..a9698b326b 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 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 a9698b326b..edead24578 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 8ea0cb8147..8ef657518f 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 490c472b32..336ba7c683 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 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 525788486a..5a65c2eb00 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 d6bf46a2f1..43a68b6274 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 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 5a65c2eb00..5479c209cb 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 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 5479c209cb..07c0b8806c 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 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 03f0465a70..b20e0c4768 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 a1846064a2..e1bd98be62 100644 --- a/libyara/lexer.l +++ b/libyara/lexer.l @@ -583,6 +583,13 @@ u?int(8|16|32)(be)? { \\. { 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 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 0ce27b2587..eb28701c32 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 }; @@ -2586,6 +2586,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; @@ -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 56bae40910..be24307935 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 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 eb28701c32..9c79512958 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 be24307935..addb55d81a 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 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 e934084f79..dff586e695 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 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 6d784e698f..388a5c64fc 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 b3744a39eb..ecb6ad4b77 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 19a0902bee..d4e8f1ccc3 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 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 9c79512958..6d4ba05c9f 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 addb55d81a..9cb4be7177 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 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 20dbe4abb3..6861843b93 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 0000000000..02fff634ad --- /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 + +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 06d8c14c0e..8d75012888 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 #include -#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 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 dff586e695..c6ee384da5 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 08bf5b6f59..1659a918d4 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 8d13b47d0c..6415933910 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 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 05d1de711a..293b905cfd 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 c6ee384da5..8ea6c94f4c 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 1659a918d4..d7a617a243 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 6415933910..062f417d8a 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 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 4c0fdeb855..9bbaa51656 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 1ce2a5314c..5e5d8e948b 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 #include #include @@ -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 a5476b0e9f..67e4bdbad7 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 9c99e171a9..95f5b37859 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 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 293b905cfd..5cac047a6c 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 8ea6c94f4c..a4f75681ad 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 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 f78a9d5970..1c90a6a723 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 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 21c21cb07a..5879b446d7 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 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 0000000000..2ba177b9cb --- /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