diff options
Diffstat (limited to 'misplays.c')
-rw-r--r-- | misplays.c | 261 |
1 files changed, 171 insertions, 90 deletions
@@ -1,7 +1,9 @@ +#include <errno.h> #include <signal.h> #include <stdlib.h> #include <string.h> #include <sys/ptrace.h> +#include <sys/wait.h> #include <linux/ptrace.h> #include <unistd.h> @@ -15,6 +17,9 @@ static PANEL *left, *right; static struct console cons; static int mode = 0; +PANEL *consolepan; + +/* static void describe_status(struct tracee *_dbg, PANEL *pan) { struct tracee dbg = *_dbg; int status = dbg.status; @@ -85,9 +90,10 @@ static void describe_status(struct tracee *_dbg, PANEL *pan) { } } } +*/ -static void list_breakpoints(struct tracee *dbg, PANEL *pan) { - struct list *breaks = &dbg->breaks; +static void list_breakpoints(struct thread *dbg, PANEL *pan) { + struct list *breaks = &dbg->proc->breakpoints; if (breaks->head != breaks->end) { pprintw(pan, "---\n"); @@ -98,7 +104,7 @@ static void list_breakpoints(struct tracee *dbg, PANEL *pan) { } } -static void describe_states(struct tracee *dbg, PANEL *pan) { +static void describe_states(struct thread *dbg, PANEL *pan) { struct list *states = &dbg->states; for (struct state *s = states->head; s != states->end; s = s->next) { pprintw(pan, "%c", (s == dbg->state ? '#' : '-')); @@ -106,7 +112,7 @@ static void describe_states(struct tracee *dbg, PANEL *pan) { pprintw(pan, "\n"); } -static void dump_registers(struct tracee *dbg, PANEL *pan) { +static void dump_registers(struct thread *dbg, PANEL *pan) { struct user_regs_struct *regs = &dbg->state->regs; pprintw(pan, "rax = 0x%016llx\n", regs->rax); pprintw(pan, "rbx = 0x%016llx\n", regs->rbx); @@ -119,7 +125,7 @@ static void dump_registers(struct tracee *dbg, PANEL *pan) { pprintw(pan, "rip = 0x%016llx\n", regs->rip); } -static void dump_stack(struct tracee *dbg, PANEL *pan) { +static void dump_stack(struct thread *dbg, PANEL *pan) { unsigned long sp = dbg->state->regs.rsp; for (size_t i = 0; i < 16; i++, sp += 8) { unsigned long word = *(unsigned long *)deref(dbg, sp,sizeof(unsigned long)); @@ -127,7 +133,17 @@ static void dump_stack(struct tracee *dbg, PANEL *pan) { } } -static void disasm(struct tracee *dbg, PANEL *pan) { +static int rip_visited(struct thread *th, unsigned long rip) { + struct list *states = &th->states; + for (struct state *s = states->head; s != states->end; s = s->next) { + if (rip == s->regs.rip) { + return 1; + } + } + return 0; +} + +static void disasm(struct thread *dbg, PANEL *pan) { csh handle; cs_insn *insn; @@ -139,11 +155,29 @@ static void disasm(struct tracee *dbg, PANEL *pan) { const uint8_t *code = deref(dbg, address, codez); insn = cs_malloc(handle); - for (size_t i = 0; i < 16; i++) { + for (size_t i = 0; i < 32; i++) { if (!cs_disasm_iter(handle, &code, &codez, &address, insn)) { break; } + if (dbg->stopped) { + if (insn->address == dbg->state->regs.rip) { + pattron(pan, COLOR_PAIR(1)); + } else if (is_breakpoint(dbg->proc, insn->address)) { + pattron(pan, COLOR_PAIR(3)); + } else if (rip_visited(dbg, insn->address)) { + pattron(pan, COLOR_PAIR(2)); + } + } pprintw(pan, "0x%"PRIx64":\t%s %s\n", insn->address, insn->mnemonic, insn->op_str); + if (dbg->stopped) { + if (insn->address == dbg->state->regs.rip) { + pattroff(pan, COLOR_PAIR(1)); + } else if (is_breakpoint(dbg->proc, insn->address)) { + pattroff(pan, COLOR_PAIR(3)); + } else if (rip_visited(dbg, insn->address)) { + pattroff(pan, COLOR_PAIR(2)); + } + } } cs_free(insn, 1); @@ -151,13 +185,14 @@ static void disasm(struct tracee *dbg, PANEL *pan) { } } -static void info_update(struct tracee *dbg, PANEL *pan) { +static void info_update(struct thread *dbg, PANEL *pan) { pclear(pan); - pprintw(pan, "PID: %li\n", (long)dbg->id); - if (!dbg->stopped) { - pprintw(pan, "Process is running...\n"); - } else { - describe_status(dbg, pan); + pprintw(pan, "TID: %li\n", (long)dbg->id); + //if (!dbg->stopped) { + // pprintw(pan, "Thread is running...\n"); + //} else { + //describe_status(dbg, pan); + pprintw(pan, "%s (%i)\n", dbg->status, dbg->signal); list_breakpoints(dbg, pan); describe_states(dbg, pan); dump_registers(dbg, pan); @@ -165,52 +200,68 @@ static void info_update(struct tracee *dbg, PANEL *pan) { dump_stack(dbg, pan); pprintw(pan, "---\n"); disasm(dbg, pan); - } + //} } -static void layout(void) { +static void layout(struct process *proc, struct thread *th) { int w = COLS/2; - reset_panel(left, LINES-1, w, 0, 0); - reset_panel(right, LINES-1, COLS-w, 0, w); + reset_panel(left, LINES-2, w, 1, 0); + reset_panel(right, LINES-2, COLS-w, 1, w); + + clear(); + attron(COLOR_PAIR(1)); + struct list *threads = &proc->threads; + for (struct thread *t = threads->head; t != threads->end; t = t->next) { + if (t == th) { + printw("**"); + } + printw("%li (%s)", (long)t->id, t->status); + if (t == th) { + printw("**"); + } + printw(" "); + } + attroff(COLOR_PAIR(1)); + //refresh(); +} + +static void wait_all_threads(struct process *proc) { + struct list *threads = &proc->threads; + for (struct thread *th = threads->head; th != threads->end; th = th->next) { + dbg_wait(th, 1); + } } int main(int argc, char **argv) { - if (argc < 3) { - fprintf(stderr, "Usage: %s <stop> <command>\n", argv[0]); + if (argc < 2) { + fprintf(stderr, "Usage: %s <pid>\n", argv[0]); return 1; } + //getchar(); + cursinit(); left = newpan(0, 0, 0, 0); right = newpan(0, 0, 0, 0); - layout(); - console_init(&cons); + consolepan = right; - argv[argc] = NULL; - struct tracee dbg; - if (dbg_new_process(&dbg, argv+2, &cons)) { - pprintw(right, "Failed to start child\n"); - } + struct process proc; + struct thread *th; - unsigned long stop = strtoul(argv[1], NULL, 0); - if (stop != 0) { - struct breakpoint *b = xmalloc(sizeof(*b)); - b->address = stop; - b->stack = 0; - b->enabled = -1; - b->active = 0; - list_insert(dbg.breaks.end, b); - dbg_cont(&dbg, PTRACE_CONT); + pid_t pid = strtoul(argv[1], NULL, 0); + if (dbg_process(&proc, pid, 0)) { + pprintw(right, "failed to attach process\n"); } + th = proc.threads.head; + int quit = 0; while (!quit) { - //if (dbg.stopped == NULL) { - dbg_wait(&dbg); - //} + wait_all_threads(&proc); console_update(&cons, right); - info_update(&dbg, left); + info_update(th, left); + layout(&proc, th); cursupdate(); int ch = getch(); @@ -218,7 +269,7 @@ int main(int argc, char **argv) { if (mode == 0) { switch (ch) { case KEY_RESIZE: - layout(); + layout(&proc, th); break; case 'q': quit = 1; @@ -228,60 +279,92 @@ int main(int argc, char **argv) { console_enter(&cons, right); break; case 'j': - if (dbg.stopped) { - if (dbg.state != dbg.states.tail) { - dbg.state = dbg.state->next; + dbg_stepin(th); + /* + if (dbg->stopped) { + if (dbg->state != dbg->states.tail) { + dbg->state = dbg->state->next; } else { - dbg_stepover(&dbg); - } - } - break; - case 'k': - if (dbg.stopped) { - if (dbg.state != dbg.states.head) { - dbg.state = dbg.state->prev; - } - } - break; - case 'l': - if (dbg.stopped) { - if (dbg.state != dbg.states.tail) { - //dbg.state = dbg.state->next; - } else { - dbg_stepin(&dbg); + dbg_stepover(dbg); } } + */ break; + //case 'k': + // if (dbg->stopped) { + // if (dbg->state != dbg->states.head) { + // dbg->state = dbg->state->prev; + // } + // } + // break; + //case 'l': + // if (dbg->stopped) { + // if (dbg->state != dbg->states.tail) { + // //dbg.state = dbg.state->next; + // } else { + // dbg_stepin(dbg); + // } + // } + // break; //case 'h': // if (dbg.stopped) { // dbg_stepout(&dbg); // } // break; - case 'g': - if (dbg.stopped) { - dbg.state = dbg.states.head; - } - break; - case 'G': - if (dbg.stopped) { - dbg.state = dbg.states.tail; - } - break; - case 's': - if (dbg.stopped) { - dbg_cont(&dbg, PTRACE_SYSCALL); - } - break; + //case 'g': + // if (dbg->stopped) { + // dbg->state = dbg->states.head; + // } + // break; + //case 'G': + // if (dbg->stopped) { + // dbg->state = dbg->states.tail; + // } + // break; + //case 's': + // if (dbg->stopped) { + // dbg_cont(dbg, PTRACE_SYSCALL); + // } + // break; case 'c': - if (dbg.stopped) { - dbg_cont(&dbg, PTRACE_CONT); - } + dbg_cont(th, PTRACE_CONT); break; case 'p': - if (!dbg.stopped) { - tgkill(dbg.id, dbg.id, SIGSTOP); - } + dbg_intr(th); break; + case 't': + do { + th = th->next; + } while (th == proc.threads.end); + break; + case 'T': + do { + th = th->prev; + } while (th == proc.threads.end); + break; + //case 'd': + // if (dbg->stopped) { + // while (dbg->breaks.head != dbg->breaks.end) { + // struct breakpoint *b = dbg->breaks.head; + // list_remove(b); + // free(b); + // } + // } + // break; + //case 'D': + // if (dbg->stopped) { + // if (ptrace(PTRACE_DETACH, dbg->id, NULL, NULL) < 0) { + // pprintw(right, "PTRACE_DETACH: %s\n", strerror(errno)); + // } + // struct tracee *rm = dbg; + // do { + // dbg = dbg->next; + // } while (dbg == tracees.end); + // list_remove(rm); + // dbg_free(rm); + // free(rm); + // } + // break; case ':': mvprintw(LINES-1, 0, ":"); curs_set(TRUE); @@ -293,25 +376,22 @@ int main(int argc, char **argv) { noecho(); timeout(25); clear(); - refresh(); + //refresh(); char *t = cmd; - struct breakpoint *b = xmalloc(sizeof(*b)); - b->enabled = 1; - b->active = 0; + int en = 1; if (t[0] == '!') { - b->enabled = -1; + en = -1; t++; } - b->address = strtoul(t, NULL, 0); - b->stack = 0; - list_insert(dbg.breaks.end, b); + unsigned long addr = strtoul(t, NULL, 0); + add_breakpoint(&proc, addr, 0, 0, en); break; } } else { switch (ch) { case KEY_RESIZE: - layout(); + layout(&proc, th); break; case 0x1b: mode = 0; @@ -326,6 +406,7 @@ int main(int argc, char **argv) { } } + dbg_detach(&proc); endwin(); return 0; } |