From 3b938a06dd3aa51e6af12b0cfa9285cf87d6ec8c Mon Sep 17 00:00:00 2001 From: kamil Date: Wed, 12 Mar 2025 14:25:55 +0100 Subject: [PATCH] Print function name and file location when caught a SIGSEGV --- .debugusrc1.js | 36 ++++++++++++++++---------------- .debugusrc1.js.txt | 36 ++++++++++++++++---------------- da.h | 4 ++-- debugus.c | 51 +++++++++++++++++++++++++++++++++++++++++++--- libelfin_wrap.cpp | 30 +++++++++++++++++++++++---- libelfin_wrap.h | 15 +++++++++++++- test.c | 5 +++++ 7 files changed, 131 insertions(+), 46 deletions(-) diff --git a/.debugusrc1.js b/.debugusrc1.js index fc30ccc..d8f7685 100644 --- a/.debugusrc1.js +++ b/.debugusrc1.js @@ -6,27 +6,27 @@ ler("Test error message"); var offset = "0x0000000000001169"; // dupa(), objdump -d ./test // Testing... -pf(); -ppid(); -pplo(); +// pf(); +// ppid(); +// pplo(); baddr(offset); lsbrk(); -lif("1 --------------------------------------------"); -dr(); -var r14 = gr("r14"); -sr("r14", "0x0"); -lif("2 --------------------------------------------"); -dr(); -sr("r14", r14); -lif("3 --------------------------------------------"); -dr(); +// lif("1 --------------------------------------------"); +// dr(); +// var r14 = gr("r14"); +// sr("r14", "0x0"); +// lif("2 --------------------------------------------"); +// dr(); +// sr("r14", r14); +// lif("3 --------------------------------------------"); +// dr(); -var r14_mem = mrdr("r14"); -lif("Memory at r14 " + r14_mem); -mwrr("r14", "0x696969"); -lif("Memory at r14 " + mrdr("r14")); -mwrr("r14", r14_mem); -lif("Memory at r14 " + mrdr("r14")); +// var r14_mem = mrdr("r14"); +// lif("Memory at r14 " + r14_mem); +// mwrr("r14", "0x696969"); +// lif("Memory at r14 " + mrdr("r14")); +// mwrr("r14", r14_mem); +// lif("Memory at r14 " + mrdr("r14")); // cont(); diff --git a/.debugusrc1.js.txt b/.debugusrc1.js.txt index c735a59..5f2c300 100644 --- a/.debugusrc1.js.txt +++ b/.debugusrc1.js.txt @@ -6,27 +6,27 @@ ler("Test error message"); var offset = "@DUPA_ADDR"; // dupa(), objdump -d ./test // Testing... -pf(); -ppid(); -pplo(); +// pf(); +// ppid(); +// pplo(); baddr(offset); lsbrk(); -lif("1 --------------------------------------------"); -dr(); -var r14 = gr("r14"); -sr("r14", "0x0"); -lif("2 --------------------------------------------"); -dr(); -sr("r14", r14); -lif("3 --------------------------------------------"); -dr(); +// lif("1 --------------------------------------------"); +// dr(); +// var r14 = gr("r14"); +// sr("r14", "0x0"); +// lif("2 --------------------------------------------"); +// dr(); +// sr("r14", r14); +// lif("3 --------------------------------------------"); +// dr(); -var r14_mem = mrdr("r14"); -lif("Memory at r14 " + r14_mem); -mwrr("r14", "0x696969"); -lif("Memory at r14 " + mrdr("r14")); -mwrr("r14", r14_mem); -lif("Memory at r14 " + mrdr("r14")); +// var r14_mem = mrdr("r14"); +// lif("Memory at r14 " + r14_mem); +// mwrr("r14", "0x696969"); +// lif("Memory at r14 " + mrdr("r14")); +// mwrr("r14", r14_mem); +// lif("Memory at r14 " + mrdr("r14")); // cont(); diff --git a/da.h b/da.h index f666a47..3c63670 100644 --- a/da.h +++ b/da.h @@ -7,11 +7,11 @@ do { \ if ((da)->count == 0) { \ (da)->capacity = 1; \ - (da)->items = malloc(sizeof(item)*sizeof((da)->capacity)); \ + (da)->items = (typeof((da)->items))malloc(sizeof(item)*sizeof((da)->capacity)); \ } else { \ if ((da)->count == (da)->capacity) { \ (da)->capacity *= 2; \ - (da)->items = realloc((da)->items, (da)->capacity * sizeof((item))); \ + (da)->items = (typeof((da)->items))realloc((da)->items, (da)->capacity * sizeof((item))); \ } \ } \ (da)->items[(da)->count++] = (item); \ diff --git a/debugus.c b/debugus.c index 8f2f9ec..1285e93 100644 --- a/debugus.c +++ b/debugus.c @@ -145,6 +145,14 @@ void brk_disable(Brk *brk) brk->enabled = false; } +void symbols_deinit(Symbols *s) +{ + for (int i = 0; i < s->count; i++) { + free((char *)s->items[i].name); + } + da_deinit(s); +} + typedef struct { const char *file; pid_t pid; @@ -152,6 +160,8 @@ typedef struct { HashTable brks; uintptr_t program_load_offset; HashTable js_descs; + Symbols symbols; + FILE *binfile; PLibelfinBinding plibelfin; } Dbg; @@ -165,7 +175,26 @@ siginfo_t dbg_get_siginfo(Dbg *dbg) void dbg_handle_sigsegv(Dbg *dbg, siginfo_t info) { unused(dbg); + uint64_t dbg_get_rip(Dbg *dbg); LOG_ERR("Caught a segfault %d. SKILL ISSUE BRO\n", info.si_code); + uintptr_t rip = (uintptr_t)dbg_get_rip(dbg); + uintptr_t nearest = rip - dbg->symbols.items[0].addr; + for (int i = 0; i < dbg->symbols.count; i++) { + if (rip - dbg->symbols.items[i].addr < nearest) { + nearest = rip - dbg->symbols.items[i].addr; + } + } + uintptr_t addr = rip - nearest; + for (int i = 0; i < dbg->symbols.count; i++) { + if (dbg->symbols.items[i].addr == addr) { + AddrInfo *ai = libelfin_wrap_info_from_rip(dbg->plibelfin, (uint64_t)(addr - dbg->program_load_offset)); + if (ai != NULL) { + LOG_INF("%s:%zu in function %s()\n", ai->file, (size_t)ai->line, dbg->symbols.items[i].name); + libelfin_wrap_free_info(ai); + } + break; + } + } } void dbg_handle_sigtrap(Dbg *dbg, siginfo_t info) @@ -538,17 +567,29 @@ void dbg_load_script(Dbg *dbg, const char *script_path) fclose(script); } -void dbg_libelfin_wrap_init(Dbg *dbg) +void dbg_init_bin(Dbg *dbg) { FILE *bin = fopen(dbg->file, "rb"); if (bin == NULL) { LOG_ERR("could not open file %s: %s\n", dbg->file, strerror(errno)); return; } + dbg->binfile = bin; +} - dbg->plibelfin = libelfin_wrap_get_binding(fileno(bin)); +void dbg_libelfin_wrap_init(Dbg *dbg) +{ + dbg->plibelfin = libelfin_wrap_get_binding(fileno(dbg->binfile), dbg->program_load_offset); +} - fclose(bin); +void dbg_load_symbols(Dbg *dbg) +{ + libelfin_wrap_get_syms(dbg->plibelfin, &dbg->symbols); + + for (int i = 0; i < dbg->symbols.count; i++) { + Symbol *s = &dbg->symbols.items[i]; + LOG_INF("Found symbol %s 0x%"PRIxPTR"\n", s->name, s->addr); + } } void dbg_init(Dbg *dbg, const char *file, pid_t pid) @@ -559,7 +600,9 @@ void dbg_init(Dbg *dbg, const char *file, pid_t pid) hashtable_init(&dbg->js_descs, MAX_JS_FUNCS); dbg_init_js(dbg); dbg_init_load_offset(dbg); + dbg_init_bin(dbg); dbg_libelfin_wrap_init(dbg); + dbg_load_symbols(dbg); hashtable_init(&dbg->brks, MAX_BRKS); dbg_load_script(dbg, INIT_SCRIPT); } @@ -569,7 +612,9 @@ void dbg_deinit(Dbg *dbg) js_freestate(dbg->js); hashtable_deinit(&dbg->brks); hashtable_deinit(&dbg->js_descs); + symbols_deinit(&dbg->symbols); libelfin_wrap_free_binding(dbg->plibelfin); + fclose(dbg->binfile); } void dbg_loop(Dbg *dbg) diff --git a/libelfin_wrap.cpp b/libelfin_wrap.cpp index 6048b07..4155f37 100644 --- a/libelfin_wrap.cpp +++ b/libelfin_wrap.cpp @@ -7,19 +7,41 @@ class LibelfinBinding { public: - LibelfinBinding(int fd) + LibelfinBinding(int fd, uintptr_t _loadoffset) : elf(elf::create_mmap_loader(fd)), - dwarf(dwarf::elf::create_loader(this->elf)) + dwarf(dwarf::elf::create_loader(this->elf)), + loadoffset(_loadoffset) { } elf::elf elf; dwarf::dwarf dwarf; + uintptr_t loadoffset; }; -DEBUGUS_EXTERNC PLibelfinBinding libelfin_wrap_get_binding(int fd) +DEBUGUS_EXTERNC void libelfin_wrap_get_syms(PLibelfinBinding *pbind, Symbols *syms) { - return (PLibelfinBinding)new LibelfinBinding(fd); + LibelfinBinding *bind = (LibelfinBinding *)pbind; + for (auto §ion : bind->elf.sections()) { + if (section.get_hdr().type == elf::sht::symtab) { + for (auto sym : section.as_symtab()) { + auto &d = sym.get_data(); + if (d.type() == elf::stt::func) { + Symbol s = { + .name = (const char *)malloc(strlen(sym.get_name().c_str())+1), + .addr = bind->loadoffset + (uintptr_t)d.value, + }; + strcpy((char*)s.name, sym.get_name().c_str()); + da_append(syms, s); + } + } + } + } +} + +DEBUGUS_EXTERNC PLibelfinBinding libelfin_wrap_get_binding(int fd, uintptr_t loadoffset) +{ + return (PLibelfinBinding)new LibelfinBinding(fd, loadoffset); } DEBUGUS_EXTERNC void libelfin_wrap_free_binding(PLibelfinBinding pbind) diff --git a/libelfin_wrap.h b/libelfin_wrap.h index 4715021..dac40d0 100644 --- a/libelfin_wrap.h +++ b/libelfin_wrap.h @@ -12,17 +12,30 @@ #include #include +#include "da.h" + typedef struct { ssize_t line; const char *file; uint64_t addr; } AddrInfo; +typedef struct { + const char *name; + uintptr_t addr; +} Symbol; + +typedef struct { + Symbol *items; + size_t count, capacity; +} Symbols; + typedef void * PLibelfinBinding; -DEBUGUS_EXTERNC PLibelfinBinding libelfin_wrap_get_binding(int fd); +DEBUGUS_EXTERNC PLibelfinBinding libelfin_wrap_get_binding(int fd, uintptr_t loadoffset); DEBUGUS_EXTERNC void libelfin_wrap_free_binding(PLibelfinBinding pbind); DEBUGUS_EXTERNC AddrInfo *libelfin_wrap_info_from_rip(PLibelfinBinding pbind, uint64_t rip); DEBUGUS_EXTERNC void libelfin_wrap_free_info(AddrInfo *ai); +DEBUGUS_EXTERNC void libelfin_wrap_get_syms(PLibelfinBinding *pbind, Symbols *syms); #endif // LIBELFIN_WRAP_H_ diff --git a/test.c b/test.c index 2c36ba1..11c23e5 100644 --- a/test.c +++ b/test.c @@ -1,5 +1,6 @@ #include #include +#include void dupa(void) { printf("KSKSKKSKSKSK\n"); @@ -15,6 +16,10 @@ int main(void) dupa(); } } + + int *a = NULL; + *a = 6969; + return 0; }