summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/pemagine/pe_ldso.h1
-rw-r--r--include/pemagine/pemagine.h2
-rw-r--r--project/common.mk1
-rw-r--r--src/ldso/pe_get_ldr_entry_from_addr.c63
4 files changed, 67 insertions, 0 deletions
diff --git a/include/pemagine/pe_ldso.h b/include/pemagine/pe_ldso.h
index 2d81774..30019c5 100644
--- a/include/pemagine/pe_ldso.h
+++ b/include/pemagine/pe_ldso.h
@@ -12,6 +12,7 @@
#define pe_get_export_symbol_info __ldso_get_export_symbol_info
#define pe_get_first_module_handle __ldso_get_first_module_handle
#define pe_get_framework_runtime_data __ldso_get_framework_runtime_data
+#define pe_get_ldr_entry_from_addr __ldso_get_ldr_entry_from_addr
#define pe_get_image_coff_hdr_addr __ldso_get_image_coff_hdr_addr
#define pe_get_image_data_dirs_addr __ldso_get_image_data_dirs_addr
#define pe_get_image_dos_hdr_addr __ldso_get_image_dos_hdr_addr
diff --git a/include/pemagine/pemagine.h b/include/pemagine/pemagine.h
index 283d579..99ba86a 100644
--- a/include/pemagine/pemagine.h
+++ b/include/pemagine/pemagine.h
@@ -241,6 +241,8 @@ pe_api void * pe_get_kernel32_module_handle (void);
/* ldso */
pe_api wchar16_t * pe_get_peb_command_line(void);
pe_api wchar16_t * pe_get_peb_environment_block(void);
+pe_api struct pe_ldr_tbl_entry * pe_get_ldr_entry_from_addr(const void * addr);
+
pe_api int32_t pe_get_framework_runtime_data(
struct pe_framework_runtime_data ** rtdata,
diff --git a/project/common.mk b/project/common.mk
index 5ff3a1e..bb39af8 100644
--- a/project/common.mk
+++ b/project/common.mk
@@ -11,6 +11,7 @@ API_SRCS = \
src/headers/pe_get_image_special_hdr_addr.c \
src/imports/pe_enum_image_import_hdrs.c \
src/ldso/pe_get_framework_runtime_data.c \
+ src/ldso/pe_get_ldr_entry_from_addr.c \
src/ldso/pe_get_peb_strings.c \
src/ldso/pe_find_framework_loader.c \
src/ldso/pe_load_framework_loader.c \
diff --git a/src/ldso/pe_get_ldr_entry_from_addr.c b/src/ldso/pe_get_ldr_entry_from_addr.c
new file mode 100644
index 0000000..69f01f5
--- /dev/null
+++ b/src/ldso/pe_get_ldr_entry_from_addr.c
@@ -0,0 +1,63 @@
+/*****************************************************************************/
+/* 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 "pe_os.h"
+
+struct ldr_entry_addr_ctx {
+ uintptr_t addr;
+ struct pe_ldr_tbl_entry * entry;
+};
+
+static int ldr_entry_addr_compare(
+ struct pe_ldr_tbl_entry * image_ldr_tbl_entry,
+ enum pe_callback_reason reason,
+ void * context)
+{
+ uintptr_t base;
+ uintptr_t cap;
+ struct ldr_entry_addr_ctx * ctx;
+
+ switch (reason) {
+ case PE_CALLBACK_REASON_INIT:
+ case PE_CALLBACK_REASON_INFO:
+ case PE_CALLBACK_REASON_QUERY:
+ return 1;
+
+ case PE_CALLBACK_REASON_DONE:
+ return 0;
+
+ case PE_CALLBACK_REASON_ERROR:
+ return OS_STATUS_INTERNAL_ERROR;
+
+ case PE_CALLBACK_REASON_ITEM:
+ break;
+ }
+
+ ctx = (struct ldr_entry_addr_ctx *)context;
+ base = (uintptr_t)image_ldr_tbl_entry->dll_base;
+ cap = base + image_ldr_tbl_entry->size_of_image;
+
+ if ((ctx->addr >= base) && (ctx->addr < cap)) {
+ ctx->entry = image_ldr_tbl_entry;
+ return 0;
+ }
+
+ return 1;
+}
+
+struct pe_ldr_tbl_entry * pe_get_ldr_entry_from_addr(const void * addr)
+{
+ struct ldr_entry_addr_ctx ctx = {(uintptr_t)addr,0};
+
+ if (pe_enum_modules_in_load_order(
+ ldr_entry_addr_compare,
+ &ctx))
+ return 0;
+
+ return ctx.entry;
+}