mirror of
https://github.com/VirusTotal/yara.git
synced 2026-10-11 22:49:58 +00:00
Refactor process memory scanning variants (#776)
Implementation details are placed into separate files and a dummy implementation stub has been added for other platforms.
This commit is contained in:
committed by
Victor M. Alvarez
parent
9e03c23f0f
commit
c4cdf42ad8
+10
-1
@@ -28,12 +28,16 @@ case $host_alias in
|
||||
i?86-*-mingw*) CFLAGS="$CFLAGS -D__MINGW_USE_VC2005_COMPAT" ;;
|
||||
esac
|
||||
|
||||
proc_interface=none
|
||||
case $host_os in
|
||||
darwin*) CFLAGS="$CFLAGS -I/opt/local/include"
|
||||
# Starting with Mac OS X 10.11 (El Capitan) the OpenSSL headers
|
||||
# are in /usr/local/opt/openssl/include
|
||||
CFLAGS="$CFLAGS -I/usr/local/opt/openssl/include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/opt/openssl/lib" ;;
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/opt/openssl/lib"
|
||||
proc_interface=mach ;;
|
||||
mingw*) proc_interface=windows ;;
|
||||
linux*|freebsd*|openbsd*) proc_interface=linux ;;
|
||||
esac
|
||||
|
||||
AC_C_BIGENDIAN
|
||||
@@ -206,6 +210,11 @@ AM_CONDITIONAL([HASH_MODULE], [test x$build_hash_module = xtrue])
|
||||
AM_CONDITIONAL([DOTNET_MODULE], [test x$build_dotnet_module = xtrue])
|
||||
AM_CONDITIONAL([GCC], [test "x$GCC" = xyes])
|
||||
|
||||
AM_CONDITIONAL([USE_WINDOWS_PROC], [test x$proc_interface = xwindows ])
|
||||
AM_CONDITIONAL([USE_LINUX_PROC], [test x$proc_interface = xlinux ])
|
||||
AM_CONDITIONAL([USE_MACH_PROC], [test x$proc_interface = xmach ])
|
||||
AM_CONDITIONAL([USE_NO_PROC], [test x$proc_interface = xnone ])
|
||||
|
||||
AC_SUBST([PC_REQUIRES_PRIVATE])
|
||||
AC_SUBST([PC_LIBS_PRIVATE])
|
||||
|
||||
|
||||
@@ -142,5 +142,18 @@ libyara_la_SOURCES = \
|
||||
threading.h \
|
||||
utils.h
|
||||
|
||||
if USE_WINDOWS_PROC
|
||||
libyara_la_SOURCES += proc_windows.c
|
||||
endif
|
||||
if USE_LINUX_PROC
|
||||
libyara_la_SOURCES += proc_linux.c
|
||||
endif
|
||||
if USE_MACH_PROC
|
||||
libyara_la_SOURCES += proc_mach.c
|
||||
endif
|
||||
if USE_NO_PROC
|
||||
libyara_la_SOURCES += proc_none.c
|
||||
endif
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
nodist_pkgconfig_DATA = yara.pc
|
||||
|
||||
@@ -32,6 +32,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <yara/types.h>
|
||||
|
||||
typedef struct _YR_PROC_ITERATOR_CTX {
|
||||
const uint8_t* buffer;
|
||||
size_t buffer_size;
|
||||
YR_MEMORY_BLOCK current_block;
|
||||
void* proc_info;
|
||||
} YR_PROC_ITERATOR_CTX;
|
||||
|
||||
YR_API int yr_process_open_iterator(
|
||||
int pid,
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator);
|
||||
|
||||
+6
-462
@@ -27,471 +27,12 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <yara/mem.h>
|
||||
#include <yara/error.h>
|
||||
#include <yara/proc.h>
|
||||
|
||||
// Windows
|
||||
|
||||
typedef struct _YR_PROC_ITERATOR_CTX
|
||||
{
|
||||
HANDLE hProcess;
|
||||
const 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,
|
||||
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))
|
||||
{
|
||||
tokenPriv.PrivilegeCount = 1;
|
||||
tokenPriv.Privileges[0].Luid = luidDebug;
|
||||
tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
|
||||
AdjustTokenPrivileges(
|
||||
hToken,
|
||||
FALSE,
|
||||
&tokenPriv,
|
||||
sizeof(tokenPriv),
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (hToken != NULL)
|
||||
CloseHandle(hToken);
|
||||
|
||||
context->hProcess = OpenProcess(
|
||||
PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
|
||||
FALSE,
|
||||
pid);
|
||||
|
||||
if (context->hProcess == NULL)
|
||||
return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
|
||||
|
||||
GetSystemInfo(&context->si);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int _yr_process_detach(
|
||||
YR_PROC_ITERATOR_CTX* context)
|
||||
{
|
||||
CloseHandle(context->hProcess);
|
||||
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;
|
||||
SIZE_T read;
|
||||
|
||||
if (context->buffer_size < block->size)
|
||||
{
|
||||
if (context->buffer != NULL)
|
||||
yr_free((void*) context->buffer);
|
||||
|
||||
context->buffer = (const uint8_t*) yr_malloc(block->size);
|
||||
|
||||
if (context->buffer != NULL)
|
||||
{
|
||||
context->buffer_size = block->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
context->buffer_size = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ReadProcessMemory(
|
||||
context->hProcess,
|
||||
(LPCVOID) block->base,
|
||||
(LPVOID) context->buffer,
|
||||
(SIZE_T) block->size,
|
||||
&read) == FALSE)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return context->buffer;
|
||||
}
|
||||
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_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);
|
||||
|
||||
while (address < context->si.lpMaximumApplicationAddress &&
|
||||
VirtualQueryEx(context->hProcess, address, &mbi, sizeof(mbi)) != 0)
|
||||
{
|
||||
if (GetLastError() != ERROR_SUCCESS)
|
||||
break;
|
||||
|
||||
if (mbi.State == MEM_COMMIT && ((mbi.Protect & PAGE_NOACCESS) == 0))
|
||||
{
|
||||
context->current_block.base = (size_t) mbi.BaseAddress;
|
||||
context->current_block.size = mbi.RegionSize;
|
||||
|
||||
return &context->current_block;
|
||||
}
|
||||
|
||||
address = (uint8_t*) address + mbi.RegionSize;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_first_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
|
||||
|
||||
context->current_block.base = (size_t) context->si.lpMinimumApplicationAddress;
|
||||
context->current_block.size = 0;
|
||||
|
||||
return yr_process_get_next_memory_block(iterator);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
|
||||
defined(__OpenBSD__) || defined(__MACH__)
|
||||
#else
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <yara/error.h>
|
||||
#include <yara/proc.h>
|
||||
#include <yara/mem.h>
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
|
||||
defined(__OpenBSD__) || defined(__MACH__)
|
||||
#define PTRACE_ATTACH PT_ATTACH
|
||||
#define PTRACE_DETACH PT_DETACH
|
||||
#endif
|
||||
|
||||
#if defined(__MACH__)
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_vm.h>
|
||||
#include <mach/vm_region.h>
|
||||
#include <mach/vm_statistics.h>
|
||||
|
||||
// Mac OS X
|
||||
|
||||
typedef struct _YR_PROC_ITERATOR_CTX {
|
||||
|
||||
task_t task;
|
||||
const uint8_t* buffer;
|
||||
size_t buffer_size;
|
||||
YR_MEMORY_BLOCK current_block;
|
||||
|
||||
} YR_PROC_ITERATOR_CTX;
|
||||
|
||||
|
||||
static 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 != KERN_SUCCESS)
|
||||
return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int _yr_process_detach(
|
||||
YR_PROC_ITERATOR_CTX* context)
|
||||
{
|
||||
if (context->task != MACH_PORT_NULL)
|
||||
mach_port_deallocate(mach_task_self(), context->task);
|
||||
|
||||
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;
|
||||
vm_size_t size = block->size;
|
||||
|
||||
if (context->buffer_size < block->size)
|
||||
{
|
||||
if (context->buffer != NULL)
|
||||
yr_free((void*) context->buffer);
|
||||
|
||||
context->buffer = (const uint8_t*) 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;
|
||||
}
|
||||
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
|
||||
|
||||
kern_return_t kr;
|
||||
mach_msg_type_number_t info_count;
|
||||
mach_port_t object;
|
||||
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(
|
||||
context->task,
|
||||
&address,
|
||||
&size,
|
||||
VM_REGION_BASIC_INFO,
|
||||
(vm_region_info_t) &info,
|
||||
&info_count,
|
||||
&object);
|
||||
|
||||
if (kr == KERN_SUCCESS)
|
||||
{
|
||||
context->current_block.base = address;
|
||||
context->current_block.size = size;
|
||||
|
||||
return &context->current_block;
|
||||
}
|
||||
|
||||
} while (kr != KERN_INVALID_ADDRESS);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_first_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
|
||||
|
||||
context->current_block.base = 0;
|
||||
context->current_block.size = 0;
|
||||
|
||||
return yr_process_get_next_memory_block(iterator);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
// Linux
|
||||
|
||||
|
||||
typedef struct _YR_PROC_ITERATOR_CTX {
|
||||
|
||||
int pid;
|
||||
int mem_fd;
|
||||
FILE* maps;
|
||||
const uint8_t* buffer;
|
||||
size_t buffer_size;
|
||||
YR_MEMORY_BLOCK current_block;
|
||||
|
||||
} YR_PROC_ITERATOR_CTX;
|
||||
|
||||
|
||||
static int _yr_process_attach(
|
||||
int pid,
|
||||
YR_PROC_ITERATOR_CTX* context)
|
||||
{
|
||||
int status;
|
||||
char buffer[256];
|
||||
|
||||
context->pid = pid;
|
||||
context->maps = NULL;
|
||||
context->mem_fd = -1;
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "/proc/%u/maps", pid);
|
||||
context->maps = fopen(buffer, "r");
|
||||
|
||||
if (context->maps == NULL)
|
||||
return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "/proc/%u/mem", pid);
|
||||
context->mem_fd = open(buffer, O_RDONLY);
|
||||
|
||||
if (context->mem_fd == -1)
|
||||
{
|
||||
fclose(context->maps);
|
||||
context->maps = NULL;
|
||||
|
||||
return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
|
||||
}
|
||||
|
||||
if (ptrace(PTRACE_ATTACH, pid, NULL, 0) == -1)
|
||||
{
|
||||
fclose(context->maps);
|
||||
context->maps = NULL;
|
||||
|
||||
close(context->mem_fd);
|
||||
context->mem_fd = -1;
|
||||
|
||||
return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
|
||||
}
|
||||
|
||||
status = 0;
|
||||
if (waitpid(pid, &status, 0) == -1)
|
||||
{
|
||||
// this is a strange error state where we attached but the proc didn't
|
||||
// stop. Try to detach and clean up.
|
||||
ptrace(PTRACE_DETACH, context->pid, NULL, 0);
|
||||
|
||||
fclose(context->maps);
|
||||
context->maps = NULL;
|
||||
|
||||
close(context->mem_fd);
|
||||
context->mem_fd = -1;
|
||||
|
||||
return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int _yr_process_detach(
|
||||
YR_PROC_ITERATOR_CTX* context)
|
||||
{
|
||||
fclose(context->maps);
|
||||
close(context->mem_fd);
|
||||
ptrace(PTRACE_DETACH, context->pid, NULL, 0);
|
||||
|
||||
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;
|
||||
|
||||
if (context->buffer_size < block->size)
|
||||
{
|
||||
if (context->buffer != NULL)
|
||||
yr_free((void*) context->buffer);
|
||||
|
||||
context->buffer = (const uint8_t*) yr_malloc(block->size);
|
||||
|
||||
if (context->buffer != NULL)
|
||||
{
|
||||
context->buffer_size = block->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
context->buffer_size = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (pread(context->mem_fd,
|
||||
(void *) context->buffer,
|
||||
block->size,
|
||||
block->base) == -1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return context->buffer;
|
||||
}
|
||||
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
|
||||
|
||||
char buffer[256];
|
||||
size_t begin, end;
|
||||
|
||||
if (fgets(buffer, sizeof(buffer), context->maps) != NULL)
|
||||
{
|
||||
sscanf(buffer, "%zx-%zx", &begin, &end);
|
||||
|
||||
context->current_block.base = begin;
|
||||
context->current_block.size = end - begin;
|
||||
|
||||
return &context->current_block;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_first_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
|
||||
|
||||
if (fseek(context->maps, 0, SEEK_SET) != 0)
|
||||
return NULL;
|
||||
|
||||
return yr_process_get_next_memory_block(iterator);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int _yr_process_attach(int, YR_PROC_ITERATOR_CTX*);
|
||||
int _yr_process_detach(YR_PROC_ITERATOR_CTX*);
|
||||
|
||||
YR_API int yr_process_open_iterator(
|
||||
int pid,
|
||||
@@ -509,11 +50,11 @@ YR_API int yr_process_open_iterator(
|
||||
|
||||
context->buffer = NULL;
|
||||
context->buffer_size = 0;
|
||||
|
||||
context->current_block.base = 0;
|
||||
context->current_block.size = 0;
|
||||
context->current_block.context = context;
|
||||
context->current_block.fetch_data = yr_process_fetch_memory_block_data;
|
||||
context->proc_info = NULL;
|
||||
|
||||
return _yr_process_attach(pid, context);
|
||||
}
|
||||
@@ -531,6 +72,9 @@ YR_API int yr_process_close_iterator(
|
||||
if (context->buffer != NULL)
|
||||
yr_free((void*) context->buffer);
|
||||
|
||||
if (context->proc_info != NULL)
|
||||
yr_free(context->proc_info);
|
||||
|
||||
yr_free(context);
|
||||
|
||||
iterator->context = NULL;
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
Copyright (c) 2007-2017. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
|
||||
defined(__OpenBSD__) || defined(__MACH__)
|
||||
#else
|
||||
#define PTRACE_ATTACH PT_ATTACH
|
||||
#define PTRACE_DETACH PT_DETACH
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <yara/error.h>
|
||||
#include <yara/proc.h>
|
||||
#include <yara/mem.h>
|
||||
|
||||
|
||||
typedef struct _YR_PROC_INFO {
|
||||
int pid;
|
||||
int mem_fd;
|
||||
FILE* maps;
|
||||
} YR_PROC_INFO;
|
||||
|
||||
|
||||
int _yr_process_attach(
|
||||
int pid,
|
||||
YR_PROC_ITERATOR_CTX* context)
|
||||
{
|
||||
int status;
|
||||
char buffer[256];
|
||||
YR_PROC_INFO* proc_info = (YR_PROC_INFO*)yr_malloc(sizeof(YR_PROC_INFO));
|
||||
if (proc_info == NULL)
|
||||
return ERROR_INSUFFICIENT_MEMORY;
|
||||
|
||||
context->proc_info = proc_info;
|
||||
|
||||
proc_info->pid = pid;
|
||||
proc_info->maps = NULL;
|
||||
proc_info->mem_fd = -1;
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "/proc/%u/maps", pid);
|
||||
proc_info->maps = fopen(buffer, "r");
|
||||
|
||||
if (proc_info->maps == NULL)
|
||||
{
|
||||
yr_free(proc_info);
|
||||
return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
|
||||
}
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "/proc/%u/mem", pid);
|
||||
proc_info->mem_fd = open(buffer, O_RDONLY);
|
||||
|
||||
if (proc_info->mem_fd == -1)
|
||||
{
|
||||
fclose(proc_info->maps);
|
||||
proc_info->maps = NULL;
|
||||
|
||||
yr_free(proc_info);
|
||||
|
||||
return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
|
||||
}
|
||||
|
||||
if (ptrace(PTRACE_ATTACH, pid, NULL, 0) == -1)
|
||||
{
|
||||
fclose(proc_info->maps);
|
||||
proc_info->maps = NULL;
|
||||
|
||||
close(proc_info->mem_fd);
|
||||
proc_info->mem_fd = -1;
|
||||
|
||||
yr_free(proc_info);
|
||||
|
||||
return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
|
||||
}
|
||||
|
||||
status = 0;
|
||||
if (waitpid(pid, &status, 0) == -1)
|
||||
{
|
||||
// this is a strange error state where we attached but the proc didn't
|
||||
// stop. Try to detach and clean up.
|
||||
ptrace(PTRACE_DETACH, proc_info->pid, NULL, 0);
|
||||
|
||||
fclose(proc_info->maps);
|
||||
proc_info->maps = NULL;
|
||||
|
||||
close(proc_info->mem_fd);
|
||||
proc_info->mem_fd = -1;
|
||||
|
||||
yr_free(proc_info);
|
||||
|
||||
return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int _yr_process_detach(
|
||||
YR_PROC_ITERATOR_CTX* context)
|
||||
{
|
||||
YR_PROC_INFO* proc_info = (YR_PROC_INFO*)context->proc_info;
|
||||
|
||||
fclose(proc_info->maps);
|
||||
close(proc_info->mem_fd);
|
||||
ptrace(PTRACE_DETACH, proc_info->pid, NULL, 0);
|
||||
|
||||
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;
|
||||
YR_PROC_INFO* proc_info = (YR_PROC_INFO*)context->proc_info;
|
||||
|
||||
if (context->buffer_size < block->size)
|
||||
{
|
||||
if (context->buffer != NULL)
|
||||
yr_free((void*) context->buffer);
|
||||
|
||||
context->buffer = (const uint8_t*) yr_malloc(block->size);
|
||||
|
||||
if (context->buffer != NULL)
|
||||
{
|
||||
context->buffer_size = block->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
context->buffer_size = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (pread(proc_info->mem_fd,
|
||||
(void *) context->buffer,
|
||||
block->size,
|
||||
block->base) == -1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return context->buffer;
|
||||
}
|
||||
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
|
||||
YR_PROC_INFO* proc_info = (YR_PROC_INFO*)context->proc_info;
|
||||
|
||||
char buffer[256];
|
||||
size_t begin, end;
|
||||
|
||||
if (fgets(buffer, sizeof(buffer), proc_info->maps) != NULL)
|
||||
{
|
||||
sscanf(buffer, "%zx-%zx", &begin, &end);
|
||||
|
||||
context->current_block.base = begin;
|
||||
context->current_block.size = end - begin;
|
||||
|
||||
return &context->current_block;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_first_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
|
||||
YR_PROC_INFO* proc_info = (YR_PROC_INFO*)context->proc_info;
|
||||
|
||||
if (fseek(proc_info->maps, 0, SEEK_SET) != 0)
|
||||
return NULL;
|
||||
|
||||
return yr_process_get_next_memory_block(iterator);
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
Copyright (c) 2007-2017. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_vm.h>
|
||||
#include <mach/vm_region.h>
|
||||
#include <mach/vm_statistics.h>
|
||||
|
||||
#include <yara/mem.h>
|
||||
#include <yara/proc.h>
|
||||
#include <yara/error.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));
|
||||
if (proc_info == NULL)
|
||||
return ERROR_INSUFFICIENT_MEMORY;
|
||||
|
||||
kern_return_t kr = task_for_pid(mach_task_self(), pid, &proc_info->task);
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
yr_free(proc_info);
|
||||
return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
|
||||
}
|
||||
|
||||
context->proc_info = proc_info;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int _yr_process_detach(
|
||||
YR_PROC_ITERATOR_CTX* context)
|
||||
{
|
||||
YR_PROC_INFO* proc_info = context->proc_info;
|
||||
|
||||
if (proc_info->task != MACH_PORT_NULL)
|
||||
mach_port_deallocate(mach_task_self(), proc_info->task);
|
||||
|
||||
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;
|
||||
YR_PROC_INFO* proc_info = context->proc_info;
|
||||
vm_size_t size = block->size;
|
||||
|
||||
if (context->buffer_size < block->size)
|
||||
{
|
||||
if (context->buffer != NULL)
|
||||
yr_free((void*) context->buffer);
|
||||
|
||||
context->buffer = (const uint8_t*) yr_malloc(block->size);
|
||||
|
||||
if (context->buffer != NULL)
|
||||
{
|
||||
context->buffer_size = block->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
context->buffer_size = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (vm_read_overwrite(
|
||||
proc_info->task,
|
||||
block->base,
|
||||
block->size,
|
||||
(vm_address_t) context->buffer,
|
||||
&size) != KERN_SUCCESS)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return context->buffer;
|
||||
}
|
||||
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
|
||||
YR_PROC_INFO* proc_info = context->proc_info;
|
||||
|
||||
kern_return_t kr;
|
||||
mach_msg_type_number_t info_count;
|
||||
mach_port_t object;
|
||||
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(
|
||||
proc_info->task,
|
||||
&address,
|
||||
&size,
|
||||
VM_REGION_BASIC_INFO,
|
||||
(vm_region_info_t) &info,
|
||||
&info_count,
|
||||
&object);
|
||||
|
||||
if (kr == KERN_SUCCESS)
|
||||
{
|
||||
context->current_block.base = address;
|
||||
context->current_block.size = size;
|
||||
|
||||
return &context->current_block;
|
||||
}
|
||||
|
||||
} while (kr != KERN_INVALID_ADDRESS);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_first_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
|
||||
|
||||
context->current_block.base = 0;
|
||||
context->current_block.size = 0;
|
||||
|
||||
return yr_process_get_next_memory_block(iterator);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
Copyright (c) 2007-2017. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <yara/error.h>
|
||||
#include <yara/proc.h>
|
||||
|
||||
int _yr_process_attach(
|
||||
int pid,
|
||||
YR_PROC_ITERATOR_CTX* context)
|
||||
{
|
||||
return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
|
||||
}
|
||||
|
||||
int _yr_process_detach(
|
||||
YR_PROC_ITERATOR_CTX* context)
|
||||
{
|
||||
return ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
YR_API const uint8_t* yr_process_fetch_memory_block_data(
|
||||
YR_MEMORY_BLOCK* block)
|
||||
{
|
||||
return ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_first_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
Copyright (c) 2007-2017. The YARA Authors. All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <yara/mem.h>
|
||||
#include <yara/error.h>
|
||||
#include <yara/proc.h>
|
||||
|
||||
|
||||
typedef struct _YR_PROC_INFO {
|
||||
HANDLE hProcess;
|
||||
SYSTEM_INFO si;
|
||||
} YR_PROC_INFO;
|
||||
|
||||
int _yr_process_attach(
|
||||
int pid,
|
||||
YR_PROC_ITERATOR_CTX* context)
|
||||
{
|
||||
TOKEN_PRIVILEGES tokenPriv;
|
||||
LUID luidDebug;
|
||||
HANDLE hToken = NULL;
|
||||
YR_PROC_INFO* proc_info = (YR_PROC_INFO*)yr_malloc(sizeof(YR_PROC_INFO));
|
||||
if (proc_info == NULL)
|
||||
return ERROR_INSUFFICIENT_MEMORY;
|
||||
|
||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken) &&
|
||||
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidDebug))
|
||||
{
|
||||
tokenPriv.PrivilegeCount = 1;
|
||||
tokenPriv.Privileges[0].Luid = luidDebug;
|
||||
tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
|
||||
AdjustTokenPrivileges(
|
||||
hToken,
|
||||
FALSE,
|
||||
&tokenPriv,
|
||||
sizeof(tokenPriv),
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (hToken != NULL)
|
||||
CloseHandle(hToken);
|
||||
|
||||
proc_info->hProcess = OpenProcess(
|
||||
PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
|
||||
FALSE,
|
||||
pid);
|
||||
|
||||
if (proc_info->hProcess == NULL)
|
||||
{
|
||||
yr_free(proc_info);
|
||||
return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
|
||||
}
|
||||
|
||||
GetSystemInfo(&proc_info->si);
|
||||
|
||||
context->proc_info = proc_info;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int _yr_process_detach(
|
||||
YR_PROC_ITERATOR_CTX* context)
|
||||
{
|
||||
YR_PROC_INFO* proc_info = (YR_PROC_INFO*)context->proc_info;
|
||||
|
||||
CloseHandle(proc_info->hProcess);
|
||||
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;
|
||||
YR_PROC_INFO* proc_info = (YR_PROC_INFO*)context->proc_info;
|
||||
SIZE_T read;
|
||||
|
||||
if (context->buffer_size < block->size)
|
||||
{
|
||||
if (context->buffer != NULL)
|
||||
yr_free((void*) context->buffer);
|
||||
|
||||
context->buffer = (const uint8_t*) yr_malloc(block->size);
|
||||
|
||||
if (context->buffer != NULL)
|
||||
{
|
||||
context->buffer_size = block->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
context->buffer_size = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ReadProcessMemory(
|
||||
proc_info->hProcess,
|
||||
(LPCVOID) block->base,
|
||||
(LPVOID) context->buffer,
|
||||
(SIZE_T) block->size,
|
||||
&read) == FALSE)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return context->buffer;
|
||||
}
|
||||
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_next_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
|
||||
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);
|
||||
|
||||
while (address < proc_info->si.lpMaximumApplicationAddress &&
|
||||
VirtualQueryEx(proc_info->hProcess, address, &mbi, sizeof(mbi)) != 0)
|
||||
{
|
||||
if (GetLastError() != ERROR_SUCCESS)
|
||||
break;
|
||||
|
||||
if (mbi.State == MEM_COMMIT && ((mbi.Protect & PAGE_NOACCESS) == 0))
|
||||
{
|
||||
context->current_block.base = (size_t) mbi.BaseAddress;
|
||||
context->current_block.size = mbi.RegionSize;
|
||||
|
||||
return &context->current_block;
|
||||
}
|
||||
|
||||
address = (uint8_t*) address + mbi.RegionSize;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
YR_API YR_MEMORY_BLOCK* yr_process_get_first_memory_block(
|
||||
YR_MEMORY_BLOCK_ITERATOR* iterator)
|
||||
{
|
||||
YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) iterator->context;
|
||||
YR_PROC_INFO* proc_info = (YR_PROC_INFO*)context->proc_info;
|
||||
|
||||
context->current_block.base = (size_t) proc_info->si.lpMinimumApplicationAddress;
|
||||
context->current_block.size = 0;
|
||||
|
||||
return yr_process_get_next_memory_block(iterator);
|
||||
}
|
||||
@@ -210,6 +210,7 @@
|
||||
<ClCompile Include="..\..\..\libyara\object.c" />
|
||||
<ClCompile Include="..\..\..\libyara\parser.c" />
|
||||
<ClCompile Include="..\..\..\libyara\proc.c" />
|
||||
<ClCompile Include="..\..\..\libyara\proc_windows.c" />
|
||||
<ClCompile Include="..\..\..\libyara\re.c" />
|
||||
<ClCompile Include="..\..\..\libyara\re_grammar.c" />
|
||||
<ClCompile Include="..\..\..\libyara\re_lexer.c" />
|
||||
|
||||
Reference in New Issue
Block a user