Compare commits
10 Commits
19d6185ffb
...
2ee6e9666e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ee6e9666e | ||
|
|
ec08cbae07 | ||
|
|
a7378a5210 | ||
|
|
46c8a1e26b | ||
|
|
07c4b9283b | ||
|
|
7a5980de69 | ||
|
|
4f60dfcd4d | ||
|
|
a9f555d916 | ||
|
|
0742db18d8 | ||
|
|
14b5368e7c |
2
.debugusrc1.js
Normal file
2
.debugusrc1.js
Normal file
@@ -0,0 +1,2 @@
|
||||
lif("Loading user init script for program ./test");
|
||||
lsf();
|
||||
@@ -1,35 +0,0 @@
|
||||
// User script
|
||||
|
||||
lif("Loading user init script for program ./test");
|
||||
ler("Test error message");
|
||||
|
||||
var offset = "@DUPA_ADDR"; // dupa(), objdump -d ./test
|
||||
|
||||
// Testing...
|
||||
// pf();
|
||||
// ppid();
|
||||
// pplo();
|
||||
// baddr(offset);
|
||||
bfn("dupa");
|
||||
// rmbfn("dupa");
|
||||
lsbrk();
|
||||
lsf();
|
||||
|
||||
// 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"));
|
||||
|
||||
// cont();
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,4 +2,3 @@
|
||||
*.d
|
||||
debugus
|
||||
test
|
||||
.debugusrc1.js
|
||||
|
||||
11
Makefile
11
Makefile
@@ -6,17 +6,14 @@ SRCS=debugus.c linenoise.c hash.c pmparser.c
|
||||
OBJS=$(patsubst %.c,%.o,$(SRCS))
|
||||
DEPS=$(patsubst %.c,%.d,$(SRCS))
|
||||
|
||||
all: debugus .debugusrc1.js test
|
||||
all: debugus test
|
||||
|
||||
test: test.o
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
test: test.o test2.o
|
||||
$(CC) -o $@ $^
|
||||
|
||||
debugus: $(OBJS) ./mujs/build/debug/libmujs.o ./libelfin_wrap.o
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
.debugusrc1.js: test .debugusrc1.js.txt
|
||||
cat .debugusrc1.js.txt | sed "s/@DUPA_ADDR/0x$$(nm ./test | grep 'dupa' | awk '{ print $$1 }')/g" > .debugusrc1.js
|
||||
|
||||
./mujs/build/debug/libmujs.o:
|
||||
make -C mujs -j$(shell nproc)
|
||||
|
||||
@@ -25,7 +22,7 @@ debugus: $(OBJS) ./mujs/build/debug/libmujs.o ./libelfin_wrap.o
|
||||
|
||||
-include $(DEPS)
|
||||
|
||||
clean: $(OBJS) test.o $(DEPS) .debugusrc1.js
|
||||
clean: $(OBJS) test.o test2.o $(DEPS)
|
||||
rm -f $^
|
||||
make -C mujs clean
|
||||
|
||||
|
||||
282
debugus.c
282
debugus.c
@@ -9,6 +9,7 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ptrace.h>
|
||||
@@ -22,6 +23,27 @@
|
||||
#include "da.h"
|
||||
#include "libelfin_wrap.h"
|
||||
|
||||
|
||||
// They took my usleep() away >;( fuck u POSIX
|
||||
int msleep(long msec)
|
||||
{
|
||||
struct timespec ts;
|
||||
int res;
|
||||
|
||||
if (msec < 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ts.tv_sec = msec/1000;
|
||||
ts.tv_nsec = (msec%1000) * 1000000;
|
||||
|
||||
do {
|
||||
res = nanosleep(&ts, &ts);
|
||||
} while(res && errno == EINTR);
|
||||
return res;
|
||||
}
|
||||
|
||||
#define LOG_ERR(fmt, ...) fprintf(stderr, "Error: " fmt, ##__VA_ARGS__)
|
||||
#define LOG_INF(fmt, ...) fprintf(stdout, "Info: " fmt, ##__VA_ARGS__)
|
||||
|
||||
@@ -32,6 +54,53 @@
|
||||
#define INIT_SCRIPT ".debugusrc.js"
|
||||
#define MAX_JS_FUNCS 100
|
||||
|
||||
#define SOURCE_EXPANSION 4
|
||||
|
||||
void print_source(const char *file, size_t line)
|
||||
{
|
||||
FILE *src = fopen(file, "r");
|
||||
if (src == NULL) {
|
||||
LOG_ERR("No source file found\n");
|
||||
return;
|
||||
}
|
||||
fseek(src, 0L, SEEK_END);
|
||||
long sz = ftell(src);
|
||||
rewind(src);
|
||||
|
||||
char *srcbuf = malloc(sz+1);
|
||||
fread(srcbuf, sz, 1, src);
|
||||
srcbuf[sz] = '\0';
|
||||
|
||||
const int expand = SOURCE_EXPANSION;
|
||||
|
||||
char *p = srcbuf;
|
||||
size_t i = 0;
|
||||
while (p) {
|
||||
char *next = strchr(p, '\n');
|
||||
if (next) {
|
||||
*next = '\0';
|
||||
}
|
||||
|
||||
int lo = line - expand;
|
||||
int hi = line + expand;
|
||||
if (i >= (lo < 0 ? 0 : lo) && i <= hi ) {
|
||||
char prefix[20];
|
||||
snprintf(prefix, sizeof(prefix), "%2s %6zu", i == line ? "->" : "", i);
|
||||
printf("%s %s\n", prefix, p);
|
||||
}
|
||||
|
||||
if (next) {
|
||||
*next = '\n';
|
||||
}
|
||||
|
||||
p = next ? (next + 1) : NULL;
|
||||
i++;
|
||||
}
|
||||
|
||||
free(srcbuf);
|
||||
fclose(src);
|
||||
}
|
||||
|
||||
// Registers
|
||||
// Taken from da goat https://source.winehq.org/source/dlls/dbghelp/cpu_x86_64.c
|
||||
|
||||
@@ -119,7 +188,6 @@ static RegisterDescriptor reg_descriptors[MAX_REGISTERS] = {
|
||||
|
||||
typedef struct {
|
||||
pid_t pid;
|
||||
pid_t proc_pid;
|
||||
uintptr_t addr;
|
||||
bool enabled;
|
||||
uint8_t data;
|
||||
@@ -145,14 +213,6 @@ 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;
|
||||
@@ -160,11 +220,22 @@ typedef struct {
|
||||
HashTable brks;
|
||||
uintptr_t program_load_offset;
|
||||
HashTable js_descs;
|
||||
Symbols symbols;
|
||||
Funcs funcs;
|
||||
FILE *binfile;
|
||||
PLibelfinBinding plibelfin;
|
||||
} Dbg;
|
||||
|
||||
void funcs_deinit(Funcs *fs)
|
||||
{
|
||||
for (int i = 0; i < fs->count; i++) {
|
||||
free((char *)fs->items[i].name);
|
||||
if (fs->items[i].ai != NULL) {
|
||||
libelfin_wrap_free_info(fs->items[i].ai);
|
||||
}
|
||||
}
|
||||
da_deinit(fs);
|
||||
}
|
||||
|
||||
siginfo_t dbg_get_siginfo(Dbg *dbg)
|
||||
{
|
||||
siginfo_t i;
|
||||
@@ -178,23 +249,13 @@ void dbg_handle_sigsegv(Dbg *dbg, siginfo_t info)
|
||||
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));
|
||||
|
||||
|
||||
AddrInfo *ai = libelfin_wrap_info_from_rip(dbg->plibelfin, (uint64_t)(rip - 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);
|
||||
print_source(ai->file, ai->line);
|
||||
libelfin_wrap_free_info(ai);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dbg_handle_sigtrap(Dbg *dbg, siginfo_t info)
|
||||
@@ -211,6 +272,7 @@ void dbg_handle_sigtrap(Dbg *dbg, siginfo_t info)
|
||||
ai = libelfin_wrap_info_from_rip(dbg->plibelfin, dbg_get_rip(dbg) - (uint64_t)dbg->program_load_offset);
|
||||
if (ai != NULL) {
|
||||
LOG_INF("Hit breakpoint at 0x%"PRIxPTR", %s:%zu\n", dbg_get_rip(dbg), ai->file, (size_t)ai->line);
|
||||
print_source(ai->file, (size_t)ai->line);
|
||||
libelfin_wrap_free_info(ai);
|
||||
} else {
|
||||
LOG_INF("Hit breakpoint at 0x%"PRIxPTR"\n", dbg_get_rip(dbg));
|
||||
@@ -326,7 +388,7 @@ void dbg_js_cont(js_State *js)
|
||||
js_pushundefined(js);
|
||||
}
|
||||
|
||||
void dbg_js_baddr(js_State *js)
|
||||
void dbg_js_boff(js_State *js)
|
||||
{
|
||||
Dbg *dbg = getdbg();
|
||||
const char *addr_str = js_tostring(js, 1);
|
||||
@@ -345,13 +407,13 @@ void dbg_js_bfn(js_State *js)
|
||||
{
|
||||
Dbg *dbg = getdbg();
|
||||
const char *fn_name = js_tostring(js, 1);
|
||||
for (int i = 0; i < dbg->symbols.count; i++) {
|
||||
Symbol *s = &dbg->symbols.items[i];
|
||||
if (strcmp(fn_name, s->name) == 0) {
|
||||
uintptr_t addr = s->addr;
|
||||
for (int i = 0; i < dbg->funcs.count; i++) {
|
||||
Func *f = &dbg->funcs.items[i];
|
||||
if (strcmp(fn_name, f->name) == 0) {
|
||||
char addr_str2[20];
|
||||
snprintf(addr_str2, sizeof(addr_str2), "0x%"PRIxPTR, addr);
|
||||
Brk brk = { .pid = dbg->pid, .addr = addr };
|
||||
snprintf(addr_str2, sizeof(addr_str2), "0x%"PRIxPTR,
|
||||
libelfin_wrap_func_addr(dbg->plibelfin, f));
|
||||
Brk brk = { .pid = dbg->pid, .addr = libelfin_wrap_func_addr(dbg->plibelfin, f) };
|
||||
brk_enable(&brk);
|
||||
hashtable_set(&dbg->brks, addr_str2, &brk, sizeof(brk));
|
||||
break;
|
||||
@@ -365,12 +427,12 @@ void dbg_js_rmbfn(js_State *js)
|
||||
Dbg *dbg = getdbg();
|
||||
const char *fn_name = js_tostring(js, 1);
|
||||
|
||||
for (int i = 0; i < dbg->symbols.count; i++) {
|
||||
Symbol *s = &dbg->symbols.items[i];
|
||||
if (strcmp(fn_name, s->name) == 0) {
|
||||
uintptr_t addr = s->addr;
|
||||
for (int i = 0; i < dbg->funcs.count; i++) {
|
||||
Func *f = &dbg->funcs.items[i];
|
||||
if (strcmp(fn_name, f->name) == 0) {
|
||||
char addr_str2[20];
|
||||
snprintf(addr_str2, sizeof(addr_str2), "0x%"PRIxPTR, addr);
|
||||
snprintf(addr_str2, sizeof(addr_str2), "0x%"PRIxPTR,
|
||||
libelfin_wrap_func_addr(dbg->plibelfin, f));
|
||||
|
||||
Brk *brk = (Brk *)hashtable_get(&dbg->brks, addr_str2);
|
||||
if (brk == NULL) {
|
||||
@@ -449,12 +511,12 @@ void dbg_js_lsbrk(js_State *js)
|
||||
void dbg_js_lsf(js_State *js)
|
||||
{
|
||||
Dbg *dbg = getdbg();
|
||||
for (int i = 0; i < dbg->symbols.count; i++) {
|
||||
Symbol *s = &dbg->symbols.items[i];
|
||||
AddrInfo *ai = libelfin_wrap_info_from_rip(dbg->plibelfin, (uint64_t)(s->addr - dbg->program_load_offset));
|
||||
if (ai != NULL) {
|
||||
LOG_INF("Sym %s 0x%"PRIxPTR" %s:%zu\n", s->name, s->addr, ai->file, (size_t)ai->line);
|
||||
libelfin_wrap_free_info(ai);
|
||||
for (int i = 0; i < dbg->funcs.count; i++) {
|
||||
Func *f = &dbg->funcs.items[i];
|
||||
if (f->ai != NULL) {
|
||||
LOG_INF("Sym %s 0x%"PRIxPTR" %s:%zu\n", f->name,
|
||||
libelfin_wrap_func_addr(dbg->plibelfin, f), f->ai->file,
|
||||
(size_t)f->ai->line);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -557,6 +619,122 @@ void dbg_js_help(js_State *js)
|
||||
js_pushundefined(js);
|
||||
}
|
||||
|
||||
void dbg_js_ebaddr(js_State *js)
|
||||
{
|
||||
Dbg *dbg = getdbg();
|
||||
const char *addr_str = js_tostring(js, 1);
|
||||
Brk *brk = (Brk *)hashtable_get(&dbg->brks, addr_str);
|
||||
if (brk == NULL) {
|
||||
LOG_ERR("No breakpoint at address: %s\n", addr_str);
|
||||
goto done;
|
||||
}
|
||||
brk_enable(brk);
|
||||
done:
|
||||
js_pushundefined(js);
|
||||
}
|
||||
|
||||
void dbg_js_dbaddr(js_State *js)
|
||||
{
|
||||
Dbg *dbg = getdbg();
|
||||
const char *addr_str = js_tostring(js, 1);
|
||||
Brk *brk = (Brk *)hashtable_get(&dbg->brks, addr_str);
|
||||
if (brk == NULL) {
|
||||
LOG_ERR("No breakpoint at address: %s\n", addr_str);
|
||||
goto done;
|
||||
}
|
||||
brk_disable(brk);
|
||||
done:
|
||||
js_pushundefined(js);
|
||||
}
|
||||
|
||||
void dbg_js_ebfn(js_State *js)
|
||||
{
|
||||
Dbg *dbg = getdbg();
|
||||
const char *fn_name = js_tostring(js, 1);
|
||||
|
||||
for (int i = 0; i < dbg->funcs.count; i++) {
|
||||
Func *f = &dbg->funcs.items[i];
|
||||
if (strcmp(fn_name, f->name) == 0) {
|
||||
char addr_str2[20];
|
||||
snprintf(addr_str2, sizeof(addr_str2), "0x%"PRIxPTR,
|
||||
libelfin_wrap_func_addr(dbg->plibelfin, f));
|
||||
|
||||
Brk *brk = (Brk *)hashtable_get(&dbg->brks, addr_str2);
|
||||
if (brk == NULL) {
|
||||
LOG_ERR("No breakpoint at function: %s\n", fn_name);
|
||||
goto done;
|
||||
}
|
||||
brk_enable(brk);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
js_pushundefined(js);
|
||||
}
|
||||
|
||||
void dbg_js_dbfn(js_State *js)
|
||||
{
|
||||
Dbg *dbg = getdbg();
|
||||
const char *fn_name = js_tostring(js, 1);
|
||||
|
||||
for (int i = 0; i < dbg->funcs.count; i++) {
|
||||
Func *f = &dbg->funcs.items[i];
|
||||
if (strcmp(fn_name, f->name) == 0) {
|
||||
char addr_str2[20];
|
||||
snprintf(addr_str2, sizeof(addr_str2), "0x%"PRIxPTR,
|
||||
libelfin_wrap_func_addr(dbg->plibelfin, f));
|
||||
|
||||
Brk *brk = (Brk *)hashtable_get(&dbg->brks, addr_str2);
|
||||
if (brk == NULL) {
|
||||
LOG_ERR("No breakpoint at function: %s\n", fn_name);
|
||||
goto done;
|
||||
}
|
||||
brk_disable(brk);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
js_pushundefined(js);
|
||||
}
|
||||
|
||||
void dbg_js_bl(js_State *js)
|
||||
{
|
||||
Dbg *dbg = getdbg();
|
||||
const char *filepath = js_tostring(js, 1);
|
||||
size_t line = (size_t)js_tonumber(js, 2);
|
||||
AddrInfo *ai = libelfin_wrap_info_from_line(dbg->plibelfin, filepath, line);
|
||||
if (ai != NULL) {
|
||||
char addr_str[20];
|
||||
snprintf(addr_str, sizeof(addr_str), "0x%"PRIxPTR, ai->addr);
|
||||
Brk brk = { .pid = dbg->pid, .addr = ai->addr };
|
||||
brk_enable(&brk);
|
||||
hashtable_set(&dbg->brks, addr_str, &brk, sizeof(brk));
|
||||
libelfin_wrap_free_info(ai);
|
||||
}
|
||||
js_pushundefined(js);
|
||||
}
|
||||
|
||||
void dbg_js_rmbl(js_State *js)
|
||||
{
|
||||
Dbg *dbg = getdbg();
|
||||
const char *filepath = js_tostring(js, 1);
|
||||
size_t line = (size_t)js_tonumber(js, 2);
|
||||
AddrInfo *ai = libelfin_wrap_info_from_line(dbg->plibelfin, filepath, line);
|
||||
if (ai != NULL) {
|
||||
char addr_str[20];
|
||||
snprintf(addr_str, sizeof(addr_str), "0x%"PRIxPTR, ai->addr);
|
||||
Brk *brk = (Brk *)hashtable_get(&dbg->brks, addr_str);
|
||||
if (brk != NULL) {
|
||||
brk_disable(brk);
|
||||
hashtable_delete(&dbg->brks, addr_str);
|
||||
}
|
||||
libelfin_wrap_free_info(ai);
|
||||
}
|
||||
js_pushundefined(js);
|
||||
}
|
||||
|
||||
void dbg_init_js(Dbg *dbg)
|
||||
{
|
||||
dbg->js = js_newstate(NULL, NULL, JS_STRICT);
|
||||
@@ -569,7 +747,7 @@ void dbg_init_js(Dbg *dbg)
|
||||
} while(0)
|
||||
|
||||
make_js_func(cont, 0, "Continue execution, ARGS=None");
|
||||
make_js_func(baddr, 1, "Place breakpoint at address, ARGS=Address:hex string");
|
||||
make_js_func(boff, 1, "Place breakpoint at offset, ARGS=Offset:hex string");
|
||||
make_js_func(rmbaddr, 1, "Remove breakpoint at address, ARGS=Address:hex string");
|
||||
make_js_func(lsbrk, 0, "List all breakpoints");
|
||||
make_js_func(splo, 1, "Set program load offset, ARGS=Offset:hex string");
|
||||
@@ -587,12 +765,22 @@ void dbg_init_js(Dbg *dbg)
|
||||
make_js_func(lsf, 0, "List functions in executable, ARGS=None");
|
||||
make_js_func(bfn, 1, "Set breakpoint at function, ARGS=Function name:string");
|
||||
make_js_func(rmbfn, 1, "Remove breakpoint at function, ARGS=Function name:string");
|
||||
make_js_func(ebaddr, 1, "Enable breakpoint at address, ARGS=Address:hex string");
|
||||
make_js_func(dbaddr, 1, "Disable breakpoint at address, ARGS=Address:hex string");
|
||||
make_js_func(ebfn, 1, "Enable breakpoint at function, ARGS=Function name:string");
|
||||
make_js_func(dbfn, 1, "Disable breakpoint at function, ARGS=Function name:string");
|
||||
make_js_func(bl, 2, "Set breakpoint at line in file, ARGS=File:string,Line:int");
|
||||
make_js_func(rmbl, 2, "Remove breakpoint at line in file, ARGS=File:string,Line:int");
|
||||
|
||||
#undef make_js_func
|
||||
}
|
||||
|
||||
void dbg_init_load_offset(Dbg *dbg)
|
||||
{
|
||||
msleep(500); // We need to sleep for a bit, because we need to ensure that our debuggee
|
||||
// program has already been loaded into memory. This is technically a bad
|
||||
// practice since we're sleeping for 500ms and praying that it's enough
|
||||
// time to ensure that debuggee has been loaded, but if it works, it works.
|
||||
procmaps_iterator maps_iter = {0};
|
||||
procmaps_error_t parser_err = PROCMAPS_SUCCESS;
|
||||
|
||||
@@ -645,9 +833,9 @@ void dbg_libelfin_wrap_init(Dbg *dbg)
|
||||
dbg->plibelfin = libelfin_wrap_get_binding(fileno(dbg->binfile), dbg->program_load_offset);
|
||||
}
|
||||
|
||||
void dbg_load_symbols(Dbg *dbg)
|
||||
void dbg_load_funcs(Dbg *dbg)
|
||||
{
|
||||
libelfin_wrap_get_syms(dbg->plibelfin, &dbg->symbols);
|
||||
libelfin_wrap_get_funcs(dbg->plibelfin, &dbg->funcs);
|
||||
}
|
||||
|
||||
void dbg_init(Dbg *dbg, const char *file, pid_t pid)
|
||||
@@ -660,7 +848,7 @@ void dbg_init(Dbg *dbg, const char *file, pid_t pid)
|
||||
dbg_init_load_offset(dbg);
|
||||
dbg_init_bin(dbg);
|
||||
dbg_libelfin_wrap_init(dbg);
|
||||
dbg_load_symbols(dbg);
|
||||
dbg_load_funcs(dbg);
|
||||
hashtable_init(&dbg->brks, MAX_BRKS);
|
||||
dbg_load_script(dbg, INIT_SCRIPT);
|
||||
}
|
||||
@@ -670,7 +858,7 @@ void dbg_deinit(Dbg *dbg)
|
||||
js_freestate(dbg->js);
|
||||
hashtable_deinit(&dbg->brks);
|
||||
hashtable_deinit(&dbg->js_descs);
|
||||
symbols_deinit(&dbg->symbols);
|
||||
funcs_deinit(&dbg->funcs);
|
||||
libelfin_wrap_free_binding(dbg->plibelfin);
|
||||
fclose(dbg->binfile);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ class LibelfinBinding
|
||||
uintptr_t loadoffset;
|
||||
};
|
||||
|
||||
DEBUGUS_EXTERNC void libelfin_wrap_get_syms(PLibelfinBinding *pbind, Symbols *syms)
|
||||
DEBUGUS_EXTERNC void libelfin_wrap_get_funcs(PLibelfinBinding pbind, Funcs *funcs)
|
||||
{
|
||||
LibelfinBinding *bind = (LibelfinBinding *)pbind;
|
||||
for (auto §ion : bind->elf.sections()) {
|
||||
@@ -27,18 +27,43 @@ DEBUGUS_EXTERNC void libelfin_wrap_get_syms(PLibelfinBinding *pbind, Symbols *sy
|
||||
for (auto sym : section.as_symtab()) {
|
||||
auto &d = sym.get_data();
|
||||
if (d.type() == elf::stt::func) {
|
||||
Symbol s = {
|
||||
Func f = {
|
||||
.name = (const char *)malloc(strlen(sym.get_name().c_str())+1),
|
||||
.addr = bind->loadoffset + (uintptr_t)d.value,
|
||||
.ai = libelfin_wrap_info_from_rip(pbind, (uintptr_t)d.value),
|
||||
};
|
||||
strcpy((char*)s.name, sym.get_name().c_str());
|
||||
da_append(syms, s);
|
||||
strcpy((char*)f.name, sym.get_name().c_str());
|
||||
da_append(funcs, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEBUGUS_EXTERNC AddrInfo *libelfin_wrap_info_from_line(PLibelfinBinding pbind, const char *file, size_t line)
|
||||
{
|
||||
LibelfinBinding *bind = (LibelfinBinding *)pbind;
|
||||
for (auto &cu : bind->dwarf.compilation_units()) {
|
||||
auto < = cu.get_line_table();
|
||||
for (auto &ent : lt) {
|
||||
if (ent.is_stmt && ent.line == line) {
|
||||
AddrInfo *ai = (AddrInfo *)malloc(sizeof(*ai));
|
||||
ai->addr = bind->loadoffset + (uintptr_t)ent.address;
|
||||
ai->line = (ssize_t)line;
|
||||
ai->file = (const char*)malloc(strlen(file)+1);
|
||||
strcpy((char*)ai->file, file);
|
||||
return ai;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEBUGUS_EXTERNC uintptr_t libelfin_wrap_func_addr(PLibelfinBinding pbind, Func *f)
|
||||
{
|
||||
LibelfinBinding *bind = (LibelfinBinding *)pbind;
|
||||
return bind->loadoffset + f->ai->addr;
|
||||
}
|
||||
|
||||
DEBUGUS_EXTERNC PLibelfinBinding libelfin_wrap_get_binding(int fd, uintptr_t loadoffset)
|
||||
{
|
||||
return (PLibelfinBinding)new LibelfinBinding(fd, loadoffset);
|
||||
|
||||
@@ -17,18 +17,18 @@
|
||||
typedef struct {
|
||||
ssize_t line;
|
||||
const char *file;
|
||||
uint64_t addr;
|
||||
uintptr_t addr;
|
||||
} AddrInfo;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
uintptr_t addr;
|
||||
} Symbol;
|
||||
AddrInfo *ai;
|
||||
} Func;
|
||||
|
||||
typedef struct {
|
||||
Symbol *items;
|
||||
Func *items;
|
||||
size_t count, capacity;
|
||||
} Symbols;
|
||||
} Funcs;
|
||||
|
||||
typedef void * PLibelfinBinding;
|
||||
|
||||
@@ -36,6 +36,8 @@ DEBUGUS_EXTERNC PLibelfinBinding libelfin_wrap_get_binding(int fd, uintptr_t loa
|
||||
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);
|
||||
DEBUGUS_EXTERNC void libelfin_wrap_get_funcs(PLibelfinBinding pbind, Funcs *funcs);
|
||||
DEBUGUS_EXTERNC uintptr_t libelfin_wrap_func_addr(PLibelfinBinding pbind, Func *f);
|
||||
DEBUGUS_EXTERNC AddrInfo *libelfin_wrap_info_from_line(PLibelfinBinding pbind, const char *file, size_t line);
|
||||
|
||||
#endif // LIBELFIN_WRAP_H_
|
||||
|
||||
8
test.c
8
test.c
@@ -2,8 +2,12 @@
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern void dupa2(void);
|
||||
|
||||
void dupa(void) {
|
||||
printf("KSKSKKSKSKSK\n");
|
||||
printf("a\n");
|
||||
printf("b\n");
|
||||
printf("c\n");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
@@ -17,6 +21,8 @@ int main(void)
|
||||
}
|
||||
}
|
||||
|
||||
dupa2();
|
||||
|
||||
int *a = NULL;
|
||||
*a = 6969;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user