summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/internal/pe_os.h20
-rw-r--r--src/ldso/pe_open_image_from_addr.c83
2 files changed, 103 insertions, 0 deletions
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 <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);
+}