[Forensics-changes] [yara] 343/368: Improve mem block iterators (#471)
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 3b6e21e9ca066e5c29f8dff942680cf5715feae0
Author: Victor M. Alvarez <plusvic at gmail.com>
Date: Mon Jun 27 15:00:15 2016 +0200
Improve mem block iterators (#471)
* Improve process memory iterators (Linux & Mac OS X)
* Fix some issues in previous commit
* Improve process memory iterators (Windows)
* Fix issues with previous commit
---
libyara/exec.c | 4 +-
libyara/include/yara/proc.h | 4 +-
libyara/include/yara/types.h | 54 ++--
libyara/modules/elf.c | 4 +-
libyara/modules/hash.c | 16 +-
libyara/modules/magic.c | 22 +-
libyara/modules/math.c | 20 +-
libyara/modules/pe.c | 4 +-
libyara/proc.c | 592 ++++++++++++++++++-------------------------
libyara/rules.c | 37 ++-
10 files changed, 318 insertions(+), 439 deletions(-)
diff --git a/libyara/exec.c b/libyara/exec.c
index c312fd8..b0a79b6 100644
--- a/libyara/exec.c
+++ b/libyara/exec.c
@@ -112,7 +112,7 @@ typedef union _STACK_ITEM {
#define function_read(type, endianess) \
- int64_t read_##type##_##endianess(YR_BLOCK_ITERATOR* iterator, size_t offset) \
+ int64_t read_##type##_##endianess(YR_MEMORY_BLOCK_ITERATOR* iterator, size_t offset) \
{ \
YR_MEMORY_BLOCK* block = iterator->first(iterator); \
while (block != NULL) \
@@ -122,7 +122,7 @@ typedef union _STACK_ITEM {
offset <= block->base + block->size - sizeof(type)) \
{ \
type result; \
- uint8_t* data = iterator->fetch_data(iterator); \
+ uint8_t* data = block->fetch_data(block); \
if (data == NULL) \
return UNDEFINED; \
result = *(type *)(data + offset - block->base); \
diff --git a/libyara/include/yara/proc.h b/libyara/include/yara/proc.h
index 7ce7c5f..644bce8 100644
--- a/libyara/include/yara/proc.h
+++ b/libyara/include/yara/proc.h
@@ -34,9 +34,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
int yr_process_open_iterator(
int pid,
- YR_BLOCK_ITERATOR* iterator);
+ YR_MEMORY_BLOCK_ITERATOR* iterator);
int yr_process_close_iterator(
- YR_BLOCK_ITERATOR* iterator);
+ YR_MEMORY_BLOCK_ITERATOR* iterator);
#endif
diff --git a/libyara/include/yara/types.h b/libyara/include/yara/types.h
index 2f1b874..bdacaa9 100644
--- a/libyara/include/yara/types.h
+++ b/libyara/include/yara/types.h
@@ -382,55 +382,39 @@ typedef struct _YR_RULES {
} YR_RULES;
-// memory block iteration types
-typedef struct _YR_MEMORY_BLOCK
-{
- size_t size;
- size_t base;
-
- struct _YR_MEMORY_BLOCK* next;
-} YR_MEMORY_BLOCK;
-
-
-typedef struct _YR_BLOCK_ITERATOR YR_BLOCK_ITERATOR;
+struct _YR_MEMORY_BLOCK;
+struct _YR_MEMORY_BLOCK_ITERATOR;
-typedef YR_MEMORY_BLOCK* (*YR_BLOCK_ITERATOR_MOVE)(
- YR_BLOCK_ITERATOR* self);
+typedef uint8_t* (*YR_MEMORY_BLOCK_FETCH_DATA_FUNC)(
+ struct _YR_MEMORY_BLOCK* self);
-typedef uint8_t* (*YR_BLOCK_ITERATOR_FETCH)(
- YR_BLOCK_ITERATOR* self);
+typedef struct _YR_MEMORY_BLOCK* (*YR_MEMORY_BLOCK_ITERATOR_FUNC)(
+ struct _YR_MEMORY_BLOCK_ITERATOR* self);
-struct _YR_BLOCK_ITERATOR
+typedef struct _YR_MEMORY_BLOCK
{
- void* context;
-
- YR_BLOCK_ITERATOR_MOVE first;
- YR_BLOCK_ITERATOR_MOVE next;
- YR_BLOCK_ITERATOR_FETCH fetch_data;
+ size_t size;
+ size_t base;
-};
+ void* context;
-// a memory block in context with its data
-typedef struct _YR_BLOCK_CONTEXT
-{
- uint8_t* data;
- YR_MEMORY_BLOCK* block;
+ YR_MEMORY_BLOCK_FETCH_DATA_FUNC fetch_data;
-} YR_BLOCK_CONTEXT;
+} YR_MEMORY_BLOCK;
-typedef struct _YR_PROCESS_CONTEXT
+typedef struct _YR_MEMORY_BLOCK_ITERATOR
{
- uint8_t* data;
- void* process_context;
- YR_MEMORY_BLOCK* blocks;
- YR_MEMORY_BLOCK* current;
+ void* context;
+
+ YR_MEMORY_BLOCK_ITERATOR_FUNC first;
+ YR_MEMORY_BLOCK_ITERATOR_FUNC next;
-} YR_PROCESS_CONTEXT;
+} YR_MEMORY_BLOCK_ITERATOR;
typedef int (*YR_CALLBACK_FUNC)(
@@ -449,7 +433,7 @@ typedef struct _YR_SCAN_CONTEXT
void* user_data;
- YR_BLOCK_ITERATOR* iterator;
+ YR_MEMORY_BLOCK_ITERATOR* iterator;
YR_HASH_TABLE* objects_table;
YR_CALLBACK_FUNC callback;
diff --git a/libyara/modules/elf.c b/libyara/modules/elf.c
index bc0e6af..ed4ccd1 100644
--- a/libyara/modules/elf.c
+++ b/libyara/modules/elf.c
@@ -324,7 +324,7 @@ int module_load(
size_t module_data_size)
{
YR_MEMORY_BLOCK* block;
- YR_BLOCK_ITERATOR* iterator = context->iterator;
+ YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
elf32_header_t* elf_header32;
elf64_header_t* elf_header64;
@@ -384,7 +384,7 @@ int module_load(
foreach_memory_block(iterator, block)
{
- uint8_t* block_data = iterator->fetch_data(iterator);
+ uint8_t* block_data = block->fetch_data(block);
if (block_data == NULL)
continue;
diff --git a/libyara/modules/hash.c b/libyara/modules/hash.c
index 0571371..63d4219 100644
--- a/libyara/modules/hash.c
+++ b/libyara/modules/hash.c
@@ -135,7 +135,7 @@ define_function(data_md5)
YR_SCAN_CONTEXT* context = scan_context();
YR_MEMORY_BLOCK* block = first_memory_block(context);
- YR_BLOCK_ITERATOR* iterator = context->iterator;
+ 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
@@ -154,7 +154,7 @@ define_function(data_md5)
if (offset >= block->base &&
offset < block->base + block->size)
{
- uint8_t* block_data = iterator->fetch_data(iterator);
+ uint8_t* block_data = block->fetch_data(block);
if (block_data != NULL)
{
@@ -210,7 +210,7 @@ define_function(data_sha1)
YR_SCAN_CONTEXT* context = scan_context();
YR_MEMORY_BLOCK* block = first_memory_block(context);
- YR_BLOCK_ITERATOR* iterator = context->iterator;
+ YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
SHA1_Init(&sha_context);
@@ -225,7 +225,7 @@ define_function(data_sha1)
if (offset >= block->base &&
offset < block->base + block->size)
{
- uint8_t* block_data = iterator->fetch_data(iterator);
+ uint8_t* block_data = block->fetch_data(block);
if (block_data != NULL)
{
@@ -281,7 +281,7 @@ define_function(data_sha256)
YR_SCAN_CONTEXT* context = scan_context();
YR_MEMORY_BLOCK* block = first_memory_block(context);
- YR_BLOCK_ITERATOR* iterator = context->iterator;
+ YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
SHA256_Init(&sha256_context);
@@ -296,7 +296,7 @@ define_function(data_sha256)
if (offset >= block->base &&
offset < block->base + block->size)
{
- uint8_t* block_data = iterator->fetch_data(iterator);
+ uint8_t* block_data = block->fetch_data(block);
if (block_data != NULL)
{
@@ -344,7 +344,7 @@ define_function(data_checksum32)
YR_SCAN_CONTEXT* context = scan_context();
YR_MEMORY_BLOCK* block = first_memory_block(context);
- YR_BLOCK_ITERATOR* iterator = context->iterator;
+ YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
uint32_t checksum = 0;
int past_first_block = FALSE;
@@ -359,7 +359,7 @@ define_function(data_checksum32)
if (offset >= block->base &&
offset < block->base + block->size)
{
- uint8_t* block_data = iterator->fetch_data(iterator);
+ uint8_t* block_data = block->fetch_data(block);
if (block_data != NULL)
{
diff --git a/libyara/modules/magic.c b/libyara/modules/magic.c
index 1e81941..f7beb23 100644
--- a/libyara/modules/magic.c
+++ b/libyara/modules/magic.c
@@ -48,7 +48,9 @@ define_function(magic_mime_type)
{
YR_MEMORY_BLOCK* block;
YR_SCAN_CONTEXT* context = scan_context();
- YR_BLOCK_ITERATOR* iterator = context->iterator;
+ YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
+
+ uint8_t* block_data;
if (context->flags & SCAN_FLAGS_PROCESS_MEMORY)
return_string(UNDEFINED);
@@ -56,15 +58,15 @@ define_function(magic_mime_type)
if (cached_mime_types[context->tidx] == NULL)
{
block = first_memory_block(context);
+ block_data = block->fetch_data(block);
- magic_setflags(magic_cookie[context->tidx], MAGIC_MIME_TYPE);
-
- uint8_t* block_data = iterator->fetch_data(iterator);
if (block_data != NULL)
{
+ magic_setflags(magic_cookie[context->tidx], MAGIC_MIME_TYPE);
+
cached_mime_types[context->tidx] = magic_buffer(
+ magic_cookie[context->tidx],
block_data,
- context->iterator->fetch_data((context)->iterator),
block->size);
}
}
@@ -80,7 +82,9 @@ define_function(magic_type)
{
YR_MEMORY_BLOCK* block;
YR_SCAN_CONTEXT* context = scan_context();
- YR_BLOCK_ITERATOR* iterator = context->iterator;
+ YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
+
+ uint8_t* block_data;
if (context->flags & SCAN_FLAGS_PROCESS_MEMORY)
return_string(UNDEFINED);
@@ -88,12 +92,12 @@ define_function(magic_type)
if (cached_types[context->tidx] == NULL)
{
block = first_memory_block(context);
+ block_data = block->fetch_data(block);
- magic_setflags(magic_cookie[context->tidx], 0);
-
- uint8_t* block_data = iterator->fetch_data(iterator);
if (block_data != NULL)
{
+ magic_setflags(magic_cookie[context->tidx], 0);
+
cached_types[context->tidx] = magic_buffer(
magic_cookie[context->tidx],
block_data,
diff --git a/libyara/modules/math.c b/libyara/modules/math.c
index 6eefe24..1c38b3d 100644
--- a/libyara/modules/math.c
+++ b/libyara/modules/math.c
@@ -93,7 +93,7 @@ define_function(data_entropy)
YR_SCAN_CONTEXT* context = scan_context();
YR_MEMORY_BLOCK* block = first_memory_block(context);
- YR_BLOCK_ITERATOR* iterator = context->iterator;
+ YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
if (offset < 0 || length < 0 || offset < block->base)
return_float(UNDEFINED);
@@ -112,7 +112,7 @@ define_function(data_entropy)
size_t data_len = (size_t) yr_min(
length, (size_t) (block->size - data_offset));
- uint8_t* block_data = iterator->fetch_data(iterator);
+ uint8_t* block_data = block->fetch_data(block);
if (block_data == NULL)
{
@@ -199,7 +199,7 @@ define_function(data_deviation)
YR_SCAN_CONTEXT* context = scan_context();
YR_MEMORY_BLOCK* block = first_memory_block(context);
- YR_BLOCK_ITERATOR* iterator = context->iterator;
+ YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
if (offset < 0 || length < 0 || offset < block->base)
return_float(UNDEFINED);
@@ -209,7 +209,7 @@ define_function(data_deviation)
if (offset >= block->base &&
offset < block->base + block->size)
{
- uint8_t* block_data = iterator->fetch_data(iterator);
+ uint8_t* block_data = block->fetch_data(block);
if (block_data == NULL)
return_float(UNDEFINED);
@@ -272,7 +272,7 @@ define_function(data_mean)
YR_SCAN_CONTEXT* context = scan_context();
YR_MEMORY_BLOCK* block = first_memory_block(context);
- YR_BLOCK_ITERATOR* iterator = context->iterator;
+ YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
size_t total_len = 0;
size_t i;
@@ -289,7 +289,7 @@ define_function(data_mean)
size_t data_len = (size_t) yr_min(
length, (size_t) (block->size - data_offset));
- uint8_t* block_data = iterator->fetch_data(iterator);
+ uint8_t* block_data = block->fetch_data(block);
if (block_data == NULL)
return_float(UNDEFINED);
@@ -336,7 +336,7 @@ define_function(data_serial_correlation)
YR_SCAN_CONTEXT* context = scan_context();
YR_MEMORY_BLOCK* block = first_memory_block(context);
- YR_BLOCK_ITERATOR* iterator = context->iterator;
+ YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
double sccun = 0;
double scclast = 0;
@@ -357,7 +357,7 @@ define_function(data_serial_correlation)
size_t data_len = (size_t) yr_min(
length, (size_t) (block->size - data_offset));
- uint8_t* block_data = iterator->fetch_data(iterator);
+ uint8_t* block_data = block->fetch_data(block);
if (block_data == NULL)
return_float(UNDEFINED);
@@ -460,7 +460,7 @@ define_function(data_monte_carlo_pi)
YR_SCAN_CONTEXT* context = scan_context();
YR_MEMORY_BLOCK* block = first_memory_block(context);
- YR_BLOCK_ITERATOR* iterator = context->iterator;
+ YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
if (offset < 0 || length < 0 || offset < block->base)
return_float(UNDEFINED);
@@ -476,7 +476,7 @@ define_function(data_monte_carlo_pi)
size_t data_len = (size_t) yr_min(
length, (size_t) (block->size - data_offset));
- uint8_t* block_data = iterator->fetch_data(iterator);
+ uint8_t* block_data = block->fetch_data(block);
if (block_data == NULL)
return_float(UNDEFINED);
diff --git a/libyara/modules/pe.c b/libyara/modules/pe.c
index 99579f6..4f7a93c 100644
--- a/libyara/modules/pe.c
+++ b/libyara/modules/pe.c
@@ -2263,7 +2263,7 @@ int module_load(
size_t module_data_size)
{
YR_MEMORY_BLOCK* block;
- YR_BLOCK_ITERATOR* iterator = context->iterator;
+ YR_MEMORY_BLOCK_ITERATOR* iterator = context->iterator;
set_integer(
IMAGE_FILE_MACHINE_UNKNOWN, module_object,
@@ -2506,7 +2506,7 @@ int module_load(
foreach_memory_block(iterator, block)
{
- uint8_t* block_data = iterator->fetch_data(iterator);
+ uint8_t* block_data = block->fetch_data(block);
if (block_data == NULL)
continue;
diff --git a/libyara/proc.c b/libyara/proc.c
index 44e0b78..21c21cb 100644
--- a/libyara/proc.c
+++ b/libyara/proc.c
@@ -35,17 +35,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <yara/error.h>
#include <yara/proc.h>
+// Windows
+
+typedef struct _YR_PROC_ITERATOR_CTX
+{
+ HANDLE hProcess;
+ uint8_t* buffer;
+ size_t buffer_size;
+ SYSTEM_INFO si;
+ YR_MEMORY_BLOCK current_block;
+
+} YR_PROC_ITERATOR_CTX;
+
int _yr_process_attach(
int pid,
- void** hProcess)
+ YR_PROC_ITERATOR_CTX* context)
{
TOKEN_PRIVILEGES tokenPriv;
LUID luidDebug;
HANDLE hToken = NULL;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken) &&
- LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidDebug))
+ LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidDebug))
{
tokenPriv.PrivilegeCount = 1;
tokenPriv.Privileges[0].Luid = luidDebug;
@@ -63,109 +75,102 @@ int _yr_process_attach(
if (hToken != NULL)
CloseHandle(hToken);
- *hProcess = OpenProcess(
+ context->hProcess = OpenProcess(
PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
FALSE,
pid);
- if (*hProcess == NULL)
+ if (context->hProcess == NULL)
return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
+ GetSystemInfo(&context->si);
+
return ERROR_SUCCESS;
}
int _yr_process_detach(
- void* hProcess)
+ YR_PROC_ITERATOR_CTX* context)
{
- if (hProcess != NULL)
- CloseHandle(hProcess);
-
+ CloseHandle(context->hProcess);
return ERROR_SUCCESS;
}
-int _yr_process_get_blocks(
- void* hProcess,
- YR_MEMORY_BLOCK** head)
+uint8_t* _yr_fetch_block_data(
+ YR_MEMORY_BLOCK* block)
{
- PVOID address;
- YR_MEMORY_BLOCK* new_block;
- YR_MEMORY_BLOCK* current = NULL;
- SYSTEM_INFO si;
- MEMORY_BASIC_INFORMATION mbi;
+ YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) block->context;
+ SIZE_T read;
- GetSystemInfo(&si);
- address = si.lpMinimumApplicationAddress;
+ if (context->buffer_size < block->size)
+ {
+ if (context->buffer != NULL)
+ yr_free(context->buffer);
- *head = NULL;
+ context->buffer = (uint8_t*) yr_malloc(block->size);
- while (address < si.lpMaximumApplicationAddress &&
- VirtualQueryEx(hProcess, address, &mbi, sizeof(mbi)) != 0)
- {
- if (mbi.State == MEM_COMMIT && ((mbi.Protect & PAGE_NOACCESS) == 0))
+ if (context->buffer != NULL)
{
- new_block = (YR_MEMORY_BLOCK*) yr_malloc(sizeof(YR_MEMORY_BLOCK));
+ context->buffer_size = block->size;
+ }
+ else
+ {
+ context->buffer_size = 0;
+ return NULL;
+ }
+ }
- if (new_block == NULL)
- return ERROR_INSUFICIENT_MEMORY;
+ if (ReadProcessMemory(
+ context->hProcess,
+ (LPCVOID) block->base,
+ context->buffer,
+ (SIZE_T) block->size,
+ &read) == FALSE)
+ {
+ return NULL;
+ }
+
+ return context->buffer;
+}
- new_block->base = (size_t) mbi.BaseAddress;
- new_block->size = mbi.RegionSize;
- new_block->next = NULL;
- if (*head == NULL)
- *head = new_block;
+YR_MEMORY_BLOCK* _yr_get_next_block(
+ YR_MEMORY_BLOCK_ITERATOR* iterator)
+{
+ YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
+
+ MEMORY_BASIC_INFORMATION mbi;
+ PVOID address = (PVOID) (context->current_block.base + \
+ context->current_block.size);
- if (current != NULL)
- current->next = new_block;
+ while (address < context->si.lpMaximumApplicationAddress &&
+ VirtualQueryEx(context->hProcess, address, &mbi, sizeof(mbi)) != 0)
+ {
+ if (mbi.State == MEM_COMMIT && ((mbi.Protect & PAGE_NOACCESS) == 0))
+ {
+ context->current_block.base = (size_t) mbi.BaseAddress;
+ context->current_block.size = mbi.RegionSize;
- current = new_block;
+ return &context->current_block;
}
address = (uint8_t*) address + mbi.RegionSize;
}
- return ERROR_SUCCESS;
+ return NULL;
}
-int _yr_process_read_block(
- void* hProcess,
- YR_MEMORY_BLOCK* block,
- uint8_t** data)
+YR_MEMORY_BLOCK* _yr_get_first_block(
+ YR_MEMORY_BLOCK_ITERATOR* iterator)
{
- SIZE_T read;
- uint8_t* buffer = NULL;
- int result = ERROR_SUCCESS;
- *data = NULL;
-
- buffer = (uint8_t*) yr_malloc(block->size);
-
- if (buffer == NULL)
- return ERROR_INSUFICIENT_MEMORY;
-
- if (ReadProcessMemory(
- (HANDLE) hProcess,
- (LPCVOID) block->base,
- buffer,
- (SIZE_T) block->size,
- &read) == FALSE)
- {
- result = ERROR_COULD_NOT_READ_PROCESS_MEMORY;
-
- if (buffer != NULL)
- {
- yr_free(buffer);
- buffer = NULL;
- }
- }
+ YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
- // TODO: compare read with block size
- // it would be bad to assume block size bytes were read
- *data = buffer;
+ context->current_block.base = (size_t) context->si.lpMinimumApplicationAddress;
+ context->current_block.size = 0;
- return result;
+ return _yr_get_next_block(iterator);
}
#else
@@ -199,26 +204,25 @@ int _yr_process_read_block(
#include <mach/vm_region.h>
#include <mach/vm_statistics.h>
-typedef struct _YR_MACH_CONTEXT
-{
- task_t task;
+// Mac OS X
-} YR_MACH_CONTEXT;
+typedef struct _YR_PROC_ITERATOR_CTX {
+ task_t task;
+ uint8_t* buffer;
+ size_t buffer_size;
+ YR_MEMORY_BLOCK current_block;
-int _yr_process_attach(
- int pid,
- void** context)
-{
- YR_MACH_CONTEXT* ctx = (YR_MACH_CONTEXT*) yr_malloc(sizeof(YR_MACH_CONTEXT));
- *context = ctx;
+} YR_PROC_ITERATOR_CTX;
- if (ctx == NULL)
- return ERROR_INSUFICIENT_MEMORY;
- kern_return_t kr;
+int _yr_process_attach(
+ int pid,
+ YR_PROC_ITERATOR_CTX* context)
+{
+ kern_return_t kr = task_for_pid(mach_task_self(), pid, &context->task);
- if ((kr = task_for_pid(mach_task_self(), pid, &ctx->task)) != KERN_SUCCESS)
+ if (kr != KERN_SUCCESS)
return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
return ERROR_SUCCESS;
@@ -226,46 +230,71 @@ int _yr_process_attach(
int _yr_process_detach(
- void* context)
+ YR_PROC_ITERATOR_CTX* context)
{
- if (context == NULL)
- return ERROR_SUCCESS;
+ if (context->task != MACH_PORT_NULL)
+ mach_port_deallocate(mach_task_self(), context->task);
- YR_MACH_CONTEXT* ctx = (YR_MACH_CONTEXT*)context;
+ return ERROR_SUCCESS;
+}
- if (ctx->task != MACH_PORT_NULL)
- mach_port_deallocate(mach_task_self(), ctx->task);
- yr_free(ctx);
+uint8_t* _yr_fetch_block_data(
+ YR_MEMORY_BLOCK* block)
+{
+ YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) block->context;
+ vm_size_t size = block->size;
- return ERROR_SUCCESS;
+ if (context->buffer_size < block->size)
+ {
+ if (context->buffer != NULL)
+ yr_free(context->buffer);
+
+ context->buffer = yr_malloc(block->size);
+
+ if (context->buffer != NULL)
+ {
+ context->buffer_size = block->size;
+ }
+ else
+ {
+ context->buffer_size = 0;
+ return NULL;
+ }
+ }
+
+ if (vm_read_overwrite(
+ context->task,
+ block->base,
+ block->size,
+ (vm_address_t) context->buffer,
+ &size) != KERN_SUCCESS)
+ {
+ return NULL;
+ }
+
+ return context->buffer;
}
-int _yr_process_get_blocks(
- void* context,
- YR_MEMORY_BLOCK** head)
+YR_MEMORY_BLOCK* _yr_get_next_block(
+ YR_MEMORY_BLOCK_ITERATOR* iterator)
{
- YR_MACH_CONTEXT* ctx = (YR_MACH_CONTEXT*)context;
+ YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
kern_return_t kr;
- vm_size_t size = 0;
- vm_address_t address = 0;
- vm_region_basic_info_data_64_t info;
mach_msg_type_number_t info_count;
mach_port_t object;
-
- YR_MEMORY_BLOCK* new_block;
- YR_MEMORY_BLOCK* current = NULL;
-
- *head = NULL;
-
+ vm_region_basic_info_data_64_t info;
+ vm_size_t size = 0;
+ vm_address_t address = context->current_block.base \
+ + context->current_block.size;
do
{
info_count = VM_REGION_BASIC_INFO_COUNT_64;
kr = vm_region_64(
- ctx->task,
+ context->task,
&address,
&size,
VM_REGION_BASIC_INFO,
@@ -275,354 +304,219 @@ int _yr_process_get_blocks(
if (kr == KERN_SUCCESS)
{
- new_block = (YR_MEMORY_BLOCK*) yr_malloc(sizeof(YR_MEMORY_BLOCK));
-
- if (new_block == NULL)
- return ERROR_INSUFICIENT_MEMORY;
+ context->current_block.base = address;
+ context->current_block.size = size;
- 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;
+ return &context->current_block;
}
} while (kr != KERN_INVALID_ADDRESS);
- return ERROR_SUCCESS;
+ return NULL;
}
-int _yr_process_read_block(
- void* context,
- YR_MEMORY_BLOCK* block,
- uint8_t** data)
+YR_MEMORY_BLOCK* _yr_get_first_block(
+ YR_MEMORY_BLOCK_ITERATOR* iterator)
{
- YR_MACH_CONTEXT* ctx = (YR_MACH_CONTEXT*)context;
+ YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
- int result = ERROR_SUCCESS;
- uint8_t* buffer;
- vm_size_t size = block->size;
- *data = NULL;
+ context->current_block.base = 0;
+ context->current_block.size = 0;
- buffer = (uint8_t*) yr_malloc(size);
+ return _yr_get_next_block(iterator);
+}
- if (buffer == NULL)
- return ERROR_INSUFICIENT_MEMORY;
- if (vm_read_overwrite(
- ctx->task,
- block->base,
- block->size,
- (vm_address_t) buffer,
- &size) != KERN_SUCCESS)
- {
- result = ERROR_COULD_NOT_READ_PROCESS_MEMORY;
+#else
- if (buffer != NULL)
- {
- yr_free(buffer);
- buffer = NULL;
- }
- }
+#include <errno.h>
- // TODO: compare read with block size
- // it would be bad to assume block size bytes were read
- *data = buffer;
+// Linux
- return result;
-}
-#else
+typedef struct _YR_PROC_ITERATOR_CTX {
-#include <errno.h>
+ int pid;
+ int mem_fd;
+ FILE* maps;
+ uint8_t* buffer;
+ size_t buffer_size;
+ YR_MEMORY_BLOCK current_block;
-typedef struct _YR_PTRACE_CONTEXT
-{
- int pid;
- int mem_fd;
- FILE* maps;
- int attached;
+} YR_PROC_ITERATOR_CTX;
-} YR_PTRACE_CONTEXT;
int _yr_process_attach(
- int pid,
- void** context)
+ int pid,
+ YR_PROC_ITERATOR_CTX* context)
{
char buffer[256];
- YR_PTRACE_CONTEXT* ctx = (YR_PTRACE_CONTEXT*) yr_malloc(
- sizeof(YR_PTRACE_CONTEXT));
-
- *context = ctx;
-
- if (ctx == NULL)
- return ERROR_INSUFICIENT_MEMORY;
-
- ctx->pid = pid;
- ctx->maps = NULL;
- ctx->mem_fd = -1;
- ctx->attached = 0;
+ context->pid = pid;
+ context->maps = NULL;
+ context->mem_fd = -1;
snprintf(buffer, sizeof(buffer), "/proc/%u/maps", pid);
- ctx->maps = fopen(buffer, "r");
+ context->maps = fopen(buffer, "r");
- if (ctx->maps == NULL)
+ if (context->maps == NULL)
return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
snprintf(buffer, sizeof(buffer), "/proc/%u/mem", pid);
- ctx->mem_fd = open(buffer, O_RDONLY);
+ context->mem_fd = open(buffer, O_RDONLY);
- if (ctx->mem_fd == -1)
- return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
+ if (context->mem_fd == -1)
+ {
+ fclose(context->maps);
+ context->maps = NULL;
- if (ptrace(PTRACE_ATTACH, pid, NULL, 0) != -1)
- ctx->attached = 1;
- else
return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
+ }
- wait(NULL);
-
- return ERROR_SUCCESS;
-}
-
-
-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 (ptrace(PTRACE_ATTACH, pid, NULL, 0) == -1)
+ {
+ fclose(context->maps);
+ context->maps = NULL;
- if (ctx->maps != NULL)
- fclose(ctx->maps);
+ close(context->mem_fd);
+ context->mem_fd = -1;
- yr_free(ctx);
+ return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
+ }
return ERROR_SUCCESS;
}
-int _yr_process_get_blocks(
- void* context,
- YR_MEMORY_BLOCK** head)
+int _yr_process_detach(
+ YR_PROC_ITERATOR_CTX* context)
{
- 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;
-
- *head = NULL;
-
- while (fgets(buffer, sizeof(buffer), ctx->maps) != NULL)
- {
- sscanf(buffer, "%zx-%zx", &begin, &end);
-
- new_block = (YR_MEMORY_BLOCK*) yr_malloc(sizeof(YR_MEMORY_BLOCK));
-
- if (new_block == NULL)
- return ERROR_INSUFICIENT_MEMORY;
-
- new_block->base = begin;
- new_block->size = end - begin;
- new_block->next = NULL;
-
- if (*head == NULL)
- *head = new_block;
-
- if (current != NULL)
- current->next = new_block;
-
- current = new_block;
- }
+ fclose(context->maps);
+ close(context->mem_fd);
+ ptrace(PTRACE_DETACH, context->pid, NULL, 0);
return ERROR_SUCCESS;
}
-int _yr_process_read_block(
- void* context,
- YR_MEMORY_BLOCK* block,
- uint8_t** data)
+uint8_t* _yr_fetch_block_data(
+ YR_MEMORY_BLOCK* block)
{
- uint8_t* buffer = NULL;
- int result = ERROR_SUCCESS;
- *data = NULL;
-
- YR_PTRACE_CONTEXT* ctx = (YR_PTRACE_CONTEXT*)context;
+ YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) block->context;
- 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)
+ if (context->buffer_size < block->size)
{
- result = ERROR_COULD_NOT_READ_PROCESS_MEMORY;
+ if (context->buffer != NULL)
+ yr_free(context->buffer);
- if (buffer != NULL)
+ context->buffer = yr_malloc(block->size);
+
+ if (context->buffer != NULL)
+ {
+ context->buffer_size = block->size;
+ }
+ else
{
- yr_free(buffer);
- buffer = NULL;
+ context->buffer_size = 0;
+ return NULL;
}
}
- *data = buffer;
-
- return result;
-}
-
-#endif
-#endif
-
-// process iterator abstraction
-
-static void _yr_free_context_data(
- YR_PROCESS_CONTEXT* context)
-{
- if (context->data != NULL)
+ if (pread(context->mem_fd,
+ context->buffer,
+ block->size,
+ block->base) == -1)
{
- yr_free(context->data);
- context->data = NULL;
+ return 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;
+ return context->buffer;
}
-static YR_MEMORY_BLOCK* _yr_get_next_block(
- YR_BLOCK_ITERATOR* iterator)
+YR_MEMORY_BLOCK* _yr_get_next_block(
+ YR_MEMORY_BLOCK_ITERATOR* iterator)
{
- YR_PROCESS_CONTEXT* ctx = (YR_PROCESS_CONTEXT*)iterator->context;
+ YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
- _yr_free_context_data(ctx);
+ char buffer[256];
+ size_t begin, end;
- if (ctx->current == NULL)
- return NULL;
+ if (fgets(buffer, sizeof(buffer), context->maps) != NULL)
+ {
+ sscanf(buffer, "%zx-%zx", &begin, &end);
- ctx->current = ctx->current->next;
+ context->current_block.base = begin;
+ context->current_block.size = end - begin;
+
+ return &context->current_block;
+ }
- return ctx->current;
+ return NULL;
}
-static uint8_t* _yr_fetch_block_data(
- YR_BLOCK_ITERATOR* iterator)
+YR_MEMORY_BLOCK* _yr_get_first_block(
+ YR_MEMORY_BLOCK_ITERATOR* iterator)
{
- YR_PROCESS_CONTEXT* ctx = (YR_PROCESS_CONTEXT*)iterator->context;
+ YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
- if (ctx->current == NULL)
+ if (fseek(context->maps, 0, SEEK_SET) != 0)
return NULL;
- // reuse cached data if available
- if (ctx->data != NULL)
- return ctx->data;
-
- _yr_free_context_data(ctx);
+ return _yr_get_next_block(iterator);
+}
- _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
+#endif
+#endif
- return ctx->data;
-}
int yr_process_open_iterator(
int pid,
- YR_BLOCK_ITERATOR* iterator)
+ YR_MEMORY_BLOCK_ITERATOR* iterator)
{
- YR_PROCESS_CONTEXT* context = (YR_PROCESS_CONTEXT*) yr_malloc(
- sizeof(YR_PROCESS_CONTEXT));
+ YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) \
+ yr_malloc(sizeof(YR_PROC_ITERATOR_CTX));
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_process_attach(
- pid,
- &context->process_context);
+ context->buffer = NULL;
+ context->buffer_size = 0;
- if (result == ERROR_SUCCESS)
- result = _yr_process_get_blocks(
- context->process_context,
- &context->blocks);
+ context->current_block.base = 0;
+ context->current_block.size = 0;
+ context->current_block.context = context;
+ context->current_block.fetch_data = _yr_fetch_block_data;
- return result;
+ return _yr_process_attach(pid, context);
}
int yr_process_close_iterator(
- YR_BLOCK_ITERATOR* iterator)
+ YR_MEMORY_BLOCK_ITERATOR* iterator)
{
- YR_PROCESS_CONTEXT* ctx = (YR_PROCESS_CONTEXT*) iterator->context;
-
- if (ctx == NULL)
- return ERROR_SUCCESS;
+ YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
- // NOTE: detach must free allocated process context
- _yr_process_detach(ctx->process_context);
+ if (context != NULL)
+ {
+ _yr_process_detach(context);
- _yr_free_context_data(ctx);
+ if (context->buffer != NULL)
+ yr_free(context->buffer);
- YR_MEMORY_BLOCK* current = ctx->blocks;
- YR_MEMORY_BLOCK* next;
+ yr_free(context);
- // free blocks list
- while(current != NULL)
- {
- next = current->next;
- yr_free(current);
- current = next;
+ iterator->context = NULL;
}
- // free the context
- yr_free(iterator->context);
- iterator->context = NULL;
-
return ERROR_SUCCESS;
}
diff --git a/libyara/rules.c b/libyara/rules.c
index 449eb18..490c472 100644
--- a/libyara/rules.c
+++ b/libyara/rules.c
@@ -330,7 +330,7 @@ int _yr_rules_scan_mem_block(
YR_API int yr_rules_scan_mem_blocks(
YR_RULES* rules,
- YR_BLOCK_ITERATOR* iterator,
+ YR_MEMORY_BLOCK_ITERATOR* iterator,
int flags,
YR_CALLBACK_FUNC callback,
void* user_data,
@@ -425,7 +425,7 @@ YR_API int yr_rules_scan_mem_blocks(
while (block != NULL)
{
- uint8_t* data = iterator->fetch_data(iterator);
+ uint8_t* data = block->fetch_data(block);
// fetch may fail
if (data == NULL)
@@ -536,26 +536,25 @@ _exit:
}
+
static YR_MEMORY_BLOCK* _yr_get_first_block(
- YR_BLOCK_ITERATOR* iterator)
+ YR_MEMORY_BLOCK_ITERATOR* iterator)
{
- YR_BLOCK_CONTEXT* ctx = (YR_BLOCK_CONTEXT*) iterator->context;
- return ctx->block;
+ return (YR_MEMORY_BLOCK*) iterator->context;
}
static YR_MEMORY_BLOCK* _yr_get_next_block(
- YR_BLOCK_ITERATOR* iterator)
+ YR_MEMORY_BLOCK_ITERATOR* iterator)
{
return NULL;
}
static uint8_t* _yr_fetch_block_data(
- YR_BLOCK_ITERATOR* iterator)
+ YR_MEMORY_BLOCK* block)
{
- YR_BLOCK_CONTEXT* ctx = (YR_BLOCK_CONTEXT*) iterator->context;
- return ctx->data;
+ return (uint8_t*) block->context;
}
@@ -569,20 +568,16 @@ YR_API int yr_rules_scan_mem(
int timeout)
{
YR_MEMORY_BLOCK block;
- YR_BLOCK_CONTEXT context;
- YR_BLOCK_ITERATOR iterator;
+ YR_MEMORY_BLOCK_ITERATOR iterator;
block.size = buffer_size;
block.base = 0;
- block.next = NULL;
-
- context.block = █
- context.data = buffer;
+ block.fetch_data = _yr_fetch_block_data;
+ block.context = buffer;
- iterator.context = &context;
+ iterator.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,
@@ -662,13 +657,14 @@ YR_API int yr_rules_scan_proc(
void* user_data,
int timeout)
{
- YR_BLOCK_ITERATOR iterator;
+ YR_MEMORY_BLOCK_ITERATOR iterator;
int result = yr_process_open_iterator(
pid,
&iterator);
- if (result == ERROR_SUCCESS)
+ if (result == ERROR_SUCCESS)
+ {
result = yr_rules_scan_mem_blocks(
rules,
&iterator,
@@ -677,7 +673,8 @@ YR_API int yr_rules_scan_proc(
user_data,
timeout);
- yr_process_close_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