diff options
Diffstat (limited to 'src/ldso')
-rw-r--r-- | src/ldso/pe_open_image_from_addr.c | 83 |
1 files changed, 83 insertions, 0 deletions
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 <psxtypes/psxtypes.h> +#include <pemagine/pemagine.h> +#include <pemagine/pe_structs.h> +#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); +} |