diff options
Diffstat (limited to 'src/ldso')
-rw-r--r-- | src/ldso/pe_get_ldr_entry_from_addr.c | 63 |
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; +} |