[Forensics-changes] [yara] 323/415: Fix some issues with chained strings

Hilko Bengen bengen at moszumanska.debian.org
Thu Apr 3 05:43:20 UTC 2014


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

bengen pushed a commit to branch debian
in repository yara.

commit f354aa4a8a92d0b7664f613acbb750f795f9297d
Author: Victor M. Alvarez <plusvic at gmail.com>
Date:   Fri Dec 20 20:12:50 2013 +0100

    Fix some issues with chained strings
---
 libyara/parser.c |  35 ++++++++++++++----
 libyara/re.h     |   6 ++-
 libyara/rules.c  | 110 ++++++++++++++++++++-----------------------------------
 libyara/yara.h   |   2 +-
 4 files changed, 71 insertions(+), 82 deletions(-)

diff --git a/libyara/parser.c b/libyara/parser.c
index a04caf1..f989db3 100644
--- a/libyara/parser.c
+++ b/libyara/parser.c
@@ -153,8 +153,16 @@ YR_STRING* yr_parser_lookup_string(
 
   while(!STRING_IS_NULL(string))
   {
-    if (strcmp(string->identifier, identifier) == 0)
+    // If some string $a gets fragmented into multiple chained
+    // strings, all those fragments have the same $a identifier
+    // but we are interested in the heading fragment, which is
+    // that with chained_to == NULL
+
+    if (strcmp(string->identifier, identifier) == 0 &&
+        string->chained_to == NULL)
+    {
       return string;
+    }
 
     string = yr_arena_next_address(
         compiler->strings_arena,
@@ -383,6 +391,7 @@ YR_STRING* yr_parser_reduce_string_declaration(
 
   YR_COMPILER* compiler = yyget_extra(yyscanner);
   YR_STRING* string = NULL;
+  YR_STRING* aux_string;
   YR_STRING* prev_string;
 
   RE* re = NULL;
@@ -460,6 +469,11 @@ YR_STRING* yr_parser_reduce_string_declaration(
       string->chain_gap_max = max_gap;
     }
 
+    // Use "aux_string" from now on, we want to keep the value of "string"
+    // because it will returned.
+
+    aux_string = string;
+
     while (remainder_re != NULL)
     {
       // Destroy regexp pointed by 're' before yr_re_split_at_jmp
@@ -473,7 +487,7 @@ YR_STRING* yr_parser_reduce_string_declaration(
       if (compiler->last_result != ERROR_SUCCESS)
         goto _exit;
 
-      prev_string = string;
+      prev_string = aux_string;
 
       compiler->last_result = _yr_parser_write_string(
           identifier,
@@ -481,7 +495,7 @@ YR_STRING* yr_parser_reduce_string_declaration(
           compiler,
           NULL,
           re,
-          &string,
+          &aux_string,
           &min_atom_length_aux);
 
       if (compiler->last_result != ERROR_SUCCESS)
@@ -490,11 +504,11 @@ YR_STRING* yr_parser_reduce_string_declaration(
       if (min_atom_length_aux < min_atom_length)
         min_atom_length = min_atom_length_aux;
 
-      string->g_flags |= STRING_GFLAGS_CHAIN_PART;
-      string->chain_gap_min = min_gap;
-      string->chain_gap_max = max_gap;
+      aux_string->g_flags |= STRING_GFLAGS_CHAIN_PART;
+      aux_string->chain_gap_min = min_gap;
+      aux_string->chain_gap_max = max_gap;
 
-      prev_string->chained_to = string;
+      prev_string->chained_to = aux_string;
     }
   }
   else
@@ -576,7 +590,12 @@ int yr_parser_reduce_rule_declaration(
 
   while(!STRING_IS_NULL(string))
   {
-    if (!STRING_IS_REFERENCED(string))
+    // Only the heading fragment in a chain of strings (the one with
+    // chained_to == NULL) must be referenced. All other fragments
+    // are never marked as referenced.
+
+    if (!STRING_IS_REFERENCED(string) &&
+        string->chained_to == NULL)
     {
       yr_compiler_set_error_extra_info(compiler, string->identifier);
       compiler->last_result = ERROR_UNREFERENCED_STRING;
diff --git a/libyara/re.h b/libyara/re.h
index 835c0b8..2cfbb54 100644
--- a/libyara/re.h
+++ b/libyara/re.h
@@ -117,7 +117,7 @@ struct RE {
 };
 
 
-typedef void RE_MATCH_CALLBACK_FUNC(
+typedef int RE_MATCH_CALLBACK_FUNC(
     uint8_t* match,
     int match_length,
     int flags,
@@ -166,7 +166,6 @@ SIZED_STRING* yr_re_extract_literal(
     RE* re);
 
 
-
 int yr_re_split_at_chaining_point(
     RE* re,
     RE** result_re,
@@ -188,10 +187,13 @@ int yr_re_exec(
     RE_MATCH_CALLBACK_FUNC callback,
     void* callback_args);
 
+
 int yr_re_initialize();
 
+
 int yr_re_finalize();
 
+
 int yr_re_finalize_thread();
 
 #endif
diff --git a/libyara/rules.c b/libyara/rules.c
index be48741..a4e2f7b 100644
--- a/libyara/rules.c
+++ b/libyara/rules.c
@@ -1,4 +1,4 @@
-    /*
+ /*
 Copyright (c) 2013. Victor M. Alvarez [plusvic at gmail.com].
 
 Licensed under the Apache License, Version 2.0 (the "License");
@@ -300,58 +300,6 @@ int _yr_scan_fast_hex_re_exec(
   return -1;
 }
 
-void _yr_scan_confirm_matches(
-    int tidx,
-    YR_STRING* string,
-    size_t match_offset,
-    int32_t match_length)
-{
-  YR_MATCH* match;
-  YR_MATCH* next_match;
-
-  if (string->chained_to == NULL)
-    return;
-
-  match = string->chained_to->unconfirmed_matches[tidx].head;
-
-  while (match != NULL)
-  {
-    next_match = match->next;
-
-    if (match_offset >= match->offset + match->length)
-    {
-      if (match->prev != NULL)
-        match->prev->next = match->next;
-
-      if (match->next != NULL)
-        match->next->prev = match->prev;
-
-      if (match == string->chained_to->unconfirmed_matches[tidx].head)
-        string->chained_to->unconfirmed_matches[tidx].head = match->next;
-
-      if (match == string->chained_to->unconfirmed_matches[tidx].tail)
-        string->chained_to->unconfirmed_matches[tidx].tail = match->prev;
-
-      match->prev = string->chained_to->matches[tidx].tail;
-      match->next = NULL;
-      match->length = match_offset - match->offset + match_length;
-
-      if (string->chained_to->matches[tidx].head == NULL)
-        string->chained_to->matches[tidx].head = match;
-
-      if (string->chained_to->matches[tidx].tail != NULL)
-        string->chained_to->matches[tidx].tail->next = match;
-
-      string->chained_to->matches[tidx].tail = match;
-
-      _yr_scan_confirm_matches(
-          tidx, string->chained_to, match->offset, match->length);
-    }
-
-    match = next_match;
-  }
-}
-
 
 void _yr_scan_update_match_chain_length(
     int tidx,
@@ -389,9 +337,7 @@ void _yr_scan_add_match_to_list(
     YR_MATCH* match,
     YR_MATCHES* matches_list)
 {
-  YR_MATCH* insertion_point;
-
-  insertion_point = matches_list->tail;
+  YR_MATCH* insertion_point = matches_list->tail;
 
   while (insertion_point != NULL)
   {
@@ -442,9 +388,13 @@ void _yr_scan_remove_match_from_list(
 
   if (matches_list->tail == match)
     matches_list->tail = match->prev;
+
+  match->next = NULL;
+  match->prev = NULL;
 }
 
-void _yr_scan_handle_chained_matches(
+
+int _yr_scan_handle_chained_matches(
     YR_ARENA* matches_arena,
     YR_STRING* matching_string,
     uint8_t* match_data,
@@ -462,6 +412,7 @@ void _yr_scan_handle_chained_matches(
   int32_t full_chain_length;
 
   int add_match = FALSE;
+  int result;
 
   if (matching_string->chained_to == NULL)
   {
@@ -530,6 +481,8 @@ void _yr_scan_handle_chained_matches(
 
           match->length = match_offset - match->offset + match_length;
           match->data = match_data - match_offset + match->offset;
+          match->prev = NULL;
+          match->next = NULL;
 
           _yr_scan_add_match_to_list(
               match, &string->matches[tidx]);
@@ -540,24 +493,31 @@ void _yr_scan_handle_chained_matches(
     }
     else
     {
-      yr_arena_allocate_memory(
+      result = yr_arena_allocate_memory(
           matches_arena,
           sizeof(YR_MATCH),
           (void**) &new_match);
 
+      if (result != ERROR_SUCCESS)
+        return result;
+
       new_match->offset = match_offset;
       new_match->length = match_length;
       new_match->data = match_data;
+      new_match->prev = NULL;
+      new_match->next = NULL;
 
       _yr_scan_add_match_to_list(
           new_match,
           &matching_string->unconfirmed_matches[tidx]);
     }
   }
+
+  return ERROR_SUCCESS;
 }
 
 
-void _yr_scan_match_callback(
+int _yr_scan_match_callback(
     uint8_t* match_data,
     int32_t match_length,
     int flags,
@@ -569,6 +529,7 @@ void _yr_scan_match_callback(
   YR_MATCH* new_match;
 
   int character_size;
+  int result = ERROR_SUCCESS;
   int tidx = callback_args->tidx;
 
   size_t match_offset = match_data - callback_args->data;
@@ -596,28 +557,28 @@ void _yr_scan_match_callback(
       if (match_offset >= 2 &&
           *(match_data - 1) == 0 &&
           isalnum(*(match_data - 2)))
-        return;
+        return ERROR_SUCCESS;
 
       if (match_offset + match_length + 1 < callback_args->data_size &&
           *(match_data + match_length + 1) == 0 &&
           isalnum(*(match_data + match_length)))
-        return;
+        return ERROR_SUCCESS;
     }
     else
     {
       if (match_offset >= 1 &&
           isalnum(*(match_data - 1)))
-        return;
+        return ERROR_SUCCESS;
 
       if (match_offset + match_length < callback_args->data_size &&
           isalnum(*(match_data + match_length)))
-        return;
+        return ERROR_SUCCESS;
     }
   }
 
   if (STRING_IS_CHAIN_PART(string))
   {
-    _yr_scan_handle_chained_matches(
+    result = _yr_scan_handle_chained_matches(
         callback_args->matches_arena,
         string,
         match_data,
@@ -627,19 +588,26 @@ void _yr_scan_match_callback(
   }
   else
   {
-    yr_arena_allocate_memory(
+    result = yr_arena_allocate_memory(
         callback_args->matches_arena,
         sizeof(YR_MATCH),
         (void**) &new_match);
 
-    new_match->offset = match_offset;
-    new_match->length = match_length;
-    new_match->data = match_data;
+    if (result == ERROR_SUCCESS)
+    {
+      new_match->offset = match_offset;
+      new_match->length = match_length;
+      new_match->data = match_data;
+      new_match->prev = NULL;
+      new_match->next = NULL;
 
-    _yr_scan_add_match_to_list(
-        new_match,
-        &string->matches[tidx]);
+      _yr_scan_add_match_to_list(
+          new_match,
+          &string->matches[tidx]);
+    }
   }
+
+  return result;
 }
 
 
diff --git a/libyara/yara.h b/libyara/yara.h
index 6c01e7b..ae952e4 100644
--- a/libyara/yara.h
+++ b/libyara/yara.h
@@ -100,7 +100,7 @@ typedef pthread_mutex_t mutex_t;
 #define MAX_LOOP_NESTING 4
 #define MAX_INCLUDE_DEPTH 16
 #define MAX_THREADS 32
-#define STRING_CHAINING_THRESHOLD 256
+#define STRING_CHAINING_THRESHOLD 200
 #define LEX_BUF_SIZE  1024
 
 

-- 
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