[Forensics-changes] [yara] 191/368: POC section reader working for Windows
Hilko Bengen
bengen at moszumanska.debian.org
Sat Jul 1 10:30:38 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 af18d8604c4c4a1091e88156dd6cc505746e9336
Author: Kyle Reed <kallanreed at outlook.com>
Date: Sat Feb 20 22:50:18 2016 -0800
POC section reader working for Windows
Signed-off-by: Kyle Reed <kallanreed at outlook.com>
# Conflicts:
# libyara/include/yara/error.h
---
libyara/include/yara/proc.h | 10 ++
libyara/include/yara/rules.h | 7 ++
libyara/include/yara/types.h | 19 ++++
libyara/proc.c | 221 +++++++++++++++++++++++++++++++++++++++++++
libyara/rules.c | 38 ++++++++
yara.c | 2 +-
6 files changed, 296 insertions(+), 1 deletion(-)
diff --git a/libyara/include/yara/proc.h b/libyara/include/yara/proc.h
index 3145ac1..1f844b0 100644
--- a/libyara/include/yara/proc.h
+++ b/libyara/include/yara/proc.h
@@ -23,4 +23,14 @@ int yr_process_get_memory(
int pid,
YR_MEMORY_BLOCK** first_block);
+int yr_open_section_reader(
+ int pid,
+ YR_SECTION_READER** reader);
+
+int yr_read_next_section(
+ YR_SECTION_READER* reader);
+
+void yr_close_section_reader(
+ YR_SECTION_READER* reader);
+
#endif
diff --git a/libyara/include/yara/rules.h b/libyara/include/yara/rules.h
index 153ce43..fa268ad 100644
--- a/libyara/include/yara/rules.h
+++ b/libyara/include/yara/rules.h
@@ -92,6 +92,13 @@ YR_API int yr_rules_scan_proc(
void* user_data,
int timeout);
+YR_API int yr_rules_scan_proc2(
+ YR_RULES* rules,
+ int pid,
+ int flags,
+ YR_CALLBACK_FUNC callback,
+ void* user_data,
+ int timeout);
YR_API int yr_rules_save(
YR_RULES* rules,
diff --git a/libyara/include/yara/types.h b/libyara/include/yara/types.h
index 2c5c582..c33d370 100644
--- a/libyara/include/yara/types.h
+++ b/libyara/include/yara/types.h
@@ -374,6 +374,25 @@ typedef struct _YR_MEMORY_BLOCK
} YR_MEMORY_BLOCK;
+typedef struct _YR_MEMORY_SECTION
+{
+ size_t base;
+ size_t size;
+
+ _YR_MEMORY_SECTION* next;
+
+} YR_MEMORY_SECTION;
+
+typedef struct _YR_SECTION_READER
+{
+ void* context;
+
+ YR_MEMORY_SECTION* sections;
+ YR_MEMORY_SECTION* current;
+ YR_MEMORY_BLOCK* block;
+
+} YR_SECTION_READER;
+
typedef int (*YR_CALLBACK_FUNC)(
int message,
void* message_data,
diff --git a/libyara/proc.c b/libyara/proc.c
index 1d050b1..ad7a548 100644
--- a/libyara/proc.c
+++ b/libyara/proc.c
@@ -22,6 +22,222 @@ limitations under the License.
#include <yara/error.h>
#include <yara/proc.h>
+
+int _attach_process(
+ int pid,
+ void** hProcess)
+{
+ 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);
+
+ *hProcess = OpenProcess(
+ PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
+ FALSE,
+ pid);
+
+ if (*hProcess == NULL)
+ return ERROR_COULD_NOT_ATTACH_TO_PROCESS;
+
+ return ERROR_SUCCESS;
+}
+
+int _detach_process(
+ void* hProcess)
+{
+ if (hProcess != NULL)
+ CloseHandle(hProcess);
+
+ return ERROR_SUCCESS;
+}
+
+int _get_sections(
+ void* hProcess,
+ YR_SECTION_READER* reader)
+{
+ PVOID address;
+ int result = ERROR_SUCCESS;
+ int sections = 0;
+
+ YR_MEMORY_SECTION* new_section;
+ YR_MEMORY_SECTION* current = NULL;
+
+ SYSTEM_INFO si;
+ MEMORY_BASIC_INFORMATION mbi;
+
+ GetSystemInfo(&si);
+
+ address = si.lpMinimumApplicationAddress;
+
+ while (address < si.lpMaximumApplicationAddress &&
+ VirtualQueryEx(hProcess, address, &mbi, sizeof(mbi)) != 0)
+ {
+ if (mbi.State == MEM_COMMIT && ((mbi.Protect & PAGE_NOACCESS) == 0))
+ {
+ YR_MEMORY_SECTION* new_section = (YR_MEMORY_SECTION*)yr_malloc(sizeof(YR_MEMORY_SECTION));
+
+ new_section->base = (size_t)mbi.BaseAddress;
+ new_section->size = mbi.RegionSize;
+
+ if (reader->sections == NULL)
+ reader->sections = new_section;
+
+ if (current != NULL)
+ current->next = new_section;
+
+ current = new_section;
+
+ ++sections;
+ }
+
+ address = (uint8_t*)address + mbi.RegionSize;
+ }
+
+ printf("%lu sections\n", sections);
+
+ return result;
+}
+int _read_section(
+ void* hProcess,
+ YR_MEMORY_SECTION* section,
+ YR_MEMORY_BLOCK** block)
+{
+ SIZE_T read;
+ uint8_t* data;
+ int result = ERROR_SUCCESS;
+ *block = NULL;
+
+ data = (uint8_t*)yr_malloc(section->size);
+
+ if (data == NULL)
+ {
+ result = ERROR_INSUFICIENT_MEMORY;
+ goto error;
+ }
+
+ if (ReadProcessMemory(
+ (HANDLE)hProcess,
+ (LPCVOID)section->base,
+ data,
+ (SIZE_T)section->size,
+ &read))
+ {
+ *block = (YR_MEMORY_BLOCK*)yr_malloc(sizeof(YR_MEMORY_BLOCK));
+
+ if (*block == NULL)
+ {
+ result = ERROR_INSUFICIENT_MEMORY;
+ goto error;
+ }
+
+ (*block)->base = section->base;
+ (*block)->size = (size_t)read;
+ (*block)->data = data;
+ }
+
+ return result;
+
+error:
+ if (data != NULL)
+ yr_free(data);
+
+ return result;
+}
+
+int yr_open_section_reader(
+ int pid,
+ YR_SECTION_READER** reader)
+{
+ *reader = (YR_SECTION_READER*)yr_malloc(sizeof(YR_SECTION_READER));
+
+ int result = _attach_process(pid, &(*reader)->context);
+
+ result = _get_sections((*reader)->context, *reader);
+
+ return result;
+}
+
+int yr_read_next_section(
+ YR_SECTION_READER* reader)
+{
+ int result = ERROR_SUCCESS;
+
+ // free the previous memory block
+ if (reader->block != NULL)
+ {
+ yr_free(reader->block->data);
+ yr_free(reader->block);
+ reader->block = NULL;
+ }
+
+ // set current to first or next
+ if(reader->current == NULL)
+ reader->current = reader->sections;
+ else
+ reader->current = reader->current->next;
+
+ if (reader->current == NULL)
+ return ERROR_SECTION_READER_COMPLETE;
+
+ result = _read_section(
+ reader->context,
+ reader->current,
+ &reader->block);
+
+ return result;
+}
+
+void yr_close_section_reader(
+ YR_SECTION_READER* reader)
+{
+ YR_MEMORY_SECTION* current;
+ YR_MEMORY_SECTION* next;
+
+ _detach_process(reader->context);
+
+ // free the list of sections
+ current = reader->sections;
+
+ while (current != NULL)
+ {
+ next = current->next;
+
+ yr_free(current);
+
+ current = next;
+ }
+
+ // free the memory block
+ if (reader->block != NULL)
+ {
+ yr_free(reader->block->data);
+ yr_free(reader->block);
+ }
+
+ // free the reader
+ yr_free(reader);
+}
+
+
int yr_process_get_memory(
int pid,
YR_MEMORY_BLOCK** first_block)
@@ -77,6 +293,7 @@ int yr_process_get_memory(
GetSystemInfo(&si);
address = si.lpMinimumApplicationAddress;
+ size_t allocated = 0;
while (address < si.lpMaximumApplicationAddress &&
VirtualQueryEx(hProcess, address, &mbi, sizeof(mbi)) != 0)
@@ -91,6 +308,8 @@ int yr_process_get_memory(
break;
}
+ allocated += mbi.RegionSize;
+
if (ReadProcessMemory(
hProcess,
mbi.BaseAddress,
@@ -129,6 +348,8 @@ int yr_process_get_memory(
address = (PVOID)((ULONG_PTR) mbi.BaseAddress + mbi.RegionSize);
}
+ printf("Allocated %lu bytes\n", allocated);
+
if (hToken != NULL)
CloseHandle(hToken);
diff --git a/libyara/rules.c b/libyara/rules.c
index 189fdf9..8ba94f3 100644
--- a/libyara/rules.c
+++ b/libyara/rules.c
@@ -308,6 +308,8 @@ int _yr_rules_scan_mem_block(
return ERROR_SUCCESS;
}
+// TODO: break up this function
+// into one that take a context
YR_API int yr_rules_scan_mem_blocks(
YR_RULES* rules,
@@ -636,6 +638,42 @@ YR_API int yr_rules_scan_proc(
return result;
}
+YR_API int yr_rules_scan_proc2(
+ YR_RULES* rules,
+ int pid,
+ int flags,
+ YR_CALLBACK_FUNC callback,
+ void* user_data,
+ int timeout)
+{
+ YR_SECTION_READER* reader;
+
+ int result = yr_open_section_reader(pid, &reader);
+
+ if (result != ERROR_SUCCESS)
+ goto _exit;
+
+ while ((result = yr_read_next_section(reader)) == ERROR_SUCCESS)
+ {
+ if(reader->block != NULL)
+ result = yr_rules_scan_mem_blocks(
+ rules,
+ reader->block,
+ flags | SCAN_FLAGS_PROCESS_MEMORY,
+ callback,
+ user_data,
+ timeout);
+ }
+
+ if (result == ERROR_SECTION_READER_COMPLETE)
+ result = ERROR_SUCCESS;
+
+_exit:
+ if (reader != NULL)
+ yr_close_section_reader(reader);
+
+ return result;
+}
YR_API int yr_rules_load_stream(
YR_STREAM* stream,
diff --git a/yara.c b/yara.c
index 5fc8f4a..79022e1 100644
--- a/yara.c
+++ b/yara.c
@@ -1076,7 +1076,7 @@ int main(
if (fast_scan)
flags |= SCAN_FLAGS_FAST_MODE;
- result = yr_rules_scan_proc(
+ result = yr_rules_scan_proc2(
rules,
pid,
flags,
--
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