[Forensics-changes] [yara] 191/407: Fix false positive in "fullword" matches when string is declared both "ascii" and "wide"

Hilko Bengen bengen at moszumanska.debian.org
Sat Jul 1 10:28:24 UTC 2017


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

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

commit 395daece2d403cb264dd7fbee857f20ee3f39ee7
Author: Victor M. Alvarez <plusvic at gmail.com>
Date:   Tue Nov 4 10:57:42 2014 +0100

    Fix false positive in "fullword" matches when string is declared both "ascii" and "wide"
    
    Also improved detection of strings fitting in atoms and removed redundant code for "fullword" handling.
---
 libyara/atoms.c              | 29 --------------------
 libyara/include/yara/atoms.h |  4 ---
 libyara/parser.c             |  2 +-
 libyara/scan.c               | 63 ++++++++++++--------------------------------
 yara-python/tests.py         | 19 +++++++++++++
 5 files changed, 37 insertions(+), 80 deletions(-)

diff --git a/libyara/atoms.c b/libyara/atoms.c
index 84119ed..a5b3ace 100644
--- a/libyara/atoms.c
+++ b/libyara/atoms.c
@@ -182,35 +182,6 @@ int yr_atoms_min_quality(
 
 
 //
-// yr_atoms_min_length
-//
-// Returns the length for the shortest atom in a list.
-//
-
-int yr_atoms_min_length(
-    YR_ATOM_LIST_ITEM* atom_list)
-{
-  YR_ATOM_LIST_ITEM* atom;
-
-  int min_length = 100000;
-
-  if (atom_list == NULL)
-    return 0;
-
-  atom = atom_list;
-
-  while (atom != NULL)
-  {
-    if (atom->atom_length < min_length)
-      min_length = atom->atom_length;
-
-    atom = atom->next;
-  }
-
-  return min_length;
-}
-
-//
 // _yr_atoms_tree_node_create
 //
 // Creates a new node for an atoms tree.
diff --git a/libyara/include/yara/atoms.h b/libyara/include/yara/atoms.h
index 68c34b1..f2ebed6 100644
--- a/libyara/include/yara/atoms.h
+++ b/libyara/include/yara/atoms.h
@@ -83,10 +83,6 @@ int yr_atoms_min_quality(
     YR_ATOM_LIST_ITEM* atom_list);
 
 
-int yr_atoms_min_length(
-    YR_ATOM_LIST_ITEM* atom_list);
-
-
 void yr_atoms_list_destroy(
     YR_ATOM_LIST_ITEM* list_head);
 
diff --git a/libyara/parser.c b/libyara/parser.c
index 99cb882..e1d340a 100644
--- a/libyara/parser.c
+++ b/libyara/parser.c
@@ -382,7 +382,7 @@ int _yr_parser_write_string(
     else
       max_string_len = (*string)->length;
 
-    if (max_string_len == yr_atoms_min_length(atom_list))
+    if (max_string_len <= MAX_ATOM_LENGTH)
       (*string)->g_flags |= STRING_GFLAGS_FITS_IN_ATOM;
   }
 
diff --git a/libyara/scan.c b/libyara/scan.c
index 0b38928..0065ed1 100644
--- a/libyara/scan.c
+++ b/libyara/scan.c
@@ -740,10 +740,7 @@ int _yr_scan_verify_literal_match(
 
   if (STRING_FITS_IN_ATOM(string))
   {
-    if (STRING_IS_WIDE(string))
-      forward_matches = string->length * 2;
-    else
-      forward_matches = string->length;
+    forward_matches = ac_match->backtrack;
   }
   else if (STRING_IS_NO_CASE(string))
   {
@@ -786,52 +783,26 @@ int _yr_scan_verify_literal_match(
     }
   }
 
-  if (forward_matches > 0)
-  {
-    if (STRING_IS_FULL_WORD(string))
-    {
-      if (STRING_IS_WIDE(string))
-      {
-        if (offset >= 2 &&
-            *(data + offset - 1) == 0 &&
-            isalnum(*(data + offset - 2)))
-          return ERROR_SUCCESS;
-
-        if (offset + forward_matches + 1 < data_size &&
-            *(data + offset + forward_matches + 1) == 0 &&
-            isalnum(*(data + offset + forward_matches)))
-          return ERROR_SUCCESS;
-      }
-      else
-      {
-        if (offset >= 1 &&
-            isalnum(*(data + offset - 1)))
-          return ERROR_SUCCESS;
-
-        if (offset + forward_matches < data_size &&
-            isalnum(*(data + offset + forward_matches)))
-          return ERROR_SUCCESS;
-      }
-    }
+  if (forward_matches == 0)
+    return ERROR_SUCCESS;
 
-    if (STRING_IS_WIDE(string))
-      flags |= RE_FLAGS_WIDE;
+  if (forward_matches == string->length * 2)
+    flags |= RE_FLAGS_WIDE;
 
-    if (STRING_IS_NO_CASE(string))
-      flags |= RE_FLAGS_NO_CASE;
+  if (STRING_IS_NO_CASE(string))
+    flags |= RE_FLAGS_NO_CASE;
 
-    callback_args.string = string;
-    callback_args.data = data;
-    callback_args.data_size = data_size;
-    callback_args.data_base = data_base;
-    callback_args.matches_arena = matches_arena;
-    callback_args.forward_matches = forward_matches;
-    callback_args.full_word = STRING_IS_FULL_WORD(string);
-    callback_args.tidx = yr_get_tidx();
+  callback_args.string = string;
+  callback_args.data = data;
+  callback_args.data_size = data_size;
+  callback_args.data_base = data_base;
+  callback_args.matches_arena = matches_arena;
+  callback_args.forward_matches = forward_matches;
+  callback_args.full_word = STRING_IS_FULL_WORD(string);
+  callback_args.tidx = yr_get_tidx();
 
-    FAIL_ON_ERROR(_yr_scan_match_callback(
-        data + offset, 0, flags, &callback_args));
-  }
+  FAIL_ON_ERROR(_yr_scan_match_callback(
+      data + offset, 0, flags, &callback_args));
 
   return ERROR_SUCCESS;
 }
diff --git a/yara-python/tests.py b/yara-python/tests.py
index 9ec5a63..1af2781 100644
--- a/yara-python/tests.py
+++ b/yara-python/tests.py
@@ -320,6 +320,7 @@ class TestYara(unittest.TestCase):
 
         self.assertTrueRules([
             'rule test { strings: $a = "a" condition: $a }',
+            'rule test { strings: $a = "ab" condition: $a }',
             'rule test { strings: $a = "abc" condition: $a }',
             'rule test { strings: $a = "xyz" condition: $a }',
             'rule test { strings: $a = "abc" nocase fullword condition: $a }',
@@ -327,11 +328,21 @@ class TestYara(unittest.TestCase):
             'rule test { strings: $a = "abc" fullword condition: $a }',
         ], "---- abc ---- xyz")
 
+        self.assertFalseRules([
+            'rule test { strings: $a = "a" fullword condition: $a }',
+            'rule test { strings: $a = "ab" fullword condition: $a }',
+            'rule test { strings: $a = "abc" wide fullword condition: $a }',
+        ], "---- abc ---- xyz")
+
         self.assertTrueRules([
             'rule test { strings: $a = "a" wide condition: $a }',
+            'rule test { strings: $a = "a" wide ascii condition: $a }',
+            'rule test { strings: $a = "ab" wide condition: $a }',
+            'rule test { strings: $a = "ab" wide ascii condition: $a }',
             'rule test { strings: $a = "abc" wide condition: $a }',
             'rule test { strings: $a = "abc" wide nocase fullword condition: $a }',
             'rule test { strings: $a = "aBc" wide nocase condition: $a }',
+            'rule test { strings: $a = "aBc" wide ascii nocase condition: $a }',
             'rule test { strings: $a = "---xyz" wide nocase condition: $a }'
         ], "---- a\x00b\x00c\x00 -\x00-\x00-\x00-\x00x\x00y\x00z\x00")
 
@@ -351,6 +362,14 @@ class TestYara(unittest.TestCase):
             'rule test { strings: $a = "abc" fullword condition: $a }',
         ], "abcx")
 
+        self.assertFalseRules([
+            'rule test { strings: $a = "abc" ascii wide fullword condition: $a }',
+        ], "abcx")
+
+        self.assertTrueRules([
+            'rule test { strings: $a = "abc" ascii wide fullword condition: $a }',
+        ], "a\x00abc")
+
         self.assertTrueRules([
             'rule test { strings: $a = "abc" wide fullword condition: $a }',
         ], "a\x00b\x00c\x00")

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



More information about the forensics-changes mailing list