From 6d58d975a6d69ffafe30f51ec83cccefbecd4883 Mon Sep 17 00:00:00 2001 From: midipix Date: Wed, 18 Jan 2017 00:00:48 +0000 Subject: ldso: added pe_open_image_from_addr(). --- src/internal/pe_os.h | 20 +++++++++ src/ldso/pe_open_image_from_addr.c | 83 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 src/ldso/pe_open_image_from_addr.c (limited to 'src') diff --git a/src/internal/pe_os.h b/src/internal/pe_os.h index f68a462..54275e3 100644 --- a/src/internal/pe_os.h +++ b/src/internal/pe_os.h @@ -19,6 +19,9 @@ #define OS_FILE_SHARE_WRITE 0x00000002 #define OS_FILE_SHARE_DELETE 0x00000004 +#define OS_CURRENT_PROCESS_HANDLE (void *)(uintptr_t)(-1) +#define OS_CURRENT_THREAD_HANDLE (void *)(uintptr_t)(-2) + enum os_object_info_class { OS_OBJECT_BASIC_INFORMATION = 0, @@ -29,6 +32,14 @@ enum os_object_info_class { }; +enum os_memory_info_class { + OS_MEMORY_BASIC_INFORMATION, + OS_MEMORY_WORKING_SET_LIST, + OS_MEMORY_SECTION_NAME, + OS_MEMORY_BASIC_VLM_INFORMATION +}; + + struct os_oa { uint32_t len; void * root_dir; @@ -56,6 +67,15 @@ typedef int32_t __stdcall os_zw_query_object( __out uint32_t * returned_length __optional); +typedef int32_t __stdcall os_zw_query_virtual_memory( + __in void * hprocess, + __in void * base_address, + __in int mem_info_class, + __out void * mem_info, + __in uint32_t mem_info_length, + __out uint32_t * returned_length __optional); + + typedef int32_t __stdcall os_zw_open_file( __out void ** hfile, __in uint32_t desired_access, diff --git a/src/ldso/pe_open_image_from_addr.c b/src/ldso/pe_open_image_from_addr.c new file mode 100644 index 0000000..2729a18 --- /dev/null +++ b/src/ldso/pe_open_image_from_addr.c @@ -0,0 +1,83 @@ +/*****************************************************************************/ +/* pemagination: a (virtual) tour into portable bits and executable bytes */ +/* Copyright (C) 2013--2017 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */ +/*****************************************************************************/ + +#include +#include +#include +#include "pe_os.h" + +struct os_memory_section_name { + struct pe_unicode_str section_name; + wchar16_t section_name_buffer[]; +}; + +pe_api int32_t pe_open_image_from_addr( + __out void ** himage, + __in void * addr, + __out uintptr_t * buffer, + __in uint32_t buffer_size, + __in uint32_t desired_access, + __in uint32_t open_options) +{ + int32_t status; + struct os_oa oa; + struct os_iosb iosb; + struct os_memory_section_name * path; + uint32_t len; + void * hntdll; + os_zw_query_virtual_memory * zw_query_virtual_memory; + os_zw_open_file * zw_open_file; + + + /* init */ + path = (struct os_memory_section_name *)buffer; + path->section_name.strlen = 0; + path->section_name.maxlen = (uint16_t)(buffer_size - sizeof(struct pe_unicode_str)); + path->section_name.buffer = path->section_name_buffer; + + if (!(hntdll = pe_get_ntdll_module_handle())) + return OS_STATUS_INTERNAL_ERROR; + + if (!(zw_query_virtual_memory = (os_zw_query_virtual_memory *)pe_get_procedure_address( + hntdll,"ZwQueryVirtualMemory"))) + return OS_STATUS_INTERNAL_ERROR; + + if (!(zw_open_file = (os_zw_open_file *)pe_get_procedure_address( + hntdll,"ZwOpenFile"))) + return OS_STATUS_INTERNAL_ERROR; + + /* native path of image containing addr */ + if ((status = zw_query_virtual_memory( + OS_CURRENT_PROCESS_HANDLE, + addr, + OS_MEMORY_SECTION_NAME, + buffer, + buffer_size, + &len))) + return status; + + /* oa */ + oa.len = sizeof(struct os_oa); + oa.root_dir = 0; + oa.obj_name = &path->section_name; + oa.obj_attr = 0; + oa.sec_desc = 0; + oa.sec_qos = 0; + + /* default access */ + desired_access = desired_access + ? desired_access + : OS_SEC_SYNCHRONIZE | OS_FILE_READ_ATTRIBUTES | OS_FILE_READ_ACCESS; + + /* open image */ + return zw_open_file( + himage, + desired_access, + &oa, + &iosb, + OS_FILE_SHARE_READ | OS_FILE_SHARE_WRITE, + open_options | OS_FILE_NON_DIRECTORY_FILE); +} -- cgit v1.2.3