[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