mirror of
https://github.com/VirusTotal/yara.git
synced 2026-10-11 22:49:58 +00:00
Add maximum size for process memory chunk (#1393)
Co-authored-by: Victor M. Alvarez <[email protected]>
This commit is contained in:
co-authored by
Victor M. Alvarez
parent
f5893ea78b
commit
605b2edf07
@@ -80,4 +80,4 @@ jobs:
|
||||
${{ runner.os }}-${{ env.cache-name }}-development
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build and run tests
|
||||
run: bazel test @jansson//... //tests/...
|
||||
run: bazel test --test_output=errors @jansson//... //tests/...
|
||||
|
||||
@@ -85,3 +85,5 @@ windows/*/packages/
|
||||
.dirstamp
|
||||
|
||||
.idea/
|
||||
|
||||
tests/mapper
|
||||
|
||||
+17
-6
@@ -157,12 +157,13 @@ static bool negate = false;
|
||||
static bool print_count_only = false;
|
||||
static bool fail_on_warnings = false;
|
||||
static bool rules_are_compiled = false;
|
||||
static long total_count = 0;
|
||||
static long limit = 0;
|
||||
static long timeout = 1000000;
|
||||
static long stack_size = DEFAULT_STACK_SIZE;
|
||||
static long threads = YR_MAX_THREADS;
|
||||
static long max_strings_per_rule = DEFAULT_MAX_STRINGS_PER_RULE;
|
||||
static int total_count = 0;
|
||||
static int limit = 0;
|
||||
static int timeout = 1000000;
|
||||
static int stack_size = DEFAULT_STACK_SIZE;
|
||||
static int threads = YR_MAX_THREADS;
|
||||
static int max_strings_per_rule = DEFAULT_MAX_STRINGS_PER_RULE;
|
||||
static int max_process_memory_chunk = DEFAULT_MAX_PROCESS_MEMORY_CHUNK;
|
||||
|
||||
#define USAGE_STRING \
|
||||
"Usage: yara [OPTION]... [NAMESPACE:]RULES_FILE... FILE | DIR | PID"
|
||||
@@ -307,6 +308,14 @@ args_option_t options[] = {
|
||||
_T("set maximum stack size (default=16384)"),
|
||||
_T("SLOTS")),
|
||||
|
||||
OPT_INTEGER(
|
||||
0,
|
||||
_T("max-process-memory-chunk"),
|
||||
&max_process_memory_chunk,
|
||||
_T("set maximum chunk size while reading process memory")
|
||||
_T(" (default=1073741824)"),
|
||||
_T("NUMBER")),
|
||||
|
||||
OPT_STRING_MULTI(
|
||||
't',
|
||||
_T("tag"),
|
||||
@@ -1359,6 +1368,8 @@ int _tmain(int argc, const char_t** argv)
|
||||
|
||||
yr_set_configuration(YR_CONFIG_STACK_SIZE, &stack_size);
|
||||
yr_set_configuration(YR_CONFIG_MAX_STRINGS_PER_RULE, &max_strings_per_rule);
|
||||
yr_set_configuration(
|
||||
YR_CONFIG_MAX_PROCESS_MEMORY_CHUNK, &max_process_memory_chunk);
|
||||
|
||||
// Try to load the rules file as a binary file containing
|
||||
// compiled rules first
|
||||
|
||||
@@ -72,14 +72,16 @@ typedef enum _YR_CONFIG_NAME
|
||||
YR_CONFIG_STACK_SIZE,
|
||||
YR_CONFIG_MAX_STRINGS_PER_RULE,
|
||||
YR_CONFIG_MAX_MATCH_DATA,
|
||||
YR_CONFIG_MAX_PROCESS_MEMORY_CHUNK,
|
||||
|
||||
YR_CONFIG_LAST // End-of-enum marker, not a configuration
|
||||
|
||||
} YR_CONFIG_NAME;
|
||||
|
||||
#define DEFAULT_STACK_SIZE 16384
|
||||
#define DEFAULT_MAX_STRINGS_PER_RULE 10000
|
||||
#define DEFAULT_MAX_MATCH_DATA 512
|
||||
#define DEFAULT_STACK_SIZE 16384
|
||||
#define DEFAULT_MAX_STRINGS_PER_RULE 10000
|
||||
#define DEFAULT_MAX_MATCH_DATA 512
|
||||
#define DEFAULT_MAX_PROCESS_MEMORY_CHUNK 1073741824
|
||||
|
||||
YR_API int yr_initialize(void);
|
||||
|
||||
|
||||
+16
-3
@@ -235,6 +235,7 @@ YR_API int yr_initialize(void)
|
||||
uint32_t def_stack_size = DEFAULT_STACK_SIZE;
|
||||
uint32_t def_max_strings_per_rule = DEFAULT_MAX_STRINGS_PER_RULE;
|
||||
uint32_t def_max_match_data = DEFAULT_MAX_MATCH_DATA;
|
||||
uint64_t def_max_process_memory_chunk = DEFAULT_MAX_PROCESS_MEMORY_CHUNK;
|
||||
|
||||
init_count++;
|
||||
|
||||
@@ -295,6 +296,9 @@ YR_API int yr_initialize(void)
|
||||
FAIL_ON_ERROR(yr_set_configuration(
|
||||
YR_CONFIG_MAX_STRINGS_PER_RULE, &def_max_strings_per_rule));
|
||||
|
||||
FAIL_ON_ERROR(yr_set_configuration(
|
||||
YR_CONFIG_MAX_PROCESS_MEMORY_CHUNK, &def_max_process_memory_chunk));
|
||||
|
||||
FAIL_ON_ERROR(
|
||||
yr_set_configuration(YR_CONFIG_MAX_MATCH_DATA, &def_max_match_data));
|
||||
|
||||
@@ -363,9 +367,10 @@ YR_API int yr_finalize(void)
|
||||
// Args:
|
||||
// name: Any of the values defined by the YR_CONFIG_NAME enum. Possible values
|
||||
// are:
|
||||
// YR_CONFIG_STACK_SIZE data type: uint32_t
|
||||
// YR_CONFIG_MAX_STRINGS_PER_RULE data type: uint32_t
|
||||
// YR_CONFIG_MAX_MATCH_DATA data type: uint32_t
|
||||
// YR_CONFIG_STACK_SIZE data type: uint32_t
|
||||
// YR_CONFIG_MAX_STRINGS_PER_RULE data type: uint32_t
|
||||
// YR_CONFIG_MAX_MATCH_DATA data type: uint32_t
|
||||
// YR_CONFIG_MAX_PROCESS_MEMORY_CHUNK data type: uint64_t
|
||||
//
|
||||
// src: Pointer to the value being set for the option.
|
||||
//
|
||||
@@ -386,6 +391,10 @@ YR_API int yr_set_configuration(YR_CONFIG_NAME name, void *src)
|
||||
yr_cfgs[name].ui32 = *(uint32_t *) src;
|
||||
break;
|
||||
|
||||
case YR_CONFIG_MAX_PROCESS_MEMORY_CHUNK:
|
||||
yr_cfgs[name].ui64 = *(uint64_t *) src;
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR_INTERNAL_FATAL_ERROR;
|
||||
}
|
||||
@@ -406,6 +415,10 @@ YR_API int yr_get_configuration(YR_CONFIG_NAME name, void *dest)
|
||||
*(uint32_t *) dest = yr_cfgs[name].ui32;
|
||||
break;
|
||||
|
||||
case YR_CONFIG_MAX_PROCESS_MEMORY_CHUNK:
|
||||
*(uint64_t *) dest = yr_cfgs[name].ui64;
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR_INTERNAL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
+28
-12
@@ -36,17 +36,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <yara/error.h>
|
||||
#include <yara/libyara.h>
|
||||
#include <yara/mem.h>
|
||||
#include <yara/proc.h>
|
||||
|
||||
|
||||
typedef struct _YR_PROC_INFO
|
||||
{
|
||||
int pid;
|
||||
struct ptrace_vm_entry vm_entry;
|
||||
} YR_PROC_INFO;
|
||||
|
||||
|
||||
int _yr_process_attach(int pid, YR_PROC_ITERATOR_CTX* context)
|
||||
{
|
||||
int status;
|
||||
@@ -56,6 +55,8 @@ int _yr_process_attach(int pid, YR_PROC_ITERATOR_CTX* context)
|
||||
if (proc_info == NULL)
|
||||
return ERROR_INSUFFICIENT_MEMORY;
|
||||
|
||||
memset(proc_info, 0, sizeof(YR_PROC_INFO));
|
||||
|
||||
context->proc_info = proc_info;
|
||||
|
||||
proc_info->pid = pid;
|
||||
@@ -79,7 +80,6 @@ int _yr_process_attach(int pid, YR_PROC_ITERATOR_CTX* context)
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int _yr_process_detach(YR_PROC_ITERATOR_CTX* context)
|
||||
{
|
||||
YR_PROC_INFO* proc_info = (YR_PROC_INFO*) context->proc_info;
|
||||
@@ -90,7 +90,6 @@ int _yr_process_detach(YR_PROC_ITERATOR_CTX* context)
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
YR_API const uint8_t* yr_process_fetch_memory_block_data(YR_MEMORY_BLOCK* block)
|
||||
{
|
||||
YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) block->context;
|
||||
@@ -128,7 +127,6 @@ YR_API const uint8_t* yr_process_fetch_memory_block_data(YR_MEMORY_BLOCK* block)
|
||||
return context->buffer;
|
||||
}
|
||||
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
@@ -142,20 +140,38 @@ YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_block(
|
||||
|
||||
iterator->last_error = ERROR_SUCCESS;
|
||||
|
||||
if (ptrace(PT_VM_ENTRY, proc_info->pid, (char*) (&proc_info->vm_entry), 0) ==
|
||||
-1)
|
||||
uint64_t current_begin = context->current_block.base +
|
||||
context->current_block.size;
|
||||
|
||||
uint64_t max_process_memory_chunk;
|
||||
|
||||
yr_get_configuration(
|
||||
YR_CONFIG_MAX_PROCESS_MEMORY_CHUNK, (void*) &max_process_memory_chunk);
|
||||
|
||||
if (proc_info->vm_entry.pve_end <= current_begin)
|
||||
{
|
||||
return NULL;
|
||||
if (ptrace(
|
||||
PT_VM_ENTRY, proc_info->pid, (char*) (&proc_info->vm_entry), 0) ==
|
||||
-1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_begin = proc_info->vm_entry.pve_start;
|
||||
}
|
||||
}
|
||||
|
||||
context->current_block.base = proc_info->vm_entry.pve_start;
|
||||
context->current_block.size = proc_info->vm_entry.pve_end -
|
||||
proc_info->vm_entry.pve_start + 1;
|
||||
context->current_block.base = current_begin;
|
||||
context->current_block.size = yr_min(
|
||||
proc_info->vm_entry.pve_end - current_begin + 1,
|
||||
max_process_memory_chunk);
|
||||
|
||||
assert(context->current_block.size > 0);
|
||||
|
||||
return &context->current_block;
|
||||
}
|
||||
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_first_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
|
||||
+75
-35
@@ -40,6 +40,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <unistd.h>
|
||||
#include <yara/error.h>
|
||||
#include <yara/globals.h>
|
||||
#include <yara/libyara.h>
|
||||
#include <yara/mem.h>
|
||||
#include <yara/proc.h>
|
||||
|
||||
@@ -49,12 +50,13 @@ typedef struct _YR_PROC_INFO
|
||||
int mem_fd;
|
||||
int pagemap_fd;
|
||||
FILE* maps;
|
||||
uint64_t map_offset;
|
||||
uint64_t next_block_end;
|
||||
int page_size;
|
||||
char map_path[PATH_MAX];
|
||||
uint64_t map_dmaj;
|
||||
uint64_t map_dmin;
|
||||
uint64_t map_ino;
|
||||
uint64_t map_offset;
|
||||
} YR_PROC_INFO;
|
||||
|
||||
static int page_size = -1;
|
||||
@@ -78,6 +80,7 @@ int _yr_process_attach(int pid, YR_PROC_ITERATOR_CTX* context)
|
||||
proc_info->maps = NULL;
|
||||
proc_info->mem_fd = -1;
|
||||
proc_info->pagemap_fd = -1;
|
||||
proc_info->next_block_end = 0;
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "/proc/%u/maps", pid);
|
||||
proc_info->maps = fopen(buffer, "r");
|
||||
@@ -303,54 +306,89 @@ _exit:;
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
YR_MEMORY_BLOCK* result = NULL;
|
||||
YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
|
||||
YR_PROC_INFO* proc_info = (YR_PROC_INFO*) context->proc_info;
|
||||
|
||||
char buffer[PATH_MAX];
|
||||
char perm[5];
|
||||
uint64_t begin, end;
|
||||
int n, len;
|
||||
|
||||
while (fgets(buffer, sizeof(buffer), proc_info->maps) != NULL)
|
||||
uint64_t current_begin = context->current_block.base +
|
||||
context->current_block.size;
|
||||
|
||||
uint64_t max_process_memory_chunk;
|
||||
|
||||
yr_get_configuration(
|
||||
YR_CONFIG_MAX_PROCESS_MEMORY_CHUNK, (void*) &max_process_memory_chunk);
|
||||
|
||||
if (proc_info->next_block_end <= current_begin)
|
||||
{
|
||||
// If we haven't read the whole line, skip over the rest.
|
||||
if (strrchr(buffer, '\n') == NULL)
|
||||
int n, path_start;
|
||||
|
||||
while (fgets(buffer, sizeof(buffer), proc_info->maps) != NULL)
|
||||
{
|
||||
int c;
|
||||
do
|
||||
// If we haven't read the whole line, skip over the rest.
|
||||
if (strrchr(buffer, '\n') == NULL)
|
||||
{
|
||||
c = fgetc(proc_info->maps);
|
||||
} while (c >= 0 && c != '\n');
|
||||
int c;
|
||||
do
|
||||
{
|
||||
c = fgetc(proc_info->maps);
|
||||
} while (c >= 0 && c != '\n');
|
||||
}
|
||||
|
||||
// Each row in /proc/$PID/maps describes a region of contiguous virtual
|
||||
// memory in a process or thread. Each row has the following fields:
|
||||
//
|
||||
// address perms offset dev inode pathname
|
||||
// 08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm
|
||||
//
|
||||
n = sscanf(
|
||||
buffer,
|
||||
"%" SCNx64 "-%" SCNx64 " %4s "
|
||||
"%" SCNx64 " %" SCNx64 ":%" SCNx64 " %" SCNu64 " %n",
|
||||
&begin,
|
||||
&end,
|
||||
perm,
|
||||
&(proc_info->map_offset),
|
||||
&(proc_info->map_dmaj),
|
||||
&(proc_info->map_dmin),
|
||||
&(proc_info->map_ino),
|
||||
&path_start);
|
||||
|
||||
// If the row was parsed correctly sscan must return 7.
|
||||
if (n == 7)
|
||||
{
|
||||
// path_start contains the offset within buffer where the path starts,
|
||||
// the path should start with /.
|
||||
if (buffer[path_start] == '/')
|
||||
strncpy(
|
||||
proc_info->map_path,
|
||||
buffer + path_start,
|
||||
sizeof(proc_info->map_path) - 1);
|
||||
else
|
||||
proc_info->map_path[0] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
n = sscanf(
|
||||
buffer,
|
||||
"%" SCNx64 "-%" SCNx64 " %4s "
|
||||
"%" SCNx64 " %" SCNx64 ":%" SCNx64 " %" SCNu64 " %n",
|
||||
&begin,
|
||||
&end,
|
||||
perm,
|
||||
&(proc_info->map_offset),
|
||||
&(proc_info->map_dmaj),
|
||||
&(proc_info->map_dmin),
|
||||
&(proc_info->map_ino),
|
||||
&len);
|
||||
|
||||
if (n == 7)
|
||||
{
|
||||
if (buffer[len] == '/')
|
||||
strncpy(
|
||||
proc_info->map_path, buffer + len, sizeof(proc_info->map_path) - 1);
|
||||
else
|
||||
proc_info->map_path[0] = '\0';
|
||||
break;
|
||||
current_begin = begin;
|
||||
proc_info->next_block_end = end;
|
||||
}
|
||||
else
|
||||
{
|
||||
YR_DEBUG_FPRINTF(2, stderr, "+ %s() = NULL\n", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (n == 7)
|
||||
{
|
||||
context->current_block.base = begin;
|
||||
context->current_block.size = end - begin;
|
||||
result = &context->current_block;
|
||||
}
|
||||
|
||||
context->current_block.base = current_begin;
|
||||
context->current_block.size = yr_min(
|
||||
proc_info->next_block_end - current_begin, max_process_memory_chunk);
|
||||
|
||||
assert(context->current_block.size > 0);
|
||||
|
||||
iterator->last_error = ERROR_SUCCESS;
|
||||
|
||||
@@ -363,7 +401,7 @@ YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_block(
|
||||
context->current_block.base,
|
||||
context->current_block.size);
|
||||
|
||||
return result;
|
||||
return &context->current_block;
|
||||
}
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_first_memory_block(
|
||||
@@ -381,6 +419,8 @@ YR_API YR_MEMORY_BLOCK* yr_process_get_first_memory_block(
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
proc_info->next_block_end = 0;
|
||||
|
||||
result = yr_process_get_next_memory_block(iterator);
|
||||
|
||||
_exit:
|
||||
|
||||
+19
-10
@@ -34,16 +34,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <mach/vm_region.h>
|
||||
#include <mach/vm_statistics.h>
|
||||
#include <yara/error.h>
|
||||
#include <yara/libyara.h>
|
||||
#include <yara/mem.h>
|
||||
#include <yara/proc.h>
|
||||
|
||||
|
||||
typedef struct _YR_PROC_INFO
|
||||
{
|
||||
task_t task;
|
||||
} YR_PROC_INFO;
|
||||
|
||||
|
||||
int _yr_process_attach(int pid, YR_PROC_ITERATOR_CTX* context)
|
||||
{
|
||||
YR_PROC_INFO* proc_info = (YR_PROC_INFO*) yr_malloc(sizeof(YR_PROC_INFO));
|
||||
@@ -64,7 +63,6 @@ int _yr_process_attach(int pid, YR_PROC_ITERATOR_CTX* context)
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int _yr_process_detach(YR_PROC_ITERATOR_CTX* context)
|
||||
{
|
||||
YR_PROC_INFO* proc_info = context->proc_info;
|
||||
@@ -75,7 +73,6 @@ int _yr_process_detach(YR_PROC_ITERATOR_CTX* context)
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
YR_API const uint8_t* yr_process_fetch_memory_block_data(YR_MEMORY_BLOCK* block)
|
||||
{
|
||||
YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) block->context;
|
||||
@@ -113,7 +110,6 @@ YR_API const uint8_t* yr_process_fetch_memory_block_data(YR_MEMORY_BLOCK* block)
|
||||
return context->buffer;
|
||||
}
|
||||
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
@@ -126,8 +122,13 @@ YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_block(
|
||||
vm_region_basic_info_data_64_t info;
|
||||
vm_size_t size = 0;
|
||||
|
||||
vm_address_t address = (vm_address_t) context->current_block.base +
|
||||
context->current_block.size;
|
||||
uint64_t current_begin = (vm_address_t) context->current_block.base +
|
||||
context->current_block.size;
|
||||
vm_address_t address = current_begin;
|
||||
uint64_t max_process_memory_chunk;
|
||||
|
||||
yr_get_configuration(
|
||||
YR_CONFIG_MAX_PROCESS_MEMORY_CHUNK, (void*) &max_process_memory_chunk);
|
||||
|
||||
iterator->last_error = ERROR_SUCCESS;
|
||||
|
||||
@@ -146,18 +147,26 @@ YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_block(
|
||||
|
||||
if (kr == KERN_SUCCESS)
|
||||
{
|
||||
context->current_block.base = address;
|
||||
context->current_block.size = size;
|
||||
size_t chunk_size = size - (size_t) (current_begin - address);
|
||||
|
||||
if (((uint64_t) chunk_size) > max_process_memory_chunk)
|
||||
{
|
||||
chunk_size = (size_t) max_process_memory_chunk;
|
||||
}
|
||||
|
||||
context->current_block.base = (size_t) current_begin;
|
||||
context->current_block.size = chunk_size;
|
||||
|
||||
return &context->current_block;
|
||||
}
|
||||
|
||||
current_begin = address;
|
||||
|
||||
} while (kr != KERN_INVALID_ADDRESS);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_first_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
|
||||
+28
-10
@@ -42,6 +42,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
// clang-format on
|
||||
|
||||
#include <yara/error.h>
|
||||
#include <yara/libyara.h>
|
||||
#include <yara/mem.h>
|
||||
#include <yara/proc.h>
|
||||
|
||||
@@ -63,6 +64,8 @@ int _yr_process_attach(int pid, YR_PROC_ITERATOR_CTX* context)
|
||||
if (proc_info == NULL)
|
||||
return ERROR_INSUFFICIENT_MEMORY;
|
||||
|
||||
memset(proc_info, 0, sizeof(YR_PROC_INFO));
|
||||
|
||||
proc_info->pid = pid;
|
||||
if (ptrace(PT_ATTACH, pid, NULL, 0) == -1)
|
||||
{
|
||||
@@ -149,19 +152,34 @@ YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_block(
|
||||
|
||||
iterator->last_error = ERROR_SUCCESS;
|
||||
|
||||
if (sysctl(mib, 3, &proc_info->vm_entry, &len, NULL, 0) < 0)
|
||||
return NULL;
|
||||
uint64_t current_begin = context->current_block.base +
|
||||
context->current_block.size;
|
||||
|
||||
// no more blocks
|
||||
if (proc_info->old_end == proc_info->vm_entry.kve_end)
|
||||
return NULL;
|
||||
uint64_t max_process_memory_chunk;
|
||||
|
||||
proc_info->old_end = proc_info->vm_entry.kve_end;
|
||||
context->current_block.base = proc_info->vm_entry.kve_start;
|
||||
context->current_block.size = proc_info->vm_entry.kve_end -
|
||||
proc_info->vm_entry.kve_start;
|
||||
yr_get_configuration(
|
||||
YR_CONFIG_MAX_PROCESS_MEMORY_CHUNK, (void*) &max_process_memory_chunk);
|
||||
|
||||
proc_info->vm_entry.kve_start = proc_info->vm_entry.kve_start + 1;
|
||||
if (proc_info->old_end <= current_begin)
|
||||
{
|
||||
if (sysctl(mib, 3, &proc_info->vm_entry, &len, NULL, 0) < 0)
|
||||
return NULL;
|
||||
|
||||
// no more blocks
|
||||
if (proc_info->old_end == proc_info->vm_entry.kve_end)
|
||||
return NULL;
|
||||
|
||||
current_begin = proc_info->vm_entry.kve_start;
|
||||
proc_info->old_end = proc_info->vm_entry.kve_end;
|
||||
|
||||
proc_info->vm_entry.kve_start = proc_info->vm_entry.kve_start + 1;
|
||||
}
|
||||
|
||||
context->current_block.base = current_begin;
|
||||
context->current_block.size = yr_min(
|
||||
proc_info->old_end - current_begin, max_process_memory_chunk);
|
||||
|
||||
assert(context->current_block.size > 0);
|
||||
|
||||
return &context->current_block;
|
||||
}
|
||||
|
||||
+19
-10
@@ -31,10 +31,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <windows.h>
|
||||
#include <yara/error.h>
|
||||
#include <yara/libyara.h>
|
||||
#include <yara/mem.h>
|
||||
#include <yara/proc.h>
|
||||
|
||||
|
||||
typedef struct _YR_PROC_INFO
|
||||
{
|
||||
HANDLE hProcess;
|
||||
@@ -82,7 +82,6 @@ int _yr_process_attach(int pid, YR_PROC_ITERATOR_CTX* context)
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int _yr_process_detach(YR_PROC_ITERATOR_CTX* context)
|
||||
{
|
||||
YR_PROC_INFO* proc_info = (YR_PROC_INFO*) context->proc_info;
|
||||
@@ -91,7 +90,6 @@ int _yr_process_detach(YR_PROC_ITERATOR_CTX* context)
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
YR_API const uint8_t* yr_process_fetch_memory_block_data(YR_MEMORY_BLOCK* block)
|
||||
{
|
||||
SIZE_T read;
|
||||
@@ -130,7 +128,6 @@ YR_API const uint8_t* yr_process_fetch_memory_block_data(YR_MEMORY_BLOCK* block)
|
||||
return context->buffer;
|
||||
}
|
||||
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
@@ -138,8 +135,12 @@ YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_block(
|
||||
YR_PROC_INFO* proc_info = (YR_PROC_INFO*) context->proc_info;
|
||||
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
PVOID address = (PVOID)(
|
||||
context->current_block.base + context->current_block.size);
|
||||
void* address =
|
||||
(void*) (context->current_block.base + context->current_block.size);
|
||||
uint64_t max_process_memory_chunk;
|
||||
|
||||
yr_get_configuration(
|
||||
YR_CONFIG_MAX_PROCESS_MEMORY_CHUNK, (void*) &max_process_memory_chunk);
|
||||
|
||||
iterator->last_error = ERROR_SUCCESS;
|
||||
|
||||
@@ -153,19 +154,27 @@ YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_block(
|
||||
|
||||
if (mbi.State == MEM_COMMIT && ((mbi.Protect & PAGE_NOACCESS) == 0))
|
||||
{
|
||||
context->current_block.base = (size_t) mbi.BaseAddress;
|
||||
context->current_block.size = mbi.RegionSize;
|
||||
size_t chuck_size =
|
||||
mbi.RegionSize -
|
||||
(size_t) (((uint8_t*) address) - ((uint8_t*) mbi.BaseAddress));
|
||||
|
||||
if (((uint64_t) chuck_size) > max_process_memory_chunk)
|
||||
{
|
||||
chuck_size = (size_t) max_process_memory_chunk;
|
||||
}
|
||||
|
||||
context->current_block.base = (size_t) address;
|
||||
context->current_block.size = chuck_size;
|
||||
|
||||
return &context->current_block;
|
||||
}
|
||||
|
||||
address = (uint8_t*) address + mbi.RegionSize;
|
||||
address = (uint8_t*) mbi.BaseAddress + mbi.RegionSize;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_first_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user