diff --git a/src/eh_elf/context_struct.h b/src/eh_elf/context_struct.h index 585cbb7c..ed7fbe75 100644 --- a/src/eh_elf/context_struct.h +++ b/src/eh_elf/context_struct.h @@ -1,5 +1,7 @@ #include +#pragma once + typedef enum { UNWF_RIP=0, UNWF_RSP=1, diff --git a/src/eh_elf/eh_elf.c b/src/eh_elf/eh_elf.c index b48af9a2..853fb5cc 100644 --- a/src/eh_elf/eh_elf.c +++ b/src/eh_elf/eh_elf.c @@ -120,12 +120,6 @@ int eh_elf_step_cursor(struct cursor *cursor) { ip - mmap_entry->offset, mmap_entry->eh_elf == NULL ? " [MISSING EH_ELF]" : ""); - // Retrieve a pointer to the eh_elf function - _fde_func_with_deref_t fde_func = - (_fde_func_with_deref_t) (dlsym(mmap_entry->eh_elf, "_eh_elf")); - if(fde_func == NULL) - return -2; - // Setup an eh_elf context unwind_context_t eh_elf_context; eh_elf_context.rip = ip; @@ -149,7 +143,7 @@ int eh_elf_step_cursor(struct cursor *cursor) { eh_elf_context.flags = 0; // Call fde_func - eh_elf_context = fde_func( + eh_elf_context = mmap_entry->fde_func( eh_elf_context, ip - mmap_entry->offset, fetchw_here); diff --git a/src/eh_elf/memory_map.c b/src/eh_elf/memory_map.c index 6dc9af2a..f7cfae8e 100644 --- a/src/eh_elf/memory_map.c +++ b/src/eh_elf/memory_map.c @@ -18,9 +18,6 @@ int mmap_init_procdir(const char* procdir); /// memory region static int mmap_order_entries(mmap_entry_t* entries, size_t count); -/// `dlopen` a new list entry, or fetch it -static dl_obj_t mmap_dlopen_eh_elf(const char* obj_name); - /// `dlopen`s the corresponding eh_elf for each entry in `entries`. static int mmap_dlopen_eh_elfs(mmap_entry_t* entries, size_t count); @@ -181,20 +178,20 @@ static int mmap_order_entries(mmap_entry_t* entries, size_t count) { return 0; } -static dl_obj_t mmap_dlopen_eh_elf(const char* obj_name) { +/// `dlopen` a new list entry, or fetch it +static dl_obj_list_t* mmap_dlopen_eh_elf(const char* obj_name) { dl_obj_list_t *cur_elt = _dl_obj_list; - Debug(1, "Obj_name: %s\n", obj_name); while(cur_elt != NULL) { - Debug(1, "Cur_elt: %s\n", cur_elt->object_name); if(strcmp(cur_elt->object_name, obj_name) == 0) { Debug(4, "Reusing previous eh_elf %s\n", obj_name); - return cur_elt->eh_elf; + return cur_elt; } cur_elt = cur_elt->next; } // Wasn't previously opened + // Open the DL object dl_obj_list_t* new_elt = malloc(sizeof(dl_obj_list_t)); new_elt->object_name = malloc(sizeof(char) * (strlen(obj_name) + 1)); new_elt->next = NULL; @@ -207,8 +204,25 @@ static dl_obj_t mmap_dlopen_eh_elf(const char* obj_name) { sprintf(eh_elf_path, "%s.eh_elf.so", obj_basename); new_elt->eh_elf = dlopen(eh_elf_path, RTLD_LAZY); free(obj_name_cpy); - if(new_elt->eh_elf == NULL) + if(new_elt->eh_elf == NULL) { + // Failed, cleanup everything + Debug(3, "Could not open eh_elf.so %s\n", eh_elf_path); + free(new_elt->object_name); + free(new_elt); return NULL; + } + + // Find the fde function + new_elt->fde_func = + (_fde_func_with_deref_t) (dlsym(new_elt->eh_elf, "_eh_elf")); + if(new_elt->fde_func == NULL) { + // Failed, cleanup everything + Debug(3, "Could not find _eh_elf in %s\n", eh_elf_path); + free(new_elt->object_name); + dlclose(new_elt->eh_elf); + free(new_elt); + return NULL; + } char opened_file[256]; dlinfo(new_elt->eh_elf, RTLD_DI_ORIGIN, opened_file); @@ -218,16 +232,18 @@ static dl_obj_t mmap_dlopen_eh_elf(const char* obj_name) { new_elt->next = _dl_obj_list; _dl_obj_list = new_elt; - return new_elt->eh_elf; + return new_elt; } /// `dlopen` the needed eh_elf objects. static int mmap_dlopen_eh_elfs(mmap_entry_t* entries, size_t count) { for(size_t id = 0; id < count; ++id) { - dl_obj_t eh_elf = mmap_dlopen_eh_elf(entries[id].object_name); - if(eh_elf == NULL) + dl_obj_list_t* eh_elf_elt = + mmap_dlopen_eh_elf(entries[id].object_name); + if(eh_elf_elt == NULL) return -1; - entries[id].eh_elf = eh_elf; + entries[id].eh_elf = eh_elf_elt->eh_elf; + entries[id].fde_func = eh_elf_elt->fde_func; } return 0; } diff --git a/src/eh_elf/memory_map.h b/src/eh_elf/memory_map.h index 56e9924c..e6867eb6 100644 --- a/src/eh_elf/memory_map.h +++ b/src/eh_elf/memory_map.h @@ -19,6 +19,7 @@ #include #include "libunwind.h" +#include "context_struct.h" /// A type representing a dlopen handle typedef void* dl_obj_t; @@ -27,6 +28,7 @@ typedef void* dl_obj_t; typedef struct dl_obj_list { char* object_name; ///< Name of the object mapped here dl_obj_t eh_elf; ///< Corresponding eh_elf file, dlopen'd + _fde_func_with_deref_t fde_func; ///< Fde deref function, directly struct dl_obj_list* next; ///< Next item in the list } dl_obj_list_t; @@ -38,6 +40,7 @@ typedef struct { char* object_name; ///< Name of the object mapped here uintptr_t beg_ip, end_ip; ///< Start and end IP of this object in memory dl_obj_t eh_elf; ///< Corresponding eh_elf file, dlopen'd + _fde_func_with_deref_t fde_func; ///< Fde deref function, directly } mmap_entry_t; /// Dealloc all allocated memory and reset internal state