diff --git a/.debugusrc.js b/.debugusrc.js index e6222d1..7f0ba57 100644 --- a/.debugusrc.js +++ b/.debugusrc.js @@ -2,6 +2,44 @@ log_inf("Loading system init script"); +var register_names = [ + "rax", + "rbx", + "rcx", + "rdx", + "rdi", + "rsi", + "rbp", + "rsp", + "r8", + "r9", + "r10", + "r11", + "r12", + "r13", + "r14", + "r15", + "rip", + "rflags", + "cs", + "orig_rax", + "fs_base", + "gs_base", + "fs", + "gs", + "ss", + "ds", + "es", +]; + +function dump_regs() +{ + log_inf("Register dump:"); + for (var i = 0; i < register_names.length; i++) { + log_inf(register_names[i] + " " + get_reg(register_names[i])); + } +} + function print_file() { log_inf("Debugging file \"" + get_file() + "\""); diff --git a/.debugusrc1.js b/.debugusrc1.js index 3542fc8..04b2b37 100644 --- a/.debugusrc1.js +++ b/.debugusrc1.js @@ -11,4 +11,5 @@ print_pid(); print_program_load_offset(); mk_brk_addr(main_offset); list_brks(); +dump_regs(); cont(); diff --git a/debugus.c b/debugus.c index ebdd92c..89ac129 100644 --- a/debugus.c +++ b/debugus.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "linenoise.h" #include "mujs.h" @@ -25,6 +26,119 @@ #define INIT_SCRIPT ".debugusrc.js" +typedef enum { + rax, + rbx, + rcx, + rdx, + rdi, + rsi, + rbp, + rsp, + r8, + r9, + r10, + r11, + r12, + r13, + r14, + r15, + rip, + rflags, + cs, + orig_rax, + fs_base, + gs_base, + fs, + gs, + ss, + ds, + es, + MAX_REGISTERS, +} Register; + +typedef struct { + Register r; + int dwarf_r; + const char *name; +} RegisterDescriptor; + +static RegisterDescriptor reg_descriptors[MAX_REGISTERS] = { + #define make_rd(r, dr) { r, dr, #r } + make_rd(orig_rax, -1), + make_rd(rip, -1), + make_rd(rax, 0), + make_rd(rdx, 1), + make_rd(rcx, 2), + make_rd(rbx, 3), + make_rd(rsi, 4), + make_rd(rdi, 5), + make_rd(rbp, 6), + make_rd(rsp, 7), + make_rd(r8, 8), + make_rd(r9, 9), + make_rd(r10, 10), + make_rd(r11, 11), + make_rd(r12, 12), + make_rd(r13, 13), + make_rd(r14, 14), + make_rd(r15, 15), + make_rd(rflags, 49), + make_rd(es, 50), + make_rd(cs, 51), + make_rd(ss, 52), + make_rd(ds, 53), + make_rd(fs, 54), + make_rd(gs, 55), + make_rd(fs_base, 58), + make_rd(gs_base, 59), + #undef make_rd +}; + +uint64_t get_reg_value(pid_t pid, Register r) +{ + struct user_regs_struct rs; + ptrace(PTRACE_GETREGS, pid, NULL, &rs); + + for (int i = 0; i < sizeof(reg_descriptors)/sizeof(reg_descriptors[0]); i++) { + if (reg_descriptors[i].r == r) { + return ((uint64_t*)&rs)[i]; + } + } +} + +void set_reg_value(pid_t pid, Register r, uint64_t v) +{ + struct user_regs_struct rs; + ptrace(PTRACE_GETREGS, pid, NULL, &rs); + + for (int i = 0; i < sizeof(reg_descriptors)/sizeof(reg_descriptors[0]); i++) { + if (reg_descriptors[i].r == r) { + ((uint64_t*)&rs)[i] = v; + ptrace(PTRACE_SETREGS, pid, NULL, &rs); + return; + } + } +} + +const char *get_reg_name(Register r) +{ + for (int i = 0; i < sizeof(reg_descriptors)/sizeof(reg_descriptors[0]); i++) { + if (reg_descriptors[i].r == r) { + return reg_descriptors[i].name; + } + } +} + +Register get_reg_from_name(const char *name) +{ + for (int i = 0; i < MAX_REGISTERS; i++) { + if (strcmp(name, reg_descriptors[i].name) == 0) { + return reg_descriptors[i].r; + } + } +} + // How breakpoints work? // We can enable/disable breakpoints by putting/removing an int 3 instruction // into/from the executed program. int 3 will trigger a SIGTRAP, which we can @@ -179,6 +293,17 @@ void dbg_js_get_pid(js_State *js) js_pushnumber(js, dbg->pid); } +void dbg_js_get_reg(js_State *js) +{ + Dbg *dbg = getdbg(); + const char *name = js_tostring(js, 1); + Register r = get_reg_from_name(name); + uint64_t v = get_reg_value(dbg->pid, r); + char buf[20]; + snprintf(buf, sizeof(buf), "0x%016"PRIx64, v); + js_pushstring(js, buf); +} + void dbg_init_js(Dbg *dbg) { dbg->js = js_newstate(NULL, NULL, JS_STRICT); @@ -200,6 +325,7 @@ void dbg_init_js(Dbg *dbg) make_js_func(get_file, 0); make_js_func(get_pid, 0); make_js_func(get_program_load_offset, 0); + make_js_func(get_reg, 1); #undef make_js_func }