diff options
-rw-r--r-- | include/pemagine/pe_ldso.h | 1 | ||||
-rw-r--r-- | include/pemagine/pemagine.h | 2 | ||||
-rw-r--r-- | project/common.mk | 1 | ||||
-rw-r--r-- | src/ldso/pe_get_ldr_entry_from_addr.c | 63 |
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; +} |