[Forensics-changes] [yara] 347/368: Implement caching in "hash" module

Hilko Bengen bengen at moszumanska.debian.org
Sat Jul 1 10:30:56 UTC 2017


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

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

commit 22ce5e09dd49ccfb175524e8c6066984d1ecfb63
Author: plusvic <plusvic at gmail.com>
Date:   Wed Jun 29 18:47:07 2016 +0200

    Implement caching in "hash" module
---
 libyara/modules/hash.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++---
 tests/test-rules.c     |  51 +++++++++++++++++++++
 2 files changed, 165 insertions(+), 6 deletions(-)

diff --git a/libyara/modules/hash.c b/libyara/modules/hash.c
index 63d4219..c4a8ad3 100644
--- a/libyara/modules/hash.c
+++ b/libyara/modules/hash.c
@@ -37,11 +37,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <inttypes.h>
 #endif
 
+
+#include <yara/mem.h>
 #include <yara/modules.h>
 
 #define MODULE_NAME hash
 
 
+typedef struct _CACHE_KEY
+{
+  int64_t offset;
+  int64_t length;
+
+} CACHE_KEY;
+
+
 void digest_to_ascii(
     unsigned char* digest,
     char* digest_ascii,
@@ -56,6 +66,53 @@ void digest_to_ascii(
 }
 
 
+char* get_from_cache(
+    YR_OBJECT* module_object,
+    const char* ns,
+    int64_t offset,
+    int64_t length)
+{
+  CACHE_KEY key;
+  YR_HASH_TABLE* hash_table = (YR_HASH_TABLE*) module_object->data;
+
+  key.offset = offset;
+  key.length = length;
+
+  return yr_hash_table_lookup_raw_key(
+      hash_table,
+      &key,
+      sizeof(key),
+      ns);
+}
+
+
+int add_to_cache(
+    YR_OBJECT* module_object,
+    const char* ns,
+    int64_t offset,
+    int64_t length,
+    const char* digest)
+{
+  CACHE_KEY key;
+  YR_HASH_TABLE* hash_table = (YR_HASH_TABLE*) module_object->data;
+
+  char* copy = yr_strdup(digest);
+
+  key.offset = offset;
+  key.length = length;
+
+  if (copy == NULL)
+    return ERROR_INSUFICIENT_MEMORY;
+
+  return yr_hash_table_add_raw_key(
+      hash_table,
+      &key,
+      sizeof(key),
+      ns,
+      (void*) copy);
+}
+
+
 define_function(string_md5)
 {
   unsigned char digest[MD5_DIGEST_LENGTH];
@@ -130,6 +187,7 @@ define_function(data_md5)
 
   unsigned char digest[MD5_DIGEST_LENGTH];
   char digest_ascii[MD5_DIGEST_LENGTH * 2 + 1];
+  char* cached_ascii_digest;
 
   int past_first_block = FALSE;
 
@@ -137,8 +195,11 @@ define_function(data_md5)
   YR_MEMORY_BLOCK* block = first_memory_block(context);
   YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
 
-  int64_t offset = integer_argument(1);   // offset where to start
-  int64_t length = integer_argument(2);   // length of bytes we want hash on
+  int64_t arg_offset = integer_argument(1);   // offset where to start
+  int64_t arg_length = integer_argument(2);   // length of bytes we want hash on
+
+  int64_t offset = arg_offset;
+  int64_t length = arg_length;
 
   MD5_Init(&md5_context);
 
@@ -147,6 +208,12 @@ define_function(data_md5)
     return ERROR_WRONG_ARGUMENTS;
   }
 
+  cached_ascii_digest = get_from_cache(
+      module(), "md5", arg_offset, arg_length);
+
+  if (cached_ascii_digest != NULL)
+    return_string(cached_ascii_digest);
+
   foreach_memory_block(iterator, block)
   {
     // if desired block within current block
@@ -192,6 +259,9 @@ define_function(data_md5)
 
   digest_to_ascii(digest, digest_ascii, MD5_DIGEST_LENGTH);
 
+  FAIL_ON_ERROR(
+      add_to_cache(module(), "md5", arg_offset, arg_length, digest_ascii));
+
   return_string(digest_ascii);
 }
 
@@ -202,11 +272,15 @@ define_function(data_sha1)
 
   unsigned char digest[SHA_DIGEST_LENGTH];
   char digest_ascii[SHA_DIGEST_LENGTH * 2 + 1];
+  char* cached_ascii_digest;
 
   int past_first_block = FALSE;
 
-  int64_t offset = integer_argument(1);   // offset where to start
-  int64_t length = integer_argument(2);   // length of bytes we want hash on
+  int64_t arg_offset = integer_argument(1);   // offset where to start
+  int64_t arg_length = integer_argument(2);   // length of bytes we want hash on
+
+  int64_t offset = arg_offset;
+  int64_t length = arg_length;
 
   YR_SCAN_CONTEXT* context = scan_context();
   YR_MEMORY_BLOCK* block = first_memory_block(context);
@@ -219,6 +293,12 @@ define_function(data_sha1)
     return ERROR_WRONG_ARGUMENTS;
   }
 
