From 6363c89afc2897c7cfabd3d294fa8c29be71bb39 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Wed, 12 Mar 2025 00:31:47 +0100 Subject: [PATCH] libelfin wrapper WIP! --- Makefile | 12 ++++--- debugus.c | 87 ++++++++--------------------------------------- libelfin_wrap.cpp | 43 +++++++++++++++++++++++ libelfin_wrap.h | 25 ++++++++++++++ 4 files changed, 91 insertions(+), 76 deletions(-) create mode 100644 libelfin_wrap.cpp create mode 100644 libelfin_wrap.h diff --git a/Makefile b/Makefile index 61ad8b3..1c6526e 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ CC=gcc -CFLAGS=-MD -MP -ggdb -I./mujs -LDFLAGS=-lm -lelf +CXX=g++ +CFLAGS=-MD -MP -gdwarf -I./mujs +LDFLAGS=-lm -ldwarf++ -lelf++ -lstdc++ SRCS=debugus.c linenoise.c hash.c pmparser.c OBJS=$(patsubst %.c,%.o,$(SRCS)) DEPS=$(patsubst %.c,%.d,$(SRCS)) @@ -10,7 +11,7 @@ all: debugus .debugusrc1.js test test: test.o $(CC) -gdwarf -o $@ $^ -debugus: $(OBJS) ./mujs/build/debug/libmujs.o +debugus: $(OBJS) ./mujs/build/debug/libmujs.o ./libelfin_wrap.o $(CC) -o $@ $^ $(LDFLAGS) .debugusrc1.js: test .debugusrc1.js.txt @@ -19,9 +20,12 @@ debugus: $(OBJS) ./mujs/build/debug/libmujs.o ./mujs/build/debug/libmujs.o: make -C mujs -j$(shell nproc) +./libelfin_wrap.o: ./libelfin_wrap.cpp + $(CXX) $(CFLAGS) -c -o $@ $< + -include $(DEPS) -clean: $(OBJS) test.o $(DEPS) +clean: $(OBJS) test.o $(DEPS) .debugusrc1.js rm -f $^ make -C mujs clean diff --git a/debugus.c b/debugus.c index a309007..dcc60d3 100644 --- a/debugus.c +++ b/debugus.c @@ -8,8 +8,6 @@ #include #include #include -#include -#include #include #include #include @@ -22,6 +20,7 @@ #include "hash.h" #include "pmparser.h" #include "da.h" +#include "libelfin_wrap.h" #define LOG_ERR(fmt, ...) fprintf(stderr, "Error: " fmt, ##__VA_ARGS__) #define LOG_INF(fmt, ...) fprintf(stdout, "Info: " fmt, ##__VA_ARGS__) @@ -146,23 +145,12 @@ void brk_disable(Brk *brk) brk->enabled = false; } -typedef struct { - const char *name; - uintptr_t addr; -} Symbol; - -typedef struct { - Symbol *items; - size_t count, capacity; -} Symbols; - typedef struct { const char *file; pid_t pid; js_State *js; HashTable brks; uintptr_t program_load_offset; - Symbols symbols; HashTable js_descs; } Dbg; @@ -184,11 +172,20 @@ void dbg_handle_sigtrap(Dbg *dbg, siginfo_t info) void dbg_set_rip(Dbg *dbg, uint64_t v); uint64_t dbg_get_rip(Dbg *dbg); + AddrInfo *ai; + switch (info.si_code) { case SI_KERNEL: case TRAP_BRKPT: dbg_set_rip(dbg, dbg_get_rip(dbg) - 1); - LOG_INF("Hit breakpoint at 0x%"PRIxPTR"\n", dbg_get_rip(dbg)); + ai = libelfin_wrap_info_from_rip(dbg_get_rip(dbg)); + if (ai != NULL) { + LOG_INF("Hit breakpoint at 0x%"PRIxPTR", %s:%zu\n", dbg_get_rip(dbg), + ai->file, (size_t)ai->line); + libelfin_wrap_free_info(ai); + } else { + LOG_INF("Hit breakpoint at 0x%"PRIxPTR"\n", dbg_get_rip(dbg)); + } return; case TRAP_TRACE: return; @@ -450,16 +447,6 @@ void dbg_js_mwr(js_State *js) js_pushundefined(js); } -void dbg_js_lsm(js_State *js) -{ - Dbg *dbg = getdbg(); - for (int i = 0; i < dbg->symbols.count; i++) { - Symbol *sym = &dbg->symbols.items[i]; - LOG_INF("Symbol %s at %"PRIxPTR"\n", sym->name, sym->addr); - } - js_pushundefined(js); -} - void dbg_js_help(js_State *js) { Dbg *dbg = getdbg(); @@ -499,7 +486,6 @@ void dbg_init_js(Dbg *dbg) make_js_func(sr, 2, "Set register value, ARGS=Register name:string,Register value:hex string"); make_js_func(mrd, 1, "Read memory at address, ARGS=Address:hex string"); make_js_func(mwr, 2, "Write memory at address, ARGS=Address:hex string,Value:hex string"); - make_js_func(lsm, 0, "List all symbols, ARGS=None"); make_js_func(help, 0, "Print help information, ARGS=None"); #undef make_js_func @@ -544,58 +530,16 @@ void dbg_load_script(Dbg *dbg, const char *script_path) fclose(script); } -void dbg_load_symbols(Dbg *dbg) +void dbg_libelfin_wrap_init(Dbg *dbg) { FILE *bin = fopen(dbg->file, "rb"); if (bin == NULL) { - LOG_ERR("Cannot load symbols from file\n"); + LOG_ERR("could not open file %s: %s\n", dbg->file, strerror(errno)); return; } - Elf *elf; - Elf_Scn *scn = NULL; - GElf_Shdr shdr; - Elf_Data *data; - GElf_Sym sym; + libelfin_wrap_init(fileno(bin)); - elf_version(EV_CURRENT); - - elf = elf_begin(fileno(bin), ELF_C_READ, NULL); - if (elf == NULL) { - LOG_ERR("Could not parse elf\n"); - fclose(bin); - return; - } - - while ((scn = elf_nextscn(elf, scn)) != NULL) { - gelf_getshdr(scn, &shdr); - if (shdr.sh_type == SHT_SYMTAB) { - break; - } - } - - data = elf_getdata(scn, NULL); - int count = shdr.sh_size / shdr.sh_entsize; - - for (int i = 0; i < count; i++) { - gelf_getsym(data, i, &sym); - if (sym.st_info != 2 /*func*/) { - char *name = elf_strptr(elf, shdr.sh_link, sym.st_name); - size_t len = strlen(name); - if (len == 0 || sym.st_value == 0x0) { - continue; - } - - char *n = malloc(len+1); - strcpy(n, name); - n[len] = '\0'; - - Symbol symbol = { .name = name, .addr = dbg->program_load_offset + (uintptr_t)sym.st_value }; - da_append(&dbg->symbols, symbol); - } - } - - elf_end(elf); fclose(bin); } @@ -607,8 +551,8 @@ 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_libelfin_wrap_init(dbg); hashtable_init(&dbg->brks, MAX_BRKS); - dbg_load_symbols(dbg); dbg_load_script(dbg, INIT_SCRIPT); } @@ -617,7 +561,6 @@ void dbg_deinit(Dbg *dbg) js_freestate(dbg->js); hashtable_deinit(&dbg->brks); hashtable_deinit(&dbg->js_descs); - da_deinit(&dbg->symbols); } void dbg_loop(Dbg *dbg) diff --git a/libelfin_wrap.cpp b/libelfin_wrap.cpp new file mode 100644 index 0000000..3d6682a --- /dev/null +++ b/libelfin_wrap.cpp @@ -0,0 +1,43 @@ +#include +#include + +#include "libelfin_wrap.h" + +static elf::elf gelf; +static dwarf::dwarf gdwarf; + +DEBUGUS_EXTERNC void libelfin_wrap_init(int fd) +{ + gelf = elf::elf{elf::create_mmap_loader(fd)}; + gdwarf = dwarf::dwarf{dwarf::elf::create_loader(gelf)}; +} + +DEBUGUS_EXTERNC AddrInfo *libelfin_wrap_info_from_rip(uint64_t rip) +{ + for (auto &cu : gdwarf.compilation_units()) { + if (die_pc_range(cu.root()).contains(rip)) { + auto < = cu.get_line_table(); + auto it = lt.find_address(rip); + if (it == lt.end()) { + printf("ADDR NOT FOUND\n"); + return NULL; + } else { + AddrInfo *ai = (AddrInfo *)malloc(sizeof(*ai)); + ai->addr = rip; + ai->line = it->line; + ai->file = (const char*)malloc(strlen(it->file->path.c_str())+1); + strcpy((char*)ai->file, it->file->path.c_str()); + return ai; + } + } + } + printf("NO CUS\n"); + return NULL; +} + +DEBUGUS_EXTERNC void libelfin_wrap_free_info(AddrInfo *ai) +{ + free((void*)ai->file); + free((void*)ai); +} + diff --git a/libelfin_wrap.h b/libelfin_wrap.h new file mode 100644 index 0000000..dc2d05b --- /dev/null +++ b/libelfin_wrap.h @@ -0,0 +1,25 @@ +#ifndef LIBELFIN_WRAP_H_ +#define LIBELFIN_WRAP_H_ + +#ifdef __cplusplus +# define DEBUGUS_EXTERNC extern "C" +#else +# define DEBUGUS_EXTERNC +#endif // __cplusplus + +#include +#include +#include +#include + +typedef struct { + ssize_t line; + const char *file; + uint64_t addr; +} AddrInfo; + +DEBUGUS_EXTERNC void libelfin_wrap_init(int fd); +DEBUGUS_EXTERNC AddrInfo *libelfin_wrap_info_from_rip(uint64_t rip); +DEBUGUS_EXTERNC void libelfin_wrap_free_info(AddrInfo *ai); + +#endif // LIBELFIN_WRAP_H_