summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ldso/pe_get_ldr_entry_from_addr.c63
1 files changed, 63 insertions, 0 deletions
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;
+}