[Forensics-changes] [yara] 313/368: Merge pull request #418
Hilko Bengen
bengen at moszumanska.debian.org
Sat Jul 1 10:30:52 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 23759af0b29bad2f407dd031de28598ea6952b96
Merge: f11220d 0d58eb2
Author: plusvic <plusvic at gmail.com>
Date: Mon Jun 13 17:05:32 2016 +0200
Merge pull request #418
libyara/exec.c | 33 ++-
libyara/include/yara/error.h | 1 +
libyara/include/yara/modules.h | 8 +-
libyara/include/yara/proc.h | 7 +-
libyara/include/yara/rules.h | 1 -
libyara/include/yara/types.h | 44 ++-
libyara/libyara.c | 2 +-
libyara/modules/elf.c | 14 +-
libyara/modules/hash.c | 92 +++---
libyara/modules/math.c | 189 +++++++------
libyara/modules/pe.c | 14 +-
libyara/proc.c | 627 ++++++++++++++++++++++++++++-------------
libyara/rules.c | 95 +++++--
13 files changed, 750 insertions(+), 377 deletions(-)
diff --cc libyara/include/yara/proc.h
index 3145ac1,fe08fb8..c3c8d7f
--- a/libyara/include/yara/proc.h
+++ b/libyara/include/yara/proc.h
@@@ -19,8 -19,11 +19,11 @@@ limitations under the License
#include <yara/types.h>
- int yr_process_get_memory(
-int yr_open_process_iterator(
++int yr_process_open_iterator(
int pid,
- YR_MEMORY_BLOCK** first_block);
+ YR_BLOCK_ITERATOR* iterator);
+
-int yr_close_process_iterator(
++int yr_process_close_iterator(
+ YR_BLOCK_ITERATOR* iterator);
#endif
diff --cc libyara/include/yara/types.h
index 4f86556,bc02958..5281cf2
--- a/libyara/include/yara/types.h
+++ b/libyara/include/yara/types.h
@@@ -359,10 -362,9 +359,10 @@@ typedef struct _YR_RULES
} YR_RULES;
+
+ // memory block iteration types
typedef struct _YR_MEMORY_BLOCK
{
- uint8_t* data;
size_t size;
size_t base;
@@@ -370,7 -372,42 +370,47 @@@
} YR_MEMORY_BLOCK;
+
+ typedef struct _YR_BLOCK_ITERATOR YR_BLOCK_ITERATOR;
+
++
+ typedef YR_MEMORY_BLOCK* (*YR_BLOCK_ITERATOR_MOVE)(
+ YR_BLOCK_ITERATOR* self);
+
++
+ typedef uint8_t* (*YR_BLOCK_ITERATOR_FETCH)(
- YR_BLOCK_ITERATOR* self);
++ YR_BLOCK_ITERATOR* self);
++
+
+ struct _YR_BLOCK_ITERATOR
+ {
+ void* context;
+
+ YR_BLOCK_ITERATOR_MOVE first;
+ YR_BLOCK_ITERATOR_MOVE next;
+ YR_BLOCK_ITERATOR_FETCH fetch_data;
+
+ };
+
+ // a memory block in context with its data
+ typedef struct _YR_BLOCK_CONTEXT
+ {
+ uint8_t* data;
+ YR_MEMORY_BLOCK* block;
+
+ } YR_BLOCK_CONTEXT;
+
++
+ typedef struct _YR_PROCESS_CONTEXT
+ {
+ uint8_t* data;
+ void* process_context;
+ YR_MEMORY_BLOCK* blocks;
+ YR_MEMORY_BLOCK* current;
+
+ } YR_PROCESS_CONTEXT;
+
+
typedef int (*YR_CALLBACK_FUNC)(
int message,
void* message_data,
diff --cc libyara/libyara.c
index d92287d,4e8fac3..2025d8b
--- a/libyara/libyara.c
+++ b/libyara/libyara.c
@@@ -175,16 -202,19 +175,16 @@@ YR_API int yr_finalize(void
return ERROR_SUCCESS;
#ifdef HAVE_LIBCRYPTO
+
for (i = 0; i < CRYPTO_num_locks(); i ++)
- pthread_mutex_destroy(&locks[i]);
- OPENSSL_free(locks);
- #endif
+ yr_mutex_destroy(&openssl_locks[i]);
+
+ OPENSSL_free(openssl_locks);
-
+
- #if defined(_WIN32) || defined(__CYGWIN__)
- TlsFree(tidx_key);
- TlsFree(recovery_state_key);
- #else
- pthread_key_delete(tidx_key);
- pthread_key_delete(recovery_state_key);
#endif
+ FAIL_ON_ERROR(yr_thread_storage_destroy(&tidx_key));
+ FAIL_ON_ERROR(yr_thread_storage_destroy(&recovery_state_key));
FAIL_ON_ERROR(yr_re_finalize());
FAIL_ON_ERROR(yr_modules_finalize());
FAIL_ON_ERROR(yr_heap_free());
diff --cc libyara/modules/hash.c
index 5b965e7,c0c9574..9d23172
--- a/libyara/modules/hash.c
+++ b/libyara/modules/hash.c
@@@ -140,14 -141,19 +141,19 @@@ define_function(data_md5
if (offset >= block->base &&
offset < block->base + block->size)
{
- size_t data_offset = (size_t) (offset - block->base);
- size_t data_len = (size_t) yr_min(
+ uint8_t* block_data = iterator->fetch_data(iterator);
+
+ if (block_data != NULL)
+ {
- size_t data_offset = (size_t)(offset - block->base);
- size_t data_len = (size_t)yr_min(
- length, (size_t)(block->size - data_offset));
++ size_t data_offset = (size_t) (offset - block->base);
++ size_t data_len = (size_t) yr_min(
+ length, (size_t) (block->size - data_offset));
- offset += data_len;
- length -= data_len;
+ offset += data_len;
+ length -= data_len;
- MD5_Update(&md5_context, block->data + data_offset, data_len);
+ MD5_Update(&md5_context, block_data + data_offset, data_len);
+ }
past_first_block = TRUE;
}
@@@ -205,14 -212,19 +212,19 @@@ define_function(data_sha1
if (offset >= block->base &&
offset < block->base + block->size)
{
- size_t data_offset = (size_t) (offset - block->base);
- size_t data_len = (size_t) yr_min(
+ uint8_t* block_data = iterator->fetch_data(iterator);
+
+ if (block_data != NULL)
+ {
- size_t data_offset = (size_t)(offset - block->base);
- size_t data_len = (size_t)yr_min(
- length, (size_t)block->size - data_offset);
++ size_t data_offset = (size_t) (offset - block->base);
++ size_t data_len = (size_t) yr_min(
+ length, (size_t) block->size - data_offset);
- offset += data_len;
- length -= data_len;
+ offset += data_len;
+ length -= data_len;
- SHA1_Update(&sha_context, block->data + data_offset, data_len);
+ SHA1_Update(&sha_context, block_data + data_offset, data_len);
+ }
past_first_block = TRUE;
}
@@@ -270,13 -283,18 +283,18 @@@ define_function(data_sha256
if (offset >= block->base &&
offset < block->base + block->size)
{
- size_t data_offset = (size_t) (offset - block->base);
- size_t data_len = (size_t) yr_min(length, block->size - data_offset);
+ uint8_t* block_data = iterator->fetch_data(iterator);
- offset += data_len;
- length -= data_len;
+ if (block_data != NULL)
+ {
- size_t data_offset = (size_t)(offset - block->base);
- size_t data_len = (size_t)yr_min(length, block->size - data_offset);
++ size_t data_offset = (size_t) (offset - block->base);
++ size_t data_len = (size_t) yr_min(length, block->size - data_offset);
- SHA256_Update(&sha256_context, block->data + data_offset, data_len);
+ offset += data_len;
+ length -= data_len;
+
+ SHA256_Update(&sha256_context, block_data + data_offset, data_len);
+ }
past_first_block = TRUE;
}
@@@ -327,16 -346,21 +346,21 @@@ define_function(data_checksum32
if (offset >= block->base &&
offset < block->base + block->size)
{
- size_t i;
+ uint8_t* block_data = iterator->fetch_data(iterator);
+
+ if (block_data != NULL)
+ {
+ size_t i;
- size_t data_offset = (size_t) (offset - block->base);
- size_t data_len = (size_t) yr_min(length, block->size - data_offset);
- size_t data_offset = (size_t)(offset - block->base);
- size_t data_len = (size_t)yr_min(length, block->size - data_offset);
++ size_t data_offset = (size_t) (offset - block->base);
++ size_t data_len = (size_t) yr_min(length, block->size - data_offset);
- offset += data_len;
- length -= data_len;
+ offset += data_len;
+ length -= data_len;
- for (i = 0; i < data_len; i++)
- checksum += *(block->data + data_offset + i);
+ for (i = 0; i < data_len; i++)
+ checksum += *(block_data + data_offset + i);
+ }
past_first_block = TRUE;
}
diff --cc libyara/modules/math.c
index e5ff873,c24268c..47da449
--- a/libyara/modules/math.c
+++ b/libyara/modules/math.c
@@@ -79,9 -79,10 +79,10 @@@ define_function(data_entropy
int64_t length = integer_argument(2); // length of bytes we want entropy on
YR_SCAN_CONTEXT* context = scan_context();
- YR_MEMORY_BLOCK* block = NULL;
-
- if (offset < 0 || length < 0 || offset < context->mem_block->base)
+ YR_MEMORY_BLOCK* block = first_memory_block(context);
+ YR_BLOCK_ITERATOR* iterator = context->iterator;
-
++
+ if (offset < 0 || length < 0 || offset < block->base)
return_float(UNDEFINED);
data = (uint32_t*) yr_calloc(256, sizeof(uint32_t));
@@@ -94,18 -95,23 +95,23 @@@
if (offset >= block->base &&
offset < block->base + block->size)
{
- size_t data_offset = (size_t) (offset - block->base);
- size_t data_len = (size_t) yr_min(
+ uint8_t* block_data = iterator->fetch_data(iterator);
+
+ if (block_data != NULL)
+ {
- size_t data_offset = (size_t)(offset - block->base);
- size_t data_len = (size_t)yr_min(
- length, (size_t)(block->size - data_offset));
++ size_t data_offset = (size_t) (offset - block->base);
++ size_t data_len = (size_t) yr_min(
+ length, (size_t) (block->size - data_offset));
- total_len += data_len;
- offset += data_len;
- length -= data_len;
+ total_len += data_len;
+ offset += data_len;
+ length -= data_len;
- for (i = 0; i < data_len; i++)
- {
- uint8_t c = *(block->data + data_offset + i);
- data[c] += 1;
+ for (i = 0; i < data_len; i++)
+ {
+ uint8_t c = *(block_data + data_offset + i);
+ data[c] += 1;
+ }
}
past_first_block = TRUE;
@@@ -163,7 -169,7 +169,7 @@@ define_function(string_deviation
define_function(data_deviation)
--{
++{
int past_first_block = FALSE;
int64_t offset = integer_argument(1);
@@@ -176,26 -182,32 +182,32 @@@
size_t i;
YR_SCAN_CONTEXT* context = scan_context();
- YR_MEMORY_BLOCK* block = NULL;
+ YR_MEMORY_BLOCK* block = first_memory_block(context);
+ YR_BLOCK_ITERATOR* iterator = context->iterator;
- if (offset < 0 || length < 0 || offset < context->mem_block->base)
+ if (offset < 0 || length < 0 || offset < block->base)
return_float(UNDEFINED);
--
- foreach_memory_block(context, block)
++
+ foreach_memory_block(iterator, block)
{
if (offset >= block->base &&
offset < block->base + block->size)
{
- size_t data_offset = (size_t) (offset - block->base);
- size_t data_len = (size_t) yr_min(
+ uint8_t* block_data = iterator->fetch_data(iterator);
+
+ if (block_data != NULL)
+ {
- size_t data_offset = (size_t)(offset - block->base);
- size_t data_len = (size_t)yr_min(
- length, (size_t)(block->size - data_offset));
++ size_t data_offset = (size_t) (offset - block->base);
++ size_t data_len = (size_t) yr_min(
+ length, (size_t) (block->size - data_offset));
- total_len += data_len;
- offset += data_len;
- length -= data_len;
+ total_len += data_len;
+ offset += data_len;
+ length -= data_len;
- for (i = 0; i < data_len; i++)
- sum += fabs(((double) *(block->data + data_offset + i)) - mean);
+ for (i = 0; i < data_len; i++)
- sum += fabs(((double)*(block_data + data_offset + i)) - mean);
++ sum += fabs(((double)* (block_data + data_offset + i)) - mean);
+ }
past_first_block = TRUE;
}
@@@ -224,7 -236,7 +236,7 @@@ define_function(string_mean
{
size_t i;
double sum = 0.0;
--
++
SIZED_STRING* s = sized_string_argument(1);
for (i = 0; i < s->length; i++)
@@@ -235,7 -247,7 +247,7 @@@
define_function(data_mean)
--{
++{
int past_first_block = FALSE;
double sum = 0.0;
@@@ -248,24 -261,29 +261,29 @@@
size_t total_len = 0;
size_t i;
- if (offset < 0 || length < 0 || offset < context->mem_block->base)
+ if (offset < 0 || length < 0 || offset < block->base)
return_float(UNDEFINED);
--
- foreach_memory_block(context, block)
++
+ foreach_memory_block(iterator, block)
{
if (offset >= block->base &&
offset < block->base + block->size)
{
- size_t data_offset = (size_t) (offset - block->base);
- size_t data_len = (size_t) yr_min(
+ uint8_t* block_data = iterator->fetch_data(iterator);
+
+ if (block_data != NULL)
+ {
- size_t data_offset = (size_t)(offset - block->base);
- size_t data_len = (size_t)yr_min(
- length, (size_t)(block->size - data_offset));
++ size_t data_offset = (size_t) (offset - block->base);
++ size_t data_len = (size_t) yr_min(
+ length, (size_t) (block->size - data_offset));
- total_len += data_len;
- offset += data_len;
- length -= data_len;
+ total_len += data_len;
+ offset += data_len;
+ length -= data_len;
- for (i = 0; i < data_len; i++)
- sum += (double) *(block->data + data_offset + i);
+ for (i = 0; i < data_len; i++)
- sum += (double)*(block_data + data_offset + i);
++ sum += (double)* (block_data + data_offset + i);
+ }
past_first_block = TRUE;
}
@@@ -310,29 -329,34 +329,34 @@@ define_function(data_serial_correlation
double scct3 = 0;
double scc = 0;
- if (offset < 0 || length < 0 || offset < context->mem_block->base)
+ if (offset < 0 || length < 0 || offset < block->base)
return_float(UNDEFINED);
--
- foreach_memory_block(context, block)
++
+ foreach_memory_block(iterator, block)
{
if (offset >= block->base &&
offset < block->base + block->size)
{
- size_t data_offset = (size_t) (offset - block->base);
- size_t data_len = (size_t) yr_min(
- length, (size_t) (block->size - data_offset));
-
- total_len += data_len;
- offset += data_len;
- length -= data_len;
+ uint8_t* block_data = iterator->fetch_data(iterator);
- for (i = 0; i < data_len; i++)
+ if (block_data != NULL)
{
- sccun = (double) *(block->data + data_offset + i);
- scct1 += scclast * sccun;
- scct2 += sccun;
- scct3 += sccun * sccun;
- scclast = sccun;
+ size_t data_offset = (size_t)(offset - block->base);
- size_t data_len = (size_t)yr_min(
- length, (size_t)(block->size - data_offset));
++ size_t data_len = (size_t) yr_min(
++ length, (size_t) (block->size - data_offset));
+
+ total_len += data_len;
+ offset += data_len;
+ length -= data_len;
+
+ for (i = 0; i < data_len; i++)
+ {
- sccun = (double)*(block_data + data_offset + i);
++ sccun = (double)* (block_data + data_offset + i);
+ scct1 += scclast * sccun;
+ scct2 += sccun;
+ scct3 += sccun * sccun;
+ scclast = sccun;
+ }
}
past_first_block = TRUE;
@@@ -419,45 -443,50 +443,50 @@@ define_function(data_monte_carlo_pi
int64_t length = integer_argument(2);
YR_SCAN_CONTEXT* context = scan_context();
- YR_MEMORY_BLOCK* block = NULL;
+ YR_MEMORY_BLOCK* block = first_memory_block(context);
+ YR_BLOCK_ITERATOR* iterator = context->iterator;
- if (offset < 0 || length < 0 || offset < context->mem_block->base)
+ if (offset < 0 || length < 0 || offset < block->base)
return_float(UNDEFINED);
--
- foreach_memory_block(context, block)
++
+ foreach_memory_block(iterator, block)
{
if (offset >= block->base &&
offset < block->base + block->size)
{
unsigned int monte[6];
+ uint8_t* block_data = iterator->fetch_data(iterator);
- size_t data_offset = (size_t) (offset - block->base);
- size_t data_len = (size_t) yr_min(
+ if (block_data != NULL)
+ {
- size_t data_offset = (size_t)(offset - block->base);
- size_t data_len = (size_t)yr_min(
- length, (size_t)(block->size - data_offset));
++ size_t data_offset = (size_t) (offset - block->base);
++ size_t data_len = (size_t) yr_min(
+ length, (size_t) (block->size - data_offset));
- offset += data_len;
- length -= data_len;
+ offset += data_len;
+ length -= data_len;
- for (i = 0; i < data_len; i++)
- {
- monte[i % 6] = (unsigned int) *(block->data + data_offset + i);
+ for (i = 0; i < data_len; i++)
+ {
- monte[i % 6] = (unsigned int)*(block_data + data_offset + i);
++ monte[i % 6] = (unsigned int)* (block_data + data_offset + i);
- if (i % 6 == 5)
- {
- double mx = 0;
- double my = 0;
- int j;
+ if (i % 6 == 5)
+ {
+ double mx = 0;
+ double my = 0;
+ int j;
- mcount++;
+ mcount++;
- for (j = 0; j < 3; j++)
- {
- mx = (mx * 256.0) + monte[j];
- my = (my * 256.0) + monte[j + 3];
- }
+ for (j = 0; j < 3; j++)
+ {
+ mx = (mx * 256.0) + monte[j];
+ my = (my * 256.0) + monte[j + 3];
+ }
- if ((mx * mx + my * my) <= INCIRC)
- inmont++;
+ if ((mx * mx + my * my) <= INCIRC)
+ inmont++;
+ }
}
}
@@@ -497,7 -526,7 +526,7 @@@ define_function(string_monte_carlo_pi
int mcount = 0;
int inmont = 0;
--
++
size_t i;
for (i = 0; i < s->length; i++)
diff --cc libyara/modules/pe.c
index 95c27c6,d74b3ab..1ac76f1
--- a/libyara/modules/pe.c
+++ b/libyara/modules/pe.c
@@@ -1008,11 -963,8 +1008,11 @@@ IMPORTED_FUNCTION* pe_parse_import_desc
yr_calloc(1, sizeof(IMPORTED_FUNCTION));
if (imported_func == NULL)
+ {
+ yr_free(name);
continue;
+ }
-
+
imported_func->name = name;
imported_func->ordinal = ordinal;
imported_func->has_ordinal = has_ordinal;
@@@ -2490,9 -2447,14 +2491,14 @@@ int module_load
RESOURCE_TYPE_MANIFEST, module_object,
"RESOURCE_TYPE_MANIFEST");
- foreach_memory_block(context, block)
+ foreach_memory_block(iterator, block)
{
- PIMAGE_NT_HEADERS32 pe_header = pe_get_header(block->data, block->size);
+ uint8_t* block_data = iterator->fetch_data(iterator);
+
- if (block_data != NULL)
++ if (block_data == NULL)
+ continue;
+
+ PIMAGE_NT_HEADERS32 pe_header = pe_get_header(block_data, block->size);
if (pe_header != NULL)
{
diff --cc libyara/proc.c
index 1d050b1,991299c..451ae23
--- a/libyara/proc.c
+++ b/libyara/proc.c
@@@ -22,25 -22,12 +22,13 @@@ limitations under the License
#include <yara/error.h>
#include <yara/proc.h>
- int yr_process_get_memory(
-int _yr_attach_process(
++
++int _yr_process_attach(
int pid,
- YR_MEMORY_BLOCK** first_block)
+ void** hProcess)
{
- PVOID address;
- SIZE_T read;
-
- unsigned char* data;
- int result = ERROR_SUCCESS;
-
- SYSTEM_INFO si;
- MEMORY_BASIC_INFORMATION mbi;
-
- YR_MEMORY_BLOCK* new_block;
- YR_MEMORY_BLOCK* current_block = NULL;
-
TOKEN_PRIVILEGES tokenPriv;
LUID luidDebug;
- HANDLE hProcess = NULL;
HANDLE hToken = NULL;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken) &&
@@@ -64,18 -54,32 +55,34 @@@
FALSE,
pid);
- *first_block = NULL;
+ if (*hProcess == NULL)
+ return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
- if (hProcess == NULL)
- {
- if (hToken != NULL)
- CloseHandle(hToken);
+ return ERROR_SUCCESS;
+ }
- return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
- }
-int _yr_detach_process(
+
- GetSystemInfo(&si);
++int _yr_process_detach(
+ void* hProcess)
+ {
+ if (hProcess != NULL)
+ CloseHandle(hProcess);
+
+ return ERROR_SUCCESS;
+ }
+
-int _yr_get_process_blocks(
++
++int _yr_process_get_blocks(
+ void* hProcess,
+ YR_MEMORY_BLOCK** head)
+ {
+ PVOID address;
+ YR_MEMORY_BLOCK* new_block;
+ YR_MEMORY_BLOCK* current = NULL;
+ SYSTEM_INFO si;
+ MEMORY_BASIC_INFORMATION mbi;
+ GetSystemInfo(&si);
address = si.lpMinimumApplicationAddress;
while (address < si.lpMaximumApplicationAddress &&
@@@ -83,57 -87,64 +90,65 @@@
{
if (mbi.State == MEM_COMMIT && ((mbi.Protect & PAGE_NOACCESS) == 0))
{
- data = (unsigned char*) yr_malloc(mbi.RegionSize);
-
- if (data == NULL)
- {
- result = ERROR_INSUFICIENT_MEMORY;
- break;
- }
-
- if (ReadProcessMemory(
- hProcess,
- mbi.BaseAddress,
- data,
- mbi.RegionSize,
- &read))
- {
- new_block = (YR_MEMORY_BLOCK*) yr_malloc(sizeof(YR_MEMORY_BLOCK));
-
- if (new_block == NULL)
- {
- yr_free(data);
- result = ERROR_INSUFICIENT_MEMORY;
- break;
- }
-
- if (*first_block == NULL)
- *first_block = new_block;
-
- new_block->base = (size_t) mbi.BaseAddress;
- new_block->size = mbi.RegionSize;
- new_block->data = data;
- new_block->next = NULL;
-
- if (current_block != NULL)
- current_block->next = new_block;
-
- current_block = new_block;
- }
- else
- {
- yr_free(data);
- }
- new_block = (YR_MEMORY_BLOCK*)yr_malloc(sizeof(YR_MEMORY_BLOCK));
++ new_block = (YR_MEMORY_BLOCK*) yr_malloc(sizeof(YR_MEMORY_BLOCK));
+
+ if (new_block == NULL)
+ return ERROR_INSUFICIENT_MEMORY;
+
- new_block->base = (size_t)mbi.BaseAddress;
++ new_block->base = (size_t) mbi.BaseAddress;
+ new_block->size = mbi.RegionSize;
+ new_block->next = NULL;
+
+ if (*head == NULL)
+ *head = new_block;
+
+ if (current != NULL)
+ current->next = new_block;
+
+ current = new_block;
}
- address = (PVOID)((ULONG_PTR) mbi.BaseAddress + mbi.RegionSize);
- address = (uint8_t*)address + mbi.RegionSize;
++ address = (uint8_t*) address + mbi.RegionSize;
}
- if (hToken != NULL)
- CloseHandle(hToken);
+ return ERROR_SUCCESS;
+ }
- if (hProcess != NULL)
- CloseHandle(hProcess);
-int _yr_read_process_block(
++
++int _yr_process_read_block(
+ void* hProcess,
+ YR_MEMORY_BLOCK* block,
+ uint8_t** data)
+ {
+ SIZE_T read;
+ uint8_t* buffer = NULL;
+ int result = ERROR_SUCCESS;
+ *data = NULL;
+
- buffer = (uint8_t*)yr_malloc(block->size);
++ buffer = (uint8_t*) yr_malloc(block->size);
+
+ if (buffer == NULL)
+ return ERROR_INSUFICIENT_MEMORY;
+
+ if (ReadProcessMemory(
- (HANDLE)hProcess,
- (LPCVOID)block->base,
++ (HANDLE) hProcess,
++ (LPCVOID) block->base,
+ buffer,
- (SIZE_T)block->size,
++ (SIZE_T) block->size,
+ &read) == FALSE)
+ {
+ result = ERROR_COULD_NOT_READ_PROCESS_MEMORY;
+
+ if (buffer != NULL)
+ {
+ yr_free(buffer);
+ buffer = NULL;
+ }
+ }
+
+ // TODO: compare read with block size
+ // it would be bad to assume block size bytes were read
+ *data = buffer;
return result;
}
@@@ -169,13 -180,53 +184,56 @@@
#include <mach/vm_region.h>
#include <mach/vm_statistics.h>
- int yr_process_get_memory(
- pid_t pid,
- YR_MEMORY_BLOCK** first_block)
+ typedef struct _YR_MACH_CONTEXT
{
task_t task;
+
+ } YR_MACH_CONTEXT;
+
-int _yr_attach_process(
++
++int _yr_process_attach(
+ int pid,
+ void** context)
+ {
- YR_MACH_CONTEXT* ctx = (YR_MACH_CONTEXT*)yr_malloc(sizeof(YR_MACH_CONTEXT));
++ YR_MACH_CONTEXT* ctx = (YR_MACH_CONTEXT*) yr_malloc(sizeof(YR_MACH_CONTEXT));
+ *context = ctx;
+
- if(ctx == NULL)
++ if (ctx == NULL)
+ return ERROR_INSUFICIENT_MEMORY;
+
kern_return_t kr;
+ if ((kr = task_for_pid(mach_task_self(), pid, &ctx->task)) != KERN_SUCCESS)
+ return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
+
+ return ERROR_SUCCESS;
+ }
+
-int _yr_detach_process(
++
++int _yr_process_detach(
+ void* context)
+ {
- if(context == NULL)
++ if (context == NULL)
+ return ERROR_SUCCESS;
+
+ YR_MACH_CONTEXT* ctx = (YR_MACH_CONTEXT*)context;
+
+ if (ctx->task != MACH_PORT_NULL)
+ mach_port_deallocate(mach_task_self(), ctx->task);
+
+ yr_free(ctx);
+
+ return ERROR_SUCCESS;
+ }
+
-int _yr_get_process_blocks(
++
++int _yr_process_get_blocks(
+ void* context,
+ YR_MEMORY_BLOCK** head)
+ {
+ YR_MACH_CONTEXT* ctx = (YR_MACH_CONTEXT*)context;
+
+ kern_return_t kr;
vm_size_t size = 0;
vm_address_t address = 0;
vm_region_basic_info_data_64_t info;
@@@ -207,45 -251,22 +258,22 @@@
if (kr == KERN_SUCCESS)
{
- data = (unsigned char*) yr_malloc(size);
- new_block = (YR_MEMORY_BLOCK*)yr_malloc(sizeof(YR_MEMORY_BLOCK));
++ new_block = (YR_MEMORY_BLOCK*) yr_malloc(sizeof(YR_MEMORY_BLOCK));
- if (data == NULL)
+ if (new_block == NULL)
return ERROR_INSUFICIENT_MEMORY;
- if (vm_read_overwrite(
- task,
- address,
- size,
- (vm_address_t)
- data,
- &size) == KERN_SUCCESS)
- {
- new_block = (YR_MEMORY_BLOCK*) yr_malloc(sizeof(YR_MEMORY_BLOCK));
-
- if (new_block == NULL)
- {
- yr_free(data);
- return ERROR_INSUFICIENT_MEMORY;
- }
-
- if (*first_block == NULL)
- *first_block = new_block;
-
- new_block->base = address;
- new_block->size = size;
- new_block->data = data;
- new_block->next = NULL;
-
- if (current_block != NULL)
- current_block->next = new_block;
-
- current_block = new_block;
- }
- else
- {
- yr_free(data);
- }
+ new_block->base = address;
+ new_block->size = size;
+ new_block->next = NULL;
+
+ if (*head == NULL)
+ *head = new_block;
+
+ if (current != NULL)
+ current->next = new_block;
+ current = new_block;
address += size;
}
@@@ -255,126 -275,317 +282,328 @@@
return ERROR_SUCCESS;
}
-int _yr_read_process_block(
++
++int _yr_process_read_block(
+ void* context,
+ YR_MEMORY_BLOCK* block,
+ uint8_t** data)
+ {
+ YR_MACH_CONTEXT* ctx = (YR_MACH_CONTEXT*)context;
+
+ int result = ERROR_SUCCESS;
+ uint8_t* buffer;
+ vm_size_t size = block->size;
+ *data = NULL;
+
- buffer = (uint8_t*)yr_malloc(size);
++ buffer = (uint8_t*) yr_malloc(size);
+
+ if (buffer == NULL)
+ return ERROR_INSUFICIENT_MEMORY;
+
+ if (vm_read_overwrite(
+ ctx->task,
+ block->base,
+ block->size,
- (vm_address_t)
- buffer,
++ (vm_address_t) buffer,
+ &size) != KERN_SUCCESS)
+ {
+ result = ERROR_COULD_NOT_READ_PROCESS_MEMORY;
+
+ if (buffer != NULL)
+ {
+ yr_free(buffer);
+ buffer = NULL;
+ }
+ }
+
+ // TODO: compare read with block size
+ // it would be bad to assume block size bytes were read
+ *data = buffer;
+
+ return result;
+ }
+
#else
#include <errno.h>
- int yr_process_get_memory(
- pid_t pid,
- YR_MEMORY_BLOCK** first_block)
+ typedef struct _YR_PTRACE_CONTEXT
+ {
+ int pid;
+ int mem_fd;
+ FILE* maps;
+ int attached;
+
+ } YR_PTRACE_CONTEXT;
+
-int _yr_attach_process(
++
++int _yr_process_attach(
+ int pid,
+ void** context)
{
char buffer[256];
- unsigned char* data = NULL;
- size_t begin, end, length;
- YR_MEMORY_BLOCK* new_block;
- YR_MEMORY_BLOCK* current_block = NULL;
- YR_PTRACE_CONTEXT* ctx = (YR_PTRACE_CONTEXT*)yr_malloc(sizeof(YR_PTRACE_CONTEXT));
++ YR_PTRACE_CONTEXT* ctx = (YR_PTRACE_CONTEXT*) yr_malloc(
++ sizeof(YR_PTRACE_CONTEXT));
+
- FILE *maps = NULL;
+ *context = ctx;
- int mem = -1;
- int result;
- int attached = 0;
+ if (ctx == NULL)
+ return ERROR_INSUFICIENT_MEMORY;
- *first_block = NULL;
+ ctx->pid = pid;
+ ctx->maps = NULL;
+ ctx->mem_fd = -1;
+ ctx->attached = 0;
snprintf(buffer, sizeof(buffer), "/proc/%u/maps", pid);
+ ctx->maps = fopen(buffer, "r");
- maps = fopen(buffer, "r");
-
- if (maps == NULL)
- {
- result = ERROR_COULD_NOT_ATTACH_TO_PROCESS;
- goto _exit;
- }
+ if (ctx->maps == NULL)
+ return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
snprintf(buffer, sizeof(buffer), "/proc/%u/mem", pid);
+ ctx->mem_fd = open(buffer, O_RDONLY);
- mem = open(buffer, O_RDONLY);
-
- if (mem == -1)
- {
- result = ERROR_COULD_NOT_ATTACH_TO_PROCESS;
- goto _exit;
- }
+ if (ctx->mem_fd == -1)
+ return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
if (ptrace(PTRACE_ATTACH, pid, NULL, 0) != -1)
- {
- attached = 1;
- }
+ ctx->attached = 1;
else
- {
- result = ERROR_COULD_NOT_ATTACH_TO_PROCESS;
- goto _exit;
- }
+ return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
wait(NULL);
- while (fgets(buffer, sizeof(buffer), maps) != NULL)
+ return ERROR_SUCCESS;
+ }
+
-int _yr_detach_process(
++
++int _yr_process_detach(
+ void* context)
+ {
+ if (context == NULL)
+ return ERROR_SUCCESS;
+
+ YR_PTRACE_CONTEXT* ctx = (YR_PTRACE_CONTEXT*)context;
+
+ if(ctx->attached)
+ ptrace(PTRACE_DETACH, ctx->pid, NULL, 0);
+
+ if (ctx->mem_fd != -1)
+ close(ctx->mem_fd);
+
+ if (ctx->maps != NULL)
+ fclose(ctx->maps);
+
+ yr_free(ctx);
+
+ return ERROR_SUCCESS;
+ }
+
-int _yr_get_process_blocks(
++
++int _yr_process_get_blocks(
+ void* context,
+ YR_MEMORY_BLOCK** head)
+ {
+ char buffer[256];
+ size_t begin, end;
+
+ YR_MEMORY_BLOCK* new_block;
+ YR_MEMORY_BLOCK* current = NULL;
+
+ YR_PTRACE_CONTEXT* ctx = (YR_PTRACE_CONTEXT*)context;
+
+ while (fgets(buffer, sizeof(buffer), ctx->maps) != NULL)
{
sscanf(buffer, "%zx-%zx", &begin, &end);
- length = end - begin;
- new_block = (YR_MEMORY_BLOCK*)yr_malloc(sizeof(YR_MEMORY_BLOCK));
++ new_block = (YR_MEMORY_BLOCK*) yr_malloc(sizeof(YR_MEMORY_BLOCK));
- data = yr_malloc(length);
+ if (new_block == NULL)
+ return ERROR_INSUFICIENT_MEMORY;
- if (data == NULL)
- {
- result = ERROR_INSUFICIENT_MEMORY;
- goto _exit;
- }
+ new_block->base = begin;
+ new_block->size = end - begin;
+ new_block->next = NULL;
- if (pread(mem, data, length, begin) != -1)
- {
- new_block = (YR_MEMORY_BLOCK*) yr_malloc(sizeof(YR_MEMORY_BLOCK));
+ if (*head == NULL)
+ *head = new_block;
- if (new_block == NULL)
- {
- result = ERROR_INSUFICIENT_MEMORY;
- goto _exit;
- }
+ if (current != NULL)
+ current->next = new_block;
- if (*first_block == NULL)
- *first_block = new_block;
+ current = new_block;
+ }
- new_block->base = begin;
- new_block->size = length;
- new_block->data = data;
- new_block->next = NULL;
+ return ERROR_SUCCESS;
+ }
- if (current_block != NULL)
- current_block->next = new_block;
-int _yr_read_process_block(
+
- current_block = new_block;
- }
- else
++int _yr_process_read_block(
+ void* context,
+ YR_MEMORY_BLOCK* block,
+ uint8_t** data)
+ {
+ uint8_t* buffer = NULL;
+ int result = ERROR_SUCCESS;
+ *data = NULL;
+
+ YR_PTRACE_CONTEXT* ctx = (YR_PTRACE_CONTEXT*)context;
+
- buffer = (uint8_t*)yr_malloc(block->size);
++ buffer = (uint8_t*) yr_malloc(block->size);
+
+ if (buffer == NULL)
+ return ERROR_INSUFICIENT_MEMORY;
+
+ if (pread(ctx->mem_fd, buffer, block->size, block->base) == -1)
+ {
+ result = ERROR_COULD_NOT_READ_PROCESS_MEMORY;
+
+ if (buffer != NULL)
{
- yr_free(data);
- data = NULL;
+ yr_free(buffer);
+ buffer = NULL;
}
}
- result = ERROR_SUCCESS;
+ *data = buffer;
+
+ return result;
+ }
+
+ #endif
+ #endif
- _exit:
+ // process iterator abstraction
- if (attached)
- ptrace(PTRACE_DETACH, pid, NULL, 0);
+ static void _yr_free_context_data(
+ YR_PROCESS_CONTEXT* context)
+ {
+ if (context->data != NULL)
+ {
+ yr_free(context->data);
+ context->data = NULL;
+ }
+ }
+
++
+ static YR_MEMORY_BLOCK* _yr_get_first_block(
+ YR_BLOCK_ITERATOR* iterator)
+ {
+ YR_PROCESS_CONTEXT* ctx = (YR_PROCESS_CONTEXT*)iterator->context;
+
+ _yr_free_context_data(ctx);
+ ctx->current = ctx->blocks;
+
+ return ctx->current;
+ }
+
++
+ static YR_MEMORY_BLOCK* _yr_get_next_block(
+ YR_BLOCK_ITERATOR* iterator)
+ {
+ YR_PROCESS_CONTEXT* ctx = (YR_PROCESS_CONTEXT*)iterator->context;
+
+ _yr_free_context_data(ctx);
+
+ if (ctx->current == NULL)
+ return NULL;
+
+ ctx->current = ctx->current->next;
+
+ return ctx->current;
+ }
+
++
+ static uint8_t* _yr_fetch_block_data(
+ YR_BLOCK_ITERATOR* iterator)
+ {
+ YR_PROCESS_CONTEXT* ctx = (YR_PROCESS_CONTEXT*)iterator->context;
- if (mem != -1)
- close(mem);
+ if (ctx->current == NULL)
+ return NULL;
- if (maps != NULL)
- fclose(maps);
+ // reuse cached data if available
+ if (ctx->data != NULL)
+ return ctx->data;
- if (data != NULL)
- yr_free(data);
+ _yr_free_context_data(ctx);
+
- _yr_read_process_block(
++ _yr_process_read_block(
+ ctx->process_context,
+ ctx->current,
+ &ctx->data);
+
+ // TODO should this return error code?
+ // On one hand it's useful, on the other failure
+ // is expected in cases when the section isn't
+ // readable and that's not a reason to exit
+
+ return ctx->data;
+ }
+
+
-int yr_open_process_iterator(
++int yr_process_open_iterator(
+ int pid,
+ YR_BLOCK_ITERATOR* iterator)
+ {
- YR_PROCESS_CONTEXT* context = (YR_PROCESS_CONTEXT*)yr_malloc(sizeof(YR_PROCESS_CONTEXT));
++ YR_PROCESS_CONTEXT* context = (YR_PROCESS_CONTEXT*) yr_malloc(
++ sizeof(YR_PROCESS_CONTEXT));
+
+ if (context == NULL)
+ return ERROR_INSUFICIENT_MEMORY;
+
+ context->blocks = NULL;
+ context->current = NULL;
+ context->data = NULL;
+ context->process_context = NULL;
+
+ iterator->context = context;
+ iterator->first = _yr_get_first_block;
+ iterator->next = _yr_get_next_block;
+ iterator->fetch_data = _yr_fetch_block_data;
+
- int result = _yr_attach_process(
++ int result = _yr_process_attach(
+ pid,
+ &context->process_context);
+
- if(result == ERROR_SUCCESS)
- result = _yr_get_process_blocks(
++ if (result == ERROR_SUCCESS)
++ result = _yr_process_get_blocks(
+ context->process_context,
+ &context->blocks);
return result;
}
- #endif
- #endif
-int yr_close_process_iterator(
++
++int yr_process_close_iterator(
+ YR_BLOCK_ITERATOR* iterator)
+ {
- YR_PROCESS_CONTEXT* ctx = (YR_PROCESS_CONTEXT*)iterator->context;
++ YR_PROCESS_CONTEXT* ctx = (YR_PROCESS_CONTEXT*) iterator->context;
+
+ if (ctx == NULL)
+ return ERROR_SUCCESS;
+
+ // NOTE: detach must free allocated process context
- _yr_detach_process(ctx->process_context);
++ _yr_process_detach(ctx->process_context);
+
+ _yr_free_context_data(ctx);
+
+ YR_MEMORY_BLOCK* current = ctx->blocks;
+ YR_MEMORY_BLOCK* next;
+
+ // free blocks list
+ while(current != NULL)
+ {
+ next = current->next;
+ yr_free(current);
+ current = next;
+ }
+
+ // free the context
+ yr_free(iterator->context);
+ iterator->context = NULL;
+
+ return ERROR_SUCCESS;
+ }
diff --cc libyara/rules.c
index c6cad2a,cd82642..e44d1de
--- a/libyara/rules.c
+++ b/libyara/rules.c
@@@ -246,67 -258,92 +247,62 @@@ int _yr_rules_scan_mem_block
{
FAIL_ON_ERROR(yr_scan_verify_match(
context,
- ac_match,
+ match,
- block->data,
+ block_data,
block->size,
block->base,
- i - ac_match->backtrack));
+ i - match->backtrack));
}
- ac_match = ac_match->next;
+ match = match->next;
}
- index = block->data[i++] + 1;
- next_state = yr_ac_next_state(current_state, block_data[i]);
++ index = block_data[i++] + 1;
+ transition = transition_table[state + index];
- while (next_state == NULL && current_state->depth > 0)
+ while (YR_AC_INVALID_TRANSITION(transition, index))
{
- current_state = current_state->failure;
- next_state = yr_ac_next_state(current_state, block_data[i]);
+ if (state != YR_AC_ROOT_STATE)
+ {
+ state = transition_table[state] >> 32;
+ transition = transition_table[state + index];
+ }
+ else
+ {
+ transition = 0;
+ break;
+ }
}
- if (next_state != NULL)
- current_state = next_state;
-
- i++;
+ state = transition >> 32;
- if (timeout > 0 && i % 256 == 0)
- {
- if (difftime(time(NULL), start_time) > timeout)
- return ERROR_SCAN_TIMEOUT;
- }
}
-
- ac_match = current_state->matches;
+ match = match_table[state].match;
- while (ac_match != NULL)
+ while (match != NULL)
{
- if (ac_match->backtrack <= block->size)
+ if (match->backtrack <= i)
{
FAIL_ON_ERROR(yr_scan_verify_match(
context,
- ac_match,
+ match,
- block->data,
+ block_data,
block->size,
block->base,
- block->size - ac_match->backtrack));
+ i - match->backtrack));
}
- ac_match = ac_match->next;
+ match = match->next;
}
-
-
return ERROR_SUCCESS;
}
-// single block iterator impl
-static YR_MEMORY_BLOCK* _yr_get_first_block(
- YR_BLOCK_ITERATOR* iterator)
-{
- YR_BLOCK_CONTEXT* ctx = (YR_BLOCK_CONTEXT*)iterator->context;
- return ctx->block;
-}
-
-static YR_MEMORY_BLOCK* _yr_get_next_block(
- YR_BLOCK_ITERATOR* iterator)
-{
- return NULL;
-}
-
-static uint8_t* _yr_fetch_block_data(
- YR_BLOCK_ITERATOR* iterator)
-{
- YR_BLOCK_CONTEXT* ctx = (YR_BLOCK_CONTEXT*)iterator->context;
- return ctx->data;
-}
-
-static void _yr_init_single_block_iterator(
- YR_BLOCK_ITERATOR* iterator,
- YR_BLOCK_CONTEXT* context)
-{
- iterator->context = context;
- iterator->first = _yr_get_first_block;
- iterator->next = _yr_get_next_block;
- iterator->fetch_data = _yr_fetch_block_data;
-}
-
-
-
YR_API int yr_rules_scan_mem_blocks(
YR_RULES* rules,
- YR_MEMORY_BLOCK* block,
+ YR_BLOCK_ITERATOR* iterator,
int flags,
YR_CALLBACK_FUNC callback,
void* user_data,
@@@ -501,6 -559,6 +510,29 @@@ _exit
}
++static YR_MEMORY_BLOCK* _yr_get_first_block(
++ YR_BLOCK_ITERATOR* iterator)
++{
++ YR_BLOCK_CONTEXT* ctx = (YR_BLOCK_CONTEXT*) iterator->context;
++ return ctx->block;
++}
++
++
++static YR_MEMORY_BLOCK* _yr_get_next_block(
++ YR_BLOCK_ITERATOR* iterator)
++{
++ return NULL;
++}
++
++
++static uint8_t* _yr_fetch_block_data(
++ YR_BLOCK_ITERATOR* iterator)
++{
++ YR_BLOCK_CONTEXT* ctx = (YR_BLOCK_CONTEXT*) iterator->context;
++ return ctx->data;
++}
++
++
YR_API int yr_rules_scan_mem(
YR_RULES* rules,
uint8_t* buffer,
@@@ -517,9 -576,16 +550,17 @@@
block.base = 0;
block.next = NULL;
+ context.block = █
+ context.data = buffer;
+
- _yr_init_single_block_iterator(
- &iterator,
- &context);
++ iterator.context = &context;
++ iterator.first = _yr_get_first_block;
++ iterator.next = _yr_get_next_block;
++ iterator.fetch_data = _yr_fetch_block_data;
+
return yr_rules_scan_mem_blocks(
rules,
- &block,
+ &iterator,
flags,
callback,
user_data,
@@@ -556,6 -622,6 +597,7 @@@ YR_API int yr_rules_scan_file
return result;
}
++
YR_API int yr_rules_scan_fd(
YR_RULES* rules,
YR_FILE_DESCRIPTOR fd,
@@@ -585,6 -651,6 +627,7 @@@
return result;
}
++
YR_API int yr_rules_scan_proc(
YR_RULES* rules,
int pid,
@@@ -593,11 -659,11 +636,11 @@@
void* user_data,
int timeout)
{
- YR_MEMORY_BLOCK* first_block;
- YR_MEMORY_BLOCK* next_block;
- YR_MEMORY_BLOCK* block;
+ YR_BLOCK_ITERATOR iterator;
- int result = yr_process_get_memory(pid, &first_block);
- int result = yr_open_process_iterator(
++ int result = yr_process_open_iterator(
+ pid,
+ &iterator);
if (result == ERROR_SUCCESS)
result = yr_rules_scan_mem_blocks(
@@@ -608,17 -674,7 +651,7 @@@
user_data,
timeout);
- block = first_block;
-
- while (block != NULL)
- {
- next_block = block->next;
-
- yr_free(block->data);
- yr_free(block);
-
- block = next_block;
- }
- yr_close_process_iterator(&iterator);
++ yr_process_close_iterator(&iterator);
return result;
}
--
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