+  cached_ascii_digest = get_from_cache(
+      module(), "sha1", arg_offset, arg_length);
+
+  if (cached_ascii_digest != NULL)
+    return_string(cached_ascii_digest);
+
   foreach_memory_block(iterator, block)
   {
     // if desired block within current block
@@ -263,6 +343,9 @@ define_function(data_sha1)
 
   digest_to_ascii(digest, digest_ascii, SHA_DIGEST_LENGTH);
 
+  FAIL_ON_ERROR(
+      add_to_cache(module(), "sha1", arg_offset, arg_length, digest_ascii));
+
   return_string(digest_ascii);
 }
 
@@ -273,11 +356,15 @@ define_function(data_sha256)
 
   unsigned char digest[SHA256_DIGEST_LENGTH];
   char digest_ascii[SHA256_DIGEST_LENGTH * 2 + 1];
+  char* cached_ascii_digest;
 
   int past_first_block = FALSE;
 
-  int64_t offset = integer_argument(1);   // offset where to start
-  int64_t length = integer_argument(2);   // length of bytes we want hash on
+  int64_t arg_offset = integer_argument(1);   // offset where to start
+  int64_t arg_length = integer_argument(2);   // length of bytes we want hash on
+
+  int64_t offset = arg_offset;
+  int64_t length = arg_length;
 
   YR_SCAN_CONTEXT* context = scan_context();
   YR_MEMORY_BLOCK* block = first_memory_block(context);
@@ -290,6 +377,12 @@ define_function(data_sha256)
     return ERROR_WRONG_ARGUMENTS;
   }
 
+  cached_ascii_digest = get_from_cache(
+      module(), "sha256", arg_offset, arg_length);
+
+  if (cached_ascii_digest != NULL)
+    return_string(cached_ascii_digest);
+
   foreach_memory_block(iterator, block)
   {
     // if desired block within current block
@@ -333,6 +426,9 @@ define_function(data_sha256)
 
   digest_to_ascii(digest, digest_ascii, SHA256_DIGEST_LENGTH);
 
+  FAIL_ON_ERROR(
+      add_to_cache(module(), "sha256", arg_offset, arg_length, digest_ascii));
+
   return_string(digest_ascii);
 }
 
@@ -437,6 +533,11 @@ int module_load(
     void* module_data,
     size_t module_data_size)
 {
+  YR_HASH_TABLE* hash_table;
+
+  FAIL_ON_ERROR(yr_hash_table_create(17, &hash_table));
+
+  module_object->data = hash_table;
 
   return ERROR_SUCCESS;
 }
@@ -445,5 +546,12 @@ int module_load(
 int module_unload(
     YR_OBJECT* module_object)
 {
+  YR_HASH_TABLE* hash_table = (YR_HASH_TABLE*) module_object->data;
+
+  if (hash_table != NULL)
+    yr_hash_table_destroy(
+        hash_table,
+        (YR_HASH_TABLE_FREE_VALUE_FUNC) yr_free);
+
   return ERROR_SUCCESS;
 }
diff --git a/tests/test-rules.c b/tests/test-rules.c
index f5deb7b..0ed2524 100644
--- a/tests/test-rules.c
+++ b/tests/test-rules.c
@@ -1264,6 +1264,56 @@ static void test_modules()
 }
 
 
+static void test_hash_module()
+{
+  uint8_t blob[] = {0x61, 0x62, 0x63, 0x64, 0x65};
+
+  assert_true_rule_blob(
+      "import \"hash\" \
+       rule test { \
+        condition: \
+          hash.md5(0, filesize) == \
+            \"ab56b4d92b40713acc5af89985d4b786\" \
+            and \
+          hash.md5(1, filesize) == \
+            \"e02cfbe5502b64aa5ae9f2d0d69eaa8d\" \
+            and \
+          hash.sha1(0, filesize) == \
+            \"03de6c570bfe24bfc328ccd7ca46b76eadaf4334\" \
+            and \
+          hash.sha1(1, filesize) == \
+            \"a302d65ae4d9e768a1538d53605f203fd8e2d6e2\" \
+            and \
+          hash.sha256(0, filesize) == \
+            \"36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0c44ca42c\" \
+            and \
+          hash.sha256(1, filesize) == \
+            \"aaaaf2863e043b9df604158ad5c16ff1adaf3fd7e9fcea5dcb322b6762b3b59a\" \
+      }",
+      blob);
+
+  // Test hash caching mechanism
+
+  assert_true_rule_blob(
+      "import \"hash\" \
+       rule test { \
+        condition: \
+          hash.md5(0, filesize) == \
+            \"ab56b4d92b40713acc5af89985d4b786\" \
+            and \
+          hash.md5(1, filesize) == \
+            \"e02cfbe5502b64aa5ae9f2d0d69eaa8d\" \
+            and \
+          hash.md5(0, filesize) == \
+            \"ab56b4d92b40713acc5af89985d4b786\" \
+            and \
+          hash.md5(1, filesize) == \
+            \"e02cfbe5502b64aa5ae9f2d0d69eaa8d\" \
+      }",
+      blob);
+}
+
+
 void test_integer_functions()
 {
   assert_true_rule(
@@ -1322,6 +1372,7 @@ int main(int argc, char** argv)
   // test_compare();
   test_comments();
   test_modules();
+  test_hash_module();
   test_integer_functions();
   // test_string_io();
   test_entrypoint();

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