summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/pemagine/pemagine.h10
-rw-r--r--project/common.mk1
-rw-r--r--src/internal/pe_os.h20
-rw-r--r--src/ldso/pe_open_image_from_addr.c83
4 files changed, 114 insertions, 0 deletions
diff --git a/include/pemagine/pemagine.h b/include/pemagine/pemagine.h
index c222406..d5d0e66 100644
--- a/include/pemagine/pemagine.h
+++ b/include/pemagine/pemagine.h
@@ -197,6 +197,15 @@ pe_api void * pe_get_kernel32_module_handle (void);
/* ldso */
+pe_api int32_t pe_open_image_from_addr(
+ void ** himage,
+ void * addr,
+ uintptr_t * buffer,
+ uint32_t buffer_size,
+ uint32_t desired_access,
+ uint32_t open_options);
+
+
pe_api int32_t pe_open_physical_parent_directory(
void ** hparent,
void * href,
@@ -205,6 +214,7 @@ pe_api int32_t pe_open_physical_parent_directory(
uint32_t desired_access,
uint32_t open_options);
+
#ifdef __cplusplus
}
#endif
diff --git a/project/common.mk b/project/common.mk
index 60c71f8..38b0a37 100644
--- a/project/common.mk
+++ b/project/common.mk
@@ -10,6 +10,7 @@ API_SRCS = \
src/headers/pe_get_image_section_tbl_addr.c \
src/headers/pe_get_image_special_hdr_addr.c \
src/imports/pe_enum_image_import_hdrs.c \
+ src/ldso/pe_open_image_from_addr.c \
src/ldso/pe_open_physical_parent_directory.c \
src/meta/pe_get_image_stack_heap_info.c \
src/meta/pe_get_symbol_module_info.c \
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);
+}