summaryrefslogtreecommitdiffhomepage
path: root/src/meta
diff options
context:
space:
mode:
Diffstat (limited to 'src/meta')
-rw-r--r--src/meta/pe_get_image_stack_heap_info.c43
-rw-r--r--src/meta/pe_get_symbol_module_info.c56
-rw-r--r--src/meta/pe_get_symbol_name.c209
3 files changed, 308 insertions, 0 deletions
diff --git a/src/meta/pe_get_image_stack_heap_info.c b/src/meta/pe_get_image_stack_heap_info.c
new file mode 100644
index 0000000..ec1aba9
--- /dev/null
+++ b/src/meta/pe_get_image_stack_heap_info.c
@@ -0,0 +1,43 @@
+/*****************************************************************************/
+/* pemagination: a (virtual) tour into portable bits and executable bytes */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */
+/*****************************************************************************/
+
+#include <psxtypes/psxtypes.h>
+#include <pemagine/pe_consts.h>
+#include <pemagine/pe_structs.h>
+#include <pemagine/pemagine.h>
+
+pe_api
+int pe_get_image_stack_heap_info(const void * base, struct pe_stack_heap_info * stack_heap_info)
+{
+ uint16_t * magic;
+ union pe_opt_hdr * hdr;
+
+ if (!(hdr = pe_get_image_opt_hdr_addr(base)))
+ return 0;
+
+ magic = (uint16_t *)hdr;
+
+ switch (*magic) {
+ case PE_MAGIC_PE32:
+ stack_heap_info->size_of_stack_reserve = *(uint32_t *)hdr->opt_hdr_32.size_of_stack_reserve;
+ stack_heap_info->size_of_stack_commit = *(uint32_t *)hdr->opt_hdr_32.size_of_stack_commit;
+ stack_heap_info->size_of_heap_reserve = *(uint32_t *)hdr->opt_hdr_32.size_of_heap_reserve;
+ stack_heap_info->size_of_heap_commit = *(uint32_t *)hdr->opt_hdr_32.size_of_heap_commit;
+ break;
+
+ case PE_MAGIC_PE32_PLUS:
+ stack_heap_info->size_of_stack_reserve = *(size_t *)hdr->opt_hdr_64.size_of_stack_reserve;
+ stack_heap_info->size_of_stack_commit = *(size_t *)hdr->opt_hdr_64.size_of_stack_commit;
+ stack_heap_info->size_of_heap_reserve = *(size_t *)hdr->opt_hdr_64.size_of_heap_reserve;
+ stack_heap_info->size_of_heap_commit = *(size_t *)hdr->opt_hdr_64.size_of_heap_commit;
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/src/meta/pe_get_symbol_module_info.c b/src/meta/pe_get_symbol_module_info.c
new file mode 100644
index 0000000..7dd8a5a
--- /dev/null
+++ b/src/meta/pe_get_symbol_module_info.c
@@ -0,0 +1,56 @@
+/*****************************************************************************/
+/* pemagination: a (virtual) tour into portable bits and executable bytes */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */
+/*****************************************************************************/
+
+#include <psxtypes/psxtypes.h>
+#include <pemagine/pemagine.h>
+
+
+struct pe_module_info_ctx {
+ uintptr_t sym_addr;
+ struct pe_ldr_tbl_entry * image_ldr_tbl_entry;
+};
+
+
+
+static int pe_get_symbol_module_info_callback(
+ struct pe_ldr_tbl_entry * ldr_tbl_entry,
+ enum pe_callback_reason reason,
+ void * context)
+{
+ uintptr_t image_base;
+ uintptr_t image_size;
+ struct pe_module_info_ctx * ctx;
+
+ if (reason != PE_CALLBACK_REASON_ITEM)
+ return 1;
+
+ ctx = (struct pe_module_info_ctx *)context;
+ image_base = (uintptr_t)(ldr_tbl_entry->dll_base);
+ image_size = (uintptr_t)(ldr_tbl_entry->size_of_image);
+
+ if ((ctx->sym_addr > image_base) && (ctx->sym_addr < image_base + image_size)) {
+ /* within bounds */
+ ctx->image_ldr_tbl_entry = ldr_tbl_entry;
+ return 0;
+ } else
+ return 1;
+}
+
+
+pe_api
+struct pe_ldr_tbl_entry * pe_get_symbol_module_info(const void * sym_addr)
+{
+ struct pe_module_info_ctx ctx;
+
+ ctx.sym_addr = (uintptr_t)sym_addr;
+ ctx.image_ldr_tbl_entry = 0;
+
+ pe_enum_modules_in_load_order(
+ pe_get_symbol_module_info_callback,
+ &ctx);
+
+ return ctx.image_ldr_tbl_entry;
+}
diff --git a/src/meta/pe_get_symbol_name.c b/src/meta/pe_get_symbol_name.c
new file mode 100644
index 0000000..f9001ef
--- /dev/null
+++ b/src/meta/pe_get_symbol_name.c
@@ -0,0 +1,209 @@
+/*****************************************************************************/
+/* pemagination: a (virtual) tour into portable bits and executable bytes */
+/* Copyright (C) 2013,2014,2015 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.PEMAGINE. */
+/*****************************************************************************/
+
+#include <psxtypes/psxtypes.h>
+#include <pemagine/pemagine.h>
+
+/* private args structure */
+struct pe_symbol_name_ctx {
+ const void * addr;
+ char * name;
+};
+
+/* private forward declarations */
+static int pe_enum_exports_callback(
+ const void * base,
+ struct pe_export_hdr * exp_hdr,
+ struct pe_export_sym * sym,
+ enum pe_callback_reason reason,
+ void * context);
+
+#if defined (__NT32)
+static char * pe_get_imported_symbol_info_32(
+ const void * sym_addr,
+ void ** sym_image_addr,
+ char ** sym_name,
+ struct pe_ldr_tbl_entry ** ldr_tbl_entry);
+#endif
+
+#if defined (__NT64)
+static char * pe_get_imported_symbol_info_64(
+ const void * sym_addr,
+ void ** sym_image_addr,
+ char ** sym_name,
+ struct pe_ldr_tbl_entry ** ldr_tbl_entry);
+;
+#endif
+
+pe_api
+char * pe_get_symbol_name(const void * base, const void * sym_addr)
+{
+ struct pe_export_sym exp_item;
+ struct pe_symbol_name_ctx ctx;
+
+ ctx.name = 0;
+ ctx.addr = sym_addr;
+
+ pe_enum_image_exports(
+ base,
+ pe_enum_exports_callback,
+ &exp_item,
+ &ctx);
+
+ return ctx.name;
+}
+
+
+pe_api
+char * pe_get_import_symbol_info(
+ const void * sym_addr,
+ void ** sym_image_addr,
+ char ** sym_name,
+ struct pe_ldr_tbl_entry ** ldr_tbl_entry)
+{
+ #if defined(__NT32)
+ return pe_get_imported_symbol_info_32(
+ sym_addr,
+ sym_image_addr,
+ sym_name,
+ ldr_tbl_entry);
+ #elif defined (__NT64)
+ return pe_get_imported_symbol_info_64(
+ sym_addr,
+ sym_image_addr,
+ sym_name,
+ ldr_tbl_entry);
+ #endif
+}
+
+static int pe_enum_exports_callback(
+ const void * base,
+ struct pe_export_hdr * exp_hdr,
+ struct pe_export_sym * sym,
+ enum pe_callback_reason reason,
+ void * context)
+{
+ struct pe_symbol_name_ctx * ctx;
+
+ if (reason != PE_CALLBACK_REASON_ITEM)
+ return 1;
+
+ ctx = (struct pe_symbol_name_ctx *)context;
+
+ if (sym->addr == ctx->addr) {
+ ctx->name = sym->name;
+ return 0;
+ } else
+ return 1;
+}
+
+
+#ifdef __NT32
+static char * pe_get_imported_symbol_info_32(
+ const void * sym_addr,
+ void ** sym_image_addr,
+ char ** sym_name,
+ struct pe_ldr_tbl_entry ** ldr_tbl_entry)
+{
+ struct symbol {
+ unsigned char call;
+ unsigned char ds;
+ unsigned char sym_addr[4];
+ unsigned char padding[2];
+ };
+
+ char * fn_name;
+ struct pe_ldr_tbl_entry * mod_info;
+ void * mod_base;
+ uint32_t *** sym_redirected_addr;
+ struct symbol * sym;
+
+ fn_name = 0;
+ mod_info = 0;
+ sym = (struct symbol *)sym_addr;
+
+ if ((sym->call == 0xff) && (sym->ds == 0x25)) {
+ sym_redirected_addr = (uint32_t ***)sym->sym_addr;
+
+ if (sym_redirected_addr)
+ mod_info = pe_get_symbol_module_info(**sym_redirected_addr);
+
+ if (mod_info)
+ mod_base = mod_info->dll_base;
+ else
+ mod_base = (void *)0;
+
+ if (mod_base)
+ fn_name = pe_get_symbol_name(
+ mod_base,
+ **sym_redirected_addr);
+ }
+
+ if (fn_name && ldr_tbl_entry)
+ *ldr_tbl_entry = mod_info;
+
+ return fn_name;
+}
+#endif
+
+
+#ifdef __NT64
+static char * pe_get_imported_symbol_info_64(
+ const void * sym_addr,
+ void ** sym_image_addr,
+ char ** sym_name,
+ struct pe_ldr_tbl_entry ** ldr_tbl_entry)
+{
+ struct symbol {
+ unsigned char call;
+ unsigned char ds;
+ unsigned char sym_addr[4];
+ unsigned char padding[2];
+ };
+
+ char * fn_name;
+ struct pe_ldr_tbl_entry * mod_info;
+ void * mod_base;
+ uint32_t * sym_offset;
+ uint32_t offset;
+ struct symbol * sym;
+
+ fn_name = 0;
+ mod_info = 0;
+ sym = (struct symbol *)sym_addr;
+
+ if ((sym->call == 0xff) && (sym->ds == 0x25)) {
+ sym_offset = (uint32_t *)sym->sym_addr;
+
+ if (sym_offset) {
+ offset = *sym_offset;
+ sym_addr = *(void **)(offset + (uintptr_t)(++sym_offset));
+ mod_info = pe_get_symbol_module_info(sym_addr);
+ }
+
+ if (mod_info)
+ mod_base = mod_info->dll_base;
+ else
+ mod_base = (void *)0;
+
+ if (mod_base)
+ fn_name = pe_get_symbol_name(mod_base,sym_addr);
+ }
+
+ if (fn_name) {
+ if (ldr_tbl_entry)
+ *ldr_tbl_entry = mod_info;
+
+ if (sym_image_addr)
+ *sym_image_addr = (void *)sym_addr;
+
+ if (sym_name)
+ *sym_name = fn_name;
+ }
+
+ return fn_name;
+}
+#endif