Implement dumping registers

This commit is contained in:
kamkow1
2025-03-09 20:01:19 +01:00
parent ddf2152d46
commit 4303a5d27f
3 changed files with 165 additions and 0 deletions

126
debugus.c
View File

@@ -10,6 +10,7 @@
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <sys/personality.h>
#include <sys/user.h>
#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
}