diff --git a/.gitignore b/.gitignore index ee07a5a..a37e177 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,26 @@ -/androguard-yara-*.tar.gz -/yara-*.tar.gz +/androguard-yara-3.5.0-fc14c0f.tar.gz +/androguard-yara-3.6.0-e4cf5fa.tar.gz +/androguard-yara-3.6.2-e4cf5fa.tar.gz +/androguard-yara-3.6.3-e4cf5fa.tar.gz +/androguard-yara-e4cf5fa.tar.gz +/androguard-yara-fa11a84.tar.gz +/androguard-yara-3eea86a.tar.gz +/androguard-yara-2020-04-22-3eea86a.tar.gz +/yara-3.5.0-7473441.tar.gz +/yara-3.6.0.tar.gz +/yara-3.6.2.tar.gz +/yara-3.6.3.tar.gz +/yara-3.7.0.tar.gz +/yara-3.7.1.tar.gz +/yara-3.8.1.tar.gz +/yara-3.9.0.tar.gz +/yara-3.10.0.tar.gz +/yara-3.11.0.tar.gz +/yara-4.0.0.tar.gz +/yara-4.0.1.tar.gz +/yara-4.0.2.tar.gz +/yara-4.0.4.tar.gz +/yara-4.0.5.tar.gz +/yara-4.1.0.tar.gz +/yara-4.1.1.tar.gz +/yara-4.1.3.tar.gz diff --git a/0001-Use-OpenSSL-accessor-functions-for-ASN1_STRING.patch b/0001-Use-OpenSSL-accessor-functions-for-ASN1_STRING.patch deleted file mode 100644 index 4cffbf9..0000000 --- a/0001-Use-OpenSSL-accessor-functions-for-ASN1_STRING.patch +++ /dev/null @@ -1,235 +0,0 @@ -From 05a1e87e77226c8dd7e2228d26e3aa462e968dc7 Mon Sep 17 00:00:00 2001 -From: rpm-build -Date: Thu, 23 Apr 2026 17:55:01 -0400 -Subject: [PATCH] Use OpenSSL accessor functions for ASN1_STRING - -Directly accessing the `data` and `length` fields of `ASN1_STRING` structures -is incompatible with newer versions of OpenSSL, where these structures are -opaque. This change replaces direct field access with the standard -`ASN1_STRING_get0_data` and `ASN1_STRING_length` accessor functions to ensure -compatibility. Additionally, an `X509_NAME_ENTRY` pointer is made `const` to -align with modern OpenSSL API signatures. - -Co-authored-by: Gemini -Signed-off-by: rpm-build ---- - .../pe/authenticode-parser/authenticode.c | 32 +++++++++---------- - .../pe/authenticode-parser/certificate.c | 4 +-- - .../pe/authenticode-parser/countersignature.c | 28 ++++++++-------- - 3 files changed, 32 insertions(+), 32 deletions(-) - -diff --git a/libyara/modules/pe/authenticode-parser/authenticode.c b/libyara/modules/pe/authenticode-parser/authenticode.c -index f385860..a2f7f74 100644 ---- a/libyara/modules/pe/authenticode-parser/authenticode.c -+++ b/libyara/modules/pe/authenticode-parser/authenticode.c -@@ -78,8 +78,8 @@ static SpcIndirectDataContent* get_content(PKCS7* content) - if (!spcContent) - return NULL; - -- int len = content->d.other->value.sequence->length; -- const uint8_t* data = content->d.other->value.sequence->data; -+ int len = ASN1_STRING_length(content->d.other->value.sequence); -+ const uint8_t* data = ASN1_STRING_get0_data(content->d.other->value.sequence); - - d2i_SpcIndirectDataContent(&spcContent, &data, len); - -@@ -88,8 +88,8 @@ static SpcIndirectDataContent* get_content(PKCS7* content) - - static char* parse_program_name(ASN1_TYPE* spcAttr) - { -- const uint8_t* spcData = spcAttr->value.sequence->data; -- int spcLen = spcAttr->value.sequence->length; -+ const uint8_t* spcData = ASN1_STRING_get0_data(spcAttr->value.sequence); -+ int spcLen = ASN1_STRING_length(spcAttr->value.sequence); - SpcSpOpusInfo* spcInfo = d2i_SpcSpOpusInfo(NULL, &spcData, spcLen); - if (!spcInfo) - return NULL; -@@ -131,8 +131,8 @@ static void parse_nested_authenticode(PKCS7_SIGNER_INFO* si, AuthenticodeArray* - ASN1_TYPE* nested = X509_ATTRIBUTE_get0_type(attr, i); - if (nested == NULL) - break; -- int len = nested->value.sequence->length; -- const uint8_t* data = nested->value.sequence->data; -+ int len = ASN1_STRING_length(nested->value.sequence); -+ const uint8_t* data = ASN1_STRING_get0_data(nested->value.sequence); - AuthenticodeArray* auth = authenticode_new(data, len); - if (!auth) - continue; -@@ -162,8 +162,8 @@ static void parse_pkcs9_countersig(PKCS7* p7, Authenticode* auth) - ASN1_TYPE* nested = X509_ATTRIBUTE_get0_type(attr, i); - if (nested == NULL) - break; -- int len = nested->value.sequence->length; -- const uint8_t* data = nested->value.sequence->data; -+ int len = ASN1_STRING_length(nested->value.sequence); -+ const uint8_t* data = ASN1_STRING_get0_data(nested->value.sequence); - - Countersignature* sig = pkcs9_countersig_new(data, len, p7->d.sign->cert, si->enc_digest); - if (!sig) -@@ -193,8 +193,8 @@ static void parse_ms_countersig(PKCS7* p7, Authenticode* auth) - ASN1_TYPE* nested = X509_ATTRIBUTE_get0_type(attr, i); - if (nested == NULL) - break; -- int len = nested->value.sequence->length; -- const uint8_t* data = nested->value.sequence->data; -+ int len = ASN1_STRING_length(nested->value.sequence); -+ const uint8_t* data = ASN1_STRING_get0_data(nested->value.sequence); - - Countersignature* csig = ms_countersig_new(data, len, si->enc_digest); - if (!csig) -@@ -209,8 +209,8 @@ static void parse_ms_countersig(PKCS7* p7, Authenticode* auth) - - static bool authenticode_verify(PKCS7* p7, PKCS7_SIGNER_INFO* si, X509* signCert) - { -- const uint8_t* contentData = p7->d.sign->contents->d.other->value.sequence->data; -- long contentLen = p7->d.sign->contents->d.other->value.sequence->length; -+ const uint8_t* contentData = ASN1_STRING_get0_data(p7->d.sign->contents->d.other->value.sequence); -+ long contentLen = ASN1_STRING_length(p7->d.sign->contents->d.other->value.sequence); - - uint64_t version = 0; - ASN1_INTEGER_get_uint64(&version, p7->d.sign->version); -@@ -315,8 +315,8 @@ AuthenticodeArray* authenticode_new(const uint8_t* data, int32_t len) - int digestnid = OBJ_obj2nid(messageDigest->digestAlgorithm->algorithm); - auth->digest_alg = strdup(OBJ_nid2ln(digestnid)); - -- int digestLen = messageDigest->digest->length; -- const uint8_t* digestData = messageDigest->digest->data; -+ int digestLen = ASN1_STRING_length(messageDigest->digest); -+ const uint8_t* digestData = ASN1_STRING_get0_data(messageDigest->digest); - byte_array_init(&auth->digest, digestData, digestLen); - - SpcIndirectDataContent_free(dataContent); -@@ -372,8 +372,8 @@ AuthenticodeArray* authenticode_new(const uint8_t* data, int32_t len) - digestnid = OBJ_obj2nid(si->digest_alg->algorithm); - signer->digest_alg = strdup(OBJ_nid2ln(digestnid)); - -- digestLen = digest->value.asn1_string->length; -- digestData = digest->value.asn1_string->data; -+ digestLen = ASN1_STRING_length(digest->value.asn1_string); -+ digestData = ASN1_STRING_get0_data(digest->value.asn1_string); - byte_array_init(&signer->digest, digestData, digestLen); - - /* Authenticode stores optional programName in non-optional SpcSpOpusInfo attribute */ -diff --git a/libyara/modules/pe/authenticode-parser/certificate.c b/libyara/modules/pe/authenticode-parser/certificate.c -index fc754e4..97c7e3e 100644 ---- a/libyara/modules/pe/authenticode-parser/certificate.c -+++ b/libyara/modules/pe/authenticode-parser/certificate.c -@@ -59,13 +59,13 @@ static void parse_name_attributes(X509_NAME* raw, Attributes* attr) - - int entryCount = X509_NAME_entry_count(raw); - for (int i = entryCount - 1; i >= 0; --i) { -- X509_NAME_ENTRY* entryName = X509_NAME_get_entry(raw, i); -+ const X509_NAME_ENTRY* entryName = X509_NAME_get_entry(raw, i); - ASN1_STRING* asn1String = X509_NAME_ENTRY_get_data(entryName); - - const char* key = OBJ_nid2sn(OBJ_obj2nid(X509_NAME_ENTRY_get_object(entryName))); - - ByteArray array = {0}; -- if (byte_array_init(&array, asn1String->data, asn1String->length) == -1) -+ if (byte_array_init(&array, ASN1_STRING_get0_data(asn1String), ASN1_STRING_length(asn1String)) == -1) - break; - - if (strcmp(key, "C") == 0 && !attr->country.data) -diff --git a/libyara/modules/pe/authenticode-parser/countersignature.c b/libyara/modules/pe/authenticode-parser/countersignature.c -index 0fb4576..6cb5eed 100644 ---- a/libyara/modules/pe/authenticode-parser/countersignature.c -+++ b/libyara/modules/pe/authenticode-parser/countersignature.c -@@ -141,13 +141,13 @@ Countersignature* pkcs9_countersig_new( - result->chain = parse_signer_chain(signCert, certs); - - /* Get digest that corresponds to decrypted encrypted digest in signature */ -- ASN1_TYPE* messageDigest = PKCS7_get_signed_attribute(si, NID_pkcs9_messageDigest); -+ const ASN1_TYPE* messageDigest = PKCS7_get_signed_attribute(si, NID_pkcs9_messageDigest); - if (!messageDigest) { - result->verify_flags = COUNTERSIGNATURE_VFY_DIGEST_MISSING; - goto end; - } - -- size_t digestLen = messageDigest->value.octet_string->length; -+ size_t digestLen = ASN1_STRING_length(messageDigest->value.octet_string); - - if (!digestLen) { - result->verify_flags = COUNTERSIGNATURE_VFY_DIGEST_MISSING; -@@ -160,7 +160,7 @@ Countersignature* pkcs9_countersig_new( - goto end; - } - -- const uint8_t* digestData = messageDigest->value.octet_string->data; -+ const uint8_t* digestData = ASN1_STRING_get0_data(messageDigest->value.octet_string); - byte_array_init(&result->digest, digestData, digestLen); - - /* By this point we all necessary things for verification -@@ -187,8 +187,8 @@ Countersignature* pkcs9_countersig_new( - goto end; - } - -- uint8_t* encData = si->enc_digest->data; -- size_t encLen = si->enc_digest->length; -+ const uint8_t* encData = ASN1_STRING_get0_data(si->enc_digest); -+ size_t encLen = ASN1_STRING_length(si->enc_digest); - - /* Decrypt the encrypted digest */ - EVP_PKEY_verify_recover_init(ctx); -@@ -220,7 +220,7 @@ Countersignature* pkcs9_countersig_new( - const uint8_t* data_ptr = decData; - DigestInfo* digest_info = d2i_DigestInfo(NULL, &data_ptr, decLen); - if (digest_info) { -- isValid = !memcmp(digest_info->digest->data, calc_digest, mdLen); -+ isValid = !memcmp(ASN1_STRING_get0_data(digest_info->digest), calc_digest, mdLen); - DigestInfo_free(digest_info); - } else { - isValid = false; -@@ -235,7 +235,7 @@ Countersignature* pkcs9_countersig_new( - - /* Now check the countersignature message-digest that should correspond - * to Signatures encrypted digest it countersigns */ -- calculate_digest(md, enc_digest->data, enc_digest->length, calc_digest); -+ calculate_digest(md, ASN1_STRING_get0_data(enc_digest), ASN1_STRING_length(enc_digest), calc_digest); - - /* Check if calculated one matches the stored one */ - if (digestLen != mdLen || memcmp(calc_digest, digestData, mdLen) != 0) { -@@ -269,8 +269,8 @@ TS_TST_INFO* IMPL_FUNC_NAME(get_ts_tst_info, cms)(CountersignatureImpl* impl) - return NULL; - } - -- const uint8_t* data = (*content)->data; -- TS_TST_INFO* ts_tst_info = d2i_TS_TST_INFO(NULL, &data, (*content)->length); -+ const uint8_t* data = ASN1_STRING_get0_data(*content); -+ TS_TST_INFO* ts_tst_info = d2i_TS_TST_INFO(NULL, &data, ASN1_STRING_length(*content)); - if (!ts_tst_info) { - return NULL; - } -@@ -400,8 +400,8 @@ int IMPL_FUNC_NAME(verify_digest, cms)( - return 0; - } - -- if (ts_imprint_digest->length != (int)digest_size || -- memcmp(ts_imprint_digest->data, digest, digest_size) != 0) { -+ if (ASN1_STRING_length(ts_imprint_digest) != (int)digest_size || -+ memcmp(ASN1_STRING_get0_data(ts_imprint_digest), digest, digest_size) != 0) { - TS_TST_INFO_free(ts_tst_info); - return 0; - } -@@ -554,8 +554,8 @@ Countersignature* ms_countersig_new(const uint8_t* data, long size, ASN1_STRING* - - ASN1_STRING* rawDigest = TS_MSG_IMPRINT_get_msg(imprint); - -- int digestLen = rawDigest->length; -- uint8_t* digestData = rawDigest->data; -+ int digestLen = ASN1_STRING_length(rawDigest); -+ const uint8_t* digestData = ASN1_STRING_get0_data(rawDigest); - - byte_array_init(&result->digest, digestData, digestLen); - -@@ -571,7 +571,7 @@ Countersignature* ms_countersig_new(const uint8_t* data, long size, ASN1_STRING* - } - - uint8_t calc_digest[EVP_MAX_MD_SIZE]; -- calculate_digest(md, enc_digest->data, enc_digest->length, calc_digest); -+ calculate_digest(md, ASN1_STRING_get0_data(enc_digest), ASN1_STRING_length(enc_digest), calc_digest); - - #if OPENSSL_VERSION_NUMBER >= 0x3000000fL - int mdLen = EVP_MD_get_size(md); --- -2.53.0 - diff --git a/changelog b/changelog deleted file mode 100644 index 298d7f6..0000000 --- a/changelog +++ /dev/null @@ -1,231 +0,0 @@ -* Mon Sep 16 2024 Michal Ambroz - 4.5.2-1 -- bump to 4.5.2 - -* Sat Jul 20 2024 Fedora Release Engineering - 4.5.1-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild - -* Mon May 27 2024 Michal Ambroz - 4.5.1-1 -- bump to 4.5.1 - -* Wed Feb 14 2024 Michal Ambroz - 4.5.0-1 -- bump to 4.5.0 - -* Fri Jan 26 2024 Fedora Release Engineering - 4.4.0-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild - -* Mon Jan 22 2024 Fedora Release Engineering - 4.4.0-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild - -* Sun Sep 17 2023 Mikel Olasagasti Uranga - 4.4.0-1 -- bump to 4.4.0 - -* Sat Jul 22 2023 Fedora Release Engineering - 4.3.2-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild - -* Wed Jun 14 2023 Michal Ambroz - 4.3.2-1 -- bump to 4.3.2 - -* Wed Apr 26 2023 Michal Ambroz - 4.3.1-1 -- bump to 4.3.1 - -* Thu Mar 30 2023 Michal Ambroz - 4.3.0-1 -- bump to 4.3.0 - -* Tue Jan 24 2023 Michal Ambroz - 4.3.0-0.rc1.3 -- fix EPEL9 build = reenable the SHA1 certificate validation in OpenSSL for make check - -* Sat Jan 21 2023 Michal Ambroz - 4.3.0-0.rc1.2 -- fix EPEL7 build - -* Sat Jan 21 2023 Fedora Release Engineering - 4.3.0-0.rc1.1.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild - -* Tue Jan 03 2023 Michal Ambroz - 4.3.0-0.rc1.1 -- bump to 4.3.0 rc1 -- remove the androguard module which is no longer available from github - -* Tue Aug 09 2022 Mikel Olasagasti Uranga - 4.2.3-1 -- Update to 4.2.3 (#2116594) - -* Sat Jul 23 2022 Fedora Release Engineering - 4.2.2-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild - -* Mon Jul 18 2022 Mikel Olasagasti Uranga - 4.2.2-1 -- Update to 4.2.2 (#2103444) -- BUGFIX: Fix buffer overrun in "dex" module (#1728). -- BUGFIX: Wrong offset used when checking Version string of .net metadata (#1708). -- BUGFIX: YARA doesn't compile if --with-debug-verbose flag is enabled (#1719). -- BUGFIX: Null-pointer dereferences while loading corrupted compiled rules (#1727). - -* Mon May 23 2022 Michal Ambroz - 4.2.1-1 -- bump to 4.2.1 -- adding changes based on proposal of Mikel Olasagasti Uranga: -- change to BSD license as yara was relicensed in 2016 -- minor changes to spec, like using https for URL -- remove old patches -- enable checks - -* Sat Mar 12 2022 Michal Ambroz - 4.2.0-1 -- bump to 4.2.0 - -* Thu Feb 17 2022 Michal Ambroz - 4.2.0-0.rc1.1 -- bump to 4.2.0-rc1 - -* Sat Jan 22 2022 Fedora Release Engineering - 4.1.3-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild - -* Wed Nov 10 2021 Michal Ambroz - 4.1.3-1 -- bump to 4.1.3 - -* Sat Nov 06 2021 Adrian Reber - 4.1.1-5 -- Rebuilt for protobuf 3.19.0 - -* Mon Oct 25 2021 Adrian Reber - 4.1.1-4 -- Rebuilt for protobuf 3.18.1 - -* Tue Sep 14 2021 Sahana Prasad - 4.1.1-3 -- Rebuilt with OpenSSL 3.0.0 - -* Fri Jul 23 2021 Fedora Release Engineering - 4.1.1-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild - -* Mon May 24 2021 Michal Ambroz - 4.1.1-1 -- bump to 4.1.1 - -* Mon Apr 26 2021 Michal Ambroz - 4.1.0-1 -- bump to 4.1.0 - -* Sun Apr 25 2021 Michal Ambroz - 4.0.5-2 -- rebuild for epel - -* Fri Feb 5 2021 Michal Ambroz - 4.0.5-1 -- bump to yara bugfix 4.0.5 release - -* Wed Feb 3 2021 Michal Ambroz - 4.0.4-1 -- bump to yara bugfix 4.0.4 release - -* Thu Jul 16 2020 Michal Ambroz - 4.0.2-1 -- bump to yara bugfix 4.0.2 release -- fix build on epel7 - -* Sun Jun 14 2020 Adrian Reber - 4.0.1-2 -- Rebuilt for protobuf 3.12 - -* Tue Jun 2 2020 Michal Ambroz - 4.0.1-1 -- bump to yara bugfix 4.0.1 release - -* Tue Apr 28 2020 Michal Ambroz - 4.0.0-1 -- bump to yara 4.0.0 release - -* Fri Jan 31 2020 Fedora Release Engineering - 3.11.0-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild - -* Fri Oct 11 2019 Michal Ambroz - 3.11.0-1 -- bump to 3.11.0 release (#1760678) -- BUGFIX: Some regexp character classes not matching correctly when used with “nocase” modifier (upstream #1117) -- BUGFIX: Reduce the number of ERROR_TOO_MANY_RE_FIBERS errors for certain hex pattern containing large jumps (upstream #1107) -- BUGFIX: Buffer overrun in “dotnet” module (upstream #1108) -- BUGFIX: Memory leak while attaching to a process fails (upstream #1070) - -* Sat Sep 28 2019 Michal Ambroz - 3.10.0-3 -- change the sphinx build dependency - -* Sat Jul 27 2019 Fedora Release Engineering - 3.10.0-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild - -* Fri May 03 2019 Michal Ambroz - 3.10.0-1 -- bump to 3.10.0 release (#1680204) -- Harden virtual machine against malicious code. -- BUGFIX: Regression bug in hex strings containing wildcards (upstream #1025). -- BUGFIX: Buffer overrun in “elf” module. -- BUGFIX: Buffer overrun in “dotnet” module. - -* Sat Mar 16 2019 Michal Ambroz - 3.9.0-1 -- bump to 3.9.0 release (#1680203) -- switch from python-sphinx to python3-sphinx for generating the documentation for fc31+ -- should fix also #1660398 (CVE-2018-19974 CVE-2018-19975 CVE-2018-19976), - but by design it might be always dangerous to run yara signatures compiled by 3rd party, - so it is advised to re-compile yara rules instead -- BUGFIX: Denial of service when using "dex" module. Found by the Cisco Talos team. (upstream #1023, CVE-2019-5020) -- BUGFIX: Buffer overflow in "dotnet" module. -- BUGFIX: Regexp regression when using nested quantifiers {x,y} for certain values of x and y. (#1018) - -* Sun Feb 03 2019 Fedora Release Engineering - 3.8.1-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild - -* Mon Aug 27 2018 Michal Ambroz - 3.8.1-1 -- bump to 3.8.1 release (#1613093) - -* Sat Jul 14 2018 Fedora Release Engineering - 3.7.1-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild - -* Fri Feb 09 2018 Fedora Release Engineering - 3.7.1-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild - -* Mon Feb 05 2018 Michal Ambroz - 3.7.1-1 -- bump to 3.7.1 release (#1534993) - -* Wed Nov 15 2017 Michal Ambroz - 3.7.0-1 -- bump to 3.7.0 release (#1511921) - -* Thu Aug 03 2017 Fedora Release Engineering - 3.6.3-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild - -* Thu Jul 27 2017 Fedora Release Engineering - 3.6.3-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild - -* Sun Jul 16 2017 Michal Ambroz - 3.6.3-1 -- bump to 3.6.3 release - bugfix CVE-2017-11328 - -* Mon Jul 03 2017 Michal Ambroz - 3.6.2-1 -- bump to 3.6.2 release - bugfix CVE-2017-9304, CVE-2017-9465 - -* Wed May 24 2017 Michal Ambroz - 3.6.0-1 -- bump to 3.6.0 release -- update the androguard-yara with bugfixes - -* Thu Apr 13 2017 Michal Ambroz - 3.5.0-7 -- Adding patch from pull request 627 until 3.5.1 is released -- https://patch-diff.githubusercontent.com/raw/VirusTotal/yara/pull/627.patch -- Fixes CVE-2016-10210 CVE-2016-10211 CVE-2017-5923 CVE-2017-5924 - -* Sat Feb 11 2017 Fedora Release Engineering - 3.5.0-6 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild - -* Tue Aug 09 2016 Michal Ambroz - 3.5.0-5 -- import package to Fedora -- remove unnecessary .buildinfo tag from doc package - -* Fri Aug 05 2016 Michal Ambroz - 3.5.0-4 -- package review - bugzilla #1362265 -- cosmetics of the changelog -- using default spinx theme to remove the static fonts - -* Fri Aug 05 2016 Michal Ambroz - 3.5.0-3 -- package review - bugzilla #1362265 -- dropped Buildroot, pkgconfig, zlib-devel, defattr -- added buildrequires gcc -- change license back to ASL 2.0 only - -* Thu Aug 04 2016 Michal Ambroz - 3.5.0-2 -- package review - bugzilla #1362265 -- changed packaging of doc sub-package - -* Thu Aug 04 2016 Michal Ambroz - 3.5.0-1 -- bump to new 3.5.0 - -* Wed Aug 03 2016 Michal Ambroz - 3.4.0-6 -- package review - bugzilla #1362265 -- dropped dependency of python-tools - -* Mon Aug 01 2016 Michal Ambroz - 3.4.0-4 -- compile with the androguard module - -* Wed Jun 08 2016 Michal Ambroz - 3.4.0-2 -- jansson dependency >= 2.5 - -* Wed Jun 08 2016 Michal Ambroz - 3.4.0-1 -- python3 stuff - -* Mon Jun 22 2015 Michal Ambroz - 3.4.0-0.git20150618 -- initial build for Fedora Project diff --git a/sources b/sources index 967aa60..769384d 100644 --- a/sources +++ b/sources @@ -1 +1,2 @@ -SHA512 (yara-4.5.8.tar.gz) = 12bbe1bebb6d51f7ae90ad6a725bdb096f3e884b757913e9ba37bfa1557bced32ef56895eb358af5f3165890336be57dc51e9fe2ad672c1e523cb30e00483c86 +SHA512 (yara-4.1.3.tar.gz) = 1bfa1787c62dfd9a87fa8db5e8c2fa68f082ae66b16b5373bdcc6bc66b32016fcaffd4baa7e59a7c1f6d3426c972eca9cc22f70d475067d7557b1014a4ab65fc +SHA512 (androguard-yara-2020-04-22-3eea86a.tar.gz) = 827962b3c6f46cb9106e40156c85ec5a99fd0d4fa3584434b5ba60adbd8265df9c85d03172df36cc15a2a0983bad0297317b27e25372aa09121411e01c1d29be diff --git a/yara-androguard.patch b/yara-androguard.patch new file mode 100644 index 0000000..b7ad794 --- /dev/null +++ b/yara-androguard.patch @@ -0,0 +1,24 @@ +diff --git a/libyara/Makefile.am b/libyara/Makefile.am +index 4fa363a..a9242b2 100644 +--- a/libyara/Makefile.am ++++ b/libyara/Makefile.am +@@ -48,6 +48,7 @@ MODULES += modules/pe/pe_utils.c + + if CUCKOO_MODULE + MODULES += modules/cuckoo/cuckoo.c ++MODULES += modules/androguard/androguard.c + endif + + if MAGIC_MODULE +diff --git a/libyara/modules/module_list b/libyara/modules/module_list +index d81b8f3..ba43609 100644 +--- a/libyara/modules/module_list ++++ b/libyara/modules/module_list +@@ -10,6 +10,7 @@ MODULE(dotnet) + + #ifdef CUCKOO_MODULE + MODULE(cuckoo) ++MODULE(androguard) + #endif + + #ifdef MAGIC_MODULE diff --git a/yara-pull627.patch b/yara-pull627.patch new file mode 100644 index 0000000..0799e1f --- /dev/null +++ b/yara-pull627.patch @@ -0,0 +1,12323 @@ +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 be389a2..20dbe4a 100644 +--- a/libyara/Makefile.am ++++ b/libyara/Makefile.am +@@ -16,6 +16,9 @@ if HASH_MODULE + MODULES += modules/hash.c + endif + ++# This isn't really a module, but needs to be compiled with them. ++MODULES += modules/pe_utils.c ++ + # + # Add your modules here: + # +diff --git a/libyara/include/yara/pe.h b/libyara/include/yara/pe.h +index 9afa314..d03e91a 100644 +--- a/libyara/include/yara/pe.h ++++ b/libyara/include/yara/pe.h +@@ -27,6 +27,11 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + ++#ifndef YR_PE_H ++#define YR_PE_H ++ ++#include ++ + #pragma pack(push, 1) + + #if defined(_WIN32) || defined(__CYGWIN__) +@@ -285,6 +290,11 @@ typedef struct _IMAGE_OPTIONAL_HEADER64 { + #define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b + #define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b + ++#define OptionalHeader(pe,field) \ ++ (IS_64BITS_PE(pe) ? \ ++ pe->header64->OptionalHeader.field : \ ++ pe->header->OptionalHeader.field) ++ + + typedef struct _IMAGE_NT_HEADERS32 { + DWORD Signature; +@@ -302,6 +312,50 @@ typedef struct _IMAGE_NT_HEADERS64 { + } IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64; + + ++// ++// Imports are stored in a linked list. Each node (IMPORTED_DLL) contains the ++// name of the DLL and a pointer to another linked list of IMPORTED_FUNCTION ++// structures containing the names of imported functions. ++// ++ ++typedef struct _IMPORTED_DLL ++{ ++ char *name; ++ ++ struct _IMPORTED_FUNCTION *functions; ++ struct _IMPORTED_DLL *next; ++ ++} IMPORTED_DLL, *PIMPORTED_DLL; ++ ++ ++typedef struct _IMPORTED_FUNCTION ++{ ++ char *name; ++ uint8_t has_ordinal; ++ uint16_t ordinal; ++ ++ struct _IMPORTED_FUNCTION *next; ++ ++} IMPORTED_FUNCTION, *PIMPORTED_FUNCTION; ++ ++ ++typedef struct _PE ++{ ++ uint8_t* data; ++ size_t data_size; ++ ++ union { ++ PIMAGE_NT_HEADERS32 header; ++ PIMAGE_NT_HEADERS64 header64; ++ }; ++ ++ YR_OBJECT* object; ++ IMPORTED_DLL* imported_dlls; ++ uint32_t resources; ++ ++} PE; ++ ++ + // IMAGE_FIRST_SECTION doesn't need 32/64 versions since the file header is + // the same either way. + +@@ -481,10 +535,5 @@ typedef struct _RICH_SIGNATURE { + #define RICH_DANS 0x536e6144 // "DanS" + #define RICH_RICH 0x68636952 // "Rich" + +-typedef struct _RICH_DATA { +- size_t len; +- BYTE* raw_data; +- BYTE* clear_data; +-} RICH_DATA, *PRICH_DATA; +- + #pragma pack(pop) ++#endif +diff --git a/libyara/include/yara/pe_utils.h b/libyara/include/yara/pe_utils.h +new file mode 100644 +index 0000000..945d843 +--- /dev/null ++++ b/libyara/include/yara/pe_utils.h +@@ -0,0 +1,30 @@ ++#ifndef YR_PE_UTILS_H ++#define YR_PE_UTILS_H ++ ++#include ++ ++#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 1af5562..8c4cb12 100644 +--- a/libyara/modules/pe.c ++++ b/libyara/modules/pe.c +@@ -52,7 +52,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #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 81a7ae4..ed69b80 100644 +--- a/libyara/modules/pe_utils.c ++++ b/libyara/modules/pe_utils.c +@@ -1,16 +1,223 @@ ++/* ++Copyright (c) 2014-2015. The YARA Authors. All Rights Reserved. + ++Redistribution and use in source and binary forms, with or without modification, ++are permitted provided that the following conditions are met: ++ ++1. Redistributions of source code must retain the above copyright notice, this ++list of conditions and the following disclaimer. ++ ++2. Redistributions in binary form must reproduce the above copyright notice, ++this list of conditions and the following disclaimer in the documentation and/or ++other materials provided with the distribution. ++ ++3. Neither the name of the copyright holder nor the names of its contributors ++may be used to endorse or promote products derived from this software without ++specific prior written permission. ++ ++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ++WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ++ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++*/ + + #include + ++#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 c7e31f7..dc3c59f 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 10d1688..f61145a 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 53a4058..054f60c 100644 +--- a/windows/vs2010/yara.sln ++++ b/windows/vs2010/yara.sln +@@ -1,16 +1,16 @@ +  + Microsoft Visual Studio Solution File, Format Version 11.00 + # Visual Studio 2010 +-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libyara", "libyara\libyara.vcxproj", "{B90417B6-5132-DA5C-DBA8-E8A830BE8172}" ++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libyara", "libyara\libyara.vcxproj", "{5E18111F-0F7D-08E0-195A-C60C1C0DD239}" + EndProject + Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yara", "yara\yara.vcxproj", "{E203D7BB-29B9-4152-9208-BB410983CE8C}" + ProjectSection(ProjectDependencies) = postProject +- {B90417B6-5132-DA5C-DBA8-E8A830BE8172} = {B90417B6-5132-DA5C-DBA8-E8A830BE8172} ++ {5E18111F-0F7D-08E0-195A-C60C1C0DD239} = {5E18111F-0F7D-08E0-195A-C60C1C0DD239} + EndProjectSection + EndProject + Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yarac", "yarac\yarac.vcxproj", "{C2EE445F-2BA5-4E2D-A9E5-44ADE8CAF8E4}" + ProjectSection(ProjectDependencies) = postProject +- {B90417B6-5132-DA5C-DBA8-E8A830BE8172} = {B90417B6-5132-DA5C-DBA8-E8A830BE8172} ++ {5E18111F-0F7D-08E0-195A-C60C1C0DD239} = {5E18111F-0F7D-08E0-195A-C60C1C0DD239} + EndProjectSection + EndProject + Global +@@ -21,14 +21,14 @@ Global + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution +- {B90417B6-5132-DA5C-DBA8-E8A830BE8172}.Debug|Win32.ActiveCfg = Debug|Win32 +- {B90417B6-5132-DA5C-DBA8-E8A830BE8172}.Debug|Win32.Build.0 = Debug|Win32 +- {B90417B6-5132-DA5C-DBA8-E8A830BE8172}.Debug|x64.ActiveCfg = Debug|x64 +- {B90417B6-5132-DA5C-DBA8-E8A830BE8172}.Debug|x64.Build.0 = Debug|x64 +- {B90417B6-5132-DA5C-DBA8-E8A830BE8172}.Release|Win32.ActiveCfg = Release|Win32 +- {B90417B6-5132-DA5C-DBA8-E8A830BE8172}.Release|Win32.Build.0 = Release|Win32 +- {B90417B6-5132-DA5C-DBA8-E8A830BE8172}.Release|x64.ActiveCfg = Release|x64 +- {B90417B6-5132-DA5C-DBA8-E8A830BE8172}.Release|x64.Build.0 = Release|x64 ++ {5E18111F-0F7D-08E0-195A-C60C1C0DD239}.Debug|Win32.ActiveCfg = Debug|Win32 ++ {5E18111F-0F7D-08E0-195A-C60C1C0DD239}.Debug|Win32.Build.0 = Debug|Win32 ++ {5E18111F-0F7D-08E0-195A-C60C1C0DD239}.Debug|x64.ActiveCfg = Debug|x64 ++ {5E18111F-0F7D-08E0-195A-C60C1C0DD239}.Debug|x64.Build.0 = Debug|x64 ++ {5E18111F-0F7D-08E0-195A-C60C1C0DD239}.Release|Win32.ActiveCfg = Release|Win32 ++ {5E18111F-0F7D-08E0-195A-C60C1C0DD239}.Release|Win32.Build.0 = Release|Win32 ++ {5E18111F-0F7D-08E0-195A-C60C1C0DD239}.Release|x64.ActiveCfg = Release|x64 ++ {5E18111F-0F7D-08E0-195A-C60C1C0DD239}.Release|x64.Build.0 = Release|x64 + {E203D7BB-29B9-4152-9208-BB410983CE8C}.Debug|Win32.ActiveCfg = Debug|Win32 + {E203D7BB-29B9-4152-9208-BB410983CE8C}.Debug|Win32.Build.0 = Debug|Win32 + {E203D7BB-29B9-4152-9208-BB410983CE8C}.Debug|x64.ActiveCfg = Debug|x64 + +From ef0f55912f40180a8ab35eeb576f6f087c9a90a3 Mon Sep 17 00:00:00 2001 +From: ejectck +Date: Wed, 10 Aug 2016 18:46:10 +0200 +Subject: [PATCH 03/36] Added missing apt-get command "install" (#500) + +(cherry picked from commit c9d0819fe2c1f330823c541f118de45f0aad3406) +--- + docs/gettingstarted.rst | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/docs/gettingstarted.rst b/docs/gettingstarted.rst +index 90f14a5..4a518da 100644 +--- a/docs/gettingstarted.rst ++++ b/docs/gettingstarted.rst +@@ -19,12 +19,12 @@ Download the source tarball and get prepared for compiling it:: + Make sure you have ``automake``, ``libtool``, ``make`` and ``gcc`` installed + in your system. Ubuntu and Debian users can use:: + +- sudo apt-get automake libtool make gcc ++ sudo apt-get install automake libtool make gcc + + If you plan to modify YARA's source code you may also need ``flex`` and + ``bison`` for generating lexers and parsers:: + +- sudo apt-get flex bison ++ sudo apt-get install flex bison + + Compile and install YARA in the standard way:: + + +From 06391f0853aeea3bf4582291bea540767a88678b Mon Sep 17 00:00:00 2001 +From: plusvic +Date: Fri, 19 Aug 2016 17:25:14 +0200 +Subject: [PATCH 04/36] Fix issue #506 + +(cherry picked from commit f4b535fa2b8adb73a0494b8f96d16af0c920180d) +--- + libyara/lexer.c | 319 ++++++++++++++++++++++++++--------------------------- + libyara/lexer.l | 2 +- + tests/test-rules.c | 10 +- + 3 files changed, 168 insertions(+), 163 deletions(-) + +diff --git a/libyara/lexer.c b/libyara/lexer.c +index d0f3688..64c3fea 100644 +--- a/libyara/lexer.c ++++ b/libyara/lexer.c +@@ -243,7 +243,7 @@ struct yy_buffer_state + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ +- yy_size_t yy_n_chars; ++ int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to +@@ -455,7 +455,7 @@ static yyconst YY_CHAR yy_ec[256] = + + static yyconst YY_CHAR yy_meta[56] = + { 0, +- 1, 2, 3, 1, 1, 4, 1, 1, 2, 5, ++ 1, 2, 3, 2, 1, 4, 1, 1, 2, 5, + 6, 7, 8, 8, 8, 8, 8, 8, 8, 1, + 9, 1, 1, 10, 10, 11, 12, 12, 13, 11, + 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, +@@ -465,32 +465,32 @@ static yyconst YY_CHAR yy_meta[56] = + + static yyconst flex_uint16_t yy_base[266] = + { 0, +- 0, 0, 53, 54, 55, 58, 343, 342, 337, 330, +- 339, 640, 640, 640, 317, 640, 0, 327, 325, 52, +- 52, 58, 45, 312, 50, 0, 0, 48, 289, 289, +- 50, 290, 32, 61, 278, 32, 273, 269, 269, 59, +- 276, 275, 298, 0, 640, 640, 70, 0, 640, 61, +- 297, 0, 640, 640, 296, 286, 640, 0, 640, 296, +- 640, 640, 0, 109, 0, 280, 279, 0, 640, 640, +- 640, 640, 640, 0, 0, 263, 67, 269, 0, 259, +- 253, 259, 258, 252, 256, 252, 250, 58, 246, 239, +- 69, 0, 0, 246, 244, 238, 247, 231, 236, 243, ++ 0, 0, 53, 54, 55, 58, 347, 346, 341, 340, ++ 349, 640, 640, 640, 327, 640, 0, 337, 329, 52, ++ 52, 58, 45, 318, 50, 0, 0, 48, 295, 295, ++ 50, 296, 32, 61, 290, 32, 287, 283, 283, 59, ++ 282, 279, 305, 0, 640, 640, 70, 0, 640, 61, ++ 304, 0, 640, 640, 303, 289, 640, 0, 640, 299, ++ 640, 640, 0, 109, 0, 283, 282, 0, 640, 640, ++ 640, 640, 640, 0, 0, 266, 67, 272, 0, 262, ++ 256, 262, 261, 255, 259, 255, 253, 58, 249, 248, ++ 69, 0, 0, 255, 253, 241, 250, 236, 241, 248, + + 63, 96, 0, 640, 640, 640, 640, 640, 0, 0, +- 230, 640, 640, 640, 0, 640, 0, 116, 640, 0, +- 0, 0, 0, 228, 102, 219, 217, 227, 0, 221, +- 228, 213, 215, 123, 221, 222, 221, 0, 202, 215, +- 210, 207, 212, 199, 210, 640, 234, 148, 0, 204, +- 203, 210, 188, 204, 186, 181, 199, 184, 180, 207, +- 209, 191, 184, 0, 167, 181, 0, 168, 0, 0, +- 0, 199, 196, 202, 0, 101, 0, 640, 0, 160, +- 167, 158, 0, 162, 157, 159, 151, 163, 161, 160, +- 159, 146, 155, 256, 128, 152, 148, 146, 135, 142, +- +- 0, 0, 151, 0, 139, 0, 143, 131, 310, 0, +- 364, 164, 131, 0, 132, 128, 132, 135, 135, 166, +- 0, 0, 0, 134, 149, 135, 136, 142, 78, 0, +- 73, 0, 0, 108, 143, 0, 146, 0, 31, 640, ++ 233, 640, 640, 640, 0, 640, 0, 116, 640, 0, ++ 0, 0, 0, 239, 102, 232, 230, 232, 0, 224, ++ 231, 219, 221, 123, 223, 224, 223, 0, 204, 217, ++ 212, 209, 214, 201, 212, 640, 236, 148, 0, 206, ++ 205, 212, 190, 206, 194, 189, 201, 186, 182, 211, ++ 213, 193, 186, 0, 177, 191, 0, 171, 0, 0, ++ 0, 202, 198, 202, 0, 101, 0, 640, 0, 162, ++ 169, 163, 0, 163, 158, 160, 152, 164, 162, 161, ++ 160, 147, 156, 256, 128, 153, 149, 147, 136, 143, ++ ++ 0, 0, 152, 0, 140, 0, 150, 132, 310, 0, ++ 364, 165, 131, 0, 133, 129, 135, 136, 135, 157, ++ 0, 0, 0, 134, 148, 135, 136, 143, 78, 0, ++ 73, 0, 0, 108, 144, 0, 158, 0, 31, 640, + 0, 640, 419, 432, 445, 458, 464, 469, 477, 484, + 489, 494, 505, 515, 527, 540, 552, 565, 578, 584, + 587, 597, 610, 616, 626 +@@ -547,30 +547,30 @@ static yyconst flex_uint16_t yy_nxt[696] = + 109, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 151, 160, 194, 161, 195, + 227, 162, 228, 235, 194, 236, 195, 237, 152, 175, +- 101, 227, 173, 228, 211, 227, 175, 228, 173, 176, +- 175, 175, 175, 175, 175, 175, 175, 234, 233, 232, +- 231, 175, 175, 230, 229, 226, 223, 222, 175, 175, +- 175, 175, 175, 175, 221, 220, 219, 218, 217, 216, +- 215, 208, 207, 206, 205, 204, 203, 202, 201, 200, +- +- 199, 198, 177, 175, 101, 197, 196, 101, 173, 193, +- 175, 192, 191, 176, 175, 175, 175, 175, 175, 175, +- 175, 190, 189, 162, 162, 175, 175, 188, 187, 186, +- 185, 184, 175, 175, 175, 175, 175, 175, 183, 182, +- 181, 180, 179, 173, 171, 134, 170, 169, 168, 167, +- 166, 165, 164, 163, 159, 158, 177, 210, 211, 157, +- 156, 155, 154, 153, 210, 212, 150, 213, 210, 210, +- 210, 210, 210, 210, 210, 112, 145, 144, 143, 210, +- 210, 142, 141, 140, 139, 136, 210, 210, 210, 210, +- 210, 210, 135, 132, 131, 130, 129, 128, 127, 126, +- +- 125, 124, 121, 119, 119, 59, 242, 116, 114, 102, +- 214, 210, 211, 100, 99, 96, 95, 94, 210, 212, +- 91, 213, 210, 210, 210, 210, 210, 210, 210, 86, +- 81, 80, 71, 210, 210, 61, 59, 57, 242, 55, +- 210, 210, 210, 210, 210, 210, 55, 53, 53, 242, +- 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, +- 242, 242, 242, 242, 214, 211, 211, 242, 242, 242, ++ 101, 175, 227, 173, 228, 211, 175, 173, 234, 176, ++ 175, 175, 175, 175, 175, 175, 175, 227, 233, 228, ++ 232, 175, 175, 231, 230, 229, 226, 223, 175, 175, ++ 175, 175, 175, 175, 222, 221, 220, 219, 218, 217, ++ 216, 215, 208, 207, 206, 205, 204, 203, 202, 201, ++ ++ 200, 199, 177, 175, 101, 175, 198, 197, 196, 101, ++ 175, 173, 193, 176, 175, 175, 175, 175, 175, 175, ++ 175, 192, 191, 190, 189, 175, 175, 162, 162, 188, ++ 187, 186, 175, 175, 175, 175, 175, 175, 185, 184, ++ 183, 182, 181, 180, 179, 173, 171, 134, 170, 169, ++ 168, 167, 166, 165, 164, 163, 177, 210, 211, 210, ++ 159, 158, 157, 156, 210, 212, 155, 213, 210, 210, ++ 210, 210, 210, 210, 210, 154, 153, 150, 112, 210, ++ 210, 145, 144, 143, 142, 141, 210, 210, 210, 210, ++ 210, 210, 140, 139, 136, 135, 132, 131, 130, 129, ++ ++ 128, 127, 126, 125, 124, 121, 119, 119, 59, 242, ++ 214, 210, 211, 210, 116, 114, 102, 100, 210, 212, ++ 99, 213, 210, 210, 210, 210, 210, 210, 210, 96, ++ 95, 94, 91, 210, 210, 86, 81, 80, 71, 61, ++ 210, 210, 210, 210, 210, 210, 59, 57, 242, 55, ++ 55, 53, 53, 242, 242, 242, 242, 242, 242, 242, ++ 242, 242, 242, 242, 214, 211, 211, 211, 242, 242, + 242, 242, 211, 173, 242, 224, 211, 211, 211, 211, + 211, 211, 211, 242, 242, 242, 242, 211, 211, 242, + 242, 242, 242, 242, 211, 211, 211, 211, 211, 211, +@@ -628,30 +628,30 @@ static yyconst flex_int16_t yy_chk[696] = + 47, 64, 64, 64, 64, 64, 64, 64, 118, 118, + 118, 118, 118, 118, 118, 125, 134, 195, 134, 195, + 213, 134, 213, 224, 226, 224, 226, 227, 125, 148, +- 148, 228, 235, 228, 235, 237, 148, 237, 225, 148, +- 148, 148, 148, 148, 148, 148, 148, 220, 219, 218, +- 217, 148, 148, 216, 215, 212, 208, 207, 148, 148, +- 148, 148, 148, 148, 205, 203, 200, 199, 198, 197, +- 196, 193, 192, 191, 190, 189, 188, 187, 186, 185, +- +- 184, 182, 148, 174, 174, 181, 180, 173, 172, 168, +- 174, 166, 165, 174, 174, 174, 174, 174, 174, 174, +- 174, 163, 162, 161, 160, 174, 174, 159, 158, 157, +- 156, 155, 174, 174, 174, 174, 174, 174, 154, 153, +- 152, 151, 150, 147, 145, 144, 143, 142, 141, 140, +- 139, 137, 136, 135, 133, 132, 174, 194, 194, 131, +- 130, 128, 127, 126, 194, 194, 124, 194, 194, 194, +- 194, 194, 194, 194, 194, 111, 100, 99, 98, 194, +- 194, 97, 96, 95, 94, 90, 194, 194, 194, 194, +- 194, 194, 89, 87, 86, 85, 84, 83, 82, 81, +- +- 80, 78, 76, 67, 66, 60, 56, 55, 51, 43, +- 194, 209, 209, 42, 41, 39, 38, 37, 209, 209, +- 35, 209, 209, 209, 209, 209, 209, 209, 209, 32, +- 30, 29, 24, 209, 209, 19, 18, 15, 11, 10, +- 209, 209, 209, 209, 209, 209, 9, 8, 7, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 209, 211, 211, 0, 0, 0, ++ 148, 148, 228, 235, 228, 235, 148, 225, 220, 148, ++ 148, 148, 148, 148, 148, 148, 148, 237, 219, 237, ++ 218, 148, 148, 217, 216, 215, 212, 208, 148, 148, ++ 148, 148, 148, 148, 207, 205, 203, 200, 199, 198, ++ 197, 196, 193, 192, 191, 190, 189, 188, 187, 186, ++ ++ 185, 184, 148, 174, 174, 174, 182, 181, 180, 173, ++ 174, 172, 168, 174, 174, 174, 174, 174, 174, 174, ++ 174, 166, 165, 163, 162, 174, 174, 161, 160, 159, ++ 158, 157, 174, 174, 174, 174, 174, 174, 156, 155, ++ 154, 153, 152, 151, 150, 147, 145, 144, 143, 142, ++ 141, 140, 139, 137, 136, 135, 174, 194, 194, 194, ++ 133, 132, 131, 130, 194, 194, 128, 194, 194, 194, ++ 194, 194, 194, 194, 194, 127, 126, 124, 111, 194, ++ 194, 100, 99, 98, 97, 96, 194, 194, 194, 194, ++ 194, 194, 95, 94, 90, 89, 87, 86, 85, 84, ++ ++ 83, 82, 81, 80, 78, 76, 67, 66, 60, 56, ++ 194, 209, 209, 209, 55, 51, 43, 42, 209, 209, ++ 41, 209, 209, 209, 209, 209, 209, 209, 209, 39, ++ 38, 37, 35, 209, 209, 32, 30, 29, 24, 19, ++ 209, 209, 209, 209, 209, 209, 18, 15, 11, 10, ++ 9, 8, 7, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 209, 211, 211, 211, 0, 0, + 0, 0, 211, 211, 0, 211, 211, 211, 211, 211, + 211, 211, 211, 0, 0, 0, 0, 211, 211, 0, + 0, 0, 0, 0, 211, 211, 211, 211, 211, 211, +@@ -736,7 +736,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + /* Lexical analyzer for YARA */ +-#line 20 "lexer.l" ++#line 33 "lexer.l" + + /* Disable warnings for unused functions in this file. + +@@ -754,11 +754,10 @@ with noyywrap then we can remove this pragma. + #include + #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 640304a..b22af75 100644 +--- a/libyara/lexer.l ++++ b/libyara/lexer.l +@@ -613,7 +613,7 @@ u?int(8|16|32)(be)? { + } + + +-\{(({hexdigit}|[ \-|\?\[\]\(\)\n\t]|\/\*[^*]*\*\/)+|\/\/.*)+\} { ++\{(({hexdigit}|[ \-|\?\[\]\(\)\n\r\t]|\/\*[^*]*\*\/)+|\/\/.*)+\} { + // Match hex-digits with whitespace or comments. The latter are stripped + // out by hex_lexer.l + +diff --git a/tests/test-rules.c b/tests/test-rules.c +index 8aa3058..a305f06 100644 +--- a/tests/test-rules.c ++++ b/tests/test-rules.c +@@ -463,7 +463,7 @@ static void test_hex_strings() + + assert_true_rule( + "rule test { \ +- strings: $a = { 31 32 [-] // Inline comment\n\ ++ strings: $a = { 31 32 [-] // Inline comment\n\r \ + 38 39 } \ + condition: $a }", + "1234567890"); +@@ -476,13 +476,19 @@ static void test_hex_strings() + + assert_true_rule( + "rule test { \ +- strings: $a = { 31 32 /* Inline multi-line\n\ ++ strings: $a = { 31 32 /* Inline multi-line\n\r \ + comment */ [-] 38 39 } \ + condition: $a }", + "1234567890"); + + assert_true_rule( + "rule test { \ ++ strings: $a = {\n 31 32 [-] 38 39 \n\r} \ ++ condition: $a }", ++ "1234567890"); ++ ++ assert_true_rule( ++ "rule test { \ + strings: $a = { 31 32 [-] 33 34 [-] 38 39 } \ + condition: $a }", + "1234567890"); + +From 755b51fac03638c689bc6652e97fdc7f12ee9d2a Mon Sep 17 00:00:00 2001 +From: plusvic +Date: Fri, 19 Aug 2016 18:10:45 +0200 +Subject: [PATCH 05/36] Fix issue #507 + +(cherry picked from commit 64930a6ea2678e7ce2d1374c984a661eb0d388fa) +--- + libyara/parser.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/libyara/parser.c b/libyara/parser.c +index 1123869..0ced96e 100644 +--- a/libyara/parser.c ++++ b/libyara/parser.c +@@ -970,6 +970,14 @@ int yr_parser_reduce_import( + + char* name; + ++ if (module_name->length == 0) ++ { ++ compiler->last_result = ERROR_UNKNOWN_MODULE; ++ yr_compiler_set_error_extra_info(compiler, ""); ++ ++ return ERROR_UNKNOWN_MODULE; ++ } ++ + module_structure = (YR_OBJECT*) yr_hash_table_lookup( + compiler->objects_table, + module_name->c_string, + +From 64711f99a6666f0cdcefd382560f84ad0e6b9014 Mon Sep 17 00:00:00 2001 +From: plusvic +Date: Thu, 25 Aug 2016 21:47:54 +0200 +Subject: [PATCH 06/36] Check error codes returned by json_unpack + +This avoid segfaults with JSON files not conforming the expected format. + +(cherry picked from commit be8ed5ff51013fc8e9a5d9b80f2ee5e884e95c49) +--- + libyara/modules/cuckoo.c | 26 ++++++++++++++------------ + 1 file changed, 14 insertions(+), 12 deletions(-) + +diff --git a/libyara/modules/cuckoo.c b/libyara/modules/cuckoo.c +index 53d30f4..2351889 100644 +--- a/libyara/modules/cuckoo.c ++++ b/libyara/modules/cuckoo.c +@@ -57,12 +57,13 @@ define_function(network_dns_lookup) + + json_array_foreach(dns_json, index, value) + { +- json_unpack(value, "{s:s, s:s}", "ip", &ip, "hostname", &hostname); +- +- if (yr_re_match(regexp_argument(1), hostname) > 0) ++ if (json_unpack(value, "{s:s, s:s}", "ip", &ip, "hostname", &hostname) == 0) + { +- result = 1; +- break; ++ if (yr_re_match(regexp_argument(1), hostname) > 0) ++ { ++ result = 1; ++ break; ++ } + } + } + +@@ -91,14 +92,15 @@ uint64_t http_request( + + json_array_foreach(http_json, index, value) + { +- json_unpack(value, "{s:s, s:s}", "uri", &uri, "method", &method); +- +- if (((methods & METHOD_GET && strcasecmp(method, "get") == 0) || +- (methods & METHOD_POST && strcasecmp(method, "post") == 0)) && +- yr_re_match(uri_regexp, uri) > 0) ++ if (json_unpack(value, "{s:s, s:s}", "uri", &uri, "method", &method) == 0) + { +- result = 1; +- break; ++ if (((methods & METHOD_GET && strcasecmp(method, "get") == 0) || ++ (methods & METHOD_POST && strcasecmp(method, "post") == 0)) && ++ yr_re_match(uri_regexp, uri) > 0) ++ { ++ result = 1; ++ break; ++ } + } + } + + +From d7420a1eec1cef1f6ee0182b49ff5b37423b226f Mon Sep 17 00:00:00 2001 +From: plusvic +Date: Fri, 26 Aug 2016 10:43:54 +0200 +Subject: [PATCH 07/36] Better error reporting for regexps exceeding + RE_MAX_SPLIT_ID + +(cherry picked from commit 5122eb96201b07cd9643bbbc51c625112b3f455e) +--- + libyara/compiler.c | 5 +++++ + libyara/include/yara/error.h | 1 + + libyara/re.c | 2 +- + 3 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/libyara/compiler.c b/libyara/compiler.c +index dd4c251..4c0fdeb 100644 +--- a/libyara/compiler.c ++++ b/libyara/compiler.c +@@ -959,6 +959,11 @@ YR_API char* yr_compiler_get_error_message( + buffer_size, + "regular expression is too large"); + break; ++ case ERROR_REGULAR_EXPRESSION_TOO_COMPLEX: ++ snprintf( ++ buffer, ++ buffer_size, ++ "regular expression is too complex"); + + } + +diff --git a/libyara/include/yara/error.h b/libyara/include/yara/error.h +index 75d56ed..a5476b0 100644 +--- a/libyara/include/yara/error.h ++++ b/libyara/include/yara/error.h +@@ -87,6 +87,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #define ERROR_TOO_MANY_RE_FIBERS 46 + #define ERROR_COULD_NOT_READ_PROCESS_MEMORY 47 + #define ERROR_INVALID_EXTERNAL_VARIABLE_TYPE 48 ++#define ERROR_REGULAR_EXPRESSION_TOO_COMPLEX 49 + + + #define FAIL_ON_ERROR(x) { \ +diff --git a/libyara/re.c b/libyara/re.c +index a33d989..a0cf4f9 100644 +--- a/libyara/re.c ++++ b/libyara/re.c +@@ -650,7 +650,7 @@ int _yr_emit_split( + assert(opcode == RE_OPCODE_SPLIT_A || opcode == RE_OPCODE_SPLIT_B); + + if (emit_context->next_split_id == RE_MAX_SPLIT_ID) +- return ERROR_INTERNAL_FATAL_ERROR; ++ return ERROR_REGULAR_EXPRESSION_TOO_COMPLEX; + + FAIL_ON_ERROR(yr_arena_write_data( + emit_context->arena, + +From 94faf4c6b398503f9c1d06ba2403e3bbc3cb3609 Mon Sep 17 00:00:00 2001 +From: plusvic +Date: Wed, 14 Sep 2016 16:35:59 +0200 +Subject: [PATCH 08/36] Fix issue #517 + +Double free caused by regexps starting with a null character. + +(cherry picked from commit 658aec6227a61b848f66b004ebd16fadcf24b5e7) +--- + libyara/lexer.c | 28 +++++++++++++++------------- + libyara/lexer.l | 2 ++ + 2 files changed, 17 insertions(+), 13 deletions(-) + +diff --git a/libyara/lexer.c b/libyara/lexer.c +index 64c3fea..03f0465 100644 +--- a/libyara/lexer.c ++++ b/libyara/lexer.c +@@ -1783,11 +1783,12 @@ YY_RULE_SETUP + { + + yyerror(yyscanner, compiler, "illegal escape sequence"); ++ yyterminate(); + } + YY_BREAK + case 63: + YY_RULE_SETUP +-#line 547 "lexer.l" ++#line 548 "lexer.l" + { + + if (yyextra->lex_buf_len > 0) +@@ -1807,6 +1808,7 @@ YY_RULE_SETUP + else + { + yyerror(yyscanner, compiler, "empty regular expression"); ++ yyterminate(); + } + + BEGIN(INITIAL); +@@ -1815,7 +1817,7 @@ YY_RULE_SETUP + YY_BREAK + case 64: + YY_RULE_SETUP +-#line 573 "lexer.l" ++#line 575 "lexer.l" + { + + LEX_CHECK_SPACE_OK("/", yyextra->lex_buf_len, LEX_BUF_SIZE); +@@ -1825,7 +1827,7 @@ YY_RULE_SETUP + YY_BREAK + case 65: + YY_RULE_SETUP +-#line 581 "lexer.l" ++#line 583 "lexer.l" + { + + LEX_CHECK_SPACE_OK("\\.", yyextra->lex_buf_len, LEX_BUF_SIZE); +@@ -1836,13 +1838,13 @@ YY_RULE_SETUP + YY_BREAK + case 66: + YY_RULE_SETUP +-#line 590 "lexer.l" ++#line 592 "lexer.l" + { YYTEXT_TO_BUFFER; } + YY_BREAK + case 67: + /* rule 67 can match eol */ + YY_RULE_SETUP +-#line 593 "lexer.l" ++#line 595 "lexer.l" + { + + yyerror(yyscanner, compiler, "unterminated regular expression"); +@@ -1851,7 +1853,7 @@ YY_RULE_SETUP + YY_BREAK + case 68: + YY_RULE_SETUP +-#line 600 "lexer.l" ++#line 602 "lexer.l" + { + + yyextra->lex_buf_ptr = yyextra->lex_buf; +@@ -1861,7 +1863,7 @@ YY_RULE_SETUP + YY_BREAK + case 69: + YY_RULE_SETUP +-#line 608 "lexer.l" ++#line 610 "lexer.l" + { + + yyextra->lex_buf_ptr = yyextra->lex_buf; +@@ -1872,7 +1874,7 @@ YY_RULE_SETUP + case 70: + /* rule 70 can match eol */ + YY_RULE_SETUP +-#line 616 "lexer.l" ++#line 618 "lexer.l" + { + // Match hex-digits with whitespace or comments. The latter are stripped + // out by hex_lexer.l +@@ -1888,12 +1890,12 @@ YY_RULE_SETUP + case 71: + /* rule 71 can match eol */ + YY_RULE_SETUP +-#line 629 "lexer.l" ++#line 631 "lexer.l" + /* skip whitespace */ + YY_BREAK + case 72: + YY_RULE_SETUP +-#line 631 "lexer.l" ++#line 633 "lexer.l" + { + + if (yytext[0] >= 32 && yytext[0] < 127) +@@ -1909,10 +1911,10 @@ YY_RULE_SETUP + YY_BREAK + case 73: + YY_RULE_SETUP +-#line 644 "lexer.l" ++#line 646 "lexer.l" + ECHO; + YY_BREAK +-#line 1916 "lexer.c" ++#line 1918 "lexer.c" + + case YY_END_OF_BUFFER: + { +@@ -3061,7 +3063,7 @@ void yara_yyfree (void * ptr , yyscan_t yyscanner) + + #define YYTABLES_NAME "yytables" + +-#line 644 "lexer.l" ++#line 646 "lexer.l" + + + +diff --git a/libyara/lexer.l b/libyara/lexer.l +index b22af75..a184606 100644 +--- a/libyara/lexer.l ++++ b/libyara/lexer.l +@@ -541,6 +541,7 @@ u?int(8|16|32)(be)? { + \\(.|\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 d03e91a..001da4d 100644 +--- a/libyara/include/yara/pe.h ++++ b/libyara/include/yara/pe.h +@@ -290,11 +290,6 @@ typedef struct _IMAGE_OPTIONAL_HEADER64 { + #define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b + #define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b + +-#define OptionalHeader(pe,field) \ +- (IS_64BITS_PE(pe) ? \ +- pe->header64->OptionalHeader.field : \ +- pe->header->OptionalHeader.field) +- + + typedef struct _IMAGE_NT_HEADERS32 { + DWORD Signature; +@@ -311,51 +306,6 @@ typedef struct _IMAGE_NT_HEADERS64 { + + } IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64; + +- +-// +-// Imports are stored in a linked list. Each node (IMPORTED_DLL) contains the +-// name of the DLL and a pointer to another linked list of IMPORTED_FUNCTION +-// structures containing the names of imported functions. +-// +- +-typedef struct _IMPORTED_DLL +-{ +- char *name; +- +- struct _IMPORTED_FUNCTION *functions; +- struct _IMPORTED_DLL *next; +- +-} IMPORTED_DLL, *PIMPORTED_DLL; +- +- +-typedef struct _IMPORTED_FUNCTION +-{ +- char *name; +- uint8_t has_ordinal; +- uint16_t ordinal; +- +- struct _IMPORTED_FUNCTION *next; +- +-} IMPORTED_FUNCTION, *PIMPORTED_FUNCTION; +- +- +-typedef struct _PE +-{ +- uint8_t* data; +- size_t data_size; +- +- union { +- PIMAGE_NT_HEADERS32 header; +- PIMAGE_NT_HEADERS64 header64; +- }; +- +- YR_OBJECT* object; +- IMPORTED_DLL* imported_dlls; +- uint32_t resources; +- +-} PE; +- +- + // IMAGE_FIRST_SECTION doesn't need 32/64 versions since the file header is + // the same either way. + +@@ -535,5 +485,6 @@ typedef struct _RICH_SIGNATURE { + #define RICH_DANS 0x536e6144 // "DanS" + #define RICH_RICH 0x68636952 // "Rich" + ++ + #pragma pack(pop) + #endif +diff --git a/libyara/include/yara/pe_utils.h b/libyara/include/yara/pe_utils.h +index 945d843..88e5a61 100644 +--- a/libyara/include/yara/pe_utils.h ++++ b/libyara/include/yara/pe_utils.h +@@ -5,9 +5,61 @@ + + #define MAX_PE_SECTIONS 96 + ++ + #define IS_64BITS_PE(pe) \ + (pe->header64->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) + ++ ++#define OptionalHeader(pe,field) \ ++ (IS_64BITS_PE(pe) ? \ ++ pe->header64->OptionalHeader.field : \ ++ pe->header->OptionalHeader.field) ++ ++ ++// ++// Imports are stored in a linked list. Each node (IMPORTED_DLL) contains the ++// name of the DLL and a pointer to another linked list of IMPORTED_FUNCTION ++// structures containing the names of imported functions. ++// ++ ++typedef struct _IMPORTED_DLL ++{ ++ char *name; ++ ++ struct _IMPORTED_FUNCTION *functions; ++ struct _IMPORTED_DLL *next; ++ ++} IMPORTED_DLL, *PIMPORTED_DLL; ++ ++ ++typedef struct _IMPORTED_FUNCTION ++{ ++ char *name; ++ uint8_t has_ordinal; ++ uint16_t ordinal; ++ ++ struct _IMPORTED_FUNCTION *next; ++ ++} IMPORTED_FUNCTION, *PIMPORTED_FUNCTION; ++ ++ ++typedef struct _PE ++{ ++ uint8_t* data; ++ size_t data_size; ++ ++ union { ++ PIMAGE_NT_HEADERS32 header; ++ PIMAGE_NT_HEADERS64 header64; ++ }; ++ ++ YR_OBJECT* object; ++ IMPORTED_DLL* imported_dlls; ++ uint32_t resources; ++ ++} PE; ++ ++ + #define fits_in_pe(pe, pointer, size) \ + ((size_t) size <= pe->data_size && \ + (uint8_t*) (pointer) >= pe->data && \ +@@ -16,11 +68,31 @@ + #define struct_fits_in_pe(pe, pointer, struct_type) \ + fits_in_pe(pe, pointer, sizeof(struct_type)) + +-PIMAGE_NT_HEADERS32 pe_get_header(uint8_t* data, size_t data_size); +-PIMAGE_DATA_DIRECTORY pe_get_directory_entry(PE* pe, int entry); +-PIMAGE_DATA_DIRECTORY pe_get_directory_entry(PE* pe, int entry); +-int64_t pe_rva_to_offset(PE* pe, uint64_t rva); +-char *ord_lookup(char *dll, uint16_t ord); ++ ++PIMAGE_NT_HEADERS32 pe_get_header( ++ uint8_t* data, ++ size_t data_size); ++ ++ ++PIMAGE_DATA_DIRECTORY pe_get_directory_entry( ++ PE* pe, ++ int entry); ++ ++ ++PIMAGE_DATA_DIRECTORY pe_get_directory_entry( ++ PE* pe, ++ int entry); ++ ++ ++int64_t pe_rva_to_offset( ++ PE* pe, ++ uint64_t rva); ++ ++ ++char *ord_lookup( ++ char *dll, ++ uint16_t ord); ++ + + #if HAVE_LIBCRYPTO + #include + +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 7707178..6d784e6 100644 +--- a/libyara/re_lexer.c ++++ b/libyara/re_lexer.c +@@ -533,7 +533,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + /* Lexical analyzer for regular expressions */ +-#line 20 "re_lexer.l" ++#line 33 "re_lexer.l" + + /* Disable warnings for unused functions in this file. + +@@ -582,7 +582,7 @@ int read_escaped_char( + + #define YY_NO_UNISTD_H 1 + +-#line 573 "re_lexer.c" ++#line 586 "re_lexer.c" + + #define INITIAL 0 + #define char_class 1 +@@ -856,10 +856,10 @@ YY_DECL + } + + { +-#line 86 "re_lexer.l" ++#line 99 "re_lexer.l" + + +-#line 850 "re_lexer.c" ++#line 863 "re_lexer.c" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + { +@@ -926,7 +926,7 @@ YY_DECL + + case 1: + YY_RULE_SETUP +-#line 88 "re_lexer.l" ++#line 101 "re_lexer.l" + { + + // Examples: {3,8} {0,5} {,5} {7,} +@@ -962,7 +962,7 @@ YY_RULE_SETUP + YY_BREAK + case 2: + YY_RULE_SETUP +-#line 122 "re_lexer.l" ++#line 135 "re_lexer.l" + { + + // Example: {10} +@@ -982,7 +982,7 @@ YY_RULE_SETUP + YY_BREAK + case 3: + YY_RULE_SETUP +-#line 140 "re_lexer.l" ++#line 153 "re_lexer.l" + { + + // Start of a negated character class. Example: [^abcd] +@@ -994,7 +994,7 @@ YY_RULE_SETUP + YY_BREAK + case 4: + YY_RULE_SETUP +-#line 149 "re_lexer.l" ++#line 162 "re_lexer.l" + { + + // Start of character negated class containing a ]. +@@ -1009,7 +1009,7 @@ YY_RULE_SETUP + YY_BREAK + case 5: + YY_RULE_SETUP +-#line 162 "re_lexer.l" ++#line 175 "re_lexer.l" + { + + // Start of character class containing a ]. +@@ -1024,7 +1024,7 @@ YY_RULE_SETUP + YY_BREAK + case 6: + YY_RULE_SETUP +-#line 175 "re_lexer.l" ++#line 188 "re_lexer.l" + { + + // Start of character class. Example: [abcd] +@@ -1037,7 +1037,7 @@ YY_RULE_SETUP + case 7: + /* rule 7 can match eol */ + YY_RULE_SETUP +-#line 185 "re_lexer.l" ++#line 198 "re_lexer.l" + { + + // Any non-special character is passed as a CHAR token to the scanner. +@@ -1048,63 +1048,63 @@ YY_RULE_SETUP + YY_BREAK + case 8: + YY_RULE_SETUP +-#line 194 "re_lexer.l" ++#line 207 "re_lexer.l" + { + return _WORD_CHAR_; + } + YY_BREAK + case 9: + YY_RULE_SETUP +-#line 199 "re_lexer.l" ++#line 212 "re_lexer.l" + { + return _NON_WORD_CHAR_; + } + YY_BREAK + case 10: + YY_RULE_SETUP +-#line 204 "re_lexer.l" ++#line 217 "re_lexer.l" + { + return _SPACE_; + } + YY_BREAK + case 11: + YY_RULE_SETUP +-#line 209 "re_lexer.l" ++#line 222 "re_lexer.l" + { + return _NON_SPACE_; + } + YY_BREAK + case 12: + YY_RULE_SETUP +-#line 214 "re_lexer.l" ++#line 227 "re_lexer.l" + { + return _DIGIT_; + } + YY_BREAK + case 13: + YY_RULE_SETUP +-#line 219 "re_lexer.l" ++#line 232 "re_lexer.l" + { + return _NON_DIGIT_; + } + YY_BREAK + case 14: + YY_RULE_SETUP +-#line 224 "re_lexer.l" ++#line 237 "re_lexer.l" + { + return _WORD_BOUNDARY_; + } + YY_BREAK + case 15: + YY_RULE_SETUP +-#line 228 "re_lexer.l" ++#line 241 "re_lexer.l" + { + return _NON_WORD_BOUNDARY_; + } + YY_BREAK + case 16: + YY_RULE_SETUP +-#line 233 "re_lexer.l" ++#line 246 "re_lexer.l" + { + + yyerror(yyscanner, lex_env, "backreferences are not allowed"); +@@ -1113,7 +1113,7 @@ YY_RULE_SETUP + YY_BREAK + case 17: + YY_RULE_SETUP +-#line 240 "re_lexer.l" ++#line 253 "re_lexer.l" + { + + uint8_t c; +@@ -1132,7 +1132,7 @@ YY_RULE_SETUP + YY_BREAK + case 18: + YY_RULE_SETUP +-#line 257 "re_lexer.l" ++#line 270 "re_lexer.l" + { + + // End of character class. +@@ -1155,7 +1155,7 @@ YY_RULE_SETUP + case 19: + /* rule 19 can match eol */ + YY_RULE_SETUP +-#line 278 "re_lexer.l" ++#line 291 "re_lexer.l" + { + + // A range inside a character class. +@@ -1199,7 +1199,7 @@ YY_RULE_SETUP + YY_BREAK + case 20: + YY_RULE_SETUP +-#line 320 "re_lexer.l" ++#line 333 "re_lexer.l" + { + + int i; +@@ -1210,7 +1210,7 @@ YY_RULE_SETUP + YY_BREAK + case 21: + YY_RULE_SETUP +-#line 329 "re_lexer.l" ++#line 342 "re_lexer.l" + { + + int i; +@@ -1221,7 +1221,7 @@ YY_RULE_SETUP + YY_BREAK + case 22: + YY_RULE_SETUP +-#line 338 "re_lexer.l" ++#line 351 "re_lexer.l" + { + + LEX_ENV->class_vector[' ' / 8] |= 1 << ' ' % 8; +@@ -1230,7 +1230,7 @@ YY_RULE_SETUP + YY_BREAK + case 23: + YY_RULE_SETUP +-#line 345 "re_lexer.l" ++#line 358 "re_lexer.l" + { + + int i; +@@ -1248,7 +1248,7 @@ YY_RULE_SETUP + YY_BREAK + case 24: + YY_RULE_SETUP +-#line 361 "re_lexer.l" ++#line 374 "re_lexer.l" + { + + char c; +@@ -1259,7 +1259,7 @@ YY_RULE_SETUP + YY_BREAK + case 25: + YY_RULE_SETUP +-#line 370 "re_lexer.l" ++#line 383 "re_lexer.l" + { + + int i; +@@ -1281,7 +1281,7 @@ YY_RULE_SETUP + YY_BREAK + case 26: + YY_RULE_SETUP +-#line 390 "re_lexer.l" ++#line 403 "re_lexer.l" + { + + uint8_t c; +@@ -1299,7 +1299,7 @@ YY_RULE_SETUP + YY_BREAK + case 27: + YY_RULE_SETUP +-#line 406 "re_lexer.l" ++#line 419 "re_lexer.l" + { + + if (yytext[0] >= 32 && yytext[0] < 127) +@@ -1317,7 +1317,7 @@ YY_RULE_SETUP + } + YY_BREAK + case YY_STATE_EOF(char_class): +-#line 423 "re_lexer.l" ++#line 436 "re_lexer.l" + { + + // End of regexp reached while scanning a character class. +@@ -1328,7 +1328,7 @@ case YY_STATE_EOF(char_class): + YY_BREAK + case 28: + YY_RULE_SETUP +-#line 432 "re_lexer.l" ++#line 445 "re_lexer.l" + { + + if (yytext[0] >= 32 && yytext[0] < 127) +@@ -1343,7 +1343,7 @@ YY_RULE_SETUP + } + YY_BREAK + case YY_STATE_EOF(INITIAL): +-#line 446 "re_lexer.l" ++#line 459 "re_lexer.l" + { + + yyterminate(); +@@ -1351,10 +1351,10 @@ case YY_STATE_EOF(INITIAL): + YY_BREAK + case 29: + YY_RULE_SETUP +-#line 451 "re_lexer.l" ++#line 464 "re_lexer.l" + ECHO; + YY_BREAK +-#line 1345 "re_lexer.c" ++#line 1358 "re_lexer.c" + + case YY_END_OF_BUFFER: + { +@@ -2503,7 +2503,7 @@ void re_yyfree (void * ptr , yyscan_t yyscanner) + + #define YYTABLES_NAME "yytables" + +-#line 451 "re_lexer.l" ++#line 464 "re_lexer.l" + + + +@@ -2563,7 +2563,7 @@ int read_escaped_char( + yyscan_t yyscanner, + uint8_t* escaped_char) + { +- char text[4]; ++ char text[4] = {0, 0, 0, 0}; + + text[0] = '\\'; + text[1] = RE_YY_INPUT(yyscanner); +diff --git a/libyara/re_lexer.l b/libyara/re_lexer.l +index f1108e5..b3744a3 100644 +--- a/libyara/re_lexer.l ++++ b/libyara/re_lexer.l +@@ -519,7 +519,7 @@ int read_escaped_char( + yyscan_t yyscanner, + uint8_t* escaped_char) + { +- char text[4]; ++ char text[4] = {0, 0, 0, 0}; + + text[0] = '\\'; + text[1] = RE_YY_INPUT(yyscanner); + +From aca4e81f18cc3d05cca882531ecc8f90f0f1949b Mon Sep 17 00:00:00 2001 +From: plusvic +Date: Fri, 23 Sep 2016 11:50:47 +0200 +Subject: [PATCH 11/36] Fix issue with mingw not recognising %llx and %lld + printf formats + +(cherry-picked from commit 197477632635e99ff3a1234eaebc4be101dde168) +--- + yara.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/yara.c b/yara.c +index a8503b7..7a7981f 100644 +--- a/yara.c ++++ b/yara.c +@@ -38,8 +38,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #include + +-#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 e9e27ee..6d821c8 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -32,6 +32,8 @@ case $host_os in + darwin*) CFLAGS="$CFLAGS -I/opt/local/include" ;; + esac + ++AC_C_BIGENDIAN ++ + ACX_PTHREAD( + [LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +diff --git a/libyara/exec.c b/libyara/exec.c +index b0a79b6..3facabd 100644 +--- a/libyara/exec.c ++++ b/libyara/exec.c +@@ -88,27 +88,18 @@ typedef union _STACK_ITEM { + + + #define little_endian_uint8_t(x) (x) +-#define little_endian_uint16_t(x) (x) +-#define little_endian_uint32_t(x) (x) + #define little_endian_int8_t(x) (x) +-#define little_endian_int16_t(x) (x) +-#define little_endian_int32_t(x) (x) +- +-#define big_endian_uint8_t(x) (x) +- +-#define big_endian_uint16_t(x) \ +- (((((uint16_t)(x) & 0xFF)) << 8) | \ +- ((((uint16_t)(x) & 0xFF00)) >> 8)) +- +-#define big_endian_uint32_t(x) \ +- (((((uint32_t)(x) & 0xFF)) << 24) | \ +- ((((uint32_t)(x) & 0xFF00)) << 8) | \ +- ((((uint32_t)(x) & 0xFF0000)) >> 8) | \ +- ((((uint32_t)(x) & 0xFF000000)) >> 24)) +- +-#define big_endian_int8_t(x) big_endian_uint8_t(x) +-#define big_endian_int16_t(x) big_endian_uint16_t(x) +-#define big_endian_int32_t(x) big_endian_uint32_t(x) ++#define little_endian_uint16_t(x) yr_le16toh(x) ++#define little_endian_int16_t(x) yr_le16toh(x) ++#define little_endian_uint32_t(x) yr_le32toh(x) ++#define little_endian_int32_t(x) yr_le32toh(x) ++ ++#define big_endian_uint8_t(x) (x) ++#define big_endian_int8_t(x) (x) ++#define big_endian_uint16_t(x) yr_be16toh(x) ++#define big_endian_int16_t(x) yr_be16toh(x) ++#define big_endian_uint32_t(x) yr_be32toh(x) ++#define big_endian_int32_t(x) yr_be32toh(x) + + + #define function_read(type, endianess) \ +diff --git a/libyara/exefiles.c b/libyara/exefiles.c +index f8d455a..599e397 100644 +--- a/libyara/exefiles.c ++++ b/libyara/exefiles.c +@@ -32,6 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #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 0f803df..0ce27b2 100644 +--- a/libyara/grammar.c ++++ b/libyara/grammar.c +@@ -68,18 +68,18 @@ + + + /* Copy the first part of user declarations. */ +-#line 17 "grammar.y" /* yacc.c:339 */ ++#line 30 "grammar.y" /* yacc.c:339 */ + + + + #include + #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 06b3cbd..0e35f37 100644 +--- a/libyara/grammar.h ++++ b/libyara/grammar.h +@@ -152,7 +152,7 @@ extern int yara_yydebug; + + union YYSTYPE + { +-#line 191 "grammar.y" /* yacc.c:1909 */ ++#line 204 "grammar.y" /* yacc.c:1909 */ + + EXPRESSION expression; + SIZED_STRING* sized_string; +diff --git a/libyara/grammar.y b/libyara/grammar.y +index 0090d73..56bae40 100644 +--- a/libyara/grammar.y ++++ b/libyara/grammar.y +@@ -609,7 +609,7 @@ identifier + compiler->last_result = yr_parser_emit_with_arg_reloc( + yyscanner, + OP_OBJ_LOAD, +- PTR_TO_INT64(id), ++ id, + NULL, + NULL); + +@@ -629,7 +629,7 @@ identifier + compiler->last_result = yr_parser_emit_with_arg_reloc( + yyscanner, + OP_PUSH_RULE, +- PTR_TO_INT64(rule), ++ rule, + NULL, + NULL); + +@@ -669,7 +669,7 @@ identifier + compiler->last_result = yr_parser_emit_with_arg_reloc( + yyscanner, + OP_OBJ_FIELD, +- PTR_TO_INT64(ident), ++ ident, + NULL, + NULL); + +@@ -772,7 +772,7 @@ identifier + compiler->last_result = yr_parser_emit_with_arg_reloc( + yyscanner, + OP_CALL, +- PTR_TO_INT64(args_fmt), ++ args_fmt, + NULL, + NULL); + +@@ -896,7 +896,7 @@ regexp + compiler->last_result = yr_parser_emit_with_arg_reloc( + yyscanner, + OP_PUSH, +- PTR_TO_INT64(re->root_node->forward_code), ++ re->root_node->forward_code, + NULL, + NULL); + +@@ -1106,8 +1106,7 @@ expression + yr_parser_emit_with_arg_reloc( + yyscanner, + OP_JNUNDEF, +- PTR_TO_INT64( +- compiler->loop_address[compiler->loop_depth]), ++ compiler->loop_address[compiler->loop_depth], + NULL, + NULL); + } +@@ -1130,8 +1129,7 @@ expression + yr_parser_emit_with_arg_reloc( + yyscanner, + OP_JLE, +- PTR_TO_INT64( +- compiler->loop_address[compiler->loop_depth]), ++ compiler->loop_address[compiler->loop_depth], + NULL, + NULL); + +@@ -1216,8 +1214,7 @@ expression + yr_parser_emit_with_arg_reloc( + yyscanner, + OP_JNUNDEF, +- PTR_TO_INT64( +- compiler->loop_address[compiler->loop_depth]), ++ compiler->loop_address[compiler->loop_depth], + NULL, + NULL); + +@@ -1256,7 +1253,7 @@ expression + | boolean_expression _AND_ + { + YR_FIXUP* fixup; +- int64_t* jmp_destination_addr; ++ void* jmp_destination_addr; + + compiler->last_result = yr_parser_emit_with_arg_reloc( + yyscanner, +@@ -1308,7 +1305,7 @@ expression + // page, so we can compute the address for the opcode following the AND + // by simply adding one to its address. + +- *(fixup->address) = PTR_TO_INT64(and_addr + 1); ++ *(void**)(fixup->address) = (void*)(and_addr + 1); + + compiler->fixup_stack_head = fixup->next; + yr_free(fixup); +@@ -1318,7 +1315,7 @@ expression + | boolean_expression _OR_ + { + YR_FIXUP* fixup; +- int64_t* jmp_destination_addr; ++ void* jmp_destination_addr; + + compiler->last_result = yr_parser_emit_with_arg_reloc( + yyscanner, +@@ -1369,7 +1366,7 @@ expression + // page, so we can compute the address for the opcode following the OR + // by simply adding one to its address. + +- *(fixup->address) = PTR_TO_INT64(or_addr + 1); ++ *(void**)(fixup->address) = (void*)(or_addr + 1); + + compiler->fixup_stack_head = fixup->next; + yr_free(fixup); +@@ -1630,7 +1627,7 @@ primary_expression + compiler->last_result = yr_parser_emit_with_arg_reloc( + yyscanner, + OP_PUSH, +- PTR_TO_INT64(sized_string), ++ sized_string, + NULL, + NULL); + +diff --git a/libyara/include/yara/compiler.h b/libyara/include/yara/compiler.h +index f111373..440b777 100644 +--- a/libyara/include/yara/compiler.h ++++ b/libyara/include/yara/compiler.h +@@ -53,7 +53,7 @@ typedef void (*YR_COMPILER_CALLBACK_FUNC)( + + typedef struct _YR_FIXUP + { +- int64_t* address; ++ void* address; + struct _YR_FIXUP* next; + + } YR_FIXUP; +diff --git a/libyara/include/yara/modules.h b/libyara/include/yara/modules.h +index 3b5b058..38e1bcd 100644 +--- a/libyara/include/yara/modules.h ++++ b/libyara/include/yara/modules.h +@@ -272,7 +272,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + #define sized_string_argument(n) \ +- ((SIZED_STRING*)(size_t)((int64_t*) __args)[n-1]) ++ (*(SIZED_STRING**) &(((int64_t*) __args)[n-1])) + + #define string_argument(n) \ + (sized_string_argument(n)->c_string) +diff --git a/libyara/include/yara/parser.h b/libyara/include/yara/parser.h +index 8fff40e..77c26b6 100644 +--- a/libyara/include/yara/parser.h ++++ b/libyara/include/yara/parser.h +@@ -59,9 +59,9 @@ int yr_parser_emit_with_arg_double( + int yr_parser_emit_with_arg_reloc( + yyscan_t yyscanner, + uint8_t instruction, +- int64_t argument, ++ void* argument, + uint8_t** instruction_address, +- int64_t** argument_address); ++ void** argument_address); + + + int yr_parser_check_types( +diff --git a/libyara/include/yara/pe.h b/libyara/include/yara/pe.h +index 001da4d..0291cb0 100644 +--- a/libyara/include/yara/pe.h ++++ b/libyara/include/yara/pe.h +@@ -31,6 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #define YR_PE_H + + #include ++#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 104d9ee..da0fb88 100644 +--- a/libyara/include/yara/utils.h ++++ b/libyara/include/yara/utils.h +@@ -31,6 +31,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #ifndef YR_UTILS_H + #define YR_UTILS_H + ++#include ++ + #ifndef TRUE + #define TRUE 1 + #endif +@@ -68,7 +70,33 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #define yr_min(x, y) ((x < y) ? (x) : (y)) + #define yr_max(x, y) ((x > y) ? (x) : (y)) + +-#define PTR_TO_INT64(x) ((int64_t) (size_t) x) ++#if defined(__GNUC__) ++#define yr_bswap16(x) __builtin_bswap16(x) ++#define yr_bswap32(x) __builtin_bswap32(x) ++#define yr_bswap64(x) __builtin_bswap64(x) ++#elif defined(_MSC_VER) ++#define yr_bswap16(x) _byteswap_ushort(x) ++#define yr_bswap32(x) _byteswap_ulong(x) ++#define yr_bswap64(x) _byteswap_uint64(x) ++#else ++#error Unknown compiler: Add yr_bswap* definitions ++#endif ++ ++#if defined(WORDS_BIGENDIAN) ++#define yr_le16toh(x) yr_bswap16(x) ++#define yr_le32toh(x) yr_bswap32(x) ++#define yr_le64toh(x) yr_bswap64(x) ++#define yr_be16toh(x) (x) ++#define yr_be32toh(x) (x) ++#define yr_be64toh(x) (x) ++#else ++#define yr_le16toh(x) (x) ++#define yr_le32toh(x) (x) ++#define yr_le64toh(x) (x) ++#define yr_be16toh(x) yr_bswap16(x) ++#define yr_be32toh(x) yr_bswap32(x) ++#define yr_be64toh(x) yr_bswap64(x) ++#endif + + + #ifdef NDEBUG +diff --git a/libyara/parser.c b/libyara/parser.c +index 0ced96e..9c99e17 100644 +--- a/libyara/parser.c ++++ b/libyara/parser.c +@@ -111,11 +111,13 @@ int yr_parser_emit_with_arg( + int yr_parser_emit_with_arg_reloc( + yyscan_t yyscanner, + uint8_t instruction, +- int64_t argument, ++ void* argument, + uint8_t** instruction_address, +- int64_t** argument_address) ++ void** argument_address) + { + int64_t* ptr = NULL; ++ DECLARE_REFERENCE(void*, argument) a; ++ a.argument = argument; + + int result = yr_arena_write_data( + yyget_extra(yyscanner)->code_arena, +@@ -126,7 +128,7 @@ int yr_parser_emit_with_arg_reloc( + if (result == ERROR_SUCCESS) + result = yr_arena_write_data( + yyget_extra(yyscanner)->code_arena, +- &argument, ++ &a, + sizeof(int64_t), + (void**) &ptr); + +@@ -138,7 +140,7 @@ int yr_parser_emit_with_arg_reloc( + EOL); + + if (argument_address != NULL) +- *argument_address = ptr; ++ *argument_address = (void*)ptr; + + return result; + } +@@ -180,7 +182,7 @@ int yr_parser_emit_pushes_for_strings( + yr_parser_emit_with_arg_reloc( + yyscanner, + OP_PUSH, +- PTR_TO_INT64(string), ++ string, + NULL, + NULL); + +@@ -747,7 +749,7 @@ YR_RULE* yr_parser_reduce_rule_declaration_phase_1( + compiler->last_result = yr_parser_emit_with_arg_reloc( + yyscanner, + OP_INIT_RULE, +- PTR_TO_INT64(rule), ++ rule, + NULL, + NULL); + +@@ -798,7 +800,7 @@ int yr_parser_reduce_rule_declaration_phase_2( + compiler->last_result = yr_parser_emit_with_arg_reloc( + yyscanner, + OP_MATCH_RULE, +- PTR_TO_INT64(rule), ++ rule, + NULL, + NULL); + +@@ -875,7 +877,7 @@ int yr_parser_reduce_string_identifier( + yr_parser_emit_with_arg_reloc( + yyscanner, + OP_PUSH, +- PTR_TO_INT64(string), ++ string, + NULL, + NULL); + +@@ -1021,7 +1023,7 @@ int yr_parser_reduce_import( + compiler->last_result = yr_parser_emit_with_arg_reloc( + yyscanner, + OP_IMPORT, +- PTR_TO_INT64(name), ++ name, + NULL, + NULL); + +diff --git a/tests/test-pe.c b/tests/test-pe.c +index c2c6270..93cb06e 100644 +--- a/tests/test-pe.c ++++ b/tests/test-pe.c +@@ -1,8 +1,11 @@ + #include ++#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 a305f06..19a0902 100644 +--- a/tests/test-rules.c ++++ b/tests/test-rules.c +@@ -613,10 +613,9 @@ static void test_at() + static void test_in() + { + assert_true_rule_blob( +- "import \"pe\" \ +- rule test { \ ++ "rule test { \ + strings: $a = { 6a 2a 58 c3 } \ +- condition: $a in (pe.entry_point .. pe.entry_point + 1) }", ++ condition: $a in (entrypoint .. entrypoint + 1) }", + PE32_FILE); + } + + +From 00b7e34c42407051dfcb4f6e48c35820416123dd Mon Sep 17 00:00:00 2001 +From: Hilko Bengen +Date: Sun, 16 Oct 2016 13:01:31 +0200 +Subject: [PATCH 13/36] Fix pe, elf module for big-endian architectures + (related to #493) (#538) + +* Fix pe module for big-endian architectures + +* No longer skip pe test on big-endian architectures + +(The ifdef was wrong anyhow.) + +* Add tests for elf module + +* Fix elf module for big-endian architectures + +(cherry picked from commit d272b9c742e15d6767f20a7f1c01579b468cceee) +--- + Makefile.am | 4 +- + libyara/include/yara/pe_utils.h | 2 +- + libyara/modules/elf.c | 135 ++++++++++++++++------------- + libyara/modules/pe.c | 187 +++++++++++++++++++++------------------- + libyara/modules/pe_utils.c | 78 ++++++++--------- + tests/test-elf.c | 29 +++++++ + tests/test-pe.c | 5 -- + 7 files changed, 244 insertions(+), 196 deletions(-) + create mode 100644 tests/test-elf.c + +diff --git a/Makefile.am b/Makefile.am +index 4d4f7fa..8c1652a 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -15,12 +15,14 @@ yarac_SOURCES = args.c args.h yarac.c + yarac_LDADD = libyara/.libs/libyara.a + + TESTS = $(check_PROGRAMS) +-check_PROGRAMS = test-alignment test-rules test-pe ++check_PROGRAMS = test-alignment test-rules test-pe test-elf + test_alignment_SOURCES = tests/test-alignment.c + test_rules_SOURCES = tests/test-rules.c tests/util.c + test_rules_LDADD = libyara/.libs/libyara.a + test_pe_SOURCES = tests/test-pe.c tests/util.c + test_pe_LDADD = libyara/.libs/libyara.a ++test_elf_SOURCES = tests/test-elf.c tests/util.c ++test_elf_LDADD = libyara/.libs/libyara.a + + # man pages + man1_MANS = yara.man yarac.man +diff --git a/libyara/include/yara/pe_utils.h b/libyara/include/yara/pe_utils.h +index 88e5a61..86571c5 100644 +--- a/libyara/include/yara/pe_utils.h ++++ b/libyara/include/yara/pe_utils.h +@@ -7,7 +7,7 @@ + + + #define IS_64BITS_PE(pe) \ +- (pe->header64->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) ++ (yr_le16toh(pe->header64->OptionalHeader.Magic) == IMAGE_NT_OPTIONAL_HDR64_MAGIC) + + + #define OptionalHeader(pe,field) \ +diff --git a/libyara/modules/elf.c b/libyara/modules/elf.c +index ed4ccd1..08c3ce4 100644 +--- a/libyara/modules/elf.c ++++ b/libyara/modules/elf.c +@@ -48,7 +48,7 @@ int get_elf_type( + + elf_ident = (elf_ident_t*) buffer; + +- if (elf_ident->magic == ELF_MAGIC) ++ if (yr_le32toh(elf_ident->magic) == ELF_MAGIC) + { + return elf_ident->_class; + } +@@ -58,11 +58,11 @@ int get_elf_type( + } + } + +-#define SIZE_OF_SECTION_TABLE_32 \ +- (sizeof(elf32_section_header_t) * elf_header->sh_entry_count) ++#define SIZE_OF_SECTION_TABLE_32(h) \ ++ (sizeof(elf32_section_header_t) * yr_le16toh(h->sh_entry_count)) + +-#define SIZE_OF_SECTION_TABLE_64 \ +- (sizeof(elf64_section_header_t) * elf_header->sh_entry_count) ++#define SIZE_OF_SECTION_TABLE_64(h) \ ++ (sizeof(elf64_section_header_t) * yr_le16toh(h->sh_entry_count)) + + + #define ELF_RVA_TO_OFFSET(bits) \ +@@ -77,30 +77,34 @@ uint64_t elf_rva_to_offset_##bits( \ + \ + /* check that sh_offset doesn't wrap when added to SIZE_OF_SECTION_TABLE */ \ + \ +- if(ULONG_MAX - elf_header->sh_offset < SIZE_OF_SECTION_TABLE_##bits) \ ++ if(ULONG_MAX - yr_le##bits##toh(elf_header->sh_offset) < \ ++ SIZE_OF_SECTION_TABLE_##bits(elf_header)) \ + { \ + return UNDEFINED; \ + } \ + \ +- if (elf_header->sh_offset == 0 || \ +- elf_header->sh_offset > elf_size || \ +- elf_header->sh_offset + SIZE_OF_SECTION_TABLE_##bits > elf_size || \ +- elf_header->sh_entry_count == 0) \ ++ if (yr_le##bits##toh(elf_header->sh_offset) == 0 || \ ++ yr_le##bits##toh(elf_header->sh_offset) > elf_size || \ ++ yr_le##bits##toh(elf_header->sh_offset) + \ ++ SIZE_OF_SECTION_TABLE_##bits(elf_header) > elf_size || \ ++ yr_le16toh(elf_header->sh_entry_count) == 0) \ + { \ + return UNDEFINED; \ + } \ + \ + section = (elf##bits##_section_header_t*) \ +- ((uint8_t*) elf_header + elf_header->sh_offset); \ ++ ((uint8_t*) elf_header + yr_le##bits##toh(elf_header->sh_offset)); \ + \ +- for (i = 0; i < elf_header->sh_entry_count; i++) \ ++ for (i = 0; i < yr_le16toh(elf_header->sh_entry_count); i++) \ + { \ +- if (section->type != ELF_SHT_NULL && \ +- section->type != ELF_SHT_NOBITS && \ +- rva >= section->addr && \ +- rva < section->addr + section->size) \ ++ if (yr_le32toh(section->type) != ELF_SHT_NULL && \ ++ yr_le32toh(section->type) != ELF_SHT_NOBITS && \ ++ rva >= yr_le##bits##toh(section->addr) && \ ++ rva < yr_le##bits##toh(section->addr) + \ ++ yr_le##bits##toh(section->size)) \ + { \ +- return section->offset + (rva - section->addr); \ ++ return yr_le##bits##toh(section->offset) + \ ++ (rva - yr_le##bits##toh(section->addr)); \ + } \ + \ + section++; \ +@@ -122,83 +126,96 @@ void parse_elf_header_##bits( \ + elf##bits##_section_header_t* section; \ + elf##bits##_program_header_t* segment; \ + \ +- set_integer(elf->type, elf_obj, "type"); \ +- set_integer(elf->machine, elf_obj, "machine"); \ +- set_integer(elf->sh_offset, elf_obj, "sh_offset"); \ +- set_integer(elf->sh_entry_size, elf_obj, "sh_entry_size"); \ +- set_integer(elf->sh_entry_count, elf_obj, "number_of_sections"); \ +- set_integer(elf->ph_offset, elf_obj, "ph_offset"); \ +- set_integer(elf->ph_entry_size, elf_obj, "ph_entry_size"); \ +- set_integer(elf->ph_entry_count, elf_obj, "number_of_segments"); \ ++ set_integer(yr_le16toh(elf->type), elf_obj, "type"); \ ++ set_integer(yr_le16toh(elf->machine), elf_obj, "machine"); \ ++ set_integer(yr_le##bits##toh(elf->sh_offset), elf_obj, "sh_offset"); \ ++ set_integer(yr_le16toh(elf->sh_entry_size), elf_obj, "sh_entry_size"); \ ++ set_integer(yr_le16toh(elf->sh_entry_count), elf_obj, "number_of_sections"); \ ++ set_integer(yr_le##bits##toh(elf->ph_offset), elf_obj, "ph_offset"); \ ++ set_integer(yr_le16toh(elf->ph_entry_size), elf_obj, "ph_entry_size"); \ ++ set_integer(yr_le16toh(elf->ph_entry_count), elf_obj, "number_of_segments"); \ + \ +- if (elf->entry != 0) \ ++ if (yr_le##bits##toh(elf->entry) != 0) \ + { \ + set_integer( \ + flags & SCAN_FLAGS_PROCESS_MEMORY ? \ +- base_address + elf->entry : \ +- elf_rva_to_offset_##bits(elf, elf->entry, elf_size), \ ++ base_address + yr_le##bits##toh(elf->entry) : \ ++ elf_rva_to_offset_##bits(elf, yr_le##bits##toh(elf->entry), elf_size), \ + elf_obj, "entry_point"); \ + } \ + \ +- if (elf->sh_entry_count < ELF_SHN_LORESERVE && \ +- elf->sh_str_table_index < elf->sh_entry_count && \ +- elf->sh_offset < elf_size && \ +- elf->sh_offset + elf->sh_entry_count * \ ++ if (yr_le16toh(elf->sh_entry_count) < ELF_SHN_LORESERVE && \ ++ yr_le16toh(elf->sh_str_table_index) < yr_le16toh(elf->sh_entry_count) && \ ++ yr_le##bits##toh(elf->sh_offset) < elf_size && \ ++ yr_le##bits##toh(elf->sh_offset) + yr_le16toh(elf->sh_entry_count) * \ + sizeof(elf##bits##_section_header_t) <= elf_size) \ + { \ + char* str_table = NULL; \ + \ + section = (elf##bits##_section_header_t*) \ +- ((uint8_t*) elf + elf->sh_offset); \ ++ ((uint8_t*) elf + yr_le##bits##toh(elf->sh_offset)); \ + \ +- if (section[elf->sh_str_table_index].offset < elf_size) \ +- str_table = (char*) elf + section[elf->sh_str_table_index].offset; \ ++ if (section[yr_le16toh(elf->sh_str_table_index)].offset < elf_size) \ ++ str_table = (char*) elf + \ ++ yr_le##bits##toh(section[yr_le16toh(elf->sh_str_table_index)].offset); \ + \ +- for (i = 0; i < elf->sh_entry_count; i++) \ ++ for (i = 0; i < yr_le16toh(elf->sh_entry_count); i++) \ + { \ +- set_integer(section->type, elf_obj, "sections[%i].type", i); \ +- set_integer(section->flags, elf_obj, "sections[%i].flags", i); \ +- set_integer(section->size, elf_obj, "sections[%i].size", i); \ +- set_integer(section->offset, elf_obj, "sections[%i].offset", i); \ ++ set_integer(yr_le32toh(section->type), elf_obj, \ ++ "sections[%i].type", i); \ ++ set_integer(yr_le32toh(section->flags), elf_obj, \ ++ "sections[%i].flags", i); \ ++ set_integer(yr_le##bits##toh(section->size), elf_obj, \ ++ "sections[%i].size", i); \ ++ set_integer(yr_le##bits##toh(section->offset), elf_obj, \ ++ "sections[%i].offset", i); \ + \ +- if (section->name < elf_size && \ ++ if (yr_le##bits##toh(section->name) < elf_size && \ + str_table > (char*) elf && \ +- str_table + section->name < (char*) elf + elf_size) \ ++ str_table + yr_le##bits##toh(section->name) < \ ++ (char*) elf + elf_size) \ + { \ +- set_string(str_table + section->name, elf_obj, "sections[%i].name", i);\ ++ set_string(str_table + yr_le##bits##toh(section->name), elf_obj, \ ++ "sections[%i].name", i); \ + } \ + \ + section++; \ + } \ + } \ + \ +- if (elf->ph_entry_count > 0 && \ +- elf->ph_entry_count < ELF_PN_XNUM && \ +- elf->ph_offset < elf_size && \ +- elf->ph_offset + elf->ph_entry_count * \ ++ if (yr_le16toh(elf->ph_entry_count) > 0 && \ ++ yr_le16toh(elf->ph_entry_count) < ELF_PN_XNUM && \ ++ yr_le##bits##toh(elf->ph_offset) < elf_size && \ ++ yr_le##bits##toh(elf->ph_offset) + yr_le16toh(elf->ph_entry_count) * \ + sizeof(elf##bits##_program_header_t) <= elf_size) \ + { \ + segment = (elf##bits##_program_header_t*) \ +- ((uint8_t*) elf + elf->ph_offset); \ ++ ((uint8_t*) elf + yr_le##bits##toh(elf->ph_offset)); \ + \ +- for (i = 0; i < elf->ph_entry_count; i++) \ ++ for (i = 0; i < yr_le16toh(elf->ph_entry_count); i++) \ + { \ + set_integer( \ +- segment->type, elf_obj, "segments[%i].type", i); \ ++ yr_le32toh(segment->type), elf_obj, "segments[%i].type", i); \ + set_integer( \ +- segment->flags, elf_obj, "segments[%i].flags", i); \ ++ yr_le32toh(segment->flags), elf_obj, "segments[%i].flags", i); \ + set_integer( \ +- segment->offset, elf_obj, "segments[%i].offset", i); \ ++ yr_le##bits##toh(segment->offset), elf_obj, \ ++ "segments[%i].offset", i); \ + set_integer( \ +- segment->virt_addr, elf_obj, "segments[%i].virtual_address", i); \ ++ yr_le##bits##toh(segment->virt_addr), elf_obj, \ ++ "segments[%i].virtual_address", i); \ + set_integer( \ +- segment->phys_addr, elf_obj, "segments[%i].physical_address", i); \ ++ yr_le##bits##toh(segment->phys_addr), elf_obj, \ ++ "segments[%i].physical_address", i); \ + set_integer( \ +- segment->file_size, elf_obj, "segments[%i].file_size", i); \ ++ yr_le##bits##toh(segment->file_size), elf_obj, \ ++ "segments[%i].file_size", i); \ + set_integer( \ +- segment->mem_size, elf_obj, "segments[%i].memory_size", i); \ ++ yr_le##bits##toh(segment->mem_size), elf_obj, \ ++ "segments[%i].memory_size", i); \ + set_integer( \ +- segment->alignment, elf_obj, "segments[%i].alignment", i); \ ++ yr_le##bits##toh(segment->alignment), elf_obj, \ ++ "segments[%i].alignment", i); \ + \ + segment++; \ + } \ +@@ -398,7 +415,7 @@ int module_load( + elf_header32 = (elf32_header_t*) block_data; + + if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) || +- elf_header32->type == ELF_ET_EXEC) ++ yr_le16toh(elf_header32->type) == ELF_ET_EXEC) + { + parse_elf_header_32( + elf_header32, +@@ -418,7 +435,7 @@ int module_load( + elf_header64 = (elf64_header_t*) block_data; + + if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) || +- elf_header64->type == ELF_ET_EXEC) ++ yr_le16toh(elf_header64->type) == ELF_ET_EXEC) + { + parse_elf_header_64( + elf_header64, +diff --git a/libyara/modules/pe.c b/libyara/modules/pe.c +index 8c4cb12..7c32daf 100644 +--- a/libyara/modules/pe.c ++++ b/libyara/modules/pe.c +@@ -156,13 +156,13 @@ void pe_parse_rich_signature( + + mz_header = (PIMAGE_DOS_HEADER) pe->data; + +- if (mz_header->e_magic != IMAGE_DOS_SIGNATURE) ++ if (yr_le16toh(mz_header->e_magic) != IMAGE_DOS_SIGNATURE) + return; + +- if (mz_header->e_lfanew < 0) ++ if (yr_le32toh(mz_header->e_lfanew) < 0) + return; + +- headers_size = mz_header->e_lfanew + \ ++ headers_size = yr_le32toh(mz_header->e_lfanew) + \ + sizeof(pe_header->Signature) + \ + sizeof(IMAGE_FILE_HEADER); + +@@ -177,9 +177,9 @@ void pe_parse_rich_signature( + + rich_signature = (PRICH_SIGNATURE) (pe->data + 0x80); + +- if (rich_signature->key1 != rich_signature->key2 || +- rich_signature->key2 != rich_signature->key3 || +- (rich_signature->dans ^ rich_signature->key1) != RICH_DANS) ++ if (yr_le32toh(rich_signature->key1) != yr_le32toh(rich_signature->key2) || ++ yr_le32toh(rich_signature->key2) != yr_le32toh(rich_signature->key3) || ++ (yr_le32toh(rich_signature->dans) ^ yr_le32toh(rich_signature->key1)) != RICH_DANS) + { + return; + } +@@ -188,7 +188,7 @@ void pe_parse_rich_signature( + rich_ptr <= (DWORD*) (pe->data + headers_size); + rich_ptr++) + { +- if (*rich_ptr == RICH_RICH) ++ if (yr_le32toh(*rich_ptr) == RICH_RICH) + { + // Multiple by 4 because we are counting in DWORDs. + rich_len = (rich_ptr - (DWORD*) rich_signature) * 4; +@@ -261,11 +261,11 @@ uint8_t* parse_resource_name( + // If high bit is set it is an offset relative to rsrc_data, which contains + // a resource directory string. + +- if (entry->Name & 0x80000000) ++ if (yr_le32toh(entry->Name) & 0x80000000) + { + DWORD length; + +- uint8_t* rsrc_str_ptr = rsrc_data + (entry->Name & 0x7FFFFFFF); ++ uint8_t* rsrc_str_ptr = rsrc_data + (yr_le32toh(entry->Name) & 0x7FFFFFFF); + + // A resource directory string is 2 bytes for a string and then a variable + // length Unicode string. Make sure we at least have two bytes. +@@ -307,15 +307,15 @@ int _pe_iterate_resources( + + // A few sanity checks to avoid corrupt files + +- if (resource_dir->Characteristics != 0 || +- resource_dir->NumberOfNamedEntries > 32768 || +- resource_dir->NumberOfIdEntries > 32768) ++ if (yr_le32toh(resource_dir->Characteristics) != 0 || ++ yr_le16toh(resource_dir->NumberOfNamedEntries) > 32768 || ++ yr_le16toh(resource_dir->NumberOfIdEntries) > 32768) + { + return result; + } + +- total_entries = resource_dir->NumberOfNamedEntries + +- resource_dir->NumberOfIdEntries; ++ total_entries = yr_le16toh(resource_dir->NumberOfNamedEntries) + ++ yr_le16toh(resource_dir->NumberOfIdEntries); + + // The first directory entry is just after the resource directory, + // by incrementing resource_dir we skip sizeof(resource_dir) bytes +@@ -333,15 +333,15 @@ int _pe_iterate_resources( + switch(rsrc_tree_level) + { + case 0: +- *type = entry->Name; ++ *type = yr_le32toh(entry->Name); + type_string = parse_resource_name(pe, rsrc_data, entry); + break; + case 1: +- *id = entry->Name; ++ *id = yr_le32toh(entry->Name); + name_string = parse_resource_name(pe, rsrc_data, entry); + break; + case 2: +- *language = entry->Name; ++ *language = yr_le32toh(entry->Name); + lang_string = parse_resource_name(pe, rsrc_data, entry); + break; + } +@@ -425,11 +425,11 @@ int pe_iterate_resources( + PIMAGE_DATA_DIRECTORY directory = pe_get_directory_entry( + pe, IMAGE_DIRECTORY_ENTRY_RESOURCE); + +- if (directory->VirtualAddress != 0) ++ if (yr_le32toh(directory->VirtualAddress) != 0) + { + PIMAGE_RESOURCE_DIRECTORY rsrc_dir; + +- offset = pe_rva_to_offset(pe, directory->VirtualAddress); ++ offset = pe_rva_to_offset(pe, yr_le32toh(directory->VirtualAddress)); + + if (offset < 0) + return 0; +@@ -438,14 +438,14 @@ int pe_iterate_resources( + + if (struct_fits_in_pe(pe, rsrc_dir, IMAGE_RESOURCE_DIRECTORY)) + { +- set_integer(rsrc_dir->TimeDateStamp, ++ set_integer(yr_le32toh(rsrc_dir->TimeDateStamp), + pe->object, + "resource_timestamp"); + +- set_integer(rsrc_dir->MajorVersion, ++ set_integer(yr_le16toh(rsrc_dir->MajorVersion), + pe->object, + "resource_version.major"); +- set_integer(rsrc_dir->MinorVersion, ++ set_integer(yr_le16toh(rsrc_dir->MinorVersion), + pe->object, + "resource_version.minor"); + +@@ -483,7 +483,7 @@ void pe_parse_version_info( + { + PVERSION_INFO version_info; + +- int64_t version_info_offset = pe_rva_to_offset(pe, rsrc_data->OffsetToData); ++ int64_t version_info_offset = pe_rva_to_offset(pe, yr_le32toh(rsrc_data->OffsetToData)); + + if (version_info_offset < 0) + return; +@@ -504,16 +504,16 @@ void pe_parse_version_info( + + while(fits_in_pe(pe, version_info->Key, sizeof("VarFileInfo") * 2) && + strcmp_w(version_info->Key, "VarFileInfo") == 0 && +- version_info->Length != 0) ++ yr_le16toh(version_info->Length) != 0) + { + version_info = ADD_OFFSET( + version_info, +- version_info->Length); ++ yr_le16toh(version_info->Length)); + } + + while(fits_in_pe(pe, version_info->Key, sizeof("StringFileInfo") * 2) && + strcmp_w(version_info->Key, "StringFileInfo") == 0 && +- version_info->Length != 0) ++ yr_le16toh(version_info->Length) != 0) + { + PVERSION_INFO string_table = ADD_OFFSET( + version_info, +@@ -521,11 +521,11 @@ void pe_parse_version_info( + + version_info = ADD_OFFSET( + version_info, +- version_info->Length); ++ yr_le16toh(version_info->Length)); + + while (struct_fits_in_pe(pe, string_table, VERSION_INFO) && + wide_string_fits_in_pe(pe, string_table->Key) && +- string_table->Length != 0 && ++ yr_le16toh(string_table->Length) != 0 && + string_table < version_info) + { + PVERSION_INFO string = ADD_OFFSET( +@@ -534,11 +534,11 @@ void pe_parse_version_info( + + string_table = ADD_OFFSET( + string_table, +- string_table->Length); ++ yr_le16toh(string_table->Length)); + + while (struct_fits_in_pe(pe, string, VERSION_INFO) && + wide_string_fits_in_pe(pe, string->Key) && +- string->Length != 0 && ++ yr_le16toh(string->Length) != 0 && + string < string_table) + { + if (string->ValueLength > 0) +@@ -577,9 +577,9 @@ int pe_collect_resources( + { + DWORD length; + +- int64_t offset = pe_rva_to_offset(pe, rsrc_data->OffsetToData); ++ int64_t offset = pe_rva_to_offset(pe, yr_le32toh(rsrc_data->OffsetToData)); + +- if (offset < 0 || !fits_in_pe(pe, pe->data + offset, rsrc_data->Size)) ++ if (offset < 0 || !fits_in_pe(pe, pe->data + offset, yr_le32toh(rsrc_data->Size))) + return RESOURCE_CALLBACK_CONTINUE; + + set_integer( +@@ -589,7 +589,7 @@ int pe_collect_resources( + pe->resources); + + set_integer( +- rsrc_data->Size, ++ yr_le32toh(rsrc_data->Size), + pe->object, + "resources[%i].length", + pe->resources); +@@ -669,13 +669,13 @@ IMPORTED_FUNCTION* pe_parse_import_descriptor( + int num_functions = 0; + + int64_t offset = pe_rva_to_offset( +- pe, import_descriptor->OriginalFirstThunk); ++ pe, yr_le32toh(import_descriptor->OriginalFirstThunk)); + + // I've seen binaries where OriginalFirstThunk is zero. In this case + // use FirstThunk. + + if (offset <= 0) +- offset = pe_rva_to_offset(pe, import_descriptor->FirstThunk); ++ offset = pe_rva_to_offset(pe, yr_le32toh(import_descriptor->FirstThunk)); + + if (offset < 0) + return NULL; +@@ -685,16 +685,16 @@ IMPORTED_FUNCTION* pe_parse_import_descriptor( + PIMAGE_THUNK_DATA64 thunks64 = (PIMAGE_THUNK_DATA64)(pe->data + offset); + + while (struct_fits_in_pe(pe, thunks64, IMAGE_THUNK_DATA64) && +- thunks64->u1.Ordinal != 0 && num_functions < MAX_PE_IMPORTS) ++ yr_le64toh(thunks64->u1.Ordinal) != 0 && num_functions < MAX_PE_IMPORTS) + { + char* name = NULL; + uint16_t ordinal = 0; + uint8_t has_ordinal = 0; + +- if (!(thunks64->u1.Ordinal & IMAGE_ORDINAL_FLAG64)) ++ if (!(yr_le64toh(thunks64->u1.Ordinal) & IMAGE_ORDINAL_FLAG64)) + { + // If imported by name +- offset = pe_rva_to_offset(pe, thunks64->u1.Function); ++ offset = pe_rva_to_offset(pe, yr_le64toh(thunks64->u1.Function)); + + if (offset >= 0) + { +@@ -712,9 +712,9 @@ IMPORTED_FUNCTION* pe_parse_import_descriptor( + else + { + // If imported by ordinal. Lookup the ordinal. +- name = ord_lookup(dll_name, thunks64->u1.Ordinal & 0xFFFF); ++ name = ord_lookup(dll_name, yr_le64toh(thunks64->u1.Ordinal) & 0xFFFF); + // Also store the ordinal. +- ordinal = thunks64->u1.Ordinal & 0xFFFF; ++ ordinal = yr_le64toh(thunks64->u1.Ordinal) & 0xFFFF; + has_ordinal = 1; + } + +@@ -752,16 +752,16 @@ IMPORTED_FUNCTION* pe_parse_import_descriptor( + PIMAGE_THUNK_DATA32 thunks32 = (PIMAGE_THUNK_DATA32)(pe->data + offset); + + while (struct_fits_in_pe(pe, thunks32, IMAGE_THUNK_DATA32) && +- thunks32->u1.Ordinal != 0 && num_functions < MAX_PE_IMPORTS) ++ yr_le32toh(thunks32->u1.Ordinal) != 0 && num_functions < MAX_PE_IMPORTS) + { + char* name = NULL; + uint16_t ordinal = 0; + uint8_t has_ordinal = 0; + +- if (!(thunks32->u1.Ordinal & IMAGE_ORDINAL_FLAG32)) ++ if (!(yr_le32toh(thunks32->u1.Ordinal) & IMAGE_ORDINAL_FLAG32)) + { + // If imported by name +- offset = pe_rva_to_offset(pe, thunks32->u1.Function); ++ offset = pe_rva_to_offset(pe, yr_le32toh(thunks32->u1.Function)); + + if (offset >= 0) + { +@@ -779,9 +779,9 @@ IMPORTED_FUNCTION* pe_parse_import_descriptor( + else + { + // If imported by ordinal. Lookup the ordinal. +- name = ord_lookup(dll_name, thunks32->u1.Ordinal & 0xFFFF); ++ name = ord_lookup(dll_name, yr_le32toh(thunks32->u1.Ordinal) & 0xFFFF); + // Also store the ordinal. +- ordinal = thunks32->u1.Ordinal & 0xFFFF; ++ ordinal = yr_le32toh(thunks32->u1.Ordinal) & 0xFFFF; + has_ordinal = 1; + } + +@@ -865,10 +865,10 @@ IMPORTED_DLL* pe_parse_imports( + PIMAGE_DATA_DIRECTORY directory = pe_get_directory_entry( + pe, IMAGE_DIRECTORY_ENTRY_IMPORT); + +- if (directory->VirtualAddress == 0) ++ if (yr_le32toh(directory->VirtualAddress) == 0) + return NULL; + +- offset = pe_rva_to_offset(pe, directory->VirtualAddress); ++ offset = pe_rva_to_offset(pe, yr_le32toh(directory->VirtualAddress)); + + if (offset < 0) + return NULL; +@@ -877,9 +877,9 @@ IMPORTED_DLL* pe_parse_imports( + (pe->data + offset); + + while (struct_fits_in_pe(pe, imports, IMAGE_IMPORT_DESCRIPTOR) && +- imports->Name != 0 && num_imports < MAX_PE_IMPORTS) ++ yr_le32toh(imports->Name) != 0 && num_imports < MAX_PE_IMPORTS) + { +- int64_t offset = pe_rva_to_offset(pe, imports->Name); ++ int64_t offset = pe_rva_to_offset(pe, yr_le32toh(imports->Name)); + + if (offset >= 0) + { +@@ -943,19 +943,19 @@ void pe_parse_certificates( + set_integer(0, pe->object, "number_of_signatures"); + + // directory->VirtualAddress is a file offset. Don't call pe_rva_to_offset(). +- if (directory->VirtualAddress == 0 || +- directory->VirtualAddress > pe->data_size || +- directory->Size > pe->data_size || +- directory->VirtualAddress + directory->Size > pe->data_size) ++ if (yr_le32toh(directory->VirtualAddress) == 0 || ++ yr_le32toh(directory->VirtualAddress) > pe->data_size || ++ yr_le32toh(directory->Size) > pe->data_size || ++ yr_le32toh(directory->VirtualAddress) + yr_le32toh(directory->Size) > pe->data_size) + { + return; + } + + // Store the end of directory, making comparisons easier. +- eod = pe->data + directory->VirtualAddress + directory->Size; ++ eod = pe->data + yr_le32toh(directory->VirtualAddress) + directory->Size; + + win_cert = (PWIN_CERTIFICATE) \ +- (pe->data + directory->VirtualAddress); ++ (pe->data + yr_le32toh(directory->VirtualAddress)); + + // + // Walk the directory, pulling out certificates. +@@ -969,10 +969,10 @@ void pe_parse_certificates( + // + + while (struct_fits_in_pe(pe, win_cert, WIN_CERTIFICATE) && +- win_cert->Length > sizeof(WIN_CERTIFICATE) && +- fits_in_pe(pe, win_cert, win_cert->Length) && ++ yr_le32toh(win_cert->Length) > sizeof(WIN_CERTIFICATE) && ++ fits_in_pe(pe, win_cert, yr_le32toh(win_cert->Length)) && + (uint8_t*) win_cert + sizeof(WIN_CERTIFICATE) < eod && +- (uint8_t*) win_cert + win_cert->Length <= eod) ++ (uint8_t*) win_cert + yr_le32toh(win_cert->Length) <= eod) + { + BIO* cert_bio; + PKCS7* pkcs7; +@@ -980,9 +980,9 @@ void pe_parse_certificates( + + // Some sanity checks + +- if (win_cert->Length == 0 || +- (win_cert->Revision != WIN_CERT_REVISION_1_0 && +- win_cert->Revision != WIN_CERT_REVISION_2_0)) ++ if (yr_le32toh(win_cert->Length) == 0 || ++ (yr_le16toh(win_cert->Revision) != WIN_CERT_REVISION_1_0 && ++ yr_le16toh(win_cert->Revision) != WIN_CERT_REVISION_2_0)) + { + break; + } +@@ -990,16 +990,16 @@ void pe_parse_certificates( + // Don't support legacy revision for now. + // Make sure type is PKCS#7 too. + +- if (win_cert->Revision != WIN_CERT_REVISION_2_0 || +- win_cert->CertificateType != WIN_CERT_TYPE_PKCS_SIGNED_DATA) ++ if (yr_le16toh(win_cert->Revision) != WIN_CERT_REVISION_2_0 || ++ yr_le16toh(win_cert->CertificateType) != WIN_CERT_TYPE_PKCS_SIGNED_DATA) + { +- uintptr_t end = (uintptr_t) ((uint8_t *) win_cert) + win_cert->Length; ++ uintptr_t end = (uintptr_t) ((uint8_t *) win_cert) + yr_le32toh(win_cert->Length); + win_cert = (PWIN_CERTIFICATE) (end + (end % 8)); + + continue; + } + +- cert_bio = BIO_new_mem_buf(win_cert->Certificate, win_cert->Length); ++ cert_bio = BIO_new_mem_buf(win_cert->Certificate, yr_le32toh(win_cert->Length)); + + if (!cert_bio) + break; +@@ -1161,29 +1161,31 @@ void pe_parse_header( + int i, scount; + + set_integer( +- pe->header->FileHeader.Machine, ++ yr_le16toh(pe->header->FileHeader.Machine), + pe->object, "machine"); + + set_integer( +- pe->header->FileHeader.NumberOfSections, ++ yr_le16toh(pe->header->FileHeader.NumberOfSections), + pe->object, "number_of_sections"); + + set_integer( +- pe->header->FileHeader.TimeDateStamp, ++ yr_le32toh(pe->header->FileHeader.TimeDateStamp), + pe->object, "timestamp"); + + set_integer( +- pe->header->FileHeader.Characteristics, ++ yr_le16toh(pe->header->FileHeader.Characteristics), + pe->object, "characteristics"); + + set_integer( + flags & SCAN_FLAGS_PROCESS_MEMORY ? +- base_address + OptionalHeader(pe, AddressOfEntryPoint) : +- pe_rva_to_offset(pe, OptionalHeader(pe, AddressOfEntryPoint)), ++ base_address + yr_le32toh(OptionalHeader(pe, AddressOfEntryPoint)) : ++ pe_rva_to_offset(pe, yr_le32toh(OptionalHeader(pe, AddressOfEntryPoint))), + pe->object, "entry_point"); + + set_integer( +- OptionalHeader(pe, ImageBase), ++ IS_64BITS_PE(pe) ? ++ yr_le64toh(OptionalHeader(pe, ImageBase)) : ++ yr_le32toh(OptionalHeader(pe, ImageBase)), + pe->object, "image_base"); + + set_integer( +@@ -1195,31 +1197,31 @@ void pe_parse_header( + pe->object, "linker_version.minor"); + + set_integer( +- OptionalHeader(pe, MajorOperatingSystemVersion), ++ yr_le16toh(OptionalHeader(pe, MajorOperatingSystemVersion)), + pe->object, "os_version.major"); + + set_integer( +- OptionalHeader(pe, MinorOperatingSystemVersion), ++ yr_le16toh(OptionalHeader(pe, MinorOperatingSystemVersion)), + pe->object, "os_version.minor"); + + set_integer( +- OptionalHeader(pe, MajorImageVersion), ++ yr_le16toh(OptionalHeader(pe, MajorImageVersion)), + pe->object, "image_version.major"); + + set_integer( +- OptionalHeader(pe, MinorImageVersion), ++ yr_le16toh(OptionalHeader(pe, MinorImageVersion)), + pe->object, "image_version.minor"); + + set_integer( +- OptionalHeader(pe, MajorSubsystemVersion), ++ yr_le16toh(OptionalHeader(pe, MajorSubsystemVersion)), + pe->object, "subsystem_version.major"); + + set_integer( +- OptionalHeader(pe, MinorSubsystemVersion), ++ yr_le16toh(OptionalHeader(pe, MinorSubsystemVersion)), + pe->object, "subsystem_version.minor"); + + set_integer( +- OptionalHeader(pe, Subsystem), ++ yr_le16toh(OptionalHeader(pe, Subsystem)), + pe->object, "subsystem"); + + pe_iterate_resources( +@@ -1231,7 +1233,7 @@ void pe_parse_header( + + section = IMAGE_FIRST_SECTION(pe->header); + +- scount = yr_min(pe->header->FileHeader.NumberOfSections, MAX_PE_SECTIONS); ++ scount = yr_min(yr_le16toh(pe->header->FileHeader.NumberOfSections), MAX_PE_SECTIONS); + + for (i = 0; i < scount; i++) + { +@@ -1246,20 +1248,23 @@ void pe_parse_header( + pe->object, "sections[%i].name", i); + + set_integer( +- section->Characteristics, ++ yr_le32toh(section->Characteristics), + pe->object, "sections[%i].characteristics", i); + +- set_integer(section->SizeOfRawData, ++ set_integer( ++ yr_le32toh(section->SizeOfRawData), + pe->object, "sections[%i].raw_data_size", i); + +- set_integer(section->PointerToRawData, ++ set_integer( ++ yr_le32toh(section->PointerToRawData), + pe->object, "sections[%i].raw_data_offset", i); + +- set_integer(section->VirtualAddress, ++ set_integer( ++ yr_le32toh(section->VirtualAddress), + pe->object, "sections[%i].virtual_address", i); + + set_integer( +- section->Misc.VirtualSize, ++ yr_le32toh(section->Misc.VirtualSize), + pe->object, "sections[%i].virtual_size", i); + + section++; +@@ -1377,7 +1382,7 @@ define_function(exports) + + // If the PE doesn't export any functions, return FALSE + +- if (directory->VirtualAddress == 0) ++ if (yr_le32toh(directory->VirtualAddress) == 0) + return_integer(0); + + offset = pe_rva_to_offset(pe, directory->VirtualAddress); +@@ -1391,18 +1396,18 @@ define_function(exports) + if (!struct_fits_in_pe(pe, exports, IMAGE_EXPORT_DIRECTORY)) + return_integer(0); + +- offset = pe_rva_to_offset(pe, exports->AddressOfNames); ++ offset = pe_rva_to_offset(pe, yr_le32toh(exports->AddressOfNames)); + + if (offset < 0) + return_integer(0); + +- if (exports->NumberOfNames > MAX_PE_EXPORTS || +- exports->NumberOfNames * sizeof(DWORD) > pe->data_size - offset) ++ if (yr_le32toh(exports->NumberOfNames) > MAX_PE_EXPORTS || ++ yr_le32toh(exports->NumberOfNames) * sizeof(DWORD) > pe->data_size - offset) + return_integer(0); + + names = (DWORD*)(pe->data + offset); + +- for (i = 0; i < exports->NumberOfNames; i++) ++ for (i = 0; i < yr_le32toh(exports->NumberOfNames); i++) + { + char* name; + offset = pe_rva_to_offset(pe, names[i]); +@@ -2299,7 +2304,7 @@ int module_load( + // Ignore DLLs while scanning a process + + if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) || +- !(pe_header->FileHeader.Characteristics & IMAGE_FILE_DLL)) ++ !(yr_le16toh(pe_header->FileHeader.Characteristics) & IMAGE_FILE_DLL)) + { + pe = (PE*) yr_malloc(sizeof(PE)); + +diff --git a/libyara/modules/pe_utils.c b/libyara/modules/pe_utils.c +index ed69b80..9b80286 100644 +--- a/libyara/modules/pe_utils.c ++++ b/libyara/modules/pe_utils.c +@@ -60,46 +60,46 @@ PIMAGE_NT_HEADERS32 pe_get_header( + + mz_header = (PIMAGE_DOS_HEADER) data; + +- if (mz_header->e_magic != IMAGE_DOS_SIGNATURE) ++ if (yr_le16toh(mz_header->e_magic) != IMAGE_DOS_SIGNATURE) + return NULL; + +- if (mz_header->e_lfanew < 0) ++ if (yr_le32toh(mz_header->e_lfanew) < 0) + return NULL; + +- headers_size = mz_header->e_lfanew + \ ++ headers_size = yr_le32toh(mz_header->e_lfanew) + \ + sizeof(pe_header->Signature) + \ + sizeof(IMAGE_FILE_HEADER); + + if (data_size < headers_size) + return NULL; + +- pe_header = (PIMAGE_NT_HEADERS32) (data + mz_header->e_lfanew); +- +- headers_size += pe_header->FileHeader.SizeOfOptionalHeader; +- +- if (pe_header->Signature == IMAGE_NT_SIGNATURE && +- (pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_UNKNOWN || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_AM33 || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_ARM || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_ARMNT || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_ARM64 || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_EBC || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_M32R || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_MIPS16 || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_MIPSFPU || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_MIPSFPU16 || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_POWERPC || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_POWERPCFP || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_R4000 || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_SH3 || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_SH3DSP || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_SH4 || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_SH5 || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_THUMB || +- pe_header->FileHeader.Machine == IMAGE_FILE_MACHINE_WCEMIPSV2) && ++ pe_header = (PIMAGE_NT_HEADERS32) (data + yr_le32toh(mz_header->e_lfanew)); ++ ++ headers_size += yr_le16toh(pe_header->FileHeader.SizeOfOptionalHeader); ++ ++ if (yr_le32toh(pe_header->Signature) == IMAGE_NT_SIGNATURE && ++ (yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_UNKNOWN || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_AM33 || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_AMD64 || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_ARM || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_ARMNT || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_ARM64 || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_EBC || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_I386 || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_IA64 || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_M32R || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_MIPS16 || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_MIPSFPU || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_MIPSFPU16 || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_POWERPC || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_POWERPCFP || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_R4000 || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_SH3 || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_SH3DSP || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_SH4 || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_SH5 || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_THUMB || ++ yr_le16toh(pe_header->FileHeader.Machine) == IMAGE_FILE_MACHINE_WCEMIPSV2) && + data_size > headers_size) + { + return pe_header; +@@ -144,17 +144,17 @@ int64_t pe_rva_to_offset( + int alignment = 0; + int rest = 0; + +- while(i < yr_min(pe->header->FileHeader.NumberOfSections, MAX_PE_SECTIONS)) ++ while(i < yr_min(yr_le16toh(pe->header->FileHeader.NumberOfSections), MAX_PE_SECTIONS)) + { + if (struct_fits_in_pe(pe, section, IMAGE_SECTION_HEADER)) + { +- if (lowest_section_rva > section->VirtualAddress) ++ if (lowest_section_rva > yr_le32toh(section->VirtualAddress)) + { +- lowest_section_rva = section->VirtualAddress; ++ lowest_section_rva = yr_le32toh(section->VirtualAddress); + } + +- if (rva >= section->VirtualAddress && +- section_rva <= section->VirtualAddress) ++ if (rva >= yr_le32toh(section->VirtualAddress) && ++ section_rva <= yr_le32toh(section->VirtualAddress)) + { + // Round section_offset + // +@@ -167,11 +167,11 @@ int64_t pe_rva_to_offset( + // If FileAlignment is >= 0x200, it is apparently ignored (see + // Ero Carreras's pefile.py, PE.adjust_FileAlignment). + +- alignment = yr_min(OptionalHeader(pe, FileAlignment), 0x200); ++ alignment = yr_min(yr_le32toh(OptionalHeader(pe, FileAlignment)), 0x200); + +- section_rva = section->VirtualAddress; +- section_offset = section->PointerToRawData; +- section_raw_size = section->SizeOfRawData; ++ section_rva = yr_le32toh(section->VirtualAddress); ++ section_offset = yr_le32toh(section->PointerToRawData); ++ section_raw_size = yr_le32toh(section->SizeOfRawData); + + if (alignment) + { +diff --git a/tests/test-elf.c b/tests/test-elf.c +new file mode 100644 +index 0000000..8d13b47 +--- /dev/null ++++ b/tests/test-elf.c +@@ -0,0 +1,29 @@ ++#include ++#include "util.h" ++#include "blob.h" ++ ++int main(int argc, char** argv) ++{ ++ yr_initialize(); ++ ++ assert_true_rule_blob("import \"elf\" rule test { condition: elf.type }", ELF32_FILE); ++ assert_true_rule_blob("import \"elf\" rule test { condition: elf.type }", ELF64_FILE); ++ ++ assert_true_rule_blob("import \"elf\" rule test { condition: elf.machine == elf.EM_386 }", ELF32_FILE) ++ assert_true_rule_blob("import \"elf\" rule test { condition: elf.machine == elf.EM_X86_64 }", ELF64_FILE) ++ ++ assert_true_rule_blob( ++ "import \"elf\" rule test { \ ++ strings: $a = { b8 01 00 00 00 bb 2a } \ ++ condition: $a at elf.entry_point }", ++ ELF32_FILE); ++ ++ assert_true_rule_blob( ++ "import \"elf\" rule test { \ ++ strings: $a = { b8 01 00 00 00 bb 2a } \ ++ condition: $a at elf.entry_point }", ++ ELF64_FILE); ++ ++ yr_finalize(); ++ return 0; ++} +diff --git a/tests/test-pe.c b/tests/test-pe.c +index 93cb06e..881939e 100644 +--- a/tests/test-pe.c ++++ b/tests/test-pe.c +@@ -5,7 +5,6 @@ + + int main(int argc, char** argv) + { +-#if (defined(HAVE_ENDIAN_H) && BYTE_ORDER == LITTLE_ENDIAN) || defined(_MSC) + yr_initialize(); + + assert_true_rule_file("import \"pe\" rule test { condition: pe.imports(\"KERNEL32.dll\", \"DeleteCriticalSection\") }", +@@ -18,9 +17,5 @@ int main(int argc, char** argv) + "tests/data/tiny-idata-5200"); + + yr_finalize(); +-#else +- puts("Not testing pe module on big-endian architectures ... yet"); +- exit(77); +-#endif + return 0; + } + +From 1cca7072d684d86fdba4a8a1f3eca63ba584befe Mon Sep 17 00:00:00 2001 +From: Hilko Bengen +Date: Mon, 24 Oct 2016 11:14:44 +0200 +Subject: [PATCH 14/36] Move yr_*toh() macros to their own header file (#542) + +See #541 +(cherry picked from commit d3b77eb1e9ee4731ea11c39fceb262cf4f2b006f) +--- + libyara/exec.c | 1 + + libyara/exefiles.c | 1 + + libyara/include/yara/endian.h | 63 +++++++++++++++++++++++++++++++++++++++++++ + libyara/include/yara/pe.h | 2 +- + libyara/include/yara/utils.h | 29 -------------------- + libyara/modules/elf.c | 1 + + libyara/modules/pe.c | 1 + + libyara/modules/pe_utils.c | 1 + + 8 files changed, 69 insertions(+), 30 deletions(-) + create mode 100644 libyara/include/yara/endian.h + +diff --git a/libyara/exec.c b/libyara/exec.c +index 3facabd..1a347c0 100644 +--- a/libyara/exec.c ++++ b/libyara/exec.c +@@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + ++#include + #include + #include + #include +diff --git a/libyara/exefiles.c b/libyara/exefiles.c +index 599e397..05d1de7 100644 +--- a/libyara/exefiles.c ++++ b/libyara/exefiles.c +@@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #include + ++#include + #include + #include + #include +diff --git a/libyara/include/yara/endian.h b/libyara/include/yara/endian.h +new file mode 100644 +index 0000000..06d8c14 +--- /dev/null ++++ b/libyara/include/yara/endian.h +@@ -0,0 +1,63 @@ ++/* ++Copyright (c) 2016. The YARA Authors. All Rights Reserved. ++ ++Redistribution and use in source and binary forms, with or without modification, ++are permitted provided that the following conditions are met: ++ ++1. Redistributions of source code must retain the above copyright notice, this ++list of conditions and the following disclaimer. ++ ++2. Redistributions in binary form must reproduce the above copyright notice, ++this list of conditions and the following disclaimer in the documentation and/or ++other materials provided with the distribution. ++ ++3. Neither the name of the copyright holder nor the names of its contributors ++may be used to endorse or promote products derived from this software without ++specific prior written permission. ++ ++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ++WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ++ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++*/ ++ ++#ifndef YR_ENDIAN_H ++#define YR_ENDIAN_H ++ ++#include ++ ++#if defined(__GNUC__) ++#define yr_bswap16(x) __builtin_bswap16(x) ++#define yr_bswap32(x) __builtin_bswap32(x) ++#define yr_bswap64(x) __builtin_bswap64(x) ++#elif defined(_MSC_VER) ++#define yr_bswap16(x) _byteswap_ushort(x) ++#define yr_bswap32(x) _byteswap_ulong(x) ++#define yr_bswap64(x) _byteswap_uint64(x) ++#else ++#error Unknown compiler: Add yr_bswap* definitions ++#endif ++ ++#if defined(WORDS_BIGENDIAN) ++#define yr_le16toh(x) yr_bswap16(x) ++#define yr_le32toh(x) yr_bswap32(x) ++#define yr_le64toh(x) yr_bswap64(x) ++#define yr_be16toh(x) (x) ++#define yr_be32toh(x) (x) ++#define yr_be64toh(x) (x) ++#else ++#define yr_le16toh(x) (x) ++#define yr_le32toh(x) (x) ++#define yr_le64toh(x) (x) ++#define yr_be16toh(x) yr_bswap16(x) ++#define yr_be32toh(x) yr_bswap32(x) ++#define yr_be64toh(x) yr_bswap64(x) ++#endif ++ ++#endif +diff --git a/libyara/include/yara/pe.h b/libyara/include/yara/pe.h +index 0291cb0..c189146 100644 +--- a/libyara/include/yara/pe.h ++++ b/libyara/include/yara/pe.h +@@ -30,8 +30,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #ifndef YR_PE_H + #define YR_PE_H + ++#include + #include +-#include + + #pragma pack(push, 1) + +diff --git a/libyara/include/yara/utils.h b/libyara/include/yara/utils.h +index da0fb88..58f1347 100644 +--- a/libyara/include/yara/utils.h ++++ b/libyara/include/yara/utils.h +@@ -70,35 +70,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #define yr_min(x, y) ((x < y) ? (x) : (y)) + #define yr_max(x, y) ((x > y) ? (x) : (y)) + +-#if defined(__GNUC__) +-#define yr_bswap16(x) __builtin_bswap16(x) +-#define yr_bswap32(x) __builtin_bswap32(x) +-#define yr_bswap64(x) __builtin_bswap64(x) +-#elif defined(_MSC_VER) +-#define yr_bswap16(x) _byteswap_ushort(x) +-#define yr_bswap32(x) _byteswap_ulong(x) +-#define yr_bswap64(x) _byteswap_uint64(x) +-#else +-#error Unknown compiler: Add yr_bswap* definitions +-#endif +- +-#if defined(WORDS_BIGENDIAN) +-#define yr_le16toh(x) yr_bswap16(x) +-#define yr_le32toh(x) yr_bswap32(x) +-#define yr_le64toh(x) yr_bswap64(x) +-#define yr_be16toh(x) (x) +-#define yr_be32toh(x) (x) +-#define yr_be64toh(x) (x) +-#else +-#define yr_le16toh(x) (x) +-#define yr_le32toh(x) (x) +-#define yr_le64toh(x) (x) +-#define yr_be16toh(x) yr_bswap16(x) +-#define yr_be32toh(x) yr_bswap32(x) +-#define yr_be64toh(x) yr_bswap64(x) +-#endif +- +- + #ifdef NDEBUG + + #define assertf(expr, msg, ...) ((void)0) +diff --git a/libyara/modules/elf.c b/libyara/modules/elf.c +index 08c3ce4..e934084 100644 +--- a/libyara/modules/elf.c ++++ b/libyara/modules/elf.c +@@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + + #include ++#include + #include + #include + +diff --git a/libyara/modules/pe.c b/libyara/modules/pe.c +index 7c32daf..f78a9d5 100644 +--- a/libyara/modules/pe.c ++++ b/libyara/modules/pe.c +@@ -47,6 +47,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #endif + #endif + ++#include + #include + #include + #include +diff --git a/libyara/modules/pe_utils.c b/libyara/modules/pe_utils.c +index 9b80286..dddbba3 100644 +--- a/libyara/modules/pe_utils.c ++++ b/libyara/modules/pe_utils.c +@@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #include + ++#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 1a347c0..5266b9a 100644 +--- a/libyara/exec.c ++++ b/libyara/exec.c +@@ -50,17 +50,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #define MEM_SIZE MAX_LOOP_NESTING * LOOP_LOCAL_VARS + +-typedef union _STACK_ITEM { +- +- int64_t i; +- double d; +- void* p; +- YR_OBJECT* o; +- YR_STRING* s; +- SIZED_STRING* ss; +- +-} STACK_ITEM; +- + + #define push(x) \ + if (sp < stack_size) \ +@@ -172,14 +161,14 @@ int yr_execute_code( + time_t start_time) + { + int64_t mem[MEM_SIZE]; +- int64_t args[MAX_FUNCTION_ARGS]; + int32_t sp = 0; + uint8_t* ip = rules->code_start; + +- STACK_ITEM *stack; +- STACK_ITEM r1; +- STACK_ITEM r2; +- STACK_ITEM r3; ++ YR_VALUE args[MAX_FUNCTION_ARGS]; ++ YR_VALUE *stack; ++ YR_VALUE r1; ++ YR_VALUE r2; ++ YR_VALUE r3; + + #ifdef PROFILING_ENABLED + YR_RULE* current_rule = NULL; +@@ -207,7 +196,7 @@ int yr_execute_code( + + yr_get_configuration(YR_CONFIG_STACK_SIZE, (void*) &stack_size); + +- stack = (STACK_ITEM*) yr_malloc(stack_size * sizeof(STACK_ITEM)); ++ stack = (YR_VALUE*) yr_malloc(stack_size * sizeof(YR_VALUE)); + + if (stack == NULL) + return ERROR_INSUFICIENT_MEMORY; +@@ -553,7 +542,7 @@ int yr_execute_code( + if (is_undef(r1)) // count the number of undefined args + count++; + +- args[i - 1] = r1.i; ++ args[i - 1] = r1; + i--; + } + +@@ -580,11 +569,7 @@ int yr_execute_code( + + if (strcmp(function->prototypes[i].arguments_fmt, args_fmt) == 0) + { +- result = function->prototypes[i].code( +- (void*) args, +- context, +- function); +- ++ result = function->prototypes[i].code(args, context, function); + break; + } + } +diff --git a/libyara/include/yara/modules.h b/libyara/include/yara/modules.h +index 38e1bcd..9e9a6e3 100644 +--- a/libyara/include/yara/modules.h ++++ b/libyara/include/yara/modules.h +@@ -266,25 +266,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #define define_function(func) \ + int func ( \ +- void* __args, \ ++ YR_VALUE* __args, \ + YR_SCAN_CONTEXT* __context, \ + YR_OBJECT_FUNCTION* __function_obj) + + + #define sized_string_argument(n) \ +- (*(SIZED_STRING**) &(((int64_t*) __args)[n-1])) ++ (__args[n-1].ss) + + #define string_argument(n) \ + (sized_string_argument(n)->c_string) + + #define integer_argument(n) \ +- (((int64_t*) __args)[n-1]) ++ (__args[n-1].i) + + #define float_argument(n) \ +- (((double*) __args)[n-1]) ++ (__args[n-1].d) + + #define regexp_argument(n) \ +- ((RE_CODE)((int64_t*) __args)[n-1]) ++ ((RE_CODE)(__args[n-1].p)) + + + #define module() yr_object_get_root((YR_OBJECT*) __function_obj) +diff --git a/libyara/include/yara/types.h b/libyara/include/yara/types.h +index bdacaa9..0fea79b 100644 +--- a/libyara/include/yara/types.h ++++ b/libyara/include/yara/types.h +@@ -382,7 +382,6 @@ typedef struct _YR_RULES { + } YR_RULES; + + +- + struct _YR_MEMORY_BLOCK; + struct _YR_MEMORY_BLOCK_ITERATOR; + +@@ -516,11 +515,23 @@ typedef struct _YR_OBJECT_DICTIONARY + } YR_OBJECT_DICTIONARY; + + ++typedef union _YR_VALUE { ++ ++ int64_t i; ++ double d; ++ void* p; ++ YR_OBJECT* o; ++ YR_STRING* s; ++ SIZED_STRING* ss; ++ ++} YR_VALUE; ++ ++ + struct _YR_OBJECT_FUNCTION; + + + typedef int (*YR_MODULE_FUNC)( +- void* args, ++ YR_VALUE* args, + YR_SCAN_CONTEXT* context, + struct _YR_OBJECT_FUNCTION* function_obj); + + +From 00bcc7c6865be713bed6d2e58cb6308e055ce3cd Mon Sep 17 00:00:00 2001 +From: Hilko Bengen +Date: Mon, 31 Oct 2016 09:40:38 +0100 +Subject: [PATCH 16/36] Don't unmask signals when setting up exception handler + (Unix) (#546) + +* YR_TRYCATCH: Remove duplicate initialization of oldmask + +* Add test for handling exceptions + +With + + #define YR_TRYCATCH(_try_clause_, _catch_clause_) {_try_clause_} + +this will cause a bus error on Linux -- as it should. + +* tests: Add assert_*_rule_blob_size, make count_matches usable from test code + +* test-exception: Block and send SIGUSR1 before 2nd yr_rules_scan_mem call + +This seems to reproduce something similar to the symptom described in + +$ ./test-exception +Scanning for "aaaa"... +err = 4, matches = 0 +Sending blocked SIGUSR1 to ourselves... +Scanning for {00 00 00 00}... +User defined signal 1 + +* exception (UNIX): Remove unneeded pthread_sigmask() calls + +sigsetjmp() already saves the signal mask for us. + +Also, setting the signal mask using the (empty) act.sa_mask was wrong +and led to the behavior described in #544. + +We still want delivery of all signals to be blocked during execution of +the signal handler. + +* Document test-exception + +cherry-picked from: + +- 8b2b6b8f82b8a8a8830bae122474b39ac2814fc6 +- 0b3d9a93276d3364b2a3561995d27e8b4a137134, "Minor re-styling" +--- + Makefile.am | 4 +- + libyara/exception.h | 7 +-- + tests/test-exception.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++ + tests/util.c | 2 +- + tests/util.h | 20 ++++++-- + 5 files changed, 147 insertions(+), 12 deletions(-) + create mode 100644 tests/test-exception.c + +diff --git a/Makefile.am b/Makefile.am +index 8c1652a..8f5ab59 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -15,7 +15,7 @@ yarac_SOURCES = args.c args.h yarac.c + yarac_LDADD = libyara/.libs/libyara.a + + TESTS = $(check_PROGRAMS) +-check_PROGRAMS = test-alignment test-rules test-pe test-elf ++check_PROGRAMS = test-alignment test-rules test-pe test-elf test-exception + test_alignment_SOURCES = tests/test-alignment.c + test_rules_SOURCES = tests/test-rules.c tests/util.c + test_rules_LDADD = libyara/.libs/libyara.a +@@ -23,6 +23,8 @@ test_pe_SOURCES = tests/test-pe.c tests/util.c + test_pe_LDADD = libyara/.libs/libyara.a + test_elf_SOURCES = tests/test-elf.c tests/util.c + test_elf_LDADD = libyara/.libs/libyara.a ++test_exception_SOURCES = tests/test-exception.c tests/util.c ++test_exception_LDADD = libyara/.libs/libyara.a + + # man pages + man1_MANS = yara.man yarac.man +diff --git a/libyara/exception.h b/libyara/exception.h +index 436d006..c70ae63 100644 +--- a/libyara/exception.h ++++ b/libyara/exception.h +@@ -99,13 +99,9 @@ typedef struct sigaction sa; + { \ + struct sigaction oldact; \ + struct sigaction act; \ +- sigset_t oldmask; \ + act.sa_handler = exception_handler; \ + act.sa_flags = 0; /* SA_ONSTACK? */ \ +- sigemptyset(&oldmask); \ +- sigemptyset(&act.sa_mask); \ +- sigemptyset(&oldmask); \ +- pthread_sigmask(SIG_SETMASK, &act.sa_mask, &oldmask); \ ++ sigfillset(&act.sa_mask); \ + sigaction(SIGBUS, &act, &oldact); \ + int tidx = yr_get_tidx(); \ + assert(tidx != -1); \ +@@ -117,7 +113,6 @@ typedef struct sigaction sa; + { _catch_clause_ } \ + exc_jmp_buf[tidx] = NULL; \ + sigaction(SIGBUS, &oldact, NULL); \ +- pthread_sigmask(SIG_SETMASK, &oldmask, NULL); \ + } while (0) + + #endif +diff --git a/tests/test-exception.c b/tests/test-exception.c +new file mode 100644 +index 0000000..8ebea58 +--- /dev/null ++++ b/tests/test-exception.c +@@ -0,0 +1,126 @@ ++/* ++Copyright (c) 2016. The YARA Authors. All Rights Reserved. ++ ++Redistribution and use in source and binary forms, with or without modification, ++are permitted provided that the following conditions are met: ++ ++1. Redistributions of source code must retain the above copyright notice, this ++list of conditions and the following disclaimer. ++ ++2. Redistributions in binary form must reproduce the above copyright notice, ++this list of conditions and the following disclaimer in the documentation and/or ++other materials provided with the distribution. ++ ++3. Neither the name of the copyright holder nor the names of its contributors ++may be used to endorse or promote products derived from this software without ++specific prior written permission. ++ ++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ++WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ++ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++*/ ++ ++#include ++#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 5597c98..59105dd 100644 +--- a/tests/util.c ++++ b/tests/util.c +@@ -82,7 +82,7 @@ YR_RULES* compile_rule( + } + + +-static int count_matches( ++int count_matches( + int message, + void* message_data, + void* user_data) +diff --git a/tests/util.h b/tests/util.h +index 89b245b..835115f 100644 +--- a/tests/util.h ++++ b/tests/util.h +@@ -36,6 +36,12 @@ YR_RULES* compile_rule( + char* string); + + ++int count_matches( ++ int message, ++ void* message_data, ++ void* user_data); ++ ++ + int matches_blob( + char* rule, + uint8_t* blob, +@@ -66,15 +72,18 @@ int read_file( + } \ + } while (0); + +-#define assert_true_rule_blob(rule, blob) \ ++#define assert_true_rule_blob_size(rule, blob, size) \ + do { \ +- if (!matches_blob(rule, (uint8_t*) (blob), sizeof(blob))) { \ ++ if (!matches_blob(rule, (uint8_t*) (blob), size)) { \ + fprintf(stderr, "%s:%d: rule does not match (but should)\n", \ + __FILE__, __LINE__ ); \ + exit(EXIT_FAILURE); \ + } \ + } while (0); + ++#define assert_true_rule_blob(rule, blob) \ ++ assert_true_rule_blob_size(rule, blob, sizeof(blob)) ++ + #define assert_true_rule_file(rule, filename) \ + do { \ + char* buf; \ +@@ -102,15 +111,18 @@ int read_file( + } \ + } while (0); + +-#define assert_false_rule_blob(rule, blob) \ ++#define assert_false_rule_blob_size(rule, blob, size) \ + do { \ +- if (matches_blob(rule, (uint8_t*) (blob), sizeof(blob))) { \ ++ if (matches_blob(rule, (uint8_t*) (blob), size)) { \ + fprintf(stderr, "%s:%d: rule matches (but shouldn't)\n", \ + __FILE__, __LINE__ ); \ + exit(EXIT_FAILURE); \ + } \ + } while (0); + ++#define assert_false_rule_blob(rule, blob) \ ++ assert_false_rule_blob_size(rule, blob, sizeof(blob)) ++ + #define assert_false_rule_file(rule, filename) \ + do { \ + char* buf; \ + +From 7a71fc986f00abd29a7c332d01c45ee101ffda25 Mon Sep 17 00:00:00 2001 +From: Hilko Bengen +Date: Mon, 31 Oct 2016 22:31:27 +0100 +Subject: [PATCH 17/36] tests: Use larger file to demonstrate SIGBUS (#549) + +Apparently, PowerPC uses larger pages so the original size did not lead +to a signal. +(cherry picked from commit ddd5e975f2c36323e408e0eeedd56db59e0148a0) +--- + tests/test-exception.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +diff --git a/tests/test-exception.c b/tests/test-exception.c +index 8ebea58..29232b2 100644 +--- a/tests/test-exception.c ++++ b/tests/test-exception.c +@@ -36,11 +36,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #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 c70ae63..a9698b3 100644 +--- a/libyara/exception.h ++++ b/libyara/exception.h +@@ -81,7 +81,7 @@ static LONG CALLBACK exception_handler( + sigjmp_buf *exc_jmp_buf[MAX_THREADS]; + + static void exception_handler(int sig) { +- if (sig == SIGBUS) ++ if (sig == SIGBUS || sig == SIGSEGV) + { + int tidx = yr_get_tidx(); + +@@ -97,12 +97,14 @@ typedef struct sigaction sa; + #define YR_TRYCATCH(_try_clause_, _catch_clause_) \ + do \ + { \ +- struct sigaction oldact; \ ++ struct sigaction old_sigbus_act; \ ++ struct sigaction old_sigsegv_act; \ + struct sigaction act; \ + act.sa_handler = exception_handler; \ + act.sa_flags = 0; /* SA_ONSTACK? */ \ + sigfillset(&act.sa_mask); \ +- sigaction(SIGBUS, &act, &oldact); \ ++ sigaction(SIGBUS, &act, &old_sigbus_act); \ ++ sigaction(SIGSEGV, &act, &old_sigsegv_act); \ + int tidx = yr_get_tidx(); \ + assert(tidx != -1); \ + sigjmp_buf jb; \ +@@ -112,7 +114,8 @@ typedef struct sigaction sa; + else \ + { _catch_clause_ } \ + exc_jmp_buf[tidx] = NULL; \ +- sigaction(SIGBUS, &oldact, NULL); \ ++ sigaction(SIGBUS, &old_sigbus_act, NULL); \ ++ sigaction(SIGSEGV, &old_sigsegv_act, NULL); \ + } while (0) + + #endif + +From 6ba610d91aebdc94de95802507bff71456ca2532 Mon Sep 17 00:00:00 2001 +From: Hilko Bengen +Date: Wed, 2 Nov 2016 22:43:58 +0100 +Subject: [PATCH 19/36] Add scan flag for disabling exceptions + +(cherry picked from commit c72536a223a3e039c147273c7cc0d43f40b77660) +--- + libyara/exception.h | 74 +++++++++++++++++++++++++++------------------ + libyara/include/yara/scan.h | 1 + + libyara/rules.c | 12 ++++++-- + 3 files changed, 54 insertions(+), 33 deletions(-) + +diff --git a/libyara/exception.h b/libyara/exception.h +index a9698b3..edead24 100644 +--- a/libyara/exception.h ++++ b/libyara/exception.h +@@ -57,20 +57,27 @@ static LONG CALLBACK exception_handler( + return EXCEPTION_CONTINUE_SEARCH; + } + +-#define YR_TRYCATCH(_try_clause_, _catch_clause_) \ ++#define YR_TRYCATCH(_do_,_try_clause_, _catch_clause_) \ + do \ + { \ +- jmp_buf jb; \ +- HANDLE exh = AddVectoredExceptionHandler(1, exception_handler); \ +- int tidx = yr_get_tidx(); \ +- assert(tidx != -1); \ +- exc_jmp_buf[tidx] = &jb; \ +- if (setjmp(jb) == 0) \ +- { _try_clause_ } \ ++ if (_do_) \ ++ { \ ++ jmp_buf jb; \ ++ HANDLE exh = AddVectoredExceptionHandler(1, exception_handler); \ ++ int tidx = yr_get_tidx(); \ ++ assert(tidx != -1); \ ++ exc_jmp_buf[tidx] = &jb; \ ++ if (setjmp(jb) == 0) \ ++ { _try_clause_ } \ ++ else \ ++ { _catch_clause_ } \ ++ exc_jmp_buf[tidx] = NULL; \ ++ RemoveVectoredExceptionHandler(exh); \ ++ } \ + else \ +- { _catch_clause_ } \ +- exc_jmp_buf[tidx] = NULL; \ +- RemoveVectoredExceptionHandler(exh); \ ++ { \ ++ _try_clause_ \ ++ } \ + } while(0) + + #else +@@ -94,28 +101,35 @@ static void exception_handler(int sig) { + + typedef struct sigaction sa; + +-#define YR_TRYCATCH(_try_clause_, _catch_clause_) \ ++#define YR_TRYCATCH(_do_,_try_clause_, _catch_clause_) \ + do \ + { \ +- struct sigaction old_sigbus_act; \ +- struct sigaction old_sigsegv_act; \ +- struct sigaction act; \ +- act.sa_handler = exception_handler; \ +- act.sa_flags = 0; /* SA_ONSTACK? */ \ +- sigfillset(&act.sa_mask); \ +- sigaction(SIGBUS, &act, &old_sigbus_act); \ +- sigaction(SIGSEGV, &act, &old_sigsegv_act); \ +- int tidx = yr_get_tidx(); \ +- assert(tidx != -1); \ +- sigjmp_buf jb; \ +- exc_jmp_buf[tidx] = &jb; \ +- if (sigsetjmp(jb, 1) == 0) \ +- { _try_clause_ } \ ++ if (_do_) \ ++ { \ ++ struct sigaction old_sigbus_act; \ ++ struct sigaction old_sigsegv_act; \ ++ struct sigaction act; \ ++ act.sa_handler = exception_handler; \ ++ act.sa_flags = 0; /* SA_ONSTACK? */ \ ++ sigfillset(&act.sa_mask); \ ++ sigaction(SIGBUS, &act, &old_sigbus_act); \ ++ sigaction(SIGSEGV, &act, &old_sigsegv_act); \ ++ int tidx = yr_get_tidx(); \ ++ assert(tidx != -1); \ ++ sigjmp_buf jb; \ ++ exc_jmp_buf[tidx] = &jb; \ ++ if (sigsetjmp(jb, 1) == 0) \ ++ { _try_clause_ } \ ++ else \ ++ { _catch_clause_ } \ ++ exc_jmp_buf[tidx] = NULL; \ ++ sigaction(SIGBUS, &old_sigbus_act, NULL); \ ++ sigaction(SIGSEGV, &old_sigsegv_act, NULL); \ ++ } \ + else \ +- { _catch_clause_ } \ +- exc_jmp_buf[tidx] = NULL; \ +- sigaction(SIGBUS, &old_sigbus_act, NULL); \ +- sigaction(SIGSEGV, &old_sigsegv_act, NULL); \ ++ { \ ++ _try_clause_ \ ++ } \ + } while (0) + + #endif +diff --git a/libyara/include/yara/scan.h b/libyara/include/yara/scan.h +index 8ea0cb8..8ef6575 100644 +--- a/libyara/include/yara/scan.h ++++ b/libyara/include/yara/scan.h +@@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + // Bitmasks for flags. + #define SCAN_FLAGS_FAST_MODE 1 + #define SCAN_FLAGS_PROCESS_MEMORY 2 ++#define SCAN_FLAGS_NO_TRYCATCH 4 + + + int yr_scan_verify_match( +diff --git a/libyara/rules.c b/libyara/rules.c +index 490c472..336ba7c 100644 +--- a/libyara/rules.c ++++ b/libyara/rules.c +@@ -436,7 +436,9 @@ YR_API int yr_rules_scan_mem_blocks( + + if (context.entry_point == UNDEFINED) + { +- YR_TRYCATCH({ ++ YR_TRYCATCH( ++ !(flags & SCAN_FLAGS_NO_TRYCATCH), ++ { + if (flags & SCAN_FLAGS_PROCESS_MEMORY) + context.entry_point = yr_get_entry_point_address( + data, +@@ -449,7 +451,9 @@ YR_API int yr_rules_scan_mem_blocks( + },{}); + } + +- YR_TRYCATCH({ ++ YR_TRYCATCH( ++ !(flags & SCAN_FLAGS_NO_TRYCATCH), ++ { + result = _yr_rules_scan_mem_block( + rules, + data, +@@ -467,7 +471,9 @@ YR_API int yr_rules_scan_mem_blocks( + block = iterator->next(iterator); + } + +- YR_TRYCATCH({ ++ YR_TRYCATCH( ++ !(flags & SCAN_FLAGS_NO_TRYCATCH), ++ { + result = yr_execute_code( + rules, + &context, + +From e7eab9a77c858ad7440810b571a3e5d0b19ca208 Mon Sep 17 00:00:00 2001 +From: Rastislav Masaryk +Date: Fri, 11 Nov 2016 10:15:57 +0100 +Subject: [PATCH 20/36] Windows mutex replaced with CriticalSection + +(cherry picked from commit 245edc994b2c8c0a9753a0f690e186d2fb513dd0) +--- + threading.c | 13 +++++-------- + threading.h | 2 +- + 2 files changed, 6 insertions(+), 9 deletions(-) + +diff --git a/threading.c b/threading.c +index 5257884..5a65c2e 100644 +--- a/threading.c ++++ b/threading.c +@@ -40,11 +40,8 @@ int mutex_init( + MUTEX* mutex) + { + #if defined(_WIN32) || defined(__CYGWIN__) +- *mutex = CreateMutex(NULL, FALSE, NULL); +- if (*mutex == NULL) +- return GetLastError(); +- else +- return 0; ++ InitializeCriticalSection(mutex); ++ return GetLastError(); + #else + return pthread_mutex_init(mutex, NULL); + #endif +@@ -54,7 +51,7 @@ void mutex_destroy( + MUTEX* mutex) + { + #if defined(_WIN32) || defined(__CYGWIN__) +- CloseHandle(*mutex); ++ DeleteCriticalSection(mutex); + #else + pthread_mutex_destroy(mutex); + #endif +@@ -65,7 +62,7 @@ void mutex_lock( + MUTEX* mutex) + { + #if defined(_WIN32) || defined(__CYGWIN__) +- WaitForSingleObject(*mutex, INFINITE); ++ EnterCriticalSection(mutex); + #else + pthread_mutex_lock(mutex); + #endif +@@ -76,7 +73,7 @@ void mutex_unlock( + MUTEX* mutex) + { + #if defined(_WIN32) || defined(__CYGWIN__) +- ReleaseMutex(*mutex); ++ LeaveCriticalSection(mutex); + #else + pthread_mutex_unlock(mutex); + #endif +diff --git a/threading.h b/threading.h +index d6bf46a..43a68b6 100644 +--- a/threading.h ++++ b/threading.h +@@ -42,7 +42,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #if defined(_WIN32) || defined(__CYGWIN__) + + typedef HANDLE SEMAPHORE; +-typedef HANDLE MUTEX; ++typedef CRITICAL_SECTION MUTEX; + typedef HANDLE THREAD; + + typedef LPTHREAD_START_ROUTINE THREAD_START_ROUTINE; + +From 405a2cc32b7c3ef73c5678133bccaad327c49733 Mon Sep 17 00:00:00 2001 +From: Rastislav Masaryk +Date: Mon, 14 Nov 2016 07:59:55 +0100 +Subject: [PATCH 21/36] CritSection in try block and return value fixed + +(cherry picked from commit 7e168cd2a344b206da799d1fd8344ac0dcdd4807) +--- + threading.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/threading.c b/threading.c +index 5a65c2e..5479c20 100644 +--- a/threading.c ++++ b/threading.c +@@ -40,8 +40,13 @@ int mutex_init( + MUTEX* mutex) + { + #if defined(_WIN32) || defined(__CYGWIN__) +- InitializeCriticalSection(mutex); +- return GetLastError(); ++ __try { ++ InitializeCriticalSection(mutex); ++ return 0; ++ } ++ __except (STATUS_NO_MEMORY) { ++ return STATUS_NO_MEMORY; ++ } + #else + return pthread_mutex_init(mutex, NULL); + #endif + +From ac1057c8f8310cdaa6eeed92aa013cd9ae8f20ff Mon Sep 17 00:00:00 2001 +From: Rastislav Masaryk +Date: Mon, 14 Nov 2016 08:57:59 +0100 +Subject: [PATCH 22/36] removed __try block around CritSection + +(cherry picked from commit e0c19f2bceee50787e9044d010b5ad59f11da93e) +--- + threading.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/threading.c b/threading.c +index 5479c20..07c0b88 100644 +--- a/threading.c ++++ b/threading.c +@@ -40,13 +40,8 @@ int mutex_init( + MUTEX* mutex) + { + #if defined(_WIN32) || defined(__CYGWIN__) +- __try { + InitializeCriticalSection(mutex); + return 0; +- } +- __except (STATUS_NO_MEMORY) { +- return STATUS_NO_MEMORY; +- } + #else + return pthread_mutex_init(mutex, NULL); + #endif + +From 8e364afcf9e328c016c109ee2e417412e634f2e0 Mon Sep 17 00:00:00 2001 +From: plusvic +Date: Wed, 4 Jan 2017 16:18:03 +0100 +Subject: [PATCH 23/36] Fix issue #576 + +(cherry picked from commit eb491e03851a11bc811173f5e13c89cefa7257ac) +--- + libyara/lexer.c | 27 +++++++++++++++++---------- + libyara/lexer.l | 7 +++++++ + 2 files changed, 24 insertions(+), 10 deletions(-) + +diff --git a/libyara/lexer.c b/libyara/lexer.c +index 03f0465..b20e0c4 100644 +--- a/libyara/lexer.c ++++ b/libyara/lexer.c +@@ -1831,6 +1831,13 @@ YY_RULE_SETUP + { + + LEX_CHECK_SPACE_OK("\\.", yyextra->lex_buf_len, LEX_BUF_SIZE); ++ ++ if (yytext[1] == 0) ++ { ++ yyerror(yyscanner, compiler, "malformed regular expression"); ++ yyterminate(); ++ } ++ + *yyextra->lex_buf_ptr++ = yytext[0]; + *yyextra->lex_buf_ptr++ = yytext[1]; + yyextra->lex_buf_len += 2; +@@ -1838,13 +1845,13 @@ YY_RULE_SETUP + YY_BREAK + case 66: + YY_RULE_SETUP +-#line 592 "lexer.l" ++#line 599 "lexer.l" + { YYTEXT_TO_BUFFER; } + YY_BREAK + case 67: + /* rule 67 can match eol */ + YY_RULE_SETUP +-#line 595 "lexer.l" ++#line 602 "lexer.l" + { + + yyerror(yyscanner, compiler, "unterminated regular expression"); +@@ -1853,7 +1860,7 @@ YY_RULE_SETUP + YY_BREAK + case 68: + YY_RULE_SETUP +-#line 602 "lexer.l" ++#line 609 "lexer.l" + { + + yyextra->lex_buf_ptr = yyextra->lex_buf; +@@ -1863,7 +1870,7 @@ YY_RULE_SETUP + YY_BREAK + case 69: + YY_RULE_SETUP +-#line 610 "lexer.l" ++#line 617 "lexer.l" + { + + yyextra->lex_buf_ptr = yyextra->lex_buf; +@@ -1874,7 +1881,7 @@ YY_RULE_SETUP + case 70: + /* rule 70 can match eol */ + YY_RULE_SETUP +-#line 618 "lexer.l" ++#line 625 "lexer.l" + { + // Match hex-digits with whitespace or comments. The latter are stripped + // out by hex_lexer.l +@@ -1890,12 +1897,12 @@ YY_RULE_SETUP + case 71: + /* rule 71 can match eol */ + YY_RULE_SETUP +-#line 631 "lexer.l" ++#line 638 "lexer.l" + /* skip whitespace */ + YY_BREAK + case 72: + YY_RULE_SETUP +-#line 633 "lexer.l" ++#line 640 "lexer.l" + { + + if (yytext[0] >= 32 && yytext[0] < 127) +@@ -1911,10 +1918,10 @@ YY_RULE_SETUP + YY_BREAK + case 73: + YY_RULE_SETUP +-#line 646 "lexer.l" ++#line 653 "lexer.l" + ECHO; + YY_BREAK +-#line 1918 "lexer.c" ++#line 1925 "lexer.c" + + case YY_END_OF_BUFFER: + { +@@ -3063,7 +3070,7 @@ void yara_yyfree (void * ptr , yyscan_t yyscanner) + + #define YYTABLES_NAME "yytables" + +-#line 646 "lexer.l" ++#line 653 "lexer.l" + + + +diff --git a/libyara/lexer.l b/libyara/lexer.l +index a184606..e1bd98b 100644 +--- a/libyara/lexer.l ++++ b/libyara/lexer.l +@@ -583,6 +583,13 @@ u?int(8|16|32)(be)? { + \\. { + + 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 0ce27b2..eb28701 100644 +--- a/libyara/grammar.c ++++ b/libyara/grammar.c +@@ -546,16 +546,16 @@ union yyalloc + /* YYFINAL -- State number of the termination state. */ + #define YYFINAL 2 + /* YYLAST -- Last index in YYTABLE. */ +-#define YYLAST 408 ++#define YYLAST 406 + + /* YYNTOKENS -- Number of terminals. */ + #define YYNTOKENS 72 + /* YYNNTS -- Number of nonterminals. */ + #define YYNNTS 41 + /* YYNRULES -- Number of rules. */ +-#define YYNRULES 121 ++#define YYNRULES 122 + /* YYNSTATES -- Number of states. */ +-#define YYNSTATES 209 ++#define YYNSTATES 210 + + /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned + by yylex, with out-of-bounds checking. */ +@@ -612,13 +612,13 @@ static const yytype_uint16 yyrline[] = + 472, 485, 502, 503, 509, 508, 524, 523, 539, 553, + 554, 559, 560, 561, 562, 567, 652, 698, 756, 801, + 802, 806, 831, 867, 913, 935, 944, 953, 968, 980, +- 994, 1007, 1019, 1049, 1018, 1163, 1162, 1241, 1247, 1254, +- 1253, 1316, 1315, 1376, 1385, 1394, 1403, 1412, 1421, 1430, +- 1434, 1442, 1443, 1448, 1470, 1482, 1498, 1497, 1503, 1514, +- 1515, 1520, 1527, 1538, 1539, 1543, 1551, 1555, 1565, 1579, +- 1595, 1605, 1614, 1639, 1651, 1663, 1679, 1691, 1707, 1752, +- 1771, 1789, 1807, 1825, 1851, 1869, 1879, 1889, 1899, 1909, +- 1919, 1929 ++ 994, 1007, 1018, 1024, 1054, 1023, 1168, 1167, 1246, 1252, ++ 1259, 1258, 1321, 1320, 1381, 1390, 1399, 1408, 1417, 1426, ++ 1435, 1439, 1447, 1448, 1453, 1475, 1487, 1503, 1502, 1508, ++ 1519, 1520, 1525, 1532, 1543, 1544, 1548, 1556, 1560, 1570, ++ 1584, 1600, 1610, 1619, 1644, 1656, 1668, 1684, 1696, 1712, ++ 1757, 1776, 1794, 1812, 1830, 1856, 1874, 1884, 1894, 1904, ++ 1914, 1924, 1934 + }; + #endif + +@@ -672,7 +672,7 @@ static const yytype_uint16 yytoknum[] = + #define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-73))) + +-#define YYTABLE_NINF -94 ++#define YYTABLE_NINF -95 + + #define yytable_value_is_error(Yytable_value) \ + 0 +@@ -681,27 +681,27 @@ static const yytype_uint16 yytoknum[] = + STATE-NUM. */ + static const yytype_int16 yypact[] = + { +- -73, 79, -73, -32, -4, -73, -73, 94, -73, -73, +- -73, -73, 13, -73, -73, -73, -73, -8, 72, 6, +- -73, 78, 111, -73, 61, 122, 123, 82, -73, 90, +- 123, -73, 147, 150, 16, -73, 96, 147, -73, 101, +- 97, -73, -73, -73, -73, 151, 53, -73, 48, -73, +- -73, -73, 149, 145, -73, -9, -73, 103, 107, -73, +- -73, 106, -73, -73, -73, -73, -73, -73, 110, -73, +- -73, 135, 48, 135, 48, -33, -73, 64, -73, 144, +- 306, -73, -73, 135, 108, 135, 135, 135, 135, -7, +- 322, -73, -73, -73, 64, 117, 163, 168, 135, 48, +- -73, -73, -6, 167, 135, 135, 135, 135, 135, 135, +- 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, +- 135, 86, 86, 322, 135, -73, 243, 261, 183, 203, +- 159, -6, -73, -73, -73, 279, 121, 125, 95, 48, +- 48, -73, -73, -73, -73, 322, 337, 351, -43, 322, +- 322, 322, 322, 322, 322, 40, 40, 58, 58, -73, +- -73, -73, -73, -73, -73, -73, -73, 129, -73, -73, +- -73, -73, 128, -73, -73, 48, 152, -73, 15, 135, +- 131, -73, 95, -73, -73, 71, -73, 223, 135, 133, +- -73, 132, -73, 15, -73, 73, 129, -73, 48, -73, +- -73, 135, 134, 31, 322, 48, -73, 49, -73 ++ -73, 90, -73, -32, -10, -73, -73, 93, -73, -73, ++ -73, -73, 1, -73, -73, -73, -73, -49, 7, -36, ++ -73, 20, 26, -73, -28, 92, 46, 4, -73, 40, ++ 46, -73, 100, 119, 16, -73, 72, 100, -73, 77, ++ 83, -73, -73, -73, -73, 134, 59, -73, 48, -73, ++ -73, -73, 133, 136, -73, -18, -73, 88, 95, -73, ++ -73, 91, -73, -73, -73, -73, -73, -73, 102, -73, ++ -73, 126, 48, 126, 48, -44, -73, 85, -73, 127, ++ 297, -73, -73, 126, 110, 126, 126, 126, 126, 2, ++ 313, -73, -73, -73, 85, 111, 154, 172, 126, 48, ++ -73, -73, -6, 162, 126, 126, 126, 126, 126, 126, ++ 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, ++ 126, 60, 60, 313, 126, -73, 234, 252, 174, 194, ++ -73, 153, -6, -73, -73, -73, 270, 117, 120, 108, ++ 48, 48, -73, -73, -73, -73, 313, 328, 342, 349, ++ 313, 313, 313, 313, 313, 313, 113, 113, 53, 53, ++ -73, -73, -73, -73, -73, -73, -73, -73, 121, -73, ++ -73, -73, -73, 124, -73, -73, 48, 151, -73, -1, ++ 126, 125, -73, 108, -73, -73, 18, -73, 214, 126, ++ 129, -73, 143, -73, -1, -73, 63, 121, -73, 48, ++ -73, -73, 126, 144, 31, 313, 48, -73, 33, -73 + }; + + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. +@@ -714,31 +714,31 @@ static const yytype_uint8 yydefact[] = + 23, 22, 12, 24, 0, 14, 0, 0, 10, 0, + 13, 25, 0, 0, 0, 26, 0, 15, 32, 0, + 0, 28, 27, 30, 31, 0, 34, 33, 0, 11, +- 29, 38, 0, 0, 45, 59, 103, 105, 107, 100, +- 101, 0, 102, 53, 97, 98, 94, 95, 0, 55, +- 56, 0, 0, 0, 0, 108, 121, 16, 54, 0, +- 79, 39, 39, 0, 0, 0, 0, 0, 0, 0, +- 93, 109, 68, 118, 0, 54, 79, 0, 0, 49, +- 71, 69, 0, 0, 0, 0, 0, 0, 0, 0, ++ 29, 38, 0, 0, 45, 59, 104, 106, 108, 101, ++ 102, 0, 103, 53, 98, 99, 95, 96, 0, 55, ++ 56, 0, 0, 0, 0, 109, 122, 16, 54, 0, ++ 80, 39, 39, 0, 0, 0, 0, 0, 0, 0, ++ 94, 110, 69, 119, 0, 54, 80, 0, 0, 49, ++ 72, 70, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 35, 37, 60, 0, 61, 0, 0, 0, 0, +- 0, 0, 80, 96, 46, 0, 0, 50, 51, 0, +- 0, 88, 86, 67, 57, 58, 117, 115, 116, 77, +- 78, 73, 75, 74, 76, 119, 120, 110, 111, 112, +- 113, 114, 42, 41, 43, 44, 40, 0, 104, 106, +- 99, 62, 0, 47, 48, 0, 72, 70, 0, 0, +- 0, 65, 52, 91, 92, 0, 89, 0, 0, 0, +- 82, 0, 87, 0, 83, 0, 84, 63, 0, 90, +- 81, 0, 0, 0, 85, 0, 66, 0, 64 ++ 62, 0, 0, 81, 97, 46, 0, 0, 50, 51, ++ 0, 0, 89, 87, 68, 57, 58, 118, 116, 117, ++ 78, 79, 74, 76, 75, 77, 120, 121, 111, 112, ++ 113, 114, 115, 42, 41, 43, 44, 40, 0, 105, ++ 107, 100, 63, 0, 47, 48, 0, 73, 71, 0, ++ 0, 0, 66, 52, 92, 93, 0, 90, 0, 0, ++ 0, 83, 0, 88, 0, 84, 0, 85, 64, 0, ++ 91, 82, 0, 0, 0, 86, 0, 67, 0, 65 + }; + + /* YYPGOTO[NTERM-NUM]. */ + static const yytype_int16 yypgoto[] = + { +- -73, -73, 199, 218, -73, -73, -73, -73, -73, -73, +- -73, -73, -73, -73, 192, -73, 186, -73, -73, 142, +- -73, -73, -73, -73, 126, -48, -72, -73, -73, -73, +- -73, -73, -73, 50, -73, 100, -73, -73, 35, 164, ++ -73, -73, 211, 212, -73, -73, -73, -73, -73, -73, ++ -73, -73, -73, -73, 189, -73, 183, -73, -73, 139, ++ -73, -73, -73, -73, 130, -48, -72, -73, -73, -73, ++ -73, -73, -73, 41, -73, 103, -73, -73, 29, 164, + -67 + }; + +@@ -747,8 +747,8 @@ static const yytype_int16 yydefgoto[] = + { + -1, 1, 5, 6, 17, 33, 25, 28, 40, 7, + 15, 19, 21, 30, 31, 37, 38, 52, 53, 121, +- 166, 75, 136, 137, 76, 94, 78, 180, 202, 191, +- 140, 139, 189, 125, 195, 143, 178, 185, 186, 79, ++ 167, 75, 137, 138, 76, 94, 78, 181, 203, 192, ++ 141, 140, 190, 125, 196, 144, 179, 186, 187, 79, + 80 + }; + +@@ -757,92 +757,92 @@ static const yytype_int16 yydefgoto[] = + number is the opposite. If YYTABLE_NINF, syntax error. */ + static const yytype_int16 yytable[] = + { +- 77, 90, 95, 130, 91, 4, 93, 96, 114, 115, +- 116, 117, 118, 119, 120, 11, 123, 83, 126, 127, +- 128, 129, 84, 16, 92, 131, 183, 138, 141, 8, +- 184, 135, 41, 97, 98, 42, 99, 145, 146, 147, +- 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, +- 158, 159, 160, 161, 43, 44, 18, 167, 54, 55, +- 56, 57, 58, 142, 59, 60, 61, 62, 22, 63, +- 45, 100, 101, 51, -36, 64, 65, 66, 67, 2, +- 3, 68, 20, -17, -17, -17, 69, 70, 23, 100, +- 101, 176, 177, 116, 117, 118, 119, 120, 12, 13, +- 14, 206, 71, 182, 100, 101, 72, 73, 162, 163, +- 164, 165, 187, 118, 119, 120, 4, 74, 24, 208, +- 54, 196, 56, 57, 58, 26, 59, 60, 61, 62, +- 27, 63, 179, 29, 204, -54, -54, 64, 65, 66, +- 67, 192, 193, 200, 201, 54, 32, 56, 57, 58, +- 203, 59, 60, 61, 62, 34, 63, 207, 36, 39, +- 49, 46, 64, 65, 71, 48, 82, 50, 81, 73, +- 85, 105, 106, 107, 86, 87, 102, 124, 134, 88, +- 114, 115, 116, 117, 118, 119, 120, 132, 63, 71, +- 171, 174, 181, 101, 73, -93, 175, 197, 103, 104, +- 188, 198, 9, 205, 88, 105, 106, 107, 108, 109, +- 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, +- 120, 10, 35, 47, 122, 105, 106, 107, 199, 144, +- 190, 172, 89, 133, 114, 115, 116, 117, 118, 119, +- 120, 0, 0, 0, 0, 105, 106, 107, 0, 0, +- 0, 0, 0, 170, 114, 115, 116, 117, 118, 119, +- 120, 0, 0, 0, 0, 105, 106, 107, 0, 0, +- 0, 0, 0, 133, 114, 115, 116, 117, 118, 119, +- 120, 0, 0, 0, 0, 105, 106, 107, 0, 0, +- 0, 0, 0, 194, 114, 115, 116, 117, 118, 119, +- 120, 0, 0, 105, 106, 107, 0, 0, 0, 0, +- 0, 168, 114, 115, 116, 117, 118, 119, 120, 0, +- 0, 105, 106, 107, 0, 0, 0, 0, 0, 169, +- 114, 115, 116, 117, 118, 119, 120, 0, -93, 0, +- 0, 103, 104, 0, 0, 0, 0, 173, 105, 106, +- 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, +- 117, 118, 119, 120, 105, 106, 107, 0, 0, 0, ++ 77, 90, 95, 130, 91, 4, 93, 96, 83, 11, ++ 184, 16, 131, 84, 185, 18, 123, 20, 126, 127, ++ 128, 129, 97, 98, 92, 99, 22, 139, 142, 8, ++ 23, 136, 41, 24, 132, 42, 26, 146, 147, 148, ++ 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, ++ 159, 160, 161, 162, 43, 44, 29, 168, 54, 55, ++ 56, 57, 58, 143, 59, 60, 61, 62, 32, 63, ++ 45, 100, 101, 100, 101, 64, 65, 66, 67, 51, ++ -36, 68, 163, 164, 165, 166, 69, 70, 193, 194, ++ 2, 3, 177, 178, -17, -17, -17, 12, 13, 14, ++ 27, 207, 71, 209, 183, 34, 72, 73, 118, 119, ++ 120, 36, 54, 188, 56, 57, 58, 74, 59, 60, ++ 61, 62, 197, 63, 180, 100, 101, 4, 39, 64, ++ 65, 66, 67, 201, 202, 205, 54, 46, 56, 57, ++ 58, 48, 59, 60, 61, 62, 49, 63, -54, -54, ++ 50, 204, 81, 64, 65, 85, 71, 82, 208, 102, ++ 87, 73, 86, 105, 106, 107, 116, 117, 118, 119, ++ 120, 88, 114, 115, 116, 117, 118, 119, 120, 124, ++ 71, 133, 135, 63, 172, 73, -94, 175, 182, 103, ++ 104, 176, 101, 198, 189, 88, 105, 106, 107, 108, ++ 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, ++ 119, 120, 199, 206, 9, 10, 105, 106, 107, 35, ++ 47, 122, 191, 200, 134, 114, 115, 116, 117, 118, ++ 119, 120, 89, 145, 0, 173, 105, 106, 107, 0, ++ 0, 0, 0, 0, 171, 114, 115, 116, 117, 118, ++ 119, 120, 0, 0, 0, 0, 105, 106, 107, 0, ++ 0, 0, 0, 0, 134, 114, 115, 116, 117, 118, ++ 119, 120, 0, 0, 0, 0, 105, 106, 107, 0, ++ 0, 0, 0, 0, 195, 114, 115, 116, 117, 118, ++ 119, 120, 0, 0, 105, 106, 107, 0, 0, 0, ++ 0, 0, 169, 114, 115, 116, 117, 118, 119, 120, ++ 0, 0, 105, 106, 107, 0, 0, 0, 0, 0, ++ 170, 114, 115, 116, 117, 118, 119, 120, 0, -94, ++ 0, 0, 103, 104, 0, 0, 0, 0, 174, 105, ++ 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, ++ 116, 117, 118, 119, 120, 105, 106, 107, 0, 0, ++ 0, 0, 0, 0, 114, 115, 116, 117, 118, 119, ++ 120, 106, 107, 0, 0, 0, 0, 0, 0, 114, ++ 115, 116, 117, 118, 119, 120, 107, 0, 0, 0, + 0, 0, 0, 114, 115, 116, 117, 118, 119, 120, +- 106, 107, 0, 0, 0, 0, 0, 0, 114, 115, +- 116, 117, 118, 119, 120, 107, 0, 0, 0, 0, +- 0, 0, 114, 115, 116, 117, 118, 119, 120 ++ 114, 115, 116, 117, 118, 119, 120 + }; + + static const yytype_int16 yycheck[] = + { +- 48, 68, 74, 10, 71, 37, 73, 74, 51, 52, +- 53, 54, 55, 56, 57, 19, 83, 26, 85, 86, +- 87, 88, 31, 10, 72, 32, 11, 99, 34, 61, +- 15, 98, 16, 66, 67, 19, 69, 104, 105, 106, ++ 48, 68, 74, 1, 71, 37, 73, 74, 26, 19, ++ 11, 10, 10, 31, 15, 64, 83, 10, 85, 86, ++ 87, 88, 66, 67, 72, 69, 62, 99, 34, 61, ++ 10, 98, 16, 7, 32, 19, 64, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, +- 117, 118, 119, 120, 38, 39, 64, 124, 10, 11, +- 12, 13, 14, 69, 16, 17, 18, 19, 62, 21, +- 54, 40, 41, 20, 21, 27, 28, 29, 30, 0, +- 1, 33, 10, 4, 5, 6, 38, 39, 10, 40, +- 41, 139, 140, 53, 54, 55, 56, 57, 4, 5, +- 6, 70, 54, 175, 40, 41, 58, 59, 22, 23, +- 24, 25, 179, 55, 56, 57, 37, 69, 7, 70, +- 10, 188, 12, 13, 14, 64, 16, 17, 18, 19, +- 8, 21, 3, 10, 201, 40, 41, 27, 28, 29, +- 30, 70, 71, 70, 71, 10, 64, 12, 13, 14, +- 198, 16, 17, 18, 19, 65, 21, 205, 11, 9, +- 63, 65, 27, 28, 54, 64, 21, 16, 19, 59, +- 67, 42, 43, 44, 67, 69, 32, 69, 10, 69, +- 51, 52, 53, 54, 55, 56, 57, 70, 21, 54, +- 31, 70, 64, 41, 59, 32, 71, 64, 35, 36, +- 69, 69, 3, 69, 69, 42, 43, 44, 45, 46, +- 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, +- 57, 3, 30, 37, 82, 42, 43, 44, 193, 103, +- 180, 131, 68, 70, 51, 52, 53, 54, 55, 56, +- 57, -1, -1, -1, -1, 42, 43, 44, -1, -1, +- -1, -1, -1, 70, 51, 52, 53, 54, 55, 56, +- 57, -1, -1, -1, -1, 42, 43, 44, -1, -1, +- -1, -1, -1, 70, 51, 52, 53, 54, 55, 56, +- 57, -1, -1, -1, -1, 42, 43, 44, -1, -1, +- -1, -1, -1, 70, 51, 52, 53, 54, 55, 56, +- 57, -1, -1, 42, 43, 44, -1, -1, -1, -1, +- -1, 68, 51, 52, 53, 54, 55, 56, 57, -1, +- -1, 42, 43, 44, -1, -1, -1, -1, -1, 68, +- 51, 52, 53, 54, 55, 56, 57, -1, 32, -1, +- -1, 35, 36, -1, -1, -1, -1, 68, 42, 43, +- 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, +- 54, 55, 56, 57, 42, 43, 44, -1, -1, -1, ++ 117, 118, 119, 120, 38, 39, 10, 124, 10, 11, ++ 12, 13, 14, 69, 16, 17, 18, 19, 64, 21, ++ 54, 40, 41, 40, 41, 27, 28, 29, 30, 20, ++ 21, 33, 22, 23, 24, 25, 38, 39, 70, 71, ++ 0, 1, 140, 141, 4, 5, 6, 4, 5, 6, ++ 8, 70, 54, 70, 176, 65, 58, 59, 55, 56, ++ 57, 11, 10, 180, 12, 13, 14, 69, 16, 17, ++ 18, 19, 189, 21, 3, 40, 41, 37, 9, 27, ++ 28, 29, 30, 70, 71, 202, 10, 65, 12, 13, ++ 14, 64, 16, 17, 18, 19, 63, 21, 40, 41, ++ 16, 199, 19, 27, 28, 67, 54, 21, 206, 32, ++ 69, 59, 67, 42, 43, 44, 53, 54, 55, 56, ++ 57, 69, 51, 52, 53, 54, 55, 56, 57, 69, ++ 54, 70, 10, 21, 31, 59, 32, 70, 64, 35, ++ 36, 71, 41, 64, 69, 69, 42, 43, 44, 45, ++ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, ++ 56, 57, 69, 69, 3, 3, 42, 43, 44, 30, ++ 37, 82, 181, 194, 70, 51, 52, 53, 54, 55, ++ 56, 57, 68, 103, -1, 132, 42, 43, 44, -1, ++ -1, -1, -1, -1, 70, 51, 52, 53, 54, 55, ++ 56, 57, -1, -1, -1, -1, 42, 43, 44, -1, ++ -1, -1, -1, -1, 70, 51, 52, 53, 54, 55, ++ 56, 57, -1, -1, -1, -1, 42, 43, 44, -1, ++ -1, -1, -1, -1, 70, 51, 52, 53, 54, 55, ++ 56, 57, -1, -1, 42, 43, 44, -1, -1, -1, ++ -1, -1, 68, 51, 52, 53, 54, 55, 56, 57, ++ -1, -1, 42, 43, 44, -1, -1, -1, -1, -1, ++ 68, 51, 52, 53, 54, 55, 56, 57, -1, 32, ++ -1, -1, 35, 36, -1, -1, -1, -1, 68, 42, ++ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, ++ 53, 54, 55, 56, 57, 42, 43, 44, -1, -1, ++ -1, -1, -1, -1, 51, 52, 53, 54, 55, 56, ++ 57, 43, 44, -1, -1, -1, -1, -1, -1, 51, ++ 52, 53, 54, 55, 56, 57, 44, -1, -1, -1, + -1, -1, -1, 51, 52, 53, 54, 55, 56, 57, +- 43, 44, -1, -1, -1, -1, -1, -1, 51, 52, +- 53, 54, 55, 56, 57, 44, -1, -1, -1, -1, +- -1, -1, 51, 52, 53, 54, 55, 56, 57 ++ 51, 52, 53, 54, 55, 56, 57 + }; + + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing +@@ -862,14 +862,14 @@ static const yytype_uint8 yystos[] = + 40, 41, 32, 35, 36, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 91, 91, 112, 69, 105, 112, 112, 112, 112, +- 10, 32, 70, 70, 10, 112, 94, 95, 98, 103, +- 102, 34, 69, 107, 96, 112, 112, 112, 112, 112, ++ 1, 10, 32, 70, 70, 10, 112, 94, 95, 98, ++ 103, 102, 34, 69, 107, 96, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, +- 112, 112, 22, 23, 24, 25, 92, 112, 68, 68, +- 70, 31, 107, 68, 70, 71, 97, 97, 108, 3, +- 99, 64, 98, 11, 15, 109, 110, 112, 69, 104, +- 105, 101, 70, 71, 70, 106, 112, 64, 69, 110, +- 70, 71, 100, 97, 112, 69, 70, 97, 70 ++ 112, 112, 112, 22, 23, 24, 25, 92, 112, 68, ++ 68, 70, 31, 107, 68, 70, 71, 97, 97, 108, ++ 3, 99, 64, 98, 11, 15, 109, 110, 112, 69, ++ 104, 105, 101, 70, 71, 70, 106, 112, 64, 69, ++ 110, 70, 71, 100, 97, 112, 69, 70, 97, 70 + }; + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +@@ -881,13 +881,13 @@ static const yytype_uint8 yyr1[] = + 86, 86, 87, 87, 89, 88, 90, 88, 88, 91, + 91, 92, 92, 92, 92, 93, 93, 93, 93, 94, + 94, 95, 95, 96, 97, 98, 98, 98, 98, 98, +- 98, 98, 99, 100, 98, 101, 98, 98, 98, 102, +- 98, 103, 98, 98, 98, 98, 98, 98, 98, 98, +- 98, 104, 104, 105, 106, 106, 108, 107, 107, 109, +- 109, 110, 110, 111, 111, 111, 112, 112, 112, 112, ++ 98, 98, 98, 99, 100, 98, 101, 98, 98, 98, ++ 102, 98, 103, 98, 98, 98, 98, 98, 98, 98, ++ 98, 98, 104, 104, 105, 106, 106, 108, 107, 107, ++ 109, 109, 110, 110, 111, 111, 111, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, +- 112, 112 ++ 112, 112, 112 + }; + + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +@@ -899,13 +899,13 @@ static const yytype_uint8 yyr2[] = + 3, 3, 1, 2, 0, 5, 0, 5, 3, 0, + 2, 1, 1, 1, 1, 1, 3, 4, 4, 0, + 1, 1, 3, 1, 1, 1, 1, 3, 3, 1, +- 3, 3, 0, 0, 11, 0, 9, 3, 2, 0, +- 4, 0, 4, 3, 3, 3, 3, 3, 3, 1, +- 3, 3, 1, 5, 1, 3, 0, 4, 1, 1, +- 3, 1, 1, 1, 1, 1, 3, 1, 1, 4, +- 1, 1, 1, 1, 4, 1, 4, 1, 1, 2, +- 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, +- 3, 1 ++ 3, 3, 3, 0, 0, 11, 0, 9, 3, 2, ++ 0, 4, 0, 4, 3, 3, 3, 3, 3, 3, ++ 1, 3, 3, 1, 5, 1, 3, 0, 4, 1, ++ 1, 3, 1, 1, 1, 1, 1, 3, 1, 1, ++ 4, 1, 1, 1, 1, 4, 1, 4, 1, 1, ++ 2, 3, 3, 3, 3, 3, 3, 3, 3, 2, ++ 3, 3, 1 + }; + + +@@ -2587,6 +2587,15 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + case 62: + #line 1019 "grammar.y" /* yacc.c:1646 */ + { ++ compiler->loop_depth--; ++ compiler->loop_identifier[compiler->loop_depth] = NULL; ++ } ++#line 2594 "grammar.c" /* yacc.c:1646 */ ++ break; ++ ++ case 63: ++#line 1024 "grammar.y" /* yacc.c:1646 */ ++ { + int var_index; + + if (compiler->loop_depth == MAX_LOOP_NESTING) +@@ -2615,11 +2624,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 2619 "grammar.c" /* yacc.c:1646 */ ++#line 2628 "grammar.c" /* yacc.c:1646 */ + break; + +- case 63: +-#line 1049 "grammar.y" /* yacc.c:1646 */ ++ case 64: ++#line 1054 "grammar.y" /* yacc.c:1646 */ + { + int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth; + uint8_t* addr; +@@ -2654,11 +2663,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + compiler->loop_identifier[compiler->loop_depth] = (yyvsp[-4].c_string); + compiler->loop_depth++; + } +-#line 2658 "grammar.c" /* yacc.c:1646 */ ++#line 2667 "grammar.c" /* yacc.c:1646 */ + break; + +- case 64: +-#line 1084 "grammar.y" /* yacc.c:1646 */ ++ case 65: ++#line 1089 "grammar.y" /* yacc.c:1646 */ + { + int mem_offset; + +@@ -2737,11 +2746,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2741 "grammar.c" /* yacc.c:1646 */ ++#line 2750 "grammar.c" /* yacc.c:1646 */ + break; + +- case 65: +-#line 1163 "grammar.y" /* yacc.c:1646 */ ++ case 66: ++#line 1168 "grammar.y" /* yacc.c:1646 */ + { + int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth; + uint8_t* addr; +@@ -2771,11 +2780,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + compiler->loop_identifier[compiler->loop_depth] = NULL; + compiler->loop_depth++; + } +-#line 2775 "grammar.c" /* yacc.c:1646 */ ++#line 2784 "grammar.c" /* yacc.c:1646 */ + break; + +- case 66: +-#line 1193 "grammar.y" /* yacc.c:1646 */ ++ case 67: ++#line 1198 "grammar.y" /* yacc.c:1646 */ + { + int mem_offset; + +@@ -2824,31 +2833,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + + } +-#line 2828 "grammar.c" /* yacc.c:1646 */ ++#line 2837 "grammar.c" /* yacc.c:1646 */ + break; + +- case 67: +-#line 1242 "grammar.y" /* yacc.c:1646 */ ++ case 68: ++#line 1247 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit(yyscanner, OP_OF, NULL); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2838 "grammar.c" /* yacc.c:1646 */ ++#line 2847 "grammar.c" /* yacc.c:1646 */ + break; + +- case 68: +-#line 1248 "grammar.y" /* yacc.c:1646 */ ++ case 69: ++#line 1253 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit(yyscanner, OP_NOT, NULL); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2848 "grammar.c" /* yacc.c:1646 */ ++#line 2857 "grammar.c" /* yacc.c:1646 */ + break; + +- case 69: +-#line 1254 "grammar.y" /* yacc.c:1646 */ ++ case 70: ++#line 1259 "grammar.y" /* yacc.c:1646 */ + { + YR_FIXUP* fixup; + void* jmp_destination_addr; +@@ -2874,11 +2883,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + fixup->next = compiler->fixup_stack_head; + compiler->fixup_stack_head = fixup; + } +-#line 2878 "grammar.c" /* yacc.c:1646 */ ++#line 2887 "grammar.c" /* yacc.c:1646 */ + break; + +- case 70: +-#line 1280 "grammar.y" /* yacc.c:1646 */ ++ case 71: ++#line 1285 "grammar.y" /* yacc.c:1646 */ + { + YR_FIXUP* fixup; + uint8_t* and_addr; +@@ -2914,11 +2923,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2918 "grammar.c" /* yacc.c:1646 */ ++#line 2927 "grammar.c" /* yacc.c:1646 */ + break; + +- case 71: +-#line 1316 "grammar.y" /* yacc.c:1646 */ ++ case 72: ++#line 1321 "grammar.y" /* yacc.c:1646 */ + { + YR_FIXUP* fixup; + void* jmp_destination_addr; +@@ -2943,11 +2952,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + fixup->next = compiler->fixup_stack_head; + compiler->fixup_stack_head = fixup; + } +-#line 2947 "grammar.c" /* yacc.c:1646 */ ++#line 2956 "grammar.c" /* yacc.c:1646 */ + break; + +- case 72: +-#line 1341 "grammar.y" /* yacc.c:1646 */ ++ case 73: ++#line 1346 "grammar.y" /* yacc.c:1646 */ + { + YR_FIXUP* fixup; + uint8_t* or_addr; +@@ -2983,11 +2992,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2987 "grammar.c" /* yacc.c:1646 */ ++#line 2996 "grammar.c" /* yacc.c:1646 */ + break; + +- case 73: +-#line 1377 "grammar.y" /* yacc.c:1646 */ ++ case 74: ++#line 1382 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "<", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -2996,11 +3005,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 3000 "grammar.c" /* yacc.c:1646 */ ++#line 3009 "grammar.c" /* yacc.c:1646 */ + break; + +- case 74: +-#line 1386 "grammar.y" /* yacc.c:1646 */ ++ case 75: ++#line 1391 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, ">", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3009,11 +3018,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 3013 "grammar.c" /* yacc.c:1646 */ ++#line 3022 "grammar.c" /* yacc.c:1646 */ + break; + +- case 75: +-#line 1395 "grammar.y" /* yacc.c:1646 */ ++ case 76: ++#line 1400 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "<=", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3022,11 +3031,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 3026 "grammar.c" /* yacc.c:1646 */ ++#line 3035 "grammar.c" /* yacc.c:1646 */ + break; + +- case 76: +-#line 1404 "grammar.y" /* yacc.c:1646 */ ++ case 77: ++#line 1409 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, ">=", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3035,11 +3044,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 3039 "grammar.c" /* yacc.c:1646 */ ++#line 3048 "grammar.c" /* yacc.c:1646 */ + break; + +- case 77: +-#line 1413 "grammar.y" /* yacc.c:1646 */ ++ case 78: ++#line 1418 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "==", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3048,11 +3057,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 3052 "grammar.c" /* yacc.c:1646 */ ++#line 3061 "grammar.c" /* yacc.c:1646 */ + break; + +- case 78: +-#line 1422 "grammar.y" /* yacc.c:1646 */ ++ case 79: ++#line 1427 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "!=", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3061,39 +3070,39 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 3065 "grammar.c" /* yacc.c:1646 */ ++#line 3074 "grammar.c" /* yacc.c:1646 */ + break; + +- case 79: +-#line 1431 "grammar.y" /* yacc.c:1646 */ ++ case 80: ++#line 1436 "grammar.y" /* yacc.c:1646 */ + { + (yyval.expression) = (yyvsp[0].expression); + } +-#line 3073 "grammar.c" /* yacc.c:1646 */ ++#line 3082 "grammar.c" /* yacc.c:1646 */ + break; + +- case 80: +-#line 1435 "grammar.y" /* yacc.c:1646 */ ++ case 81: ++#line 1440 "grammar.y" /* yacc.c:1646 */ + { + (yyval.expression) = (yyvsp[-1].expression); + } +-#line 3081 "grammar.c" /* yacc.c:1646 */ ++#line 3090 "grammar.c" /* yacc.c:1646 */ + break; + +- case 81: +-#line 1442 "grammar.y" /* yacc.c:1646 */ ++ case 82: ++#line 1447 "grammar.y" /* yacc.c:1646 */ + { (yyval.integer) = INTEGER_SET_ENUMERATION; } +-#line 3087 "grammar.c" /* yacc.c:1646 */ ++#line 3096 "grammar.c" /* yacc.c:1646 */ + break; + +- case 82: +-#line 1443 "grammar.y" /* yacc.c:1646 */ ++ case 83: ++#line 1448 "grammar.y" /* yacc.c:1646 */ + { (yyval.integer) = INTEGER_SET_RANGE; } +-#line 3093 "grammar.c" /* yacc.c:1646 */ ++#line 3102 "grammar.c" /* yacc.c:1646 */ + break; + +- case 83: +-#line 1449 "grammar.y" /* yacc.c:1646 */ ++ case 84: ++#line 1454 "grammar.y" /* yacc.c:1646 */ + { + if ((yyvsp[-3].expression).type != EXPRESSION_TYPE_INTEGER) + { +@@ -3111,11 +3120,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3115 "grammar.c" /* yacc.c:1646 */ ++#line 3124 "grammar.c" /* yacc.c:1646 */ + break; + +- case 84: +-#line 1471 "grammar.y" /* yacc.c:1646 */ ++ case 85: ++#line 1476 "grammar.y" /* yacc.c:1646 */ + { + if ((yyvsp[0].expression).type != EXPRESSION_TYPE_INTEGER) + { +@@ -3127,11 +3136,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3131 "grammar.c" /* yacc.c:1646 */ ++#line 3140 "grammar.c" /* yacc.c:1646 */ + break; + +- case 85: +-#line 1483 "grammar.y" /* yacc.c:1646 */ ++ case 86: ++#line 1488 "grammar.y" /* yacc.c:1646 */ + { + if ((yyvsp[0].expression).type != EXPRESSION_TYPE_INTEGER) + { +@@ -3142,77 +3151,77 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3146 "grammar.c" /* yacc.c:1646 */ ++#line 3155 "grammar.c" /* yacc.c:1646 */ + break; + +- case 86: +-#line 1498 "grammar.y" /* yacc.c:1646 */ ++ case 87: ++#line 1503 "grammar.y" /* yacc.c:1646 */ + { + // Push end-of-list marker + yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL); + } +-#line 3155 "grammar.c" /* yacc.c:1646 */ ++#line 3164 "grammar.c" /* yacc.c:1646 */ + break; + +- case 88: +-#line 1504 "grammar.y" /* yacc.c:1646 */ ++ case 89: ++#line 1509 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL); + yr_parser_emit_pushes_for_strings(yyscanner, "$*"); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3166 "grammar.c" /* yacc.c:1646 */ ++#line 3175 "grammar.c" /* yacc.c:1646 */ + break; + +- case 91: +-#line 1521 "grammar.y" /* yacc.c:1646 */ ++ case 92: ++#line 1526 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[0].c_string)); + yr_free((yyvsp[0].c_string)); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3177 "grammar.c" /* yacc.c:1646 */ ++#line 3186 "grammar.c" /* yacc.c:1646 */ + break; + +- case 92: +-#line 1528 "grammar.y" /* yacc.c:1646 */ ++ case 93: ++#line 1533 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[0].c_string)); + yr_free((yyvsp[0].c_string)); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3188 "grammar.c" /* yacc.c:1646 */ ++#line 3197 "grammar.c" /* yacc.c:1646 */ + break; + +- case 94: +-#line 1540 "grammar.y" /* yacc.c:1646 */ ++ case 95: ++#line 1545 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL); + } +-#line 3196 "grammar.c" /* yacc.c:1646 */ ++#line 3205 "grammar.c" /* yacc.c:1646 */ + break; + +- case 95: +-#line 1544 "grammar.y" /* yacc.c:1646 */ ++ case 96: ++#line 1549 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit_with_arg(yyscanner, OP_PUSH, 1, NULL, NULL); + } +-#line 3204 "grammar.c" /* yacc.c:1646 */ ++#line 3213 "grammar.c" /* yacc.c:1646 */ + break; + +- case 96: +-#line 1552 "grammar.y" /* yacc.c:1646 */ ++ case 97: ++#line 1557 "grammar.y" /* yacc.c:1646 */ + { + (yyval.expression) = (yyvsp[-1].expression); + } +-#line 3212 "grammar.c" /* yacc.c:1646 */ ++#line 3221 "grammar.c" /* yacc.c:1646 */ + break; + +- case 97: +-#line 1556 "grammar.y" /* yacc.c:1646 */ ++ case 98: ++#line 1561 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_emit( + yyscanner, OP_FILESIZE, NULL); +@@ -3222,11 +3231,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3226 "grammar.c" /* yacc.c:1646 */ ++#line 3235 "grammar.c" /* yacc.c:1646 */ + break; + +- case 98: +-#line 1566 "grammar.y" /* yacc.c:1646 */ ++ case 99: ++#line 1571 "grammar.y" /* yacc.c:1646 */ + { + yywarning(yyscanner, + "Using deprecated \"entrypoint\" keyword. Use the \"entry_point\" " +@@ -3240,11 +3249,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3244 "grammar.c" /* yacc.c:1646 */ ++#line 3253 "grammar.c" /* yacc.c:1646 */ + break; + +- case 99: +-#line 1580 "grammar.y" /* yacc.c:1646 */ ++ case 100: ++#line 1585 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-1].expression), EXPRESSION_TYPE_INTEGER, "intXXXX or uintXXXX"); + +@@ -3260,11 +3269,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3264 "grammar.c" /* yacc.c:1646 */ ++#line 3273 "grammar.c" /* yacc.c:1646 */ + break; + +- case 100: +-#line 1596 "grammar.y" /* yacc.c:1646 */ ++ case 101: ++#line 1601 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_emit_with_arg( + yyscanner, OP_PUSH, (yyvsp[0].integer), NULL, NULL); +@@ -3274,11 +3283,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = (yyvsp[0].integer); + } +-#line 3278 "grammar.c" /* yacc.c:1646 */ ++#line 3287 "grammar.c" /* yacc.c:1646 */ + break; + +- case 101: +-#line 1606 "grammar.y" /* yacc.c:1646 */ ++ case 102: ++#line 1611 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_emit_with_arg_double( + yyscanner, OP_PUSH, (yyvsp[0].double_), NULL, NULL); +@@ -3287,11 +3296,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_FLOAT; + } +-#line 3291 "grammar.c" /* yacc.c:1646 */ ++#line 3300 "grammar.c" /* yacc.c:1646 */ + break; + +- case 102: +-#line 1615 "grammar.y" /* yacc.c:1646 */ ++ case 103: ++#line 1620 "grammar.y" /* yacc.c:1646 */ + { + SIZED_STRING* sized_string; + +@@ -3316,11 +3325,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_STRING; + (yyval.expression).value.sized_string = sized_string; + } +-#line 3320 "grammar.c" /* yacc.c:1646 */ ++#line 3329 "grammar.c" /* yacc.c:1646 */ + break; + +- case 103: +-#line 1640 "grammar.y" /* yacc.c:1646 */ ++ case 104: ++#line 1645 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_string_identifier( + yyscanner, (yyvsp[0].c_string), OP_COUNT, UNDEFINED); +@@ -3332,11 +3341,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3336 "grammar.c" /* yacc.c:1646 */ ++#line 3345 "grammar.c" /* yacc.c:1646 */ + break; + +- case 104: +-#line 1652 "grammar.y" /* yacc.c:1646 */ ++ case 105: ++#line 1657 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_string_identifier( + yyscanner, (yyvsp[-3].c_string), OP_OFFSET, UNDEFINED); +@@ -3348,11 +3357,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3352 "grammar.c" /* yacc.c:1646 */ ++#line 3361 "grammar.c" /* yacc.c:1646 */ + break; + +- case 105: +-#line 1664 "grammar.y" /* yacc.c:1646 */ ++ case 106: ++#line 1669 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_emit_with_arg( + yyscanner, OP_PUSH, 1, NULL, NULL); +@@ -3368,11 +3377,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3372 "grammar.c" /* yacc.c:1646 */ ++#line 3381 "grammar.c" /* yacc.c:1646 */ + break; + +- case 106: +-#line 1680 "grammar.y" /* yacc.c:1646 */ ++ case 107: ++#line 1685 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_string_identifier( + yyscanner, (yyvsp[-3].c_string), OP_LENGTH, UNDEFINED); +@@ -3384,11 +3393,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3388 "grammar.c" /* yacc.c:1646 */ ++#line 3397 "grammar.c" /* yacc.c:1646 */ + break; + +- case 107: +-#line 1692 "grammar.y" /* yacc.c:1646 */ ++ case 108: ++#line 1697 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_emit_with_arg( + yyscanner, OP_PUSH, 1, NULL, NULL); +@@ -3404,11 +3413,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3408 "grammar.c" /* yacc.c:1646 */ ++#line 3417 "grammar.c" /* yacc.c:1646 */ + break; + +- case 108: +-#line 1708 "grammar.y" /* yacc.c:1646 */ ++ case 109: ++#line 1713 "grammar.y" /* yacc.c:1646 */ + { + if ((yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER) // loop identifier + { +@@ -3453,11 +3462,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3457 "grammar.c" /* yacc.c:1646 */ ++#line 3466 "grammar.c" /* yacc.c:1646 */ + break; + +- case 109: +-#line 1753 "grammar.y" /* yacc.c:1646 */ ++ case 110: ++#line 1758 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER | EXPRESSION_TYPE_FLOAT, "-"); + +@@ -3476,11 +3485,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3480 "grammar.c" /* yacc.c:1646 */ ++#line 3489 "grammar.c" /* yacc.c:1646 */ + break; + +- case 110: +-#line 1772 "grammar.y" /* yacc.c:1646 */ ++ case 111: ++#line 1777 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "+", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3498,11 +3507,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_FLOAT; + } + } +-#line 3502 "grammar.c" /* yacc.c:1646 */ ++#line 3511 "grammar.c" /* yacc.c:1646 */ + break; + +- case 111: +-#line 1790 "grammar.y" /* yacc.c:1646 */ ++ case 112: ++#line 1795 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "-", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3520,11 +3529,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_FLOAT; + } + } +-#line 3524 "grammar.c" /* yacc.c:1646 */ ++#line 3533 "grammar.c" /* yacc.c:1646 */ + break; + +- case 112: +-#line 1808 "grammar.y" /* yacc.c:1646 */ ++ case 113: ++#line 1813 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "*", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3542,11 +3551,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_FLOAT; + } + } +-#line 3546 "grammar.c" /* yacc.c:1646 */ ++#line 3555 "grammar.c" /* yacc.c:1646 */ + break; + +- case 113: +-#line 1826 "grammar.y" /* yacc.c:1646 */ ++ case 114: ++#line 1831 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "\\", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3572,11 +3581,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_FLOAT; + } + } +-#line 3576 "grammar.c" /* yacc.c:1646 */ ++#line 3585 "grammar.c" /* yacc.c:1646 */ + break; + +- case 114: +-#line 1852 "grammar.y" /* yacc.c:1646 */ ++ case 115: ++#line 1857 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "%"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "%"); +@@ -3594,11 +3603,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } + } +-#line 3598 "grammar.c" /* yacc.c:1646 */ ++#line 3607 "grammar.c" /* yacc.c:1646 */ + break; + +- case 115: +-#line 1870 "grammar.y" /* yacc.c:1646 */ ++ case 116: ++#line 1875 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^"); +@@ -3608,11 +3617,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = OPERATION(^, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); + } +-#line 3612 "grammar.c" /* yacc.c:1646 */ ++#line 3621 "grammar.c" /* yacc.c:1646 */ + break; + +- case 116: +-#line 1880 "grammar.y" /* yacc.c:1646 */ ++ case 117: ++#line 1885 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^"); +@@ -3622,11 +3631,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = OPERATION(&, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); + } +-#line 3626 "grammar.c" /* yacc.c:1646 */ ++#line 3635 "grammar.c" /* yacc.c:1646 */ + break; + +- case 117: +-#line 1890 "grammar.y" /* yacc.c:1646 */ ++ case 118: ++#line 1895 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "|"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "|"); +@@ -3636,11 +3645,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = OPERATION(|, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); + } +-#line 3640 "grammar.c" /* yacc.c:1646 */ ++#line 3649 "grammar.c" /* yacc.c:1646 */ + break; + +- case 118: +-#line 1900 "grammar.y" /* yacc.c:1646 */ ++ case 119: ++#line 1905 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "~"); + +@@ -3650,11 +3659,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).value.integer = ((yyvsp[0].expression).value.integer == UNDEFINED) ? + UNDEFINED : ~((yyvsp[0].expression).value.integer); + } +-#line 3654 "grammar.c" /* yacc.c:1646 */ ++#line 3663 "grammar.c" /* yacc.c:1646 */ + break; + +- case 119: +-#line 1910 "grammar.y" /* yacc.c:1646 */ ++ case 120: ++#line 1915 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "<<"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "<<"); +@@ -3664,11 +3673,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = OPERATION(<<, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); + } +-#line 3668 "grammar.c" /* yacc.c:1646 */ ++#line 3677 "grammar.c" /* yacc.c:1646 */ + break; + +- case 120: +-#line 1920 "grammar.y" /* yacc.c:1646 */ ++ case 121: ++#line 1925 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, ">>"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, ">>"); +@@ -3678,19 +3687,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = OPERATION(>>, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); + } +-#line 3682 "grammar.c" /* yacc.c:1646 */ ++#line 3691 "grammar.c" /* yacc.c:1646 */ + break; + +- case 121: +-#line 1930 "grammar.y" /* yacc.c:1646 */ ++ case 122: ++#line 1935 "grammar.y" /* yacc.c:1646 */ + { + (yyval.expression) = (yyvsp[0].expression); + } +-#line 3690 "grammar.c" /* yacc.c:1646 */ ++#line 3699 "grammar.c" /* yacc.c:1646 */ + break; + + +-#line 3694 "grammar.c" /* yacc.c:1646 */ ++#line 3703 "grammar.c" /* yacc.c:1646 */ + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires +@@ -3918,5 +3927,5 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + #endif + return yyresult; + } +-#line 1935 "grammar.y" /* yacc.c:1906 */ ++#line 1940 "grammar.y" /* yacc.c:1906 */ + +diff --git a/libyara/grammar.y b/libyara/grammar.y +index 56bae40..be24307 100644 +--- a/libyara/grammar.y ++++ b/libyara/grammar.y +@@ -1015,6 +1015,11 @@ expression + + $$.type = EXPRESSION_TYPE_BOOLEAN; + } ++ | _FOR_ for_expression error ++ { ++ compiler->loop_depth--; ++ compiler->loop_identifier[compiler->loop_depth] = NULL; ++ } + | _FOR_ for_expression _IDENTIFIER_ _IN_ + { + int var_index; + +From 03dc5bdb2f3fa820fb6c757f502c323aacd88f35 Mon Sep 17 00:00:00 2001 +From: plusvic +Date: Mon, 9 Jan 2017 13:17:39 +0100 +Subject: [PATCH 25/36] Make sure that loop depth is greater than 0 before + decrementing it. + +(cherry picked from commit 7f02eca670f29c00a1d2c305e96febae6ce5d37b) +--- + libyara/grammar.c | 251 +++++++++++++++++++++++++++--------------------------- + libyara/grammar.y | 7 +- + 2 files changed, 132 insertions(+), 126 deletions(-) + +diff --git a/libyara/grammar.c b/libyara/grammar.c +index eb28701..9c79512 100644 +--- a/libyara/grammar.c ++++ b/libyara/grammar.c +@@ -612,13 +612,13 @@ static const yytype_uint16 yyrline[] = + 472, 485, 502, 503, 509, 508, 524, 523, 539, 553, + 554, 559, 560, 561, 562, 567, 652, 698, 756, 801, + 802, 806, 831, 867, 913, 935, 944, 953, 968, 980, +- 994, 1007, 1018, 1024, 1054, 1023, 1168, 1167, 1246, 1252, +- 1259, 1258, 1321, 1320, 1381, 1390, 1399, 1408, 1417, 1426, +- 1435, 1439, 1447, 1448, 1453, 1475, 1487, 1503, 1502, 1508, +- 1519, 1520, 1525, 1532, 1543, 1544, 1548, 1556, 1560, 1570, +- 1584, 1600, 1610, 1619, 1644, 1656, 1668, 1684, 1696, 1712, +- 1757, 1776, 1794, 1812, 1830, 1856, 1874, 1884, 1894, 1904, +- 1914, 1924, 1934 ++ 994, 1007, 1018, 1027, 1057, 1026, 1171, 1170, 1249, 1255, ++ 1262, 1261, 1324, 1323, 1384, 1393, 1402, 1411, 1420, 1429, ++ 1438, 1442, 1450, 1451, 1456, 1478, 1490, 1506, 1505, 1511, ++ 1522, 1523, 1528, 1535, 1546, 1547, 1551, 1559, 1563, 1573, ++ 1587, 1603, 1613, 1622, 1647, 1659, 1671, 1687, 1699, 1715, ++ 1760, 1779, 1797, 1815, 1833, 1859, 1877, 1887, 1897, 1907, ++ 1917, 1927, 1937 + }; + #endif + +@@ -2587,14 +2587,17 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + case 62: + #line 1019 "grammar.y" /* yacc.c:1646 */ + { +- compiler->loop_depth--; +- compiler->loop_identifier[compiler->loop_depth] = NULL; ++ if (compiler->loop_depth > 0) ++ { ++ compiler->loop_depth--; ++ compiler->loop_identifier[compiler->loop_depth] = NULL; ++ } + } +-#line 2594 "grammar.c" /* yacc.c:1646 */ ++#line 2597 "grammar.c" /* yacc.c:1646 */ + break; + + case 63: +-#line 1024 "grammar.y" /* yacc.c:1646 */ ++#line 1027 "grammar.y" /* yacc.c:1646 */ + { + int var_index; + +@@ -2624,11 +2627,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 2628 "grammar.c" /* yacc.c:1646 */ ++#line 2631 "grammar.c" /* yacc.c:1646 */ + break; + + case 64: +-#line 1054 "grammar.y" /* yacc.c:1646 */ ++#line 1057 "grammar.y" /* yacc.c:1646 */ + { + int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth; + uint8_t* addr; +@@ -2663,11 +2666,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + compiler->loop_identifier[compiler->loop_depth] = (yyvsp[-4].c_string); + compiler->loop_depth++; + } +-#line 2667 "grammar.c" /* yacc.c:1646 */ ++#line 2670 "grammar.c" /* yacc.c:1646 */ + break; + + case 65: +-#line 1089 "grammar.y" /* yacc.c:1646 */ ++#line 1092 "grammar.y" /* yacc.c:1646 */ + { + int mem_offset; + +@@ -2746,11 +2749,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2750 "grammar.c" /* yacc.c:1646 */ ++#line 2753 "grammar.c" /* yacc.c:1646 */ + break; + + case 66: +-#line 1168 "grammar.y" /* yacc.c:1646 */ ++#line 1171 "grammar.y" /* yacc.c:1646 */ + { + int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth; + uint8_t* addr; +@@ -2780,11 +2783,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + compiler->loop_identifier[compiler->loop_depth] = NULL; + compiler->loop_depth++; + } +-#line 2784 "grammar.c" /* yacc.c:1646 */ ++#line 2787 "grammar.c" /* yacc.c:1646 */ + break; + + case 67: +-#line 1198 "grammar.y" /* yacc.c:1646 */ ++#line 1201 "grammar.y" /* yacc.c:1646 */ + { + int mem_offset; + +@@ -2833,31 +2836,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + + } +-#line 2837 "grammar.c" /* yacc.c:1646 */ ++#line 2840 "grammar.c" /* yacc.c:1646 */ + break; + + case 68: +-#line 1247 "grammar.y" /* yacc.c:1646 */ ++#line 1250 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit(yyscanner, OP_OF, NULL); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2847 "grammar.c" /* yacc.c:1646 */ ++#line 2850 "grammar.c" /* yacc.c:1646 */ + break; + + case 69: +-#line 1253 "grammar.y" /* yacc.c:1646 */ ++#line 1256 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit(yyscanner, OP_NOT, NULL); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2857 "grammar.c" /* yacc.c:1646 */ ++#line 2860 "grammar.c" /* yacc.c:1646 */ + break; + + case 70: +-#line 1259 "grammar.y" /* yacc.c:1646 */ ++#line 1262 "grammar.y" /* yacc.c:1646 */ + { + YR_FIXUP* fixup; + void* jmp_destination_addr; +@@ -2883,11 +2886,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + fixup->next = compiler->fixup_stack_head; + compiler->fixup_stack_head = fixup; + } +-#line 2887 "grammar.c" /* yacc.c:1646 */ ++#line 2890 "grammar.c" /* yacc.c:1646 */ + break; + + case 71: +-#line 1285 "grammar.y" /* yacc.c:1646 */ ++#line 1288 "grammar.y" /* yacc.c:1646 */ + { + YR_FIXUP* fixup; + uint8_t* and_addr; +@@ -2923,11 +2926,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2927 "grammar.c" /* yacc.c:1646 */ ++#line 2930 "grammar.c" /* yacc.c:1646 */ + break; + + case 72: +-#line 1321 "grammar.y" /* yacc.c:1646 */ ++#line 1324 "grammar.y" /* yacc.c:1646 */ + { + YR_FIXUP* fixup; + void* jmp_destination_addr; +@@ -2952,11 +2955,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + fixup->next = compiler->fixup_stack_head; + compiler->fixup_stack_head = fixup; + } +-#line 2956 "grammar.c" /* yacc.c:1646 */ ++#line 2959 "grammar.c" /* yacc.c:1646 */ + break; + + case 73: +-#line 1346 "grammar.y" /* yacc.c:1646 */ ++#line 1349 "grammar.y" /* yacc.c:1646 */ + { + YR_FIXUP* fixup; + uint8_t* or_addr; +@@ -2992,11 +2995,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2996 "grammar.c" /* yacc.c:1646 */ ++#line 2999 "grammar.c" /* yacc.c:1646 */ + break; + + case 74: +-#line 1382 "grammar.y" /* yacc.c:1646 */ ++#line 1385 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "<", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3005,11 +3008,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 3009 "grammar.c" /* yacc.c:1646 */ ++#line 3012 "grammar.c" /* yacc.c:1646 */ + break; + + case 75: +-#line 1391 "grammar.y" /* yacc.c:1646 */ ++#line 1394 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, ">", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3018,11 +3021,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 3022 "grammar.c" /* yacc.c:1646 */ ++#line 3025 "grammar.c" /* yacc.c:1646 */ + break; + + case 76: +-#line 1400 "grammar.y" /* yacc.c:1646 */ ++#line 1403 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "<=", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3031,11 +3034,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 3035 "grammar.c" /* yacc.c:1646 */ ++#line 3038 "grammar.c" /* yacc.c:1646 */ + break; + + case 77: +-#line 1409 "grammar.y" /* yacc.c:1646 */ ++#line 1412 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, ">=", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3044,11 +3047,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 3048 "grammar.c" /* yacc.c:1646 */ ++#line 3051 "grammar.c" /* yacc.c:1646 */ + break; + + case 78: +-#line 1418 "grammar.y" /* yacc.c:1646 */ ++#line 1421 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "==", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3057,11 +3060,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 3061 "grammar.c" /* yacc.c:1646 */ ++#line 3064 "grammar.c" /* yacc.c:1646 */ + break; + + case 79: +-#line 1427 "grammar.y" /* yacc.c:1646 */ ++#line 1430 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "!=", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3070,39 +3073,39 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 3074 "grammar.c" /* yacc.c:1646 */ ++#line 3077 "grammar.c" /* yacc.c:1646 */ + break; + + case 80: +-#line 1436 "grammar.y" /* yacc.c:1646 */ ++#line 1439 "grammar.y" /* yacc.c:1646 */ + { + (yyval.expression) = (yyvsp[0].expression); + } +-#line 3082 "grammar.c" /* yacc.c:1646 */ ++#line 3085 "grammar.c" /* yacc.c:1646 */ + break; + + case 81: +-#line 1440 "grammar.y" /* yacc.c:1646 */ ++#line 1443 "grammar.y" /* yacc.c:1646 */ + { + (yyval.expression) = (yyvsp[-1].expression); + } +-#line 3090 "grammar.c" /* yacc.c:1646 */ ++#line 3093 "grammar.c" /* yacc.c:1646 */ + break; + + case 82: +-#line 1447 "grammar.y" /* yacc.c:1646 */ ++#line 1450 "grammar.y" /* yacc.c:1646 */ + { (yyval.integer) = INTEGER_SET_ENUMERATION; } +-#line 3096 "grammar.c" /* yacc.c:1646 */ ++#line 3099 "grammar.c" /* yacc.c:1646 */ + break; + + case 83: +-#line 1448 "grammar.y" /* yacc.c:1646 */ ++#line 1451 "grammar.y" /* yacc.c:1646 */ + { (yyval.integer) = INTEGER_SET_RANGE; } +-#line 3102 "grammar.c" /* yacc.c:1646 */ ++#line 3105 "grammar.c" /* yacc.c:1646 */ + break; + + case 84: +-#line 1454 "grammar.y" /* yacc.c:1646 */ ++#line 1457 "grammar.y" /* yacc.c:1646 */ + { + if ((yyvsp[-3].expression).type != EXPRESSION_TYPE_INTEGER) + { +@@ -3120,11 +3123,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3124 "grammar.c" /* yacc.c:1646 */ ++#line 3127 "grammar.c" /* yacc.c:1646 */ + break; + + case 85: +-#line 1476 "grammar.y" /* yacc.c:1646 */ ++#line 1479 "grammar.y" /* yacc.c:1646 */ + { + if ((yyvsp[0].expression).type != EXPRESSION_TYPE_INTEGER) + { +@@ -3136,11 +3139,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3140 "grammar.c" /* yacc.c:1646 */ ++#line 3143 "grammar.c" /* yacc.c:1646 */ + break; + + case 86: +-#line 1488 "grammar.y" /* yacc.c:1646 */ ++#line 1491 "grammar.y" /* yacc.c:1646 */ + { + if ((yyvsp[0].expression).type != EXPRESSION_TYPE_INTEGER) + { +@@ -3151,77 +3154,77 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3155 "grammar.c" /* yacc.c:1646 */ ++#line 3158 "grammar.c" /* yacc.c:1646 */ + break; + + case 87: +-#line 1503 "grammar.y" /* yacc.c:1646 */ ++#line 1506 "grammar.y" /* yacc.c:1646 */ + { + // Push end-of-list marker + yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL); + } +-#line 3164 "grammar.c" /* yacc.c:1646 */ ++#line 3167 "grammar.c" /* yacc.c:1646 */ + break; + + case 89: +-#line 1509 "grammar.y" /* yacc.c:1646 */ ++#line 1512 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL); + yr_parser_emit_pushes_for_strings(yyscanner, "$*"); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3175 "grammar.c" /* yacc.c:1646 */ ++#line 3178 "grammar.c" /* yacc.c:1646 */ + break; + + case 92: +-#line 1526 "grammar.y" /* yacc.c:1646 */ ++#line 1529 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[0].c_string)); + yr_free((yyvsp[0].c_string)); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3186 "grammar.c" /* yacc.c:1646 */ ++#line 3189 "grammar.c" /* yacc.c:1646 */ + break; + + case 93: +-#line 1533 "grammar.y" /* yacc.c:1646 */ ++#line 1536 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[0].c_string)); + yr_free((yyvsp[0].c_string)); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3197 "grammar.c" /* yacc.c:1646 */ ++#line 3200 "grammar.c" /* yacc.c:1646 */ + break; + + case 95: +-#line 1545 "grammar.y" /* yacc.c:1646 */ ++#line 1548 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL); + } +-#line 3205 "grammar.c" /* yacc.c:1646 */ ++#line 3208 "grammar.c" /* yacc.c:1646 */ + break; + + case 96: +-#line 1549 "grammar.y" /* yacc.c:1646 */ ++#line 1552 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit_with_arg(yyscanner, OP_PUSH, 1, NULL, NULL); + } +-#line 3213 "grammar.c" /* yacc.c:1646 */ ++#line 3216 "grammar.c" /* yacc.c:1646 */ + break; + + case 97: +-#line 1557 "grammar.y" /* yacc.c:1646 */ ++#line 1560 "grammar.y" /* yacc.c:1646 */ + { + (yyval.expression) = (yyvsp[-1].expression); + } +-#line 3221 "grammar.c" /* yacc.c:1646 */ ++#line 3224 "grammar.c" /* yacc.c:1646 */ + break; + + case 98: +-#line 1561 "grammar.y" /* yacc.c:1646 */ ++#line 1564 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_emit( + yyscanner, OP_FILESIZE, NULL); +@@ -3231,11 +3234,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3235 "grammar.c" /* yacc.c:1646 */ ++#line 3238 "grammar.c" /* yacc.c:1646 */ + break; + + case 99: +-#line 1571 "grammar.y" /* yacc.c:1646 */ ++#line 1574 "grammar.y" /* yacc.c:1646 */ + { + yywarning(yyscanner, + "Using deprecated \"entrypoint\" keyword. Use the \"entry_point\" " +@@ -3249,11 +3252,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3253 "grammar.c" /* yacc.c:1646 */ ++#line 3256 "grammar.c" /* yacc.c:1646 */ + break; + + case 100: +-#line 1585 "grammar.y" /* yacc.c:1646 */ ++#line 1588 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-1].expression), EXPRESSION_TYPE_INTEGER, "intXXXX or uintXXXX"); + +@@ -3269,11 +3272,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3273 "grammar.c" /* yacc.c:1646 */ ++#line 3276 "grammar.c" /* yacc.c:1646 */ + break; + + case 101: +-#line 1601 "grammar.y" /* yacc.c:1646 */ ++#line 1604 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_emit_with_arg( + yyscanner, OP_PUSH, (yyvsp[0].integer), NULL, NULL); +@@ -3283,11 +3286,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = (yyvsp[0].integer); + } +-#line 3287 "grammar.c" /* yacc.c:1646 */ ++#line 3290 "grammar.c" /* yacc.c:1646 */ + break; + + case 102: +-#line 1611 "grammar.y" /* yacc.c:1646 */ ++#line 1614 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_emit_with_arg_double( + yyscanner, OP_PUSH, (yyvsp[0].double_), NULL, NULL); +@@ -3296,11 +3299,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_FLOAT; + } +-#line 3300 "grammar.c" /* yacc.c:1646 */ ++#line 3303 "grammar.c" /* yacc.c:1646 */ + break; + + case 103: +-#line 1620 "grammar.y" /* yacc.c:1646 */ ++#line 1623 "grammar.y" /* yacc.c:1646 */ + { + SIZED_STRING* sized_string; + +@@ -3325,11 +3328,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_STRING; + (yyval.expression).value.sized_string = sized_string; + } +-#line 3329 "grammar.c" /* yacc.c:1646 */ ++#line 3332 "grammar.c" /* yacc.c:1646 */ + break; + + case 104: +-#line 1645 "grammar.y" /* yacc.c:1646 */ ++#line 1648 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_string_identifier( + yyscanner, (yyvsp[0].c_string), OP_COUNT, UNDEFINED); +@@ -3341,11 +3344,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3345 "grammar.c" /* yacc.c:1646 */ ++#line 3348 "grammar.c" /* yacc.c:1646 */ + break; + + case 105: +-#line 1657 "grammar.y" /* yacc.c:1646 */ ++#line 1660 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_string_identifier( + yyscanner, (yyvsp[-3].c_string), OP_OFFSET, UNDEFINED); +@@ -3357,11 +3360,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3361 "grammar.c" /* yacc.c:1646 */ ++#line 3364 "grammar.c" /* yacc.c:1646 */ + break; + + case 106: +-#line 1669 "grammar.y" /* yacc.c:1646 */ ++#line 1672 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_emit_with_arg( + yyscanner, OP_PUSH, 1, NULL, NULL); +@@ -3377,11 +3380,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3381 "grammar.c" /* yacc.c:1646 */ ++#line 3384 "grammar.c" /* yacc.c:1646 */ + break; + + case 107: +-#line 1685 "grammar.y" /* yacc.c:1646 */ ++#line 1688 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_string_identifier( + yyscanner, (yyvsp[-3].c_string), OP_LENGTH, UNDEFINED); +@@ -3393,11 +3396,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3397 "grammar.c" /* yacc.c:1646 */ ++#line 3400 "grammar.c" /* yacc.c:1646 */ + break; + + case 108: +-#line 1697 "grammar.y" /* yacc.c:1646 */ ++#line 1700 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_emit_with_arg( + yyscanner, OP_PUSH, 1, NULL, NULL); +@@ -3413,11 +3416,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3417 "grammar.c" /* yacc.c:1646 */ ++#line 3420 "grammar.c" /* yacc.c:1646 */ + break; + + case 109: +-#line 1713 "grammar.y" /* yacc.c:1646 */ ++#line 1716 "grammar.y" /* yacc.c:1646 */ + { + if ((yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER) // loop identifier + { +@@ -3462,11 +3465,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3466 "grammar.c" /* yacc.c:1646 */ ++#line 3469 "grammar.c" /* yacc.c:1646 */ + break; + + case 110: +-#line 1758 "grammar.y" /* yacc.c:1646 */ ++#line 1761 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER | EXPRESSION_TYPE_FLOAT, "-"); + +@@ -3485,11 +3488,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3489 "grammar.c" /* yacc.c:1646 */ ++#line 3492 "grammar.c" /* yacc.c:1646 */ + break; + + case 111: +-#line 1777 "grammar.y" /* yacc.c:1646 */ ++#line 1780 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "+", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3507,11 +3510,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_FLOAT; + } + } +-#line 3511 "grammar.c" /* yacc.c:1646 */ ++#line 3514 "grammar.c" /* yacc.c:1646 */ + break; + + case 112: +-#line 1795 "grammar.y" /* yacc.c:1646 */ ++#line 1798 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "-", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3529,11 +3532,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_FLOAT; + } + } +-#line 3533 "grammar.c" /* yacc.c:1646 */ ++#line 3536 "grammar.c" /* yacc.c:1646 */ + break; + + case 113: +-#line 1813 "grammar.y" /* yacc.c:1646 */ ++#line 1816 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "*", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3551,11 +3554,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_FLOAT; + } + } +-#line 3555 "grammar.c" /* yacc.c:1646 */ ++#line 3558 "grammar.c" /* yacc.c:1646 */ + break; + + case 114: +-#line 1831 "grammar.y" /* yacc.c:1646 */ ++#line 1834 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "\\", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3581,11 +3584,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_FLOAT; + } + } +-#line 3585 "grammar.c" /* yacc.c:1646 */ ++#line 3588 "grammar.c" /* yacc.c:1646 */ + break; + + case 115: +-#line 1857 "grammar.y" /* yacc.c:1646 */ ++#line 1860 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "%"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "%"); +@@ -3603,11 +3606,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } + } +-#line 3607 "grammar.c" /* yacc.c:1646 */ ++#line 3610 "grammar.c" /* yacc.c:1646 */ + break; + + case 116: +-#line 1875 "grammar.y" /* yacc.c:1646 */ ++#line 1878 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^"); +@@ -3617,11 +3620,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = OPERATION(^, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); + } +-#line 3621 "grammar.c" /* yacc.c:1646 */ ++#line 3624 "grammar.c" /* yacc.c:1646 */ + break; + + case 117: +-#line 1885 "grammar.y" /* yacc.c:1646 */ ++#line 1888 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^"); +@@ -3631,11 +3634,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = OPERATION(&, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); + } +-#line 3635 "grammar.c" /* yacc.c:1646 */ ++#line 3638 "grammar.c" /* yacc.c:1646 */ + break; + + case 118: +-#line 1895 "grammar.y" /* yacc.c:1646 */ ++#line 1898 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "|"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "|"); +@@ -3645,11 +3648,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = OPERATION(|, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); + } +-#line 3649 "grammar.c" /* yacc.c:1646 */ ++#line 3652 "grammar.c" /* yacc.c:1646 */ + break; + + case 119: +-#line 1905 "grammar.y" /* yacc.c:1646 */ ++#line 1908 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "~"); + +@@ -3659,11 +3662,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).value.integer = ((yyvsp[0].expression).value.integer == UNDEFINED) ? + UNDEFINED : ~((yyvsp[0].expression).value.integer); + } +-#line 3663 "grammar.c" /* yacc.c:1646 */ ++#line 3666 "grammar.c" /* yacc.c:1646 */ + break; + + case 120: +-#line 1915 "grammar.y" /* yacc.c:1646 */ ++#line 1918 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "<<"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "<<"); +@@ -3673,11 +3676,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = OPERATION(<<, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); + } +-#line 3677 "grammar.c" /* yacc.c:1646 */ ++#line 3680 "grammar.c" /* yacc.c:1646 */ + break; + + case 121: +-#line 1925 "grammar.y" /* yacc.c:1646 */ ++#line 1928 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, ">>"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, ">>"); +@@ -3687,19 +3690,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = OPERATION(>>, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); + } +-#line 3691 "grammar.c" /* yacc.c:1646 */ ++#line 3694 "grammar.c" /* yacc.c:1646 */ + break; + + case 122: +-#line 1935 "grammar.y" /* yacc.c:1646 */ ++#line 1938 "grammar.y" /* yacc.c:1646 */ + { + (yyval.expression) = (yyvsp[0].expression); + } +-#line 3699 "grammar.c" /* yacc.c:1646 */ ++#line 3702 "grammar.c" /* yacc.c:1646 */ + break; + + +-#line 3703 "grammar.c" /* yacc.c:1646 */ ++#line 3706 "grammar.c" /* yacc.c:1646 */ + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires +@@ -3927,5 +3930,5 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + #endif + return yyresult; + } +-#line 1940 "grammar.y" /* yacc.c:1906 */ ++#line 1943 "grammar.y" /* yacc.c:1906 */ + +diff --git a/libyara/grammar.y b/libyara/grammar.y +index be24307..addb55d 100644 +--- a/libyara/grammar.y ++++ b/libyara/grammar.y +@@ -1017,8 +1017,11 @@ expression + } + | _FOR_ for_expression error + { +- compiler->loop_depth--; +- compiler->loop_identifier[compiler->loop_depth] = NULL; ++ if (compiler->loop_depth > 0) ++ { ++ compiler->loop_depth--; ++ compiler->loop_identifier[compiler->loop_depth] = NULL; ++ } + } + | _FOR_ for_expression _IDENTIFIER_ _IN_ + { + +From b9ca16ab1c5c11461c3cdd929dacafe5d74a72f0 Mon Sep 17 00:00:00 2001 +From: Hilko Bengen +Date: Tue, 15 Nov 2016 00:17:56 +0100 +Subject: [PATCH 26/36] Add support for big-endian ELF files (#560) + +cherry picked from: + +- c9c0dfb61ed5b27bdad3433d1e8d095f2f0c5684 +- 79316a3b911b4ccfda0b3961d26523f0fd8ccfd5, "Minor re-styling" +--- + libyara/modules/elf.c | 211 +++++++++++++++++++++++++++++++------------------- + 1 file changed, 133 insertions(+), 78 deletions(-) + +diff --git a/libyara/modules/elf.c b/libyara/modules/elf.c +index e934084..dff586e 100644 +--- a/libyara/modules/elf.c ++++ b/libyara/modules/elf.c +@@ -37,8 +37,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + #define MODULE_NAME elf + ++#define CLASS_DATA(c,d) ((c << 8) | d) + +-int get_elf_type( ++int get_elf_class_data( + uint8_t* buffer, + size_t buffer_length) + { +@@ -51,7 +52,7 @@ int get_elf_type( + + if (yr_le32toh(elf_ident->magic) == ELF_MAGIC) + { +- return elf_ident->_class; ++ return CLASS_DATA(elf_ident->_class, elf_ident->data); + } + else + { +@@ -59,15 +60,13 @@ int get_elf_type( + } + } + +-#define SIZE_OF_SECTION_TABLE_32(h) \ +- (sizeof(elf32_section_header_t) * yr_le16toh(h->sh_entry_count)) ++#define ELF_SIZE_OF_SECTION_TABLE(bits,bo,h) \ ++ (sizeof(elf##bits##_section_header_t) * yr_##bo##16toh(h->sh_entry_count)) + +-#define SIZE_OF_SECTION_TABLE_64(h) \ +- (sizeof(elf64_section_header_t) * yr_le16toh(h->sh_entry_count)) + + +-#define ELF_RVA_TO_OFFSET(bits) \ +-uint64_t elf_rva_to_offset_##bits( \ ++#define ELF_RVA_TO_OFFSET(bits,bo) \ ++uint64_t elf_rva_to_offset_##bits##_##bo( \ + elf##bits##_header_t* elf_header, \ + uint64_t rva, \ + size_t elf_size) \ +@@ -78,34 +77,34 @@ uint64_t elf_rva_to_offset_##bits( \ + \ + /* check that sh_offset doesn't wrap when added to SIZE_OF_SECTION_TABLE */ \ + \ +- if(ULONG_MAX - yr_le##bits##toh(elf_header->sh_offset) < \ +- SIZE_OF_SECTION_TABLE_##bits(elf_header)) \ ++ if(ULONG_MAX - yr_##bo##bits##toh(elf_header->sh_offset) < \ ++ ELF_SIZE_OF_SECTION_TABLE(bits,bo,elf_header)) \ + { \ + return UNDEFINED; \ + } \ + \ +- if (yr_le##bits##toh(elf_header->sh_offset) == 0 || \ +- yr_le##bits##toh(elf_header->sh_offset) > elf_size || \ +- yr_le##bits##toh(elf_header->sh_offset) + \ +- SIZE_OF_SECTION_TABLE_##bits(elf_header) > elf_size || \ +- yr_le16toh(elf_header->sh_entry_count) == 0) \ ++ if (yr_##bo##bits##toh(elf_header->sh_offset) == 0 || \ ++ yr_##bo##bits##toh(elf_header->sh_offset) > elf_size || \ ++ yr_##bo##bits##toh(elf_header->sh_offset) + \ ++ ELF_SIZE_OF_SECTION_TABLE(bits,bo,elf_header) > elf_size || \ ++ yr_##bo##16toh(elf_header->sh_entry_count) == 0) \ + { \ + return UNDEFINED; \ + } \ + \ + section = (elf##bits##_section_header_t*) \ +- ((uint8_t*) elf_header + yr_le##bits##toh(elf_header->sh_offset)); \ ++ ((uint8_t*) elf_header + yr_##bo##bits##toh(elf_header->sh_offset)); \ + \ +- for (i = 0; i < yr_le16toh(elf_header->sh_entry_count); i++) \ ++ for (i = 0; i < yr_##bo##16toh(elf_header->sh_entry_count); i++) \ + { \ +- if (yr_le32toh(section->type) != ELF_SHT_NULL && \ +- yr_le32toh(section->type) != ELF_SHT_NOBITS && \ +- rva >= yr_le##bits##toh(section->addr) && \ +- rva < yr_le##bits##toh(section->addr) + \ +- yr_le##bits##toh(section->size)) \ ++ if (yr_##bo##32toh(section->type) != ELF_SHT_NULL && \ ++ yr_##bo##32toh(section->type) != ELF_SHT_NOBITS && \ ++ rva >= yr_##bo##bits##toh(section->addr) && \ ++ rva < yr_##bo##bits##toh(section->addr) + \ ++ yr_##bo##bits##toh(section->size)) \ + { \ +- return yr_le##bits##toh(section->offset) + \ +- (rva - yr_le##bits##toh(section->addr)); \ ++ return yr_##bo##bits##toh(section->offset) + \ ++ (rva - yr_##bo##bits##toh(section->addr)); \ + } \ + \ + section++; \ +@@ -114,8 +113,8 @@ uint64_t elf_rva_to_offset_##bits( \ + return UNDEFINED; \ + } + +-#define PARSE_ELF_HEADER(bits) \ +-void parse_elf_header_##bits( \ ++#define PARSE_ELF_HEADER(bits,bo) \ ++void parse_elf_header_##bits##_##bo( \ + elf##bits##_header_t* elf, \ + size_t base_address, \ + size_t elf_size, \ +@@ -127,56 +126,67 @@ void parse_elf_header_##bits( \ + elf##bits##_section_header_t* section; \ + elf##bits##_program_header_t* segment; \ + \ +- set_integer(yr_le16toh(elf->type), elf_obj, "type"); \ +- set_integer(yr_le16toh(elf->machine), elf_obj, "machine"); \ +- set_integer(yr_le##bits##toh(elf->sh_offset), elf_obj, "sh_offset"); \ +- set_integer(yr_le16toh(elf->sh_entry_size), elf_obj, "sh_entry_size"); \ +- set_integer(yr_le16toh(elf->sh_entry_count), elf_obj, "number_of_sections"); \ +- set_integer(yr_le##bits##toh(elf->ph_offset), elf_obj, "ph_offset"); \ +- set_integer(yr_le16toh(elf->ph_entry_size), elf_obj, "ph_entry_size"); \ +- set_integer(yr_le16toh(elf->ph_entry_count), elf_obj, "number_of_segments"); \ ++ set_integer(yr_##bo##16toh(elf->type), elf_obj, "type"); \ ++ set_integer(yr_##bo##16toh(elf->machine), elf_obj, "machine"); \ ++ set_integer(yr_##bo##bits##toh(elf->sh_offset), elf_obj, \ ++ "sh_offset"); \ ++ set_integer(yr_##bo##16toh(elf->sh_entry_size), elf_obj, \ ++ "sh_entry_size"); \ ++ set_integer(yr_##bo##16toh(elf->sh_entry_count), elf_obj, \ ++ "number_of_sections"); \ ++ set_integer(yr_##bo##bits##toh(elf->ph_offset), elf_obj, \ ++ "ph_offset"); \ ++ set_integer(yr_##bo##16toh(elf->ph_entry_size), elf_obj, \ ++ "ph_entry_size"); \ ++ set_integer(yr_##bo##16toh(elf->ph_entry_count), elf_obj, \ ++ "number_of_segments"); \ + \ +- if (yr_le##bits##toh(elf->entry) != 0) \ ++ if (yr_##bo##bits##toh(elf->entry) != 0) \ + { \ + set_integer( \ + flags & SCAN_FLAGS_PROCESS_MEMORY ? \ +- base_address + yr_le##bits##toh(elf->entry) : \ +- elf_rva_to_offset_##bits(elf, yr_le##bits##toh(elf->entry), elf_size), \ ++ base_address + yr_##bo##bits##toh(elf->entry) : \ ++ elf_rva_to_offset_##bits##_##bo( \ ++ elf, yr_##bo##bits##toh(elf->entry), elf_size), \ + elf_obj, "entry_point"); \ + } \ + \ +- if (yr_le16toh(elf->sh_entry_count) < ELF_SHN_LORESERVE && \ +- yr_le16toh(elf->sh_str_table_index) < yr_le16toh(elf->sh_entry_count) && \ +- yr_le##bits##toh(elf->sh_offset) < elf_size && \ +- yr_le##bits##toh(elf->sh_offset) + yr_le16toh(elf->sh_entry_count) * \ +- sizeof(elf##bits##_section_header_t) <= elf_size) \ ++ if (yr_##bo##16toh(elf->sh_entry_count) < ELF_SHN_LORESERVE && \ ++ yr_##bo##16toh(elf->sh_str_table_index) < \ ++ yr_##bo##16toh(elf->sh_entry_count) && \ ++ yr_##bo##bits##toh(elf->sh_offset) < elf_size && \ ++ yr_##bo##bits##toh(elf->sh_offset) + \ ++ yr_##bo##16toh(elf->sh_entry_count) * \ ++ sizeof(elf##bits##_section_header_t) <= elf_size) \ + { \ + char* str_table = NULL; \ + \ + section = (elf##bits##_section_header_t*) \ +- ((uint8_t*) elf + yr_le##bits##toh(elf->sh_offset)); \ ++ ((uint8_t*) elf + yr_##bo##bits##toh(elf->sh_offset)); \ + \ +- if (section[yr_le16toh(elf->sh_str_table_index)].offset < elf_size) \ +- str_table = (char*) elf + \ +- yr_le##bits##toh(section[yr_le16toh(elf->sh_str_table_index)].offset); \ ++ if (section[yr_##bo##16toh(elf->sh_str_table_index)].offset < elf_size) \ ++ { \ ++ str_table = (char*) elf + yr_##bo##bits##toh( \ ++ section[yr_##bo##16toh(elf->sh_str_table_index)].offset); \ ++ } \ + \ +- for (i = 0; i < yr_le16toh(elf->sh_entry_count); i++) \ ++ for (i = 0; i < yr_##bo##16toh(elf->sh_entry_count); i++) \ + { \ +- set_integer(yr_le32toh(section->type), elf_obj, \ ++ set_integer(yr_##bo##32toh(section->type), elf_obj, \ + "sections[%i].type", i); \ +- set_integer(yr_le32toh(section->flags), elf_obj, \ ++ set_integer(yr_##bo##32toh(section->flags), elf_obj, \ + "sections[%i].flags", i); \ +- set_integer(yr_le##bits##toh(section->size), elf_obj, \ ++ set_integer(yr_##bo##bits##toh(section->size), elf_obj, \ + "sections[%i].size", i); \ +- set_integer(yr_le##bits##toh(section->offset), elf_obj, \ ++ set_integer(yr_##bo##bits##toh(section->offset), elf_obj, \ + "sections[%i].offset", i); \ + \ +- if (yr_le##bits##toh(section->name) < elf_size && \ ++ if (yr_##bo##bits##toh(section->name) < elf_size && \ + str_table > (char*) elf && \ +- str_table + yr_le##bits##toh(section->name) < \ +- (char*) elf + elf_size) \ ++ str_table + yr_##bo##bits##toh(section->name) < \ ++ (char*) elf + elf_size) \ + { \ +- set_string(str_table + yr_le##bits##toh(section->name), elf_obj, \ ++ set_string(str_table + yr_##bo##bits##toh(section->name), elf_obj, \ + "sections[%i].name", i); \ + } \ + \ +@@ -184,38 +194,39 @@ void parse_elf_header_##bits( \ + } \ + } \ + \ +- if (yr_le16toh(elf->ph_entry_count) > 0 && \ +- yr_le16toh(elf->ph_entry_count) < ELF_PN_XNUM && \ +- yr_le##bits##toh(elf->ph_offset) < elf_size && \ +- yr_le##bits##toh(elf->ph_offset) + yr_le16toh(elf->ph_entry_count) * \ ++ if (yr_##bo##16toh(elf->ph_entry_count) > 0 && \ ++ yr_##bo##16toh(elf->ph_entry_count) < ELF_PN_XNUM && \ ++ yr_##bo##bits##toh(elf->ph_offset) < elf_size && \ ++ yr_##bo##bits##toh(elf->ph_offset) + \ ++ yr_##bo##16toh(elf->ph_entry_count) * \ + sizeof(elf##bits##_program_header_t) <= elf_size) \ + { \ + segment = (elf##bits##_program_header_t*) \ +- ((uint8_t*) elf + yr_le##bits##toh(elf->ph_offset)); \ ++ ((uint8_t*) elf + yr_##bo##bits##toh(elf->ph_offset)); \ + \ +- for (i = 0; i < yr_le16toh(elf->ph_entry_count); i++) \ ++ for (i = 0; i < yr_##bo##16toh(elf->ph_entry_count); i++) \ + { \ + set_integer( \ +- yr_le32toh(segment->type), elf_obj, "segments[%i].type", i); \ ++ yr_##bo##32toh(segment->type), elf_obj, "segments[%i].type", i); \ + set_integer( \ +- yr_le32toh(segment->flags), elf_obj, "segments[%i].flags", i); \ ++ yr_##bo##32toh(segment->flags), elf_obj, "segments[%i].flags", i); \ + set_integer( \ +- yr_le##bits##toh(segment->offset), elf_obj, \ ++ yr_##bo##bits##toh(segment->offset), elf_obj, \ + "segments[%i].offset", i); \ + set_integer( \ +- yr_le##bits##toh(segment->virt_addr), elf_obj, \ ++ yr_##bo##bits##toh(segment->virt_addr), elf_obj, \ + "segments[%i].virtual_address", i); \ + set_integer( \ +- yr_le##bits##toh(segment->phys_addr), elf_obj, \ ++ yr_##bo##bits##toh(segment->phys_addr), elf_obj, \ + "segments[%i].physical_address", i); \ + set_integer( \ +- yr_le##bits##toh(segment->file_size), elf_obj, \ ++ yr_##bo##bits##toh(segment->file_size), elf_obj, \ + "segments[%i].file_size", i); \ + set_integer( \ +- yr_le##bits##toh(segment->mem_size), elf_obj, \ ++ yr_##bo##bits##toh(segment->mem_size), elf_obj, \ + "segments[%i].memory_size", i); \ + set_integer( \ +- yr_le##bits##toh(segment->alignment), elf_obj, \ ++ yr_##bo##bits##toh(segment->alignment), elf_obj, \ + "segments[%i].alignment", i); \ + \ + segment++; \ +@@ -224,12 +235,16 @@ void parse_elf_header_##bits( \ + } + + +-ELF_RVA_TO_OFFSET(32); +-ELF_RVA_TO_OFFSET(64); ++ELF_RVA_TO_OFFSET(32,le); ++ELF_RVA_TO_OFFSET(64,le); ++ELF_RVA_TO_OFFSET(32,be); ++ELF_RVA_TO_OFFSET(64,be); + + +-PARSE_ELF_HEADER(32); +-PARSE_ELF_HEADER(64); ++PARSE_ELF_HEADER(32,le); ++PARSE_ELF_HEADER(64,le); ++PARSE_ELF_HEADER(32,be); ++PARSE_ELF_HEADER(64,be); + + + begin_declarations; +@@ -407,9 +422,9 @@ int module_load( + if (block_data == NULL) + continue; + +- switch(get_elf_type(block_data, block->size)) ++ switch(get_elf_class_data(block_data, block->size)) + { +- case ELF_CLASS_32: ++ case CLASS_DATA(ELF_CLASS_32, ELF_DATA_2LSB): + + if (block->size > sizeof(elf32_header_t)) + { +@@ -418,7 +433,27 @@ int module_load( + if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) || + yr_le16toh(elf_header32->type) == ELF_ET_EXEC) + { +- parse_elf_header_32( ++ parse_elf_header_32_le( ++ elf_header32, ++ block->base, ++ block->size, ++ context->flags, ++ module_object); ++ } ++ } ++ ++ break; ++ ++ case CLASS_DATA(ELF_CLASS_32, ELF_DATA_2MSB): ++ ++ if (block->size > sizeof(elf32_header_t)) ++ { ++ elf_header32 = (elf32_header_t*) block_data; ++ ++ if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) || ++ yr_be16toh(elf_header32->type) == ELF_ET_EXEC) ++ { ++ parse_elf_header_32_be( + elf_header32, + block->base, + block->size, +@@ -429,7 +464,7 @@ int module_load( + + break; + +- case ELF_CLASS_64: ++ case CLASS_DATA(ELF_CLASS_64,ELF_DATA_2LSB): + + if (block->size > sizeof(elf64_header_t)) + { +@@ -438,7 +473,27 @@ int module_load( + if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) || + yr_le16toh(elf_header64->type) == ELF_ET_EXEC) + { +- parse_elf_header_64( ++ parse_elf_header_64_le( ++ elf_header64, ++ block->base, ++ block->size, ++ context->flags, ++ module_object); ++ } ++ } ++ ++ break; ++ ++ case CLASS_DATA(ELF_CLASS_64,ELF_DATA_2MSB): ++ ++ if (block->size > sizeof(elf64_header_t)) ++ { ++ elf_header64 = (elf64_header_t*) block_data; ++ ++ if (!(context->flags & SCAN_FLAGS_PROCESS_MEMORY) || ++ yr_be16toh(elf_header64->type) == ELF_ET_EXEC) ++ { ++ parse_elf_header_64_be( + elf_header64, + block->base, + block->size, + +From c221d4bb820a6005a7b9da44499ce4829f7cf591 Mon Sep 17 00:00:00 2001 +From: Hilko Bengen +Date: Tue, 17 Jan 2017 17:07:02 +0100 +Subject: [PATCH 27/36] re_lexer: Make reading escape sequences more robust + (#586) + +* Add test for issue #503 + +* re_lexer: Make reading escape sequences more robust + +This commit fixes parsing incomplete escape sequences at the end of a +regular expression and parsing things like \xxy (invalid hex digits) +which before were silently turned into (char)255. + +Close #503 + +* Update re_lexer.c + +(cherry picked from commit 3119b232c9c453c98d8fa8b6ae4e37ba18117cd4) +--- + libyara/re_lexer.c | 22 +++++++++++----------- + libyara/re_lexer.l | 12 ++++++------ + tests/test-rules.c | 6 ++++++ + 3 files changed, 23 insertions(+), 17 deletions(-) + +diff --git a/libyara/re_lexer.c b/libyara/re_lexer.c +index 6d784e6..388a5c6 100644 +--- a/libyara/re_lexer.c ++++ b/libyara/re_lexer.c +@@ -243,7 +243,7 @@ struct yy_buffer_state + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ +- yy_size_t yy_n_chars; ++ int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to +@@ -612,7 +612,7 @@ struct yyguts_t + size_t yy_buffer_stack_max; /**< capacity of stack. */ + YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ + char yy_hold_char; +- yy_size_t yy_n_chars; ++ int yy_n_chars; + yy_size_t yyleng_r; + char *yy_c_buf_p; + int yy_init; +@@ -1125,7 +1125,7 @@ YY_RULE_SETUP + } + else + { +- yyerror(yyscanner, lex_env, "unexpected end of buffer"); ++ yyerror(yyscanner, lex_env, "illegal escape sequence"); + yyterminate(); + } + } +@@ -1180,7 +1180,7 @@ YY_RULE_SETUP + { + if (!read_escaped_char(yyscanner, &end)) + { +- yyerror(yyscanner, lex_env, "unexpected end of buffer"); ++ yyerror(yyscanner, lex_env, "illegal escape sequence"); + yyterminate(); + } + } +@@ -1292,7 +1292,7 @@ YY_RULE_SETUP + } + else + { +- yyerror(yyscanner, lex_env, "unexpected end of buffer"); ++ yyerror(yyscanner, lex_env, "illegal escape sequence"); + yyterminate(); + } + } +@@ -1610,9 +1610,9 @@ static int yy_get_next_buffer (yyscan_t yyscanner) + else + ret_val = EOB_ACT_CONTINUE_SCAN; + +- if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { ++ if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ +- yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); ++ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) re_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); +@@ -2012,7 +2012,7 @@ static void re_yyensure_buffer_stack (yyscan_t yyscanner) + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ +- num_to_alloc = 1; // After all that talk, this was set to 1 anyways... ++ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + yyg->yy_buffer_stack = (struct yy_buffer_state**)re_yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); +@@ -2568,19 +2568,19 @@ int read_escaped_char( + text[0] = '\\'; + text[1] = RE_YY_INPUT(yyscanner); + +- if (text[1] == EOF) ++ if (text[1] == EOF || text[1] == 0) + return 0; + + if (text[1] == 'x') + { + text[2] = RE_YY_INPUT(yyscanner); + +- if (text[2] == EOF) ++ if (!isxdigit(text[2])) + return 0; + + text[3] = RE_YY_INPUT(yyscanner); + +- if (text[3] == EOF) ++ if (!isxdigit(text[3])) + return 0; + } + +diff --git a/libyara/re_lexer.l b/libyara/re_lexer.l +index b3744a3..ecb6ad4 100644 +--- a/libyara/re_lexer.l ++++ b/libyara/re_lexer.l +@@ -261,7 +261,7 @@ hex_digit [0-9a-fA-F] + } + else + { +- yyerror(yyscanner, lex_env, "unexpected end of buffer"); ++ yyerror(yyscanner, lex_env, "illegal escape sequence"); + yyterminate(); + } + } +@@ -312,7 +312,7 @@ hex_digit [0-9a-fA-F] + { + if (!read_escaped_char(yyscanner, &end)) + { +- yyerror(yyscanner, lex_env, "unexpected end of buffer"); ++ yyerror(yyscanner, lex_env, "illegal escape sequence"); + yyterminate(); + } + } +@@ -410,7 +410,7 @@ hex_digit [0-9a-fA-F] + } + else + { +- yyerror(yyscanner, lex_env, "unexpected end of buffer"); ++ yyerror(yyscanner, lex_env, "illegal escape sequence"); + yyterminate(); + } + } +@@ -524,19 +524,19 @@ int read_escaped_char( + text[0] = '\\'; + text[1] = RE_YY_INPUT(yyscanner); + +- if (text[1] == EOF) ++ if (text[1] == EOF || text[1] == 0) + return 0; + + if (text[1] == 'x') + { + text[2] = RE_YY_INPUT(yyscanner); + +- if (text[2] == EOF) ++ if (!isxdigit(text[2])) + return 0; + + text[3] = RE_YY_INPUT(yyscanner); + +- if (text[3] == EOF) ++ if (!isxdigit(text[3])) + return 0; + } + +diff --git a/tests/test-rules.c b/tests/test-rules.c +index 19a0902..d4e8f1c 100644 +--- a/tests/test-rules.c ++++ b/tests/test-rules.c +@@ -1013,6 +1013,12 @@ void test_re() + + // Test case for issue #324 + assert_true_regexp("whatever| x. x", " xy x", " xy x"); ++ ++ // test case for issue #503, \x without two following hex-digits ++ assert_regexp_syntax_error("\\x0"); ++ assert_regexp_syntax_error("\\x"); ++ ++ assert_regexp_syntax_error("\\xxy"); + } + + + +From c869ac16178d10ffdc3d3eeb1931dfb08262525b Mon Sep 17 00:00:00 2001 +From: plusvic +Date: Mon, 23 Jan 2017 18:08:51 +0100 +Subject: [PATCH 28/36] Fix issue #597 + +(cherry picked from commit ab906da53ff2a68c6fd6d1fa73f2b7c7bf0bc636) +--- + libyara/grammar.c | 296 ++++++++++++++++++++++++++++-------------------------- + libyara/grammar.y | 6 ++ + 2 files changed, 157 insertions(+), 145 deletions(-) + +diff --git a/libyara/grammar.c b/libyara/grammar.c +index 9c79512..6d4ba05 100644 +--- a/libyara/grammar.c ++++ b/libyara/grammar.c +@@ -611,14 +611,14 @@ static const yytype_uint16 yyrline[] = + 347, 353, 356, 374, 387, 424, 425, 430, 446, 459, + 472, 485, 502, 503, 509, 508, 524, 523, 539, 553, + 554, 559, 560, 561, 562, 567, 652, 698, 756, 801, +- 802, 806, 831, 867, 913, 935, 944, 953, 968, 980, +- 994, 1007, 1018, 1027, 1057, 1026, 1171, 1170, 1249, 1255, +- 1262, 1261, 1324, 1323, 1384, 1393, 1402, 1411, 1420, 1429, +- 1438, 1442, 1450, 1451, 1456, 1478, 1490, 1506, 1505, 1511, +- 1522, 1523, 1528, 1535, 1546, 1547, 1551, 1559, 1563, 1573, +- 1587, 1603, 1613, 1622, 1647, 1659, 1671, 1687, 1699, 1715, +- 1760, 1779, 1797, 1815, 1833, 1859, 1877, 1887, 1897, 1907, +- 1917, 1927, 1937 ++ 802, 806, 833, 871, 917, 939, 948, 957, 972, 984, ++ 998, 1011, 1022, 1033, 1063, 1032, 1177, 1176, 1255, 1261, ++ 1268, 1267, 1330, 1329, 1390, 1399, 1408, 1417, 1426, 1435, ++ 1444, 1448, 1456, 1457, 1462, 1484, 1496, 1512, 1511, 1517, ++ 1528, 1529, 1534, 1541, 1552, 1553, 1557, 1565, 1569, 1579, ++ 1593, 1609, 1619, 1628, 1653, 1665, 1677, 1693, 1705, 1721, ++ 1766, 1785, 1803, 1821, 1839, 1865, 1883, 1893, 1903, 1913, ++ 1923, 1933, 1943 + }; + #endif + +@@ -2361,15 +2361,17 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + case EXPRESSION_TYPE_REGEXP: + strlcpy((yyval.c_string), "r", MAX_FUNCTION_ARGS); + break; ++ default: ++ assert(FALSE); + } + + ERROR_IF((yyval.c_string) == NULL); + } +-#line 2369 "grammar.c" /* yacc.c:1646 */ ++#line 2371 "grammar.c" /* yacc.c:1646 */ + break; + + case 52: +-#line 832 "grammar.y" /* yacc.c:1646 */ ++#line 834 "grammar.y" /* yacc.c:1646 */ + { + if (strlen((yyvsp[-2].c_string)) == MAX_FUNCTION_ARGS) + { +@@ -2394,6 +2396,8 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + case EXPRESSION_TYPE_REGEXP: + strlcat((yyvsp[-2].c_string), "r", MAX_FUNCTION_ARGS); + break; ++ default: ++ assert(FALSE); + } + } + +@@ -2401,11 +2405,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.c_string) = (yyvsp[-2].c_string); + } +-#line 2405 "grammar.c" /* yacc.c:1646 */ ++#line 2409 "grammar.c" /* yacc.c:1646 */ + break; + + case 53: +-#line 868 "grammar.y" /* yacc.c:1646 */ ++#line 872 "grammar.y" /* yacc.c:1646 */ + { + SIZED_STRING* sized_string = (yyvsp[0].sized_string); + RE* re; +@@ -2447,11 +2451,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_REGEXP; + } +-#line 2451 "grammar.c" /* yacc.c:1646 */ ++#line 2455 "grammar.c" /* yacc.c:1646 */ + break; + + case 54: +-#line 914 "grammar.y" /* yacc.c:1646 */ ++#line 918 "grammar.y" /* yacc.c:1646 */ + { + if ((yyvsp[0].expression).type == EXPRESSION_TYPE_STRING) + { +@@ -2470,11 +2474,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2474 "grammar.c" /* yacc.c:1646 */ ++#line 2478 "grammar.c" /* yacc.c:1646 */ + break; + + case 55: +-#line 936 "grammar.y" /* yacc.c:1646 */ ++#line 940 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_emit_with_arg( + yyscanner, OP_PUSH, 1, NULL, NULL); +@@ -2483,11 +2487,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2487 "grammar.c" /* yacc.c:1646 */ ++#line 2491 "grammar.c" /* yacc.c:1646 */ + break; + + case 56: +-#line 945 "grammar.y" /* yacc.c:1646 */ ++#line 949 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_emit_with_arg( + yyscanner, OP_PUSH, 0, NULL, NULL); +@@ -2496,11 +2500,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2500 "grammar.c" /* yacc.c:1646 */ ++#line 2504 "grammar.c" /* yacc.c:1646 */ + break; + + case 57: +-#line 954 "grammar.y" /* yacc.c:1646 */ ++#line 958 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_STRING, "matches"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_REGEXP, "matches"); +@@ -2515,11 +2519,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2519 "grammar.c" /* yacc.c:1646 */ ++#line 2523 "grammar.c" /* yacc.c:1646 */ + break; + + case 58: +-#line 969 "grammar.y" /* yacc.c:1646 */ ++#line 973 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_STRING, "contains"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_STRING, "contains"); +@@ -2531,11 +2535,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2535 "grammar.c" /* yacc.c:1646 */ ++#line 2539 "grammar.c" /* yacc.c:1646 */ + break; + + case 59: +-#line 981 "grammar.y" /* yacc.c:1646 */ ++#line 985 "grammar.y" /* yacc.c:1646 */ + { + int result = yr_parser_reduce_string_identifier( + yyscanner, +@@ -2549,11 +2553,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2553 "grammar.c" /* yacc.c:1646 */ ++#line 2557 "grammar.c" /* yacc.c:1646 */ + break; + + case 60: +-#line 995 "grammar.y" /* yacc.c:1646 */ ++#line 999 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "at"); + +@@ -2566,11 +2570,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2570 "grammar.c" /* yacc.c:1646 */ ++#line 2574 "grammar.c" /* yacc.c:1646 */ + break; + + case 61: +-#line 1008 "grammar.y" /* yacc.c:1646 */ ++#line 1012 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_string_identifier( + yyscanner, (yyvsp[-2].c_string), OP_FOUND_IN, UNDEFINED); +@@ -2581,23 +2585,25 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2585 "grammar.c" /* yacc.c:1646 */ ++#line 2589 "grammar.c" /* yacc.c:1646 */ + break; + + case 62: +-#line 1019 "grammar.y" /* yacc.c:1646 */ ++#line 1023 "grammar.y" /* yacc.c:1646 */ + { + if (compiler->loop_depth > 0) + { + compiler->loop_depth--; + compiler->loop_identifier[compiler->loop_depth] = NULL; + } ++ ++ YYERROR; + } +-#line 2597 "grammar.c" /* yacc.c:1646 */ ++#line 2603 "grammar.c" /* yacc.c:1646 */ + break; + + case 63: +-#line 1027 "grammar.y" /* yacc.c:1646 */ ++#line 1033 "grammar.y" /* yacc.c:1646 */ + { + int var_index; + +@@ -2627,11 +2633,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 2631 "grammar.c" /* yacc.c:1646 */ ++#line 2637 "grammar.c" /* yacc.c:1646 */ + break; + + case 64: +-#line 1057 "grammar.y" /* yacc.c:1646 */ ++#line 1063 "grammar.y" /* yacc.c:1646 */ + { + int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth; + uint8_t* addr; +@@ -2666,11 +2672,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + compiler->loop_identifier[compiler->loop_depth] = (yyvsp[-4].c_string); + compiler->loop_depth++; + } +-#line 2670 "grammar.c" /* yacc.c:1646 */ ++#line 2676 "grammar.c" /* yacc.c:1646 */ + break; + + case 65: +-#line 1092 "grammar.y" /* yacc.c:1646 */ ++#line 1098 "grammar.y" /* yacc.c:1646 */ + { + int mem_offset; + +@@ -2749,11 +2755,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2753 "grammar.c" /* yacc.c:1646 */ ++#line 2759 "grammar.c" /* yacc.c:1646 */ + break; + + case 66: +-#line 1171 "grammar.y" /* yacc.c:1646 */ ++#line 1177 "grammar.y" /* yacc.c:1646 */ + { + int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth; + uint8_t* addr; +@@ -2783,11 +2789,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + compiler->loop_identifier[compiler->loop_depth] = NULL; + compiler->loop_depth++; + } +-#line 2787 "grammar.c" /* yacc.c:1646 */ ++#line 2793 "grammar.c" /* yacc.c:1646 */ + break; + + case 67: +-#line 1201 "grammar.y" /* yacc.c:1646 */ ++#line 1207 "grammar.y" /* yacc.c:1646 */ + { + int mem_offset; + +@@ -2836,31 +2842,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + + } +-#line 2840 "grammar.c" /* yacc.c:1646 */ ++#line 2846 "grammar.c" /* yacc.c:1646 */ + break; + + case 68: +-#line 1250 "grammar.y" /* yacc.c:1646 */ ++#line 1256 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit(yyscanner, OP_OF, NULL); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2850 "grammar.c" /* yacc.c:1646 */ ++#line 2856 "grammar.c" /* yacc.c:1646 */ + break; + + case 69: +-#line 1256 "grammar.y" /* yacc.c:1646 */ ++#line 1262 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit(yyscanner, OP_NOT, NULL); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2860 "grammar.c" /* yacc.c:1646 */ ++#line 2866 "grammar.c" /* yacc.c:1646 */ + break; + + case 70: +-#line 1262 "grammar.y" /* yacc.c:1646 */ ++#line 1268 "grammar.y" /* yacc.c:1646 */ + { + YR_FIXUP* fixup; + void* jmp_destination_addr; +@@ -2886,11 +2892,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + fixup->next = compiler->fixup_stack_head; + compiler->fixup_stack_head = fixup; + } +-#line 2890 "grammar.c" /* yacc.c:1646 */ ++#line 2896 "grammar.c" /* yacc.c:1646 */ + break; + + case 71: +-#line 1288 "grammar.y" /* yacc.c:1646 */ ++#line 1294 "grammar.y" /* yacc.c:1646 */ + { + YR_FIXUP* fixup; + uint8_t* and_addr; +@@ -2926,11 +2932,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2930 "grammar.c" /* yacc.c:1646 */ ++#line 2936 "grammar.c" /* yacc.c:1646 */ + break; + + case 72: +-#line 1324 "grammar.y" /* yacc.c:1646 */ ++#line 1330 "grammar.y" /* yacc.c:1646 */ + { + YR_FIXUP* fixup; + void* jmp_destination_addr; +@@ -2955,11 +2961,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + fixup->next = compiler->fixup_stack_head; + compiler->fixup_stack_head = fixup; + } +-#line 2959 "grammar.c" /* yacc.c:1646 */ ++#line 2965 "grammar.c" /* yacc.c:1646 */ + break; + + case 73: +-#line 1349 "grammar.y" /* yacc.c:1646 */ ++#line 1355 "grammar.y" /* yacc.c:1646 */ + { + YR_FIXUP* fixup; + uint8_t* or_addr; +@@ -2995,11 +3001,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 2999 "grammar.c" /* yacc.c:1646 */ ++#line 3005 "grammar.c" /* yacc.c:1646 */ + break; + + case 74: +-#line 1385 "grammar.y" /* yacc.c:1646 */ ++#line 1391 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "<", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3008,11 +3014,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 3012 "grammar.c" /* yacc.c:1646 */ ++#line 3018 "grammar.c" /* yacc.c:1646 */ + break; + + case 75: +-#line 1394 "grammar.y" /* yacc.c:1646 */ ++#line 1400 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, ">", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3021,11 +3027,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 3025 "grammar.c" /* yacc.c:1646 */ ++#line 3031 "grammar.c" /* yacc.c:1646 */ + break; + + case 76: +-#line 1403 "grammar.y" /* yacc.c:1646 */ ++#line 1409 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "<=", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3034,11 +3040,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 3038 "grammar.c" /* yacc.c:1646 */ ++#line 3044 "grammar.c" /* yacc.c:1646 */ + break; + + case 77: +-#line 1412 "grammar.y" /* yacc.c:1646 */ ++#line 1418 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, ">=", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3047,11 +3053,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 3051 "grammar.c" /* yacc.c:1646 */ ++#line 3057 "grammar.c" /* yacc.c:1646 */ + break; + + case 78: +-#line 1421 "grammar.y" /* yacc.c:1646 */ ++#line 1427 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "==", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3060,11 +3066,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 3064 "grammar.c" /* yacc.c:1646 */ ++#line 3070 "grammar.c" /* yacc.c:1646 */ + break; + + case 79: +-#line 1430 "grammar.y" /* yacc.c:1646 */ ++#line 1436 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "!=", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3073,39 +3079,39 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_BOOLEAN; + } +-#line 3077 "grammar.c" /* yacc.c:1646 */ ++#line 3083 "grammar.c" /* yacc.c:1646 */ + break; + + case 80: +-#line 1439 "grammar.y" /* yacc.c:1646 */ ++#line 1445 "grammar.y" /* yacc.c:1646 */ + { + (yyval.expression) = (yyvsp[0].expression); + } +-#line 3085 "grammar.c" /* yacc.c:1646 */ ++#line 3091 "grammar.c" /* yacc.c:1646 */ + break; + + case 81: +-#line 1443 "grammar.y" /* yacc.c:1646 */ ++#line 1449 "grammar.y" /* yacc.c:1646 */ + { + (yyval.expression) = (yyvsp[-1].expression); + } +-#line 3093 "grammar.c" /* yacc.c:1646 */ ++#line 3099 "grammar.c" /* yacc.c:1646 */ + break; + + case 82: +-#line 1450 "grammar.y" /* yacc.c:1646 */ ++#line 1456 "grammar.y" /* yacc.c:1646 */ + { (yyval.integer) = INTEGER_SET_ENUMERATION; } +-#line 3099 "grammar.c" /* yacc.c:1646 */ ++#line 3105 "grammar.c" /* yacc.c:1646 */ + break; + + case 83: +-#line 1451 "grammar.y" /* yacc.c:1646 */ ++#line 1457 "grammar.y" /* yacc.c:1646 */ + { (yyval.integer) = INTEGER_SET_RANGE; } +-#line 3105 "grammar.c" /* yacc.c:1646 */ ++#line 3111 "grammar.c" /* yacc.c:1646 */ + break; + + case 84: +-#line 1457 "grammar.y" /* yacc.c:1646 */ ++#line 1463 "grammar.y" /* yacc.c:1646 */ + { + if ((yyvsp[-3].expression).type != EXPRESSION_TYPE_INTEGER) + { +@@ -3123,11 +3129,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3127 "grammar.c" /* yacc.c:1646 */ ++#line 3133 "grammar.c" /* yacc.c:1646 */ + break; + + case 85: +-#line 1479 "grammar.y" /* yacc.c:1646 */ ++#line 1485 "grammar.y" /* yacc.c:1646 */ + { + if ((yyvsp[0].expression).type != EXPRESSION_TYPE_INTEGER) + { +@@ -3139,11 +3145,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3143 "grammar.c" /* yacc.c:1646 */ ++#line 3149 "grammar.c" /* yacc.c:1646 */ + break; + + case 86: +-#line 1491 "grammar.y" /* yacc.c:1646 */ ++#line 1497 "grammar.y" /* yacc.c:1646 */ + { + if ((yyvsp[0].expression).type != EXPRESSION_TYPE_INTEGER) + { +@@ -3154,77 +3160,77 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3158 "grammar.c" /* yacc.c:1646 */ ++#line 3164 "grammar.c" /* yacc.c:1646 */ + break; + + case 87: +-#line 1506 "grammar.y" /* yacc.c:1646 */ ++#line 1512 "grammar.y" /* yacc.c:1646 */ + { + // Push end-of-list marker + yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL); + } +-#line 3167 "grammar.c" /* yacc.c:1646 */ ++#line 3173 "grammar.c" /* yacc.c:1646 */ + break; + + case 89: +-#line 1512 "grammar.y" /* yacc.c:1646 */ ++#line 1518 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL); + yr_parser_emit_pushes_for_strings(yyscanner, "$*"); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3178 "grammar.c" /* yacc.c:1646 */ ++#line 3184 "grammar.c" /* yacc.c:1646 */ + break; + + case 92: +-#line 1529 "grammar.y" /* yacc.c:1646 */ ++#line 1535 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[0].c_string)); + yr_free((yyvsp[0].c_string)); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3189 "grammar.c" /* yacc.c:1646 */ ++#line 3195 "grammar.c" /* yacc.c:1646 */ + break; + + case 93: +-#line 1536 "grammar.y" /* yacc.c:1646 */ ++#line 1542 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[0].c_string)); + yr_free((yyvsp[0].c_string)); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3200 "grammar.c" /* yacc.c:1646 */ ++#line 3206 "grammar.c" /* yacc.c:1646 */ + break; + + case 95: +-#line 1548 "grammar.y" /* yacc.c:1646 */ ++#line 1554 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL); + } +-#line 3208 "grammar.c" /* yacc.c:1646 */ ++#line 3214 "grammar.c" /* yacc.c:1646 */ + break; + + case 96: +-#line 1552 "grammar.y" /* yacc.c:1646 */ ++#line 1558 "grammar.y" /* yacc.c:1646 */ + { + yr_parser_emit_with_arg(yyscanner, OP_PUSH, 1, NULL, NULL); + } +-#line 3216 "grammar.c" /* yacc.c:1646 */ ++#line 3222 "grammar.c" /* yacc.c:1646 */ + break; + + case 97: +-#line 1560 "grammar.y" /* yacc.c:1646 */ ++#line 1566 "grammar.y" /* yacc.c:1646 */ + { + (yyval.expression) = (yyvsp[-1].expression); + } +-#line 3224 "grammar.c" /* yacc.c:1646 */ ++#line 3230 "grammar.c" /* yacc.c:1646 */ + break; + + case 98: +-#line 1564 "grammar.y" /* yacc.c:1646 */ ++#line 1570 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_emit( + yyscanner, OP_FILESIZE, NULL); +@@ -3234,11 +3240,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3238 "grammar.c" /* yacc.c:1646 */ ++#line 3244 "grammar.c" /* yacc.c:1646 */ + break; + + case 99: +-#line 1574 "grammar.y" /* yacc.c:1646 */ ++#line 1580 "grammar.y" /* yacc.c:1646 */ + { + yywarning(yyscanner, + "Using deprecated \"entrypoint\" keyword. Use the \"entry_point\" " +@@ -3252,11 +3258,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3256 "grammar.c" /* yacc.c:1646 */ ++#line 3262 "grammar.c" /* yacc.c:1646 */ + break; + + case 100: +-#line 1588 "grammar.y" /* yacc.c:1646 */ ++#line 1594 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-1].expression), EXPRESSION_TYPE_INTEGER, "intXXXX or uintXXXX"); + +@@ -3272,11 +3278,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3276 "grammar.c" /* yacc.c:1646 */ ++#line 3282 "grammar.c" /* yacc.c:1646 */ + break; + + case 101: +-#line 1604 "grammar.y" /* yacc.c:1646 */ ++#line 1610 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_emit_with_arg( + yyscanner, OP_PUSH, (yyvsp[0].integer), NULL, NULL); +@@ -3286,11 +3292,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = (yyvsp[0].integer); + } +-#line 3290 "grammar.c" /* yacc.c:1646 */ ++#line 3296 "grammar.c" /* yacc.c:1646 */ + break; + + case 102: +-#line 1614 "grammar.y" /* yacc.c:1646 */ ++#line 1620 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_emit_with_arg_double( + yyscanner, OP_PUSH, (yyvsp[0].double_), NULL, NULL); +@@ -3299,11 +3305,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + (yyval.expression).type = EXPRESSION_TYPE_FLOAT; + } +-#line 3303 "grammar.c" /* yacc.c:1646 */ ++#line 3309 "grammar.c" /* yacc.c:1646 */ + break; + + case 103: +-#line 1623 "grammar.y" /* yacc.c:1646 */ ++#line 1629 "grammar.y" /* yacc.c:1646 */ + { + SIZED_STRING* sized_string; + +@@ -3328,11 +3334,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_STRING; + (yyval.expression).value.sized_string = sized_string; + } +-#line 3332 "grammar.c" /* yacc.c:1646 */ ++#line 3338 "grammar.c" /* yacc.c:1646 */ + break; + + case 104: +-#line 1648 "grammar.y" /* yacc.c:1646 */ ++#line 1654 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_string_identifier( + yyscanner, (yyvsp[0].c_string), OP_COUNT, UNDEFINED); +@@ -3344,11 +3350,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3348 "grammar.c" /* yacc.c:1646 */ ++#line 3354 "grammar.c" /* yacc.c:1646 */ + break; + + case 105: +-#line 1660 "grammar.y" /* yacc.c:1646 */ ++#line 1666 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_string_identifier( + yyscanner, (yyvsp[-3].c_string), OP_OFFSET, UNDEFINED); +@@ -3360,11 +3366,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3364 "grammar.c" /* yacc.c:1646 */ ++#line 3370 "grammar.c" /* yacc.c:1646 */ + break; + + case 106: +-#line 1672 "grammar.y" /* yacc.c:1646 */ ++#line 1678 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_emit_with_arg( + yyscanner, OP_PUSH, 1, NULL, NULL); +@@ -3380,11 +3386,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3384 "grammar.c" /* yacc.c:1646 */ ++#line 3390 "grammar.c" /* yacc.c:1646 */ + break; + + case 107: +-#line 1688 "grammar.y" /* yacc.c:1646 */ ++#line 1694 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_string_identifier( + yyscanner, (yyvsp[-3].c_string), OP_LENGTH, UNDEFINED); +@@ -3396,11 +3402,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3400 "grammar.c" /* yacc.c:1646 */ ++#line 3406 "grammar.c" /* yacc.c:1646 */ + break; + + case 108: +-#line 1700 "grammar.y" /* yacc.c:1646 */ ++#line 1706 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_emit_with_arg( + yyscanner, OP_PUSH, 1, NULL, NULL); +@@ -3416,11 +3422,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = UNDEFINED; + } +-#line 3420 "grammar.c" /* yacc.c:1646 */ ++#line 3426 "grammar.c" /* yacc.c:1646 */ + break; + + case 109: +-#line 1716 "grammar.y" /* yacc.c:1646 */ ++#line 1722 "grammar.y" /* yacc.c:1646 */ + { + if ((yyvsp[0].expression).type == EXPRESSION_TYPE_INTEGER) // loop identifier + { +@@ -3465,11 +3471,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3469 "grammar.c" /* yacc.c:1646 */ ++#line 3475 "grammar.c" /* yacc.c:1646 */ + break; + + case 110: +-#line 1761 "grammar.y" /* yacc.c:1646 */ ++#line 1767 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER | EXPRESSION_TYPE_FLOAT, "-"); + +@@ -3488,11 +3494,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } +-#line 3492 "grammar.c" /* yacc.c:1646 */ ++#line 3498 "grammar.c" /* yacc.c:1646 */ + break; + + case 111: +-#line 1780 "grammar.y" /* yacc.c:1646 */ ++#line 1786 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "+", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3510,11 +3516,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_FLOAT; + } + } +-#line 3514 "grammar.c" /* yacc.c:1646 */ ++#line 3520 "grammar.c" /* yacc.c:1646 */ + break; + + case 112: +-#line 1798 "grammar.y" /* yacc.c:1646 */ ++#line 1804 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "-", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3532,11 +3538,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_FLOAT; + } + } +-#line 3536 "grammar.c" /* yacc.c:1646 */ ++#line 3542 "grammar.c" /* yacc.c:1646 */ + break; + + case 113: +-#line 1816 "grammar.y" /* yacc.c:1646 */ ++#line 1822 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "*", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3554,11 +3560,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_FLOAT; + } + } +-#line 3558 "grammar.c" /* yacc.c:1646 */ ++#line 3564 "grammar.c" /* yacc.c:1646 */ + break; + + case 114: +-#line 1834 "grammar.y" /* yacc.c:1646 */ ++#line 1840 "grammar.y" /* yacc.c:1646 */ + { + compiler->last_result = yr_parser_reduce_operation( + yyscanner, "\\", (yyvsp[-2].expression), (yyvsp[0].expression)); +@@ -3584,11 +3590,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_FLOAT; + } + } +-#line 3588 "grammar.c" /* yacc.c:1646 */ ++#line 3594 "grammar.c" /* yacc.c:1646 */ + break; + + case 115: +-#line 1860 "grammar.y" /* yacc.c:1646 */ ++#line 1866 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "%"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "%"); +@@ -3606,11 +3612,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + ERROR_IF(compiler->last_result != ERROR_SUCCESS); + } + } +-#line 3610 "grammar.c" /* yacc.c:1646 */ ++#line 3616 "grammar.c" /* yacc.c:1646 */ + break; + + case 116: +-#line 1878 "grammar.y" /* yacc.c:1646 */ ++#line 1884 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^"); +@@ -3620,11 +3626,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = OPERATION(^, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); + } +-#line 3624 "grammar.c" /* yacc.c:1646 */ ++#line 3630 "grammar.c" /* yacc.c:1646 */ + break; + + case 117: +-#line 1888 "grammar.y" /* yacc.c:1646 */ ++#line 1894 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "^"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "^"); +@@ -3634,11 +3640,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = OPERATION(&, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); + } +-#line 3638 "grammar.c" /* yacc.c:1646 */ ++#line 3644 "grammar.c" /* yacc.c:1646 */ + break; + + case 118: +-#line 1898 "grammar.y" /* yacc.c:1646 */ ++#line 1904 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "|"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "|"); +@@ -3648,11 +3654,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = OPERATION(|, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); + } +-#line 3652 "grammar.c" /* yacc.c:1646 */ ++#line 3658 "grammar.c" /* yacc.c:1646 */ + break; + + case 119: +-#line 1908 "grammar.y" /* yacc.c:1646 */ ++#line 1914 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "~"); + +@@ -3662,11 +3668,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).value.integer = ((yyvsp[0].expression).value.integer == UNDEFINED) ? + UNDEFINED : ~((yyvsp[0].expression).value.integer); + } +-#line 3666 "grammar.c" /* yacc.c:1646 */ ++#line 3672 "grammar.c" /* yacc.c:1646 */ + break; + + case 120: +-#line 1918 "grammar.y" /* yacc.c:1646 */ ++#line 1924 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, "<<"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, "<<"); +@@ -3676,11 +3682,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = OPERATION(<<, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); + } +-#line 3680 "grammar.c" /* yacc.c:1646 */ ++#line 3686 "grammar.c" /* yacc.c:1646 */ + break; + + case 121: +-#line 1928 "grammar.y" /* yacc.c:1646 */ ++#line 1934 "grammar.y" /* yacc.c:1646 */ + { + CHECK_TYPE((yyvsp[-2].expression), EXPRESSION_TYPE_INTEGER, ">>"); + CHECK_TYPE((yyvsp[0].expression), EXPRESSION_TYPE_INTEGER, ">>"); +@@ -3690,19 +3696,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + (yyval.expression).type = EXPRESSION_TYPE_INTEGER; + (yyval.expression).value.integer = OPERATION(>>, (yyvsp[-2].expression).value.integer, (yyvsp[0].expression).value.integer); + } +-#line 3694 "grammar.c" /* yacc.c:1646 */ ++#line 3700 "grammar.c" /* yacc.c:1646 */ + break; + + case 122: +-#line 1938 "grammar.y" /* yacc.c:1646 */ ++#line 1944 "grammar.y" /* yacc.c:1646 */ + { + (yyval.expression) = (yyvsp[0].expression); + } +-#line 3702 "grammar.c" /* yacc.c:1646 */ ++#line 3708 "grammar.c" /* yacc.c:1646 */ + break; + + +-#line 3706 "grammar.c" /* yacc.c:1646 */ ++#line 3712 "grammar.c" /* yacc.c:1646 */ + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires +@@ -3930,5 +3936,5 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + #endif + return yyresult; + } +-#line 1943 "grammar.y" /* yacc.c:1906 */ ++#line 1949 "grammar.y" /* yacc.c:1906 */ + +diff --git a/libyara/grammar.y b/libyara/grammar.y +index addb55d..9cb4be7 100644 +--- a/libyara/grammar.y ++++ b/libyara/grammar.y +@@ -824,6 +824,8 @@ arguments_list + case EXPRESSION_TYPE_REGEXP: + strlcpy($$, "r", MAX_FUNCTION_ARGS); + break; ++ default: ++ assert(FALSE); + } + + ERROR_IF($$ == NULL); +@@ -853,6 +855,8 @@ arguments_list + case EXPRESSION_TYPE_REGEXP: + strlcat($1, "r", MAX_FUNCTION_ARGS); + break; ++ default: ++ assert(FALSE); + } + } + +@@ -1022,6 +1026,8 @@ expression + compiler->loop_depth--; + compiler->loop_identifier[compiler->loop_depth] = NULL; + } ++ ++ YYERROR; + } + | _FOR_ for_expression _IDENTIFIER_ _IN_ + { + +From e91ceb150bd55d3249b0b523a3ce454f8dec5e81 Mon Sep 17 00:00:00 2001 +From: plusvic +Date: Tue, 7 Feb 2017 11:34:49 +0100 +Subject: [PATCH 29/36] Fix detection of bswap compiler features in endian.h + +Cherry picked from commits + +- 764f33dd04135f8d3f9428c8f9bed213494d538f +- 16c3dd1215ea013bf472820878e22aaaab0fd8cd +- ca3927fcebb85c429231087ef796753a37d5b079 +- 0541a7932517364f5ec042af710ce48f92f6e5bd +--- + libyara/Makefile.am | 1 + + libyara/endian.c | 53 +++++++++++++++++++++++++++++++++++++++ + libyara/include/yara/endian.h | 58 +++++++++++++++++++++++++++++++++++-------- + 3 files changed, 102 insertions(+), 10 deletions(-) + create mode 100644 libyara/endian.c + +diff --git a/libyara/Makefile.am b/libyara/Makefile.am +index 20dbe4a..6861843 100644 +--- a/libyara/Makefile.am ++++ b/libyara/Makefile.am +@@ -73,6 +73,7 @@ libyara_la_SOURCES = \ + arena.c \ + atoms.c \ + compiler.c \ ++ endian.c \ + exec.c \ + exefiles.c \ + exefiles.h \ +diff --git a/libyara/endian.c b/libyara/endian.c +new file mode 100644 +index 0000000..02fff63 +--- /dev/null ++++ b/libyara/endian.c +@@ -0,0 +1,53 @@ ++/* ++Copyright (c) 2017. The YARA Authors. All Rights Reserved. ++ ++Redistribution and use in source and binary forms, with or without modification, ++are permitted provided that the following conditions are met: ++ ++1. Redistributions of source code must retain the above copyright notice, this ++list of conditions and the following disclaimer. ++ ++2. Redistributions in binary form must reproduce the above copyright notice, ++this list of conditions and the following disclaimer in the documentation and/or ++other materials provided with the distribution. ++ ++3. Neither the name of the copyright holder nor the names of its contributors ++may be used to endorse or promote products derived from this software without ++specific prior written permission. ++ ++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ++WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ++ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++*/ ++ ++#include ++ ++uint16_t _yr_bswap16(uint16_t x) ++{ ++ return (x >> 8 | x << 8); ++} ++ ++uint32_t _yr_bswap32(uint32_t x) ++{ ++ return ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | ++ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)); ++} ++ ++uint64_t _yr_bswap64(uint64_t x) ++{ ++ return ((((x) & 0xff00000000000000ull) >> 56) ++ | (((x) & 0x00ff000000000000ull) >> 40) ++ | (((x) & 0x0000ff0000000000ull) >> 24) ++ | (((x) & 0x000000ff00000000ull) >> 8) ++ | (((x) & 0x00000000ff000000ull) << 8) ++ | (((x) & 0x0000000000ff0000ull) << 24) ++ | (((x) & 0x000000000000ff00ull) << 40) ++ | (((x) & 0x00000000000000ffull) << 56)); ++} +diff --git a/libyara/include/yara/endian.h b/libyara/include/yara/endian.h +index 06d8c14..8d75012 100644 +--- a/libyara/include/yara/endian.h ++++ b/libyara/include/yara/endian.h +@@ -30,20 +30,58 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #ifndef YR_ENDIAN_H + #define YR_ENDIAN_H + ++#include + #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 dff586e..c6ee384 100644 +--- a/libyara/modules/elf.c ++++ b/libyara/modules/elf.c +@@ -164,7 +164,8 @@ void parse_elf_header_##bits##_##bo( \ + section = (elf##bits##_section_header_t*) \ + ((uint8_t*) elf + yr_##bo##bits##toh(elf->sh_offset)); \ + \ +- if (section[yr_##bo##16toh(elf->sh_str_table_index)].offset < elf_size) \ ++ if (yr_##bo##bits##toh( \ ++ section[yr_##bo##16toh(elf->sh_str_table_index)].offset) < elf_size) \ + { \ + str_table = (char*) elf + yr_##bo##bits##toh( \ + section[yr_##bo##16toh(elf->sh_str_table_index)].offset); \ +diff --git a/tests/blob.h b/tests/blob.h +index 08bf5b6..1659a91 100644 +--- a/tests/blob.h ++++ b/tests/blob.h +@@ -178,3 +178,158 @@ uint8_t ELF64_FILE[] = { + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; ++ ++uint8_t ELF32_MIPS_FILE[] = { ++ 0x7f, 0x45, 0x4c, 0x46, 0x01, 0x02, 0x01, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, ++ 0x00, 0x40, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x34, ++ 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x10, 0x07, ++ 0x00, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x28, ++ 0x00, 0x0b, 0x00, 0x08, 0x70, 0x00, 0x00, 0x03, ++ 0x00, 0x00, 0x00, 0x98, 0x00, 0x40, 0x00, 0x98, ++ 0x00, 0x40, 0x00, 0x98, 0x00, 0x00, 0x00, 0x18, ++ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, ++ 0x00, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0xb0, 0x00, 0x40, 0x00, 0xb0, ++ 0x00, 0x40, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x18, ++ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, ++ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, ++ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, ++ 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x05, ++ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x80, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x80, 0xd0, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x03, 0xe0, 0x00, 0x08, 0x24, 0x02, 0x00, 0x2a, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x47, 0x43, 0x43, 0x3a, 0x20, 0x28, 0x47, 0x4e, ++ 0x55, 0x29, 0x20, 0x35, 0x2e, 0x33, 0x2e, 0x30, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0xd0, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, ++ 0x00, 0x00, 0x00, 0x1f, 0x41, 0x00, 0x00, 0x00, ++ 0x0f, 0x67, 0x6e, 0x75, 0x00, 0x01, 0x00, 0x00, ++ 0x00, 0x07, 0x04, 0x01, 0x00, 0x2e, 0x73, 0x79, ++ 0x6d, 0x74, 0x61, 0x62, 0x00, 0x2e, 0x73, 0x74, ++ 0x72, 0x74, 0x61, 0x62, 0x00, 0x2e, 0x73, 0x68, ++ 0x73, 0x74, 0x72, 0x74, 0x61, 0x62, 0x00, 0x2e, ++ 0x4d, 0x49, 0x50, 0x53, 0x2e, 0x61, 0x62, 0x69, ++ 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x2e, 0x72, ++ 0x65, 0x67, 0x69, 0x6e, 0x66, 0x6f, 0x00, 0x2e, ++ 0x74, 0x65, 0x78, 0x74, 0x00, 0x2e, 0x63, 0x6f, ++ 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x2e, 0x70, ++ 0x64, 0x72, 0x00, 0x2e, 0x67, 0x6e, 0x75, 0x2e, ++ 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, ++ 0x65, 0x73, 0x00, 0x2e, 0x6d, 0x64, 0x65, 0x62, ++ 0x75, 0x67, 0x2e, 0x61, 0x62, 0x69, 0x33, 0x32, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x40, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, ++ 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x40, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, ++ 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x40, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, ++ 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x04, 0x00, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x04, 0x00, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x08, ++ 0x00, 0x41, 0x80, 0xd0, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0xff, 0xf1, 0x00, 0x00, 0x00, 0x0c, ++ 0x00, 0x41, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, ++ 0x10, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, ++ 0x00, 0x40, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, ++ 0x10, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x22, ++ 0x00, 0x41, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, ++ 0x10, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2e, ++ 0x00, 0x40, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x08, ++ 0x12, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x33, ++ 0x00, 0x41, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, ++ 0x10, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, ++ 0x00, 0x41, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, ++ 0x10, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3f, ++ 0x00, 0x41, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, ++ 0x10, 0x00, 0x00, 0x03, 0x00, 0x6d, 0x61, 0x69, ++ 0x6e, 0x2e, 0x63, 0x00, 0x5f, 0x67, 0x70, 0x00, ++ 0x5f, 0x66, 0x64, 0x61, 0x74, 0x61, 0x00, 0x5f, ++ 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x5f, ++ 0x66, 0x74, 0x65, 0x78, 0x74, 0x00, 0x5f, 0x5f, ++ 0x62, 0x73, 0x73, 0x5f, 0x73, 0x74, 0x61, 0x72, ++ 0x74, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x5f, ++ 0x65, 0x64, 0x61, 0x74, 0x61, 0x00, 0x5f, 0x65, ++ 0x6e, 0x64, 0x00, 0x5f, 0x66, 0x62, 0x73, 0x73, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, ++ 0x70, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x02, ++ 0x00, 0x40, 0x00, 0x98, 0x00, 0x00, 0x00, 0x98, ++ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, ++ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x2a, ++ 0x70, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, ++ 0x00, 0x40, 0x00, 0xb0, 0x00, 0x00, 0x00, 0xb0, ++ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, ++ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x33, ++ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, ++ 0x00, 0x40, 0x00, 0xd0, 0x00, 0x00, 0x00, 0xd0, ++ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, ++ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, ++ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, ++ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x42, ++ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, ++ 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, ++ 0x6f, 0xff, 0xff, 0xf5, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x14, ++ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, ++ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x24, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, ++ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x24, ++ 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, ++ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8c, ++ 0x00, 0x00, 0x01, 0x30, 0x00, 0x00, 0x00, 0x0a, ++ 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x04, ++ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x09, ++ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xbc, ++ 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, ++ 0x00, 0x00, 0x00, 0x00 ++}; +\ No newline at end of file +diff --git a/tests/test-elf.c b/tests/test-elf.c +index 8d13b47..6415933 100644 +--- a/tests/test-elf.c ++++ b/tests/test-elf.c +@@ -24,6 +24,27 @@ int main(int argc, char** argv) + condition: $a at elf.entry_point }", + ELF64_FILE); + ++ assert_true_rule_blob("import \"elf\" rule test { \ ++ condition: elf.sections[2].name == \".comment\" }", ELF64_FILE); ++ ++ assert_true_rule_blob("import \"elf\" rule test { \ ++ condition: elf.machine == elf.EM_MIPS }", ELF32_MIPS_FILE); ++ ++ assert_true_rule_blob("import \"elf\" rule test { \ ++ condition: elf.number_of_sections == 11 and \ ++ elf.number_of_segments == 3 }", ELF32_MIPS_FILE); ++ ++ assert_true_rule_blob("import \"elf\" rule test { \ ++ condition: for any i in (0..elf.number_of_sections): ( \ ++ elf.sections[i].type == elf.SHT_PROGBITS and \ ++ elf.sections[i].name == \".text\")}", ELF32_MIPS_FILE); ++ ++ assert_true_rule_blob("import \"elf\" rule test { \ ++ condition: for any i in (0..elf.number_of_segments): ( \ ++ elf.segments[i].type == elf.PT_LOAD and \ ++ elf.segments[i].virtual_address == 0x00400000 and \ ++ elf.segments[i].file_size == 0xe0)}", ELF32_MIPS_FILE); ++ + yr_finalize(); + return 0; + } + +From 5daf58f4f5b98f4aeb33c60a70b7abec4f13f9b8 Mon Sep 17 00:00:00 2001 +From: Jacob Baines +Date: Wed, 15 Feb 2017 03:50:18 -0500 +Subject: [PATCH 31/36] Use the program headers to determine the physical + offset of the ELF entry point (#606) + +(cherry picked from commit 8fc561b50121227b78baa85fd0d56482655c290d) +--- + libyara/exefiles.c | 189 ++++++++++----- + libyara/modules/elf.c | 100 +++++--- + tests/blob.h | 625 +++++++++++++++++++++++++++++++++++++++++++++++++- + tests/test-elf.c | 7 +- + 4 files changed, 834 insertions(+), 87 deletions(-) + +diff --git a/libyara/exefiles.c b/libyara/exefiles.c +index 05d1de7..293b905 100644 +--- a/libyara/exefiles.c ++++ b/libyara/exefiles.c +@@ -150,54 +150,95 @@ int yr_get_elf_type( + } + + +-uint64_t yr_elf_rva_to_offset_32( ++static uint64_t yr_elf_rva_to_offset_32( + elf32_header_t* elf_header, + uint64_t rva, + size_t buffer_length) + { +- int i; +- elf32_section_header_t* section; ++ // if the binary is an executable then prefer the program headers to resolve ++ // the offset ++ if (elf_header->type == ELF_ET_EXEC) ++ { ++ int i; ++ elf32_program_header_t* program; ++ if (elf_header->ph_offset == 0 || elf_header->ph_entry_count == 0) ++ return 0; + +- if (elf_header->sh_offset == 0 || elf_header->sh_entry_count == 0) +- return 0; ++ // check to prevent integer wraps ++ if (ULONG_MAX - yr_le16toh(elf_header->ph_entry_count) < ++ sizeof(elf32_program_header_t) * yr_le16toh(elf_header->ph_entry_count)) ++ return 0; + +- // check to prevent integer wraps ++ // check that 'ph_offset' doesn't wrap when added to the ++ // size of entries. ++ if(ULONG_MAX - yr_le32toh(elf_header->ph_offset) < ++ sizeof(elf32_program_header_t) * yr_le16toh(elf_header->ph_entry_count)) ++ return 0; + +- if (ULONG_MAX - yr_le16toh(elf_header->sh_entry_count) < +- sizeof(elf32_section_header_t) * yr_le16toh(elf_header->sh_entry_count)) +- return 0; ++ // ensure we don't exceed the buffer size ++ if (yr_le32toh(elf_header->ph_offset) + sizeof(elf32_program_header_t) * ++ yr_le16toh(elf_header->ph_entry_count) > buffer_length) ++ return 0; + +- // check that 'sh_offset' doesn't wrap when added to the +- // size of entries. ++ program = (elf32_program_header_t*) ++ ((uint8_t*) elf_header + yr_le32toh(elf_header->ph_offset)); + +- if (ULONG_MAX - yr_le32toh(elf_header->sh_offset) < +- sizeof(elf32_section_header_t) * yr_le16toh(elf_header->sh_entry_count)) +- return 0; ++ for (i = 0; i < yr_le16toh(elf_header->ph_entry_count); i++) ++ { ++ if (rva >= yr_le32toh(program->virt_addr) && ++ rva < yr_le32toh(program->virt_addr) + yr_le32toh(program->mem_size)) ++ { ++ return yr_le32toh(program->offset) + (rva - yr_le32toh(program->virt_addr)); ++ } + +- if (yr_le32toh(elf_header->sh_offset) + \ +- sizeof(elf32_section_header_t) * \ +- yr_le16toh(elf_header->sh_entry_count) > buffer_length) +- return 0; ++ program++; ++ } ++ } ++ else ++ { ++ int i; ++ elf32_section_header_t* section; ++ ++ if (elf_header->sh_offset == 0 || elf_header->sh_entry_count == 0) ++ return 0; ++ ++ // check to prevent integer wraps + +- section = (elf32_section_header_t*) \ ++ if (ULONG_MAX - yr_le16toh(elf_header->sh_entry_count) < ++ sizeof(elf32_section_header_t) * yr_le16toh(elf_header->sh_entry_count)) ++ return 0; ++ ++ // check that 'sh_offset' doesn't wrap when added to the ++ // size of entries. ++ ++ if (ULONG_MAX - yr_le32toh(elf_header->sh_offset) < ++ sizeof(elf32_section_header_t) * yr_le16toh(elf_header->sh_entry_count)) ++ return 0; ++ ++ if (yr_le32toh(elf_header->sh_offset) + sizeof(elf32_section_header_t) * ++ yr_le16toh(elf_header->sh_entry_count) > buffer_length) ++ return 0; ++ ++ section = (elf32_section_header_t*) + ((unsigned char*) elf_header + yr_le32toh(elf_header->sh_offset)); + +- for (i = 0; i < yr_le16toh(elf_header->sh_entry_count); i++) +- { +- if (yr_le32toh(section->type) != ELF_SHT_NULL && +- yr_le32toh(section->type) != ELF_SHT_NOBITS && +- rva >= yr_le32toh(section->addr) && +- rva < yr_le32toh(section->addr) + yr_le32toh(section->size)) ++ for (i = 0; i < yr_le16toh(elf_header->sh_entry_count); i++) + { +- // prevent integer wrapping with the return value ++ if (yr_le32toh(section->type) != ELF_SHT_NULL && ++ yr_le32toh(section->type) != ELF_SHT_NOBITS && ++ rva >= yr_le32toh(section->addr) && ++ rva < yr_le32toh(section->addr) + yr_le32toh(section->size)) ++ { ++ // prevent integer wrapping with the return value + +- if (ULONG_MAX - yr_le32toh(section->offset) < (rva - yr_le32toh(section->addr))) +- return 0; +- else +- return yr_le32toh(section->offset) + (rva - yr_le32toh(section->addr)); +- } ++ if (ULONG_MAX - yr_le32toh(section->offset) < (rva - yr_le32toh(section->addr))) ++ return 0; ++ else ++ return yr_le32toh(section->offset) + (rva - yr_le32toh(section->addr)); ++ } + +- section++; ++ section++; ++ } + } + + return 0; +@@ -205,42 +246,78 @@ uint64_t yr_elf_rva_to_offset_32( + } + + +-uint64_t yr_elf_rva_to_offset_64( ++static uint64_t yr_elf_rva_to_offset_64( + elf64_header_t* elf_header, + uint64_t rva, + size_t buffer_length) + { +- int i; +- elf64_section_header_t* section; ++ // if the binary is an executable then prefer the program headers to resolve ++ // the offset ++ if (elf_header->type == ELF_ET_EXEC) ++ { ++ int i; ++ elf64_program_header_t* program; ++ if (elf_header->ph_offset == 0 || elf_header->ph_entry_count == 0) ++ return 0; + +- if (elf_header->sh_offset == 0 || elf_header->sh_entry_count == 0) +- return 0; ++ // check that 'ph_offset' doesn't wrap when added to the ++ // size of entries. ++ if(ULONG_MAX - yr_le64toh(elf_header->ph_offset) < ++ sizeof(elf64_program_header_t) * yr_le16toh(elf_header->ph_entry_count)) ++ return 0; + +- // check that 'sh_offset' doesn't wrap when added to the +- // size of entries. +- if(ULONG_MAX - yr_le64toh(elf_header->sh_offset) < +- sizeof(elf64_section_header_t) * yr_le16toh(elf_header->sh_entry_count)) +- return 0; ++ // ensure we don't exceed the buffer size ++ if (yr_le64toh(elf_header->ph_offset) + sizeof(elf64_program_header_t) * ++ yr_le16toh(elf_header->ph_entry_count) > buffer_length) ++ return 0; + +- if (yr_le64toh(elf_header->sh_offset) + \ +- sizeof(elf64_section_header_t) * \ +- yr_le16toh(elf_header->sh_entry_count) > buffer_length) +- return 0; ++ program = (elf64_program_header_t*) ++ ((uint8_t*) elf_header + yr_le64toh(elf_header->ph_offset)); + +- section = (elf64_section_header_t*) \ +- ((uint8_t*) elf_header + yr_le64toh(elf_header->sh_offset)); ++ for (i = 0; i < yr_le16toh(elf_header->ph_entry_count); i++) ++ { ++ if (rva >= yr_le64toh(program->virt_addr) && ++ rva < yr_le64toh(program->virt_addr) + yr_le64toh(program->mem_size)) ++ { ++ return yr_le64toh(program->offset) + (rva - yr_le64toh(program->virt_addr)); ++ } + +- for (i = 0; i < yr_le16toh(elf_header->sh_entry_count); i++) ++ program++; ++ } ++ } ++ else + { +- if (yr_le32toh(section->type) != ELF_SHT_NULL && +- yr_le32toh(section->type) != ELF_SHT_NOBITS && +- rva >= yr_le64toh(section->addr) && +- rva < yr_le64toh(section->addr) + yr_le64toh(section->size)) ++ int i; ++ elf64_section_header_t* section; ++ ++ if (elf_header->sh_offset == 0 || elf_header->sh_entry_count == 0) ++ return 0; ++ ++ // check that 'sh_offset' doesn't wrap when added to the ++ // size of entries. ++ if(ULONG_MAX - yr_le64toh(elf_header->sh_offset) < ++ sizeof(elf64_section_header_t) * yr_le16toh(elf_header->sh_entry_count)) ++ return 0; ++ ++ if (yr_le64toh(elf_header->sh_offset) + sizeof(elf64_section_header_t) * ++ yr_le16toh(elf_header->sh_entry_count) > buffer_length) ++ return 0; ++ ++ section = (elf64_section_header_t*) ++ ((uint8_t*) elf_header + yr_le64toh(elf_header->sh_offset)); ++ ++ for (i = 0; i < yr_le16toh(elf_header->sh_entry_count); i++) + { +- return yr_le64toh(section->offset) + (rva - yr_le64toh(section->addr)); +- } ++ if (yr_le32toh(section->type) != ELF_SHT_NULL && ++ yr_le32toh(section->type) != ELF_SHT_NOBITS && ++ rva >= yr_le64toh(section->addr) && ++ rva < yr_le64toh(section->addr) + yr_le64toh(section->size)) ++ { ++ return yr_le64toh(section->offset) + (rva - yr_le64toh(section->addr)); ++ } + +- section++; ++ section++; ++ } + } + + return 0; +diff --git a/libyara/modules/elf.c b/libyara/modules/elf.c +index c6ee384..8ea6c94 100644 +--- a/libyara/modules/elf.c ++++ b/libyara/modules/elf.c +@@ -63,7 +63,8 @@ int get_elf_class_data( + #define ELF_SIZE_OF_SECTION_TABLE(bits,bo,h) \ + (sizeof(elf##bits##_section_header_t) * yr_##bo##16toh(h->sh_entry_count)) + +- ++#define ELF_SIZE_OF_PROGRAM_TABLE(bits,bo,h) \ ++ (sizeof(elf##bits##_program_header_t) * yr_##bo##16toh(h->ph_entry_count)) + + #define ELF_RVA_TO_OFFSET(bits,bo) \ + uint64_t elf_rva_to_offset_##bits##_##bo( \ +@@ -71,45 +72,86 @@ uint64_t elf_rva_to_offset_##bits##_##bo( \ + uint64_t rva, \ + size_t elf_size) \ + { \ +- int i; \ ++ if (elf_header->type == ELF_ET_EXEC) \ ++ { \ ++ int i; \ + \ +- elf##bits##_section_header_t* section; \ ++ elf##bits##_program_header_t* program; \ + \ +- /* check that sh_offset doesn't wrap when added to SIZE_OF_SECTION_TABLE */ \ ++ /* check that ph_offset doesn't wrap when added to SIZE_OF_PROGRAM_TABLE */\ + \ +- if(ULONG_MAX - yr_##bo##bits##toh(elf_header->sh_offset) < \ +- ELF_SIZE_OF_SECTION_TABLE(bits,bo,elf_header)) \ +- { \ +- return UNDEFINED; \ +- } \ ++ if(ULONG_MAX - yr_##bo##bits##toh(elf_header->ph_offset) < \ ++ ELF_SIZE_OF_PROGRAM_TABLE(bits,bo,elf_header)) \ ++ { \ ++ return UNDEFINED; \ ++ } \ + \ +- if (yr_##bo##bits##toh(elf_header->sh_offset) == 0 || \ +- yr_##bo##bits##toh(elf_header->sh_offset) > elf_size || \ +- yr_##bo##bits##toh(elf_header->sh_offset) + \ +- ELF_SIZE_OF_SECTION_TABLE(bits,bo,elf_header) > elf_size || \ +- yr_##bo##16toh(elf_header->sh_entry_count) == 0) \ +- { \ +- return UNDEFINED; \ +- } \ ++ if (yr_##bo##bits##toh(elf_header->ph_offset) == 0 || \ ++ yr_##bo##bits##toh(elf_header->ph_offset) > elf_size || \ ++ yr_##bo##bits##toh(elf_header->ph_offset) + \ ++ ELF_SIZE_OF_PROGRAM_TABLE(bits,bo,elf_header) > elf_size || \ ++ yr_##bo##16toh(elf_header->ph_entry_count) == 0) \ ++ { \ ++ return UNDEFINED; \ ++ } \ + \ +- section = (elf##bits##_section_header_t*) \ +- ((uint8_t*) elf_header + yr_##bo##bits##toh(elf_header->sh_offset)); \ ++ program = (elf##bits##_program_header_t*) \ ++ ((uint8_t*) elf_header + yr_##bo##bits##toh(elf_header->ph_offset)); \ + \ +- for (i = 0; i < yr_##bo##16toh(elf_header->sh_entry_count); i++) \ ++ for (i = 0; i < yr_##bo##16toh(elf_header->ph_entry_count); i++) \ ++ { \ ++ if (rva >= yr_##bo##bits##toh(program->virt_addr) && \ ++ rva < yr_##bo##bits##toh(program->virt_addr) + \ ++ yr_##bo##bits##toh(program->mem_size)) \ ++ { \ ++ return yr_##bo##bits##toh(program->offset) + \ ++ (rva - yr_##bo##bits##toh(program->virt_addr)); \ ++ } \ ++ \ ++ program++; \ ++ } \ ++ } \ ++ else \ + { \ +- if (yr_##bo##32toh(section->type) != ELF_SHT_NULL && \ +- yr_##bo##32toh(section->type) != ELF_SHT_NOBITS && \ +- rva >= yr_##bo##bits##toh(section->addr) && \ +- rva < yr_##bo##bits##toh(section->addr) + \ +- yr_##bo##bits##toh(section->size)) \ ++ int i; \ ++ \ ++ elf##bits##_section_header_t* section; \ ++ \ ++ /* check that sh_offset doesn't wrap when added to SIZE_OF_SECTION_TABLE */\ ++ \ ++ if(ULONG_MAX - yr_##bo##bits##toh(elf_header->sh_offset) < \ ++ ELF_SIZE_OF_SECTION_TABLE(bits,bo,elf_header)) \ + { \ +- return yr_##bo##bits##toh(section->offset) + \ +- (rva - yr_##bo##bits##toh(section->addr)); \ ++ return UNDEFINED; \ + } \ + \ +- section++; \ +- } \ ++ if (yr_##bo##bits##toh(elf_header->sh_offset) == 0 || \ ++ yr_##bo##bits##toh(elf_header->sh_offset) > elf_size || \ ++ yr_##bo##bits##toh(elf_header->sh_offset) + \ ++ ELF_SIZE_OF_SECTION_TABLE(bits,bo,elf_header) > elf_size || \ ++ yr_##bo##16toh(elf_header->sh_entry_count) == 0) \ ++ { \ ++ return UNDEFINED; \ ++ } \ ++ \ ++ section = (elf##bits##_section_header_t*) \ ++ ((uint8_t*) elf_header + yr_##bo##bits##toh(elf_header->sh_offset)); \ + \ ++ for (i = 0; i < yr_##bo##16toh(elf_header->sh_entry_count); i++) \ ++ { \ ++ if (yr_##bo##32toh(section->type) != ELF_SHT_NULL && \ ++ yr_##bo##32toh(section->type) != ELF_SHT_NOBITS && \ ++ rva >= yr_##bo##bits##toh(section->addr) && \ ++ rva < yr_##bo##bits##toh(section->addr) + \ ++ yr_##bo##bits##toh(section->size)) \ ++ { \ ++ return yr_##bo##bits##toh(section->offset) + \ ++ (rva - yr_##bo##bits##toh(section->addr)); \ ++ } \ ++ \ ++ section++; \ ++ } \ ++ } \ + return UNDEFINED; \ + } + +diff --git a/tests/blob.h b/tests/blob.h +index 1659a91..d7a617a 100644 +--- a/tests/blob.h ++++ b/tests/blob.h +@@ -179,6 +179,628 @@ uint8_t ELF64_FILE[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + ++ ++uint8_t ELF32_NOSECTIONS[] = { ++ 0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, ++ 0xa0, 0x80, 0x04, 0x08, 0x34, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x34, 0x00, 0x20, 0x00, 0x02, 0x00, 0x28, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x08, ++ 0x00, 0x80, 0x04, 0x08, 0xac, 0x00, 0x00, 0x00, ++ 0xac, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, ++ 0x00, 0x10, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, ++ 0x74, 0x00, 0x00, 0x00, 0x74, 0x80, 0x04, 0x08, ++ 0x74, 0x80, 0x04, 0x08, 0x24, 0x00, 0x00, 0x00, ++ 0x24, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, ++ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, ++ 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, ++ 0x47, 0x4e, 0x55, 0x00, 0x72, 0x5c, 0x33, 0xa6, ++ 0xcd, 0xed, 0x46, 0xf2, 0xc7, 0xa2, 0x8c, 0x1f, ++ 0xbd, 0x65, 0x7a, 0xd1, 0x9f, 0x0f, 0x51, 0x80, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0xb8, 0x01, 0x00, 0x00, 0x00, 0xbb, 0x2a, 0x00, ++ 0x00, 0x00, 0xcd, 0x80, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ++}; ++ ++uint8_t ELF32_SHAREDOBJ[] = { ++ 0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x03, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, ++ 0xa0, 0x01, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, ++ 0x54, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x34, 0x00, 0x20, 0x00, 0x05, 0x00, 0x28, 0x00, ++ 0x09, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0xac, 0x01, 0x00, 0x00, ++ 0xac, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, ++ 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, ++ 0xa8, 0x0f, 0x00, 0x00, 0xa8, 0x1f, 0x00, 0x00, ++ 0xa8, 0x1f, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, ++ 0x58, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, ++ 0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, ++ 0xa8, 0x0f, 0x00, 0x00, 0xa8, 0x1f, 0x00, 0x00, ++ 0xa8, 0x1f, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, ++ 0x58, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, ++ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, ++ 0xd4, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, ++ 0xd4, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, ++ 0x24, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, ++ 0x04, 0x00, 0x00, 0x00, 0x52, 0xe5, 0x74, 0x64, ++ 0xa8, 0x0f, 0x00, 0x00, 0xa8, 0x1f, 0x00, 0x00, ++ 0xa8, 0x1f, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, ++ 0x58, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, ++ 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, ++ 0x47, 0x4e, 0x55, 0x00, 0x6e, 0x96, 0x9b, 0xbc, ++ 0x8b, 0x0c, 0x9d, 0x95, 0x29, 0xfc, 0x07, 0x04, ++ 0x15, 0x95, 0xc5, 0xf0, 0xb9, 0xd5, 0xcd, 0xae, ++ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, ++ 0x08, 0x44, 0x06, 0x29, 0x01, 0x00, 0x00, 0x00, ++ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x42, 0x45, 0xd5, 0xec, 0xbb, 0xe3, 0x92, 0x7c, ++ 0x32, 0x62, 0xdb, 0xed, 0xd9, 0x71, 0x58, 0x1c, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x07, 0x00, ++ 0x14, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x07, 0x00, ++ 0x0d, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x05, 0x00, ++ 0x08, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x07, 0x00, ++ 0x00, 0x5f, 0x65, 0x64, 0x61, 0x74, 0x61, 0x00, ++ 0x5f, 0x5f, 0x62, 0x73, 0x73, 0x5f, 0x73, 0x74, ++ 0x61, 0x72, 0x74, 0x00, 0x5f, 0x65, 0x6e, 0x64, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0xb8, 0x01, 0x00, 0x00, 0x00, 0xbb, 0x2a, 0x00, ++ 0x00, 0x00, 0xcd, 0x80, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0xf5, 0xfe, 0xff, 0x6f, 0xf8, 0x00, 0x00, 0x00, ++ 0x05, 0x00, 0x00, 0x00, 0x78, 0x01, 0x00, 0x00, ++ 0x06, 0x00, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00, ++ 0x0a, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, ++ 0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x2e, 0x73, 0x68, 0x73, 0x74, 0x72, 0x74, ++ 0x61, 0x62, 0x00, 0x2e, 0x6e, 0x6f, 0x74, 0x65, ++ 0x2e, 0x67, 0x6e, 0x75, 0x2e, 0x62, 0x75, 0x69, ++ 0x6c, 0x64, 0x2d, 0x69, 0x64, 0x00, 0x2e, 0x67, ++ 0x6e, 0x75, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x00, ++ 0x2e, 0x64, 0x79, 0x6e, 0x73, 0x79, 0x6d, 0x00, ++ 0x2e, 0x64, 0x79, 0x6e, 0x73, 0x74, 0x72, 0x00, ++ 0x2e, 0x74, 0x65, 0x78, 0x74, 0x00, 0x2e, 0x65, ++ 0x68, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x00, ++ 0x2e, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, ++ 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, ++ 0xd4, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, ++ 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, ++ 0xf6, 0xff, 0xff, 0x6f, 0x02, 0x00, 0x00, 0x00, ++ 0xf8, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, ++ 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, ++ 0x04, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, ++ 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, ++ 0x28, 0x01, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00, ++ 0x50, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, ++ 0x10, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, ++ 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, ++ 0x78, 0x01, 0x00, 0x00, 0x78, 0x01, 0x00, 0x00, ++ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, ++ 0xa0, 0x01, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, ++ 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, ++ 0xac, 0x01, 0x00, 0x00, 0xac, 0x01, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, ++ 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, ++ 0xa8, 0x1f, 0x00, 0x00, 0xa8, 0x0f, 0x00, 0x00, ++ 0x58, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, ++ 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, ++ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, ++ 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00 ++}; ++ ++ + uint8_t ELF32_MIPS_FILE[] = { + 0x7f, 0x45, 0x4c, 0x46, 0x01, 0x02, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +@@ -332,4 +954,5 @@ uint8_t ELF32_MIPS_FILE[] = { + 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00 +-}; +\ No newline at end of file ++}; ++ +diff --git a/tests/test-elf.c b/tests/test-elf.c +index 6415933..062f417 100644 +--- a/tests/test-elf.c ++++ b/tests/test-elf.c +@@ -24,6 +24,12 @@ int main(int argc, char** argv) + condition: $a at elf.entry_point }", + ELF64_FILE); + ++ assert_true_rule_blob( ++ "import \"elf\" rule test { condition: elf.entry_point == 0xa0 }", ELF32_NOSECTIONS); ++ ++ assert_true_rule_blob( ++ "import \"elf\" rule test { condition: elf.entry_point == 0x1a0 }", ELF32_SHAREDOBJ); ++ + assert_true_rule_blob("import \"elf\" rule test { \ + condition: elf.sections[2].name == \".comment\" }", ELF64_FILE); + +@@ -46,5 +52,4 @@ int main(int argc, char** argv) + elf.segments[i].file_size == 0xe0)}", ELF32_MIPS_FILE); + + yr_finalize(); +- return 0; + } + +From a2d40e616b831fbd81628479de7b62de306c8db1 Mon Sep 17 00:00:00 2001 +From: plusvic +Date: Wed, 8 Mar 2017 16:56:17 +0100 +Subject: [PATCH 32/36] Fix issue #516 + +(cherry-picked from commit 2a36c168bb2097c0831d4ddf24a6c04bafe28dca) +--- + libyara/compiler.c | 7 +++++++ + libyara/hash.c | 3 +++ + libyara/include/yara/error.h | 1 + + libyara/parser.c | 21 +++++++++++++++++---- + 4 files changed, 28 insertions(+), 4 deletions(-) + +diff --git a/libyara/compiler.c b/libyara/compiler.c +index 4c0fdeb..9bbaa51 100644 +--- a/libyara/compiler.c ++++ b/libyara/compiler.c +@@ -914,6 +914,13 @@ YR_API char* yr_compiler_get_error_message( + "unknown module \"%s\"", + compiler->last_error_extra_info); + break; ++ case ERROR_INVALID_MODULE_NAME: ++ snprintf( ++ buffer, ++ buffer_size, ++ "invalid module name \"%s\"", ++ compiler->last_error_extra_info); ++ break; + case ERROR_DUPLICATED_STRUCTURE_MEMBER: + snprintf(buffer, + buffer_size, +diff --git a/libyara/hash.c b/libyara/hash.c +index 1ce2a53..5e5d8e9 100644 +--- a/libyara/hash.c ++++ b/libyara/hash.c +@@ -27,6 +27,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + ++#include + #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 a5476b0..67e4bdb 100644 +--- a/libyara/include/yara/error.h ++++ b/libyara/include/yara/error.h +@@ -88,6 +88,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #define ERROR_COULD_NOT_READ_PROCESS_MEMORY 47 + #define ERROR_INVALID_EXTERNAL_VARIABLE_TYPE 48 + #define ERROR_REGULAR_EXPRESSION_TOO_COMPLEX 49 ++#define ERROR_INVALID_MODULE_NAME 50 + + + #define FAIL_ON_ERROR(x) { \ +diff --git a/libyara/parser.c b/libyara/parser.c +index 9c99e17..95f5b37 100644 +--- a/libyara/parser.c ++++ b/libyara/parser.c +@@ -963,6 +963,19 @@ YR_META* yr_parser_reduce_meta_declaration( + } + + ++int _yr_parser_valid_module_name( ++ SIZED_STRING* module_name) ++{ ++ if (module_name->length == 0) ++ return FALSE; ++ ++ if (strlen(module_name->c_string) != module_name->length) ++ return FALSE; ++ ++ return TRUE; ++} ++ ++ + int yr_parser_reduce_import( + yyscan_t yyscanner, + SIZED_STRING* module_name) +@@ -972,12 +985,12 @@ int yr_parser_reduce_import( + + char* name; + +- if (module_name->length == 0) ++ if (!_yr_parser_valid_module_name(module_name)) + { +- compiler->last_result = ERROR_UNKNOWN_MODULE; +- yr_compiler_set_error_extra_info(compiler, ""); ++ compiler->last_result = ERROR_INVALID_MODULE_NAME; ++ yr_compiler_set_error_extra_info(compiler, module_name->c_string); + +- return ERROR_UNKNOWN_MODULE; ++ return ERROR_INVALID_MODULE_NAME; + } + + module_structure = (YR_OBJECT*) yr_hash_table_lookup( + +From f4003355bf05daf84cface923d9a21d399a1a9d5 Mon Sep 17 00:00:00 2001 +From: Jacob Baines +Date: Thu, 16 Mar 2017 08:38:51 -0700 +Subject: [PATCH 33/36] Fix ELF module issues on big endian system (#618) + +(cherry picked from commit 75dba10e60313d5dd44548b6f60f1386320556c7) +--- + libyara/exefiles.c | 16 ++++++++++------ + libyara/modules/elf.c | 8 ++++---- + 2 files changed, 14 insertions(+), 10 deletions(-) + +diff --git a/libyara/exefiles.c b/libyara/exefiles.c +index 293b905..5cac047 100644 +--- a/libyara/exefiles.c ++++ b/libyara/exefiles.c +@@ -157,11 +157,12 @@ static uint64_t yr_elf_rva_to_offset_32( + { + // if the binary is an executable then prefer the program headers to resolve + // the offset +- if (elf_header->type == ELF_ET_EXEC) ++ if (yr_le16toh(elf_header->type) == ELF_ET_EXEC) + { + int i; + elf32_program_header_t* program; +- if (elf_header->ph_offset == 0 || elf_header->ph_entry_count == 0) ++ if (yr_le32toh(elf_header->ph_offset) == 0 || ++ yr_le16toh(elf_header->ph_entry_count == 0)) + return 0; + + // check to prevent integer wraps +@@ -199,7 +200,8 @@ static uint64_t yr_elf_rva_to_offset_32( + int i; + elf32_section_header_t* section; + +- if (elf_header->sh_offset == 0 || elf_header->sh_entry_count == 0) ++ if (yr_le32toh(elf_header->sh_offset) == 0 || ++ yr_le16toh(elf_header->sh_entry_count == 0)) + return 0; + + // check to prevent integer wraps +@@ -253,11 +255,12 @@ static uint64_t yr_elf_rva_to_offset_64( + { + // if the binary is an executable then prefer the program headers to resolve + // the offset +- if (elf_header->type == ELF_ET_EXEC) ++ if (yr_le16toh(elf_header->type) == ELF_ET_EXEC) + { + int i; + elf64_program_header_t* program; +- if (elf_header->ph_offset == 0 || elf_header->ph_entry_count == 0) ++ if (yr_le64toh(elf_header->ph_offset) == 0 || ++ yr_le16toh(elf_header->ph_entry_count == 0)) + return 0; + + // check that 'ph_offset' doesn't wrap when added to the +@@ -290,7 +293,8 @@ static uint64_t yr_elf_rva_to_offset_64( + int i; + elf64_section_header_t* section; + +- if (elf_header->sh_offset == 0 || elf_header->sh_entry_count == 0) ++ if (yr_le64toh(elf_header->sh_offset) == 0 || ++ yr_le16toh(elf_header->sh_entry_count) == 0) + return 0; + + // check that 'sh_offset' doesn't wrap when added to the +diff --git a/libyara/modules/elf.c b/libyara/modules/elf.c +index 8ea6c94..a4f7568 100644 +--- a/libyara/modules/elf.c ++++ b/libyara/modules/elf.c +@@ -72,7 +72,7 @@ uint64_t elf_rva_to_offset_##bits##_##bo( \ + uint64_t rva, \ + size_t elf_size) \ + { \ +- if (elf_header->type == ELF_ET_EXEC) \ ++ if (yr_##bo##16toh(elf_header->type) == ELF_ET_EXEC) \ + { \ + int i; \ + \ +@@ -224,12 +224,12 @@ void parse_elf_header_##bits##_##bo( \ + set_integer(yr_##bo##bits##toh(section->offset), elf_obj, \ + "sections[%i].offset", i); \ + \ +- if (yr_##bo##bits##toh(section->name) < elf_size && \ ++ if (yr_##bo##32toh(section->name) < elf_size && \ + str_table > (char*) elf && \ +- str_table + yr_##bo##bits##toh(section->name) < \ ++ str_table + yr_##bo##32toh(section->name) < \ + (char*) elf + elf_size) \ + { \ +- set_string(str_table + yr_##bo##bits##toh(section->name), elf_obj, \ ++ set_string(str_table + yr_##bo##32toh(section->name), elf_obj, \ + "sections[%i].name", i); \ + } \ + \ + +From 3aa1d8ae08a07bdbde992f03edb8322d6cf6ad2c Mon Sep 17 00:00:00 2001 +From: plusvic +Date: Thu, 16 Mar 2017 16:38:16 +0100 +Subject: [PATCH 34/36] Add missing endianness conversions + +(cherry picked from commit b6851ea05bfcc7938101aff26f48094cba3e07f5) +--- + libyara/modules/pe.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/libyara/modules/pe.c b/libyara/modules/pe.c +index f78a9d5..1c90a6a 100644 +--- a/libyara/modules/pe.c ++++ b/libyara/modules/pe.c +@@ -542,7 +542,7 @@ void pe_parse_version_info( + yr_le16toh(string->Length) != 0 && + string < string_table) + { +- if (string->ValueLength > 0) ++ if (yr_le16toh(string->ValueLength) > 0) + { + char* string_value = (char*) ADD_OFFSET(string, + sizeof(VERSION_INFO) + 2 * (strnlen_w(string->Key) + 1)); +@@ -559,7 +559,7 @@ void pe_parse_version_info( + } + } + +- string = ADD_OFFSET(string, string->Length); ++ string = ADD_OFFSET(string, yr_le16toh(string->Length)); + } + } + } +@@ -953,7 +953,9 @@ void pe_parse_certificates( + } + + // Store the end of directory, making comparisons easier. +- eod = pe->data + yr_le32toh(directory->VirtualAddress) + directory->Size; ++ eod = pe->data + \ ++ yr_le32toh(directory->VirtualAddress) + \ ++ yr_le32toh(directory->Size); + + win_cert = (PWIN_CERTIFICATE) \ + (pe->data + yr_le32toh(directory->VirtualAddress)); +@@ -1137,7 +1139,10 @@ void pe_parse_certificates( + counter++; + } + +- uintptr_t end = (uintptr_t)((uint8_t *) win_cert) + win_cert->Length; ++ uintptr_t end = \ ++ (uintptr_t)((uint8_t *) win_cert) + \ ++ yr_le32toh(win_cert->Length); ++ + win_cert = (PWIN_CERTIFICATE)(end + (end % 8)); + + BIO_free(cert_bio); +@@ -1777,7 +1782,7 @@ static uint64_t rich_internal( + + for (i = 0; i < rich_count; i++) + { +- DWORD id_version = clear_rich_signature->versions[i].id_version; ++ DWORD id_version = yr_le32toh(clear_rich_signature->versions[i].id_version); + + int match_version = (version == RICH_VERSION_VERSION(id_version)); + int match_toolid = (toolid == RICH_VERSION_ID(id_version)); + +From f6553648f19ed33d9a1bbdcf9f458215e50d35a8 Mon Sep 17 00:00:00 2001 +From: Jacob Baines +Date: Mon, 20 Mar 2017 02:17:24 -0700 +Subject: [PATCH 35/36] Linux Memory Scan Can Leave Process In Stopped State + (#622) + +* Wait for process to stop + +* Specify which process to wait for + +(cherry picked from commit 68ffbbcdc992e3f1969d0aa37d3d0b1568b5514b) +--- + libyara/proc.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/libyara/proc.c b/libyara/proc.c +index 21c21cb..5879b44 100644 +--- a/libyara/proc.c ++++ b/libyara/proc.c +@@ -352,6 +352,7 @@ int _yr_process_attach( + int pid, + YR_PROC_ITERATOR_CTX* context) + { ++ int status; + char buffer[256]; + + context->pid = pid; +@@ -386,6 +387,22 @@ int _yr_process_attach( + return ERROR_COULD_NOT_ATTACH_TO_PROCESS; + } + ++ status = 0; ++ if (waitpid(pid, &status, 0) == -1) ++ { ++ // this is a strange error state where we attached but the proc didn't ++ // stop. Try to detach and clean up. ++ ptrace(PTRACE_DETACH, context->pid, NULL, 0); ++ ++ fclose(context->maps); ++ context->maps = NULL; ++ ++ close(context->mem_fd); ++ context->mem_fd = -1; ++ ++ return ERROR_COULD_NOT_ATTACH_TO_PROCESS; ++ } ++ + return ERROR_SUCCESS; + } + + +From 62ad5a701b04d0fa955ef5593bcd7ec789d1241e Mon Sep 17 00:00:00 2001 +From: plusvic +Date: Fri, 23 Sep 2016 12:03:30 +0200 +Subject: [PATCH 36/36] Add appveyor config file + +(cherry picked from commit b254eeef98a7042b6df28b3432c065860583e8cc) +--- + appveyor.yml | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + create mode 100644 appveyor.yml + +diff --git a/appveyor.yml b/appveyor.yml +new file mode 100644 +index 0000000..2ba177b +--- /dev/null ++++ b/appveyor.yml +@@ -0,0 +1,15 @@ ++# AppVeyor CI for Windows ++ ++version: 3.5.{build} ++pull_requests: ++ do_not_increment_build_number: true ++configuration: Release ++platform: ++- x64 ++- x86 ++before_build: ++- ps: nuget restore windows/vs2015/yara.sln ++build: ++ project: windows/vs2015/yara.sln ++ verbosity: minimal ++test: off diff --git a/yara.spec b/yara.spec index 2da48b6..e05dc05 100644 --- a/yara.spec +++ b/yara.spec @@ -1,49 +1,57 @@ Name: yara -Version: 4.5.8 +Version: 4.1.3 +Release: 1%{?dist} Summary: Pattern matching Swiss knife for malware researchers -URL: https://VirusTotal.github.io/yara/ -VCS: git:https://github.com/VirusTotal/yara/ -# https://github.com/VirusTotal/yara/releases -# yara package itself is licensed with BSD 3 clause license -# bison grammar parsers in libyara/* are licensed with GPLv3+ license with exception from FSF alloving usage in larger work -# resulting binary package licensed as BSD -License: BSD-3-Clause - -%global common_description %{expand: -YARA is a tool aimed at (but not limited to) helping malware researchers to -identify and classify malware samples. With YARA you can create descriptions -of malware families (or whatever you want to describe) based on textual or -binary patterns. Each description, a.k.a rule, consists of a set of strings -and a Boolean expression which determine its logic.} +# yara package itself is licensed as ASL 2.0 +# bison grammar parsers in libyara/* are dual licensed under ASL 2.0 and GPLv3+ license. +# resulting binary package licensed as ASL 2.0 +License: ASL 2.0 +VCS: http://github.com/VirusTotal/yara/ +# http://github.com/VirusTotal/yara/releases +URL: http://VirusTotal.github.io/yara/ %global gituser VirusTotal %global gitname yara -# Commit of version 4.5.8 -%global gitdate 20260728 -%global commit 84b0e3cc0e42f8f8e6b84d19c97ec3ac6ff8aee8 +# Commit of version 4.1.1 +%global commit 8206dc6f728fe50e21af92cb40e454b68ef6af05 %global shortcommit %(c=%{commit}; echo ${c:0:7}) -%bcond_without release +# additional module for yara +%global androguard_gituser Koodous +%global androguard_gitname androguard-yara +# Commit from 2020-04-22 +%global androguard_commit 3eea86ae2c4ee6ad3cc1cb3c2711b03db078831a +%global androguard_shortcommit %(c=%{androguard_commit}; echo ${c:0:7}) +%global androguard_gitdate 2020-04-22 - -# Build from git release version -%if %{with release} -Release: %autorelease -# Source0: https://github.com/%%{gituser}/%%{gitname}/archive/v%%{upversion}.tar.gz#/%%{name}-%%{upversion}.tar.gz -Source0: https://github.com/%{gituser}/%{gitname}/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz -%else # Build from git commit baseline -Release: %autorelease -s %{gitdate}git%{shortcommit} -Source0: https://github.com/%{gituser}/%{gitname}/archive/%{commit}/%{name}-%{version}-git%{gitdate}-%{shortcommit}.tar.gz -%endif +#Source0: https://github.com/%%{gituser}/%%{gitname}/archive/%%{commit}/%%{name}-%%{version}-%%{shortcommit}.tar.gz +# Build from git release version +Source0: https://github.com/%{gituser}/%{gitname}/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz + +# http://github.com/Koodous/androguard-yara/ +Source1: https://github.com/%{androguard_gituser}/%{androguard_gitname}/archive/%{androguard_commit}/%{androguard_gitname}-%{androguard_gitdate}-%{androguard_shortcommit}.tar.gz + +# Patch based on the androguard-yara installation guide to enable the androguard module +Patch0: yara-androguard.patch # Use default sphix theme to generate documentation rather than sphinx_rtd_theme # to avoid static installation of font files on fedora >= 24 Patch1: yara-docs-theme.patch -# OpenSSL 4 build fixes -Patch2: 0001-Use-OpenSSL-accessor-functions-for-ASN1_STRING.patch + +# Fixed in 3.6.0 upstream +# Patch https://patch-diff.githubusercontent.com/raw/VirusTotal/yara/pull/627.patch +# Fixes: CVE-2016-10210 CVE-2016-10211 CVE-2017-5923 CVE-2017-5924 +# Patch2: %%{name}-pull627.patch + +# API of yr_re_match changed, fix needed for Androguard +# https://github.com/Koodous/androguard-yara/issues/8 +# merged in https://github.com/Koodous/androguard-yara/commit/034f0a49e58d798abcaa28c9864451da9da29413 +# Patch3: yara-androguard-matchapi.patch + + BuildRequires: git BuildRequires: gcc @@ -54,29 +62,30 @@ BuildRequires: binutils BuildRequires: coreutils BuildRequires: sharutils BuildRequires: file -BuildRequires: sed BuildRequires: gawk BuildRequires: gzip BuildRequires: xz +BuildRequires: pcre BuildRequires: bison BuildRequires: flex BuildRequires: libtool BuildRequires: file-devel -BuildRequires: jansson-devel >= 2.5 +#jansson is in version 2.4 in epel +#BuildRequires: jansson-devel >= 2.5 +BuildRequires: openssl-devel BuildRequires: protobuf-c-devel BuildRequires: protobuf-compiler -%if 0%{?rhel} && 0%{?rhel} == 7 -BuildRequires: openssl11-devel -%else -BuildRequires: openssl-devel -%endif - # html doc generation BuildRequires: /usr/bin/sphinx-build %description -%{common_description} +YARA is a tool aimed at (but not limited to) helping malware researchers to +identify and classify malware samples. With YARA you can create descriptions +of malware families (or whatever you want to describe) based on textual or +binary patterns. Each description, a.k.a rule, consists of a set of strings +and a Boolean expression which determine its logic. + %package doc Summary: Documentation for %{name} @@ -84,7 +93,6 @@ BuildArch: noarch %description doc This package contains documentation for %{name}. -%{common_description} %package devel @@ -95,27 +103,36 @@ Requires: %{name}%{?_isa} = %{version}-%{release} %description devel The %{name}-devel package contains libraries and header files for developing applications that use %{name}. -%{common_description} + %prep -%if %{with release} - %autosetup -n %{gitname}-%{version} -p 1 -S git -%else - %autosetup -n %{gitname}-%{commit} -p 1 -S git -%endif +# autosetup -n %%{gitname}-%%{commit} -p 1 -S git +%autosetup -p 1 -S git + +# Add the Androguard module +# %%setup -qn %%{gitname}-%%{commit} -a 1 -D -T +%setup -q -a 1 -D -T +pushd %{androguard_gitname}-%{androguard_commit} + +mkdir -p ../libyara/modules/androguard +cp -p androguard.c ../libyara/modules/androguard/ +popd + + autoreconf --force --install + %build -# Add missing protobuf definition on RHEL7, and also configure for the libcrypto11/openssl11 from EPEL +# Add missing definition on RHEL7 %if 0%{?rhel} && 0%{?rhel} == 7 -export CFLAGS="%{optflags} -D PROTOBUF_C_FIELD_FLAG_ONEOF=4 $(pkg-config --cflags libcrypto11)" -export LDFLAGS="$LDFLAGS $(pkg-config --libs libcrypto11)" +export CFLAGS="$CFLAGS -D PROTOBUF_C_FIELD_FLAG_ONEOF=4" %endif -# macro %%configure already does use CFLAGS="%%{optflags}" and yara build +# macro %%configure already does use CFLAGS="\{optflags}" and yara build # scripts configure/make already honors that CFLAGS -%configure --enable-magic --enable-cuckoo --enable-debug --enable-dotnet \ +# jansson >= 2.5 not available in EPEL7 thus building without cuckoo support +%configure --enable-magic --enable-debug --enable-dotnet \ --enable-macho --enable-dex --enable-pb-tests \ --with-crypto \ --htmldir=%{_datadir}/doc/%{name}/html @@ -142,28 +159,6 @@ rm -f %{buildroot}%{_datadir}/doc/%{name}/html/.buildinfo %ldconfig_scriptlets %endif -%check -# reenable the validation of SHA1 certificates in OPENSSL (RHEL9 disabled that by default) -export OPENSSL_ENABLE_SHA1_SIGNATURES=yes -make check || ( - # print more verbose info in case the test(s) fail - echo "===== ./test-suite.log" - [ -f ./test-suite.log ] && cat ./test-suite.log - # Build in COPR lacking the hwinfo.log - echo "===== /proc/cpu" - head -n 35 /proc/cpuinfo - echo "===== /etc/os-release" - cat /etc/os-release - echo "===== uname -a" - uname -a - -%ifarch s390x - # test-pe and test-dotnet fails for x390x at this point - ignored for rc1 - true -%else - false -%endif -) %files %license COPYING @@ -188,4 +183,158 @@ make check || ( %changelog -%autochangelog +* Wed Nov 10 2021 Michal Ambroz - 4.1.3-1 +- bump to 4.1.3 + +* Sat Nov 06 2021 Adrian Reber - 4.1.1-5 +- Rebuilt for protobuf 3.19.0 + +* Mon Oct 25 2021 Adrian Reber - 4.1.1-4 +- Rebuilt for protobuf 3.18.1 + +* Tue Sep 14 2021 Sahana Prasad - 4.1.1-3 +- Rebuilt with OpenSSL 3.0.0 + +* Fri Jul 23 2021 Fedora Release Engineering - 4.1.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Mon May 24 2021 Michal Ambroz - 4.1.1-1 +- bump to 4.1.1 + +* Mon Apr 26 2021 Michal Ambroz - 4.1.0-1 +- bump to 4.1.0 + +* Sun Apr 25 2021 Michal Ambroz - 4.0.5-2 +- rebuild for epel + +* Fri Feb 5 2021 Michal Ambroz - 4.0.5-1 +- bump to yara bugfix 4.0.5 release + +* Wed Feb 3 2021 Michal Ambroz - 4.0.4-1 +- bump to yara bugfix 4.0.4 release + +* Thu Jul 16 2020 Michal Ambroz - 4.0.2-1 +- bump to yara bugfix 4.0.2 release +- fix build on epel7 + +* Sun Jun 14 2020 Adrian Reber - 4.0.1-2 +- Rebuilt for protobuf 3.12 + +* Tue Jun 2 2020 Michal Ambroz - 4.0.1-1 +- bump to yara bugfix 4.0.1 release + +* Tue Apr 28 2020 Michal Ambroz - 4.0.0-1 +- bump to yara 4.0.0 release + +* Fri Jan 31 2020 Fedora Release Engineering - 3.11.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Fri Oct 11 2019 Michal Ambroz - 3.11.0-1 +- bump to 3.11.0 release (#1760678) +- BUGFIX: Some regexp character classes not matching correctly when used with “nocase” modifier (upstream #1117) +- BUGFIX: Reduce the number of ERROR_TOO_MANY_RE_FIBERS errors for certain hex pattern containing large jumps (upstream #1107) +- BUGFIX: Buffer overrun in “dotnet” module (upstream #1108) +- BUGFIX: Memory leak while attaching to a process fails (upstream #1070) + +* Sat Sep 28 2019 Michal Ambroz - 3.10.0-3 +- change the sphinx build dependency + +* Sat Jul 27 2019 Fedora Release Engineering - 3.10.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Fri May 03 2019 Michal Ambroz - 3.10.0-1 +- bump to 3.10.0 release (#1680204) +- Harden virtual machine against malicious code. +- BUGFIX: Regression bug in hex strings containing wildcards (upstream #1025). +- BUGFIX: Buffer overrun in “elf” module. +- BUGFIX: Buffer overrun in “dotnet” module. + +* Sat Mar 16 2019 Michal Ambroz - 3.9.0-1 +- bump to 3.9.0 release (#1680203) +- switch from python-sphinx to python3-sphinx for generating the documentation for fc31+ +- should fix also #1660398 (CVE-2018-19974 CVE-2018-19975 CVE-2018-19976), + but by design it might be always dangerous to run yara signatures compiled by 3rd party, + so it is advised to re-compile yara rules instead +- BUGFIX: Denial of service when using "dex" module. Found by the Cisco Talos team. (upstream #1023, CVE-2019-5020) +- BUGFIX: Buffer overflow in "dotnet" module. +- BUGFIX: Regexp regression when using nested quantifiers {x,y} for certain values of x and y. (#1018) + +* Sun Feb 03 2019 Fedora Release Engineering - 3.8.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Mon Aug 27 2018 Michal Ambroz - 3.8.1-1 +- bump to 3.8.1 release (#1613093) + +* Sat Jul 14 2018 Fedora Release Engineering - 3.7.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Fri Feb 09 2018 Fedora Release Engineering - 3.7.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Mon Feb 05 2018 Michal Ambroz - 3.7.1-1 +- bump to 3.7.1 release (#1534993) + +* Wed Nov 15 2017 Michal Ambroz - 3.7.0-1 +- bump to 3.7.0 release (#1511921) + +* Thu Aug 03 2017 Fedora Release Engineering - 3.6.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Thu Jul 27 2017 Fedora Release Engineering - 3.6.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Sun Jul 16 2017 Michal Ambroz - 3.6.3-1 +- bump to 3.6.3 release - bugfix CVE-2017-11328 + +* Mon Jul 03 2017 Michal Ambroz - 3.6.2-1 +- bump to 3.6.2 release - bugfix CVE-2017-9304, CVE-2017-9465 + +* Wed May 24 2017 Michal Ambroz - 3.6.0-1 +- bump to 3.6.0 release +- update the androguard-yara with bugfixes + +* Thu Apr 13 2017 Michal Ambroz - 3.5.0-7 +- Adding patch from pull request 627 until 3.5.1 is released +- https://patch-diff.githubusercontent.com/raw/VirusTotal/yara/pull/627.patch +- Fixes CVE-2016-10210 CVE-2016-10211 CVE-2017-5923 CVE-2017-5924 + +* Sat Feb 11 2017 Fedora Release Engineering - 3.5.0-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Tue Aug 09 2016 Michal Ambroz - 3.5.0-5 +- import package to Fedora +- remove unnecessary .buildinfo tag from doc package + +* Fri Aug 05 2016 Michal Ambroz - 3.5.0-4 +- package review - bugzilla #1362265 +- cosmetics of the changelog +- using default spinx theme to remove the static fonts + +* Fri Aug 05 2016 Michal Ambroz - 3.5.0-3 +- package review - bugzilla #1362265 +- dropped Buildroot, pkgconfig, zlib-devel, defattr +- added buildrequires gcc +- change license back to ASL 2.0 only + +* Thu Aug 04 2016 Michal Ambroz - 3.5.0-2 +- package review - bugzilla #1362265 +- changed packaging of doc sub-package + +* Thu Aug 04 2016 Michal Ambroz - 3.5.0-1 +- bump to new 3.5.0 + +* Wed Aug 03 2016 Michal Ambroz - 3.4.0-6 +- package review - bugzilla #1362265 +- dropped dependency of python-tools + +* Mon Aug 01 2016 Michal Ambroz - 3.4.0-4 +- compile with the androguard module + +* Wed Jun 08 2016 Michal Ambroz - 3.4.0-2 +- jansson dependency >= 2.5 + +* Wed Jun 08 2016 Michal Ambroz - 3.4.0-1 +- python3 stuff + +* Mon Jun 22 2015 Michal Ambroz - 3.4.0-0.git20150618 +- initial build for Fedora Project