Implement dumping registers
This commit is contained in:
@@ -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() + "\"");
|
||||
|
||||
@@ -11,4 +11,5 @@ print_pid();
|
||||
print_program_load_offset();
|
||||
mk_brk_addr(main_offset);
|
||||
list_brks();
|
||||
dump_regs();
|
||||
cont();
|
||||
|
||||
126
debugus.c
126
debugus.c
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user