debugger: added breakpoints
This commit is contained in:
11
Info.plist
Normal file
11
Info.plist
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SecTaskAccess</key>
|
||||
<array>
|
||||
<string>allowed</string>
|
||||
<string>debug</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
5
Makefile
5
Makefile
@@ -3,12 +3,13 @@ BUILDDIR=bin/
|
||||
PREFIX=/usr/local/bin/
|
||||
SOURCES=$(wildcard src/*.c)
|
||||
MAIN=main.c
|
||||
override CFLAGS+=-Werror -Wall -g -fPIC -O2 -DNDEBUG -ftrapv -Wfloat-equal -Wundef -Wwrite-strings -Wuninitialized -pedantic -std=c11
|
||||
OSX_BS=-sectcreate __TEXT __info_plist Info.plist
|
||||
override CFLAGS+=-Werror -Wall -g -fPIC -O2 -DNDEBUG -ftrapv -Wfloat-equal -Wundef -Wwrite-strings -Wuninitialized -pedantic -std=gnu11
|
||||
override LDFLAGS+=-ledit
|
||||
|
||||
all: main.c
|
||||
mkdir -p $(BUILDDIR)
|
||||
$(CC) $(MAIN) $(SOURCES) -o $(BUILDDIR)$(TARGET) $(CFLAGS) $(LDFLAGS)
|
||||
$(CC) $(MAIN) $(SOURCES) -o $(BUILDDIR)$(TARGET) $(CFLAGS) $(LDFLAGS) $(OSX_BS)
|
||||
|
||||
install: all
|
||||
install $(BUILDDIR)$(TARGET) $(PREFIX)$(TARGET)
|
||||
|
@@ -1,5 +1,55 @@
|
||||
#include "debugger.h"
|
||||
|
||||
debugger* new_debugger(pid_t pid) {
|
||||
debugger* d = malloc(sizeof(debugger));
|
||||
d->breakpoints = NULL;
|
||||
d->n_breakpoints = 0;
|
||||
d->pid = pid;
|
||||
return d;
|
||||
}
|
||||
|
||||
breakpoint* new_breakpoint(pid_t pid, void* addr) {
|
||||
breakpoint* b = malloc(sizeof(breakpoint));
|
||||
b->pid = pid;
|
||||
b->addr = addr;
|
||||
b->enabled = 0;
|
||||
b->data = 0;
|
||||
return b;
|
||||
}
|
||||
|
||||
void free_debugger(debugger* d) {
|
||||
int i;
|
||||
for (i = 0; i < d->n_breakpoints; i++) free(d->breakpoints[i]);
|
||||
free(d);
|
||||
}
|
||||
|
||||
void enable(breakpoint* b) {
|
||||
long data = ptrace(PTRACE_PEEKDATA, b->pid, b->addr, 0);
|
||||
b->data = data & 0xff;
|
||||
uint64_t int3 = 0xcc;
|
||||
uint64_t data_with_int3 = ((data & ~0xff) | int3);
|
||||
ptrace(PTRACE_POKEDATA, b->pid, b->addr, data_with_int3);
|
||||
|
||||
b->enabled = 1;
|
||||
}
|
||||
|
||||
void disable(breakpoint* b) {
|
||||
long data = ptrace(PTRACE_PEEKDATA, b->pid, b->addr, 0);
|
||||
long restored = ((data & ~0xff) | b->data);
|
||||
ptrace(PTRACE_POKEDATA, b->pid, b->addr, restored);
|
||||
|
||||
b->enabled = 0;
|
||||
}
|
||||
|
||||
void set_breakpoint(debugger* d, void* addr) {
|
||||
printf("Setting breakpoint at addres %p\n", addr);
|
||||
breakpoint* b = new_breakpoint(d->pid, addr);
|
||||
enable(b);
|
||||
d->breakpoints = realloc(d->breakpoints,
|
||||
(++d->n_breakpoints)*sizeof(breakpoint*));
|
||||
d->breakpoints[d->n_breakpoints-1] = b;
|
||||
}
|
||||
|
||||
void run_target(char* program) {
|
||||
if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) perror("Error while creating child: ptrace failed");
|
||||
else execl(program, program, NULL);
|
||||
@@ -12,25 +62,42 @@ void debug_continue(pid_t pid) {
|
||||
waitpid(pid, &status, 0);
|
||||
}
|
||||
|
||||
void debug_loop(char* command, pid_t pid) {
|
||||
short debug_loop(char* command, debugger* d) {
|
||||
int quit = 0;
|
||||
int i = 0;
|
||||
char** args = split(command, ' ');
|
||||
command = args[0];
|
||||
|
||||
if (!strcmp(command, "c")) {
|
||||
debug_continue(pid);
|
||||
debug_continue(d->pid);
|
||||
} else if (!strcmp(command, "b")) {
|
||||
if (!args[1]) puts("'b' needs an argument");
|
||||
else set_breakpoint(d, (void*)strtol(args[1], NULL, 16));
|
||||
} else if ((!strcmp(command, "e")) || (!strcmp(command, "q"))) {
|
||||
puts("Moriturus te saluto.");
|
||||
quit = 1;
|
||||
} else {
|
||||
printf("%s: Unknown command\n", command);
|
||||
}
|
||||
while(args[i]) free(args[i++]);
|
||||
free(args);
|
||||
return quit;
|
||||
}
|
||||
|
||||
void run_debugger(pid_t pid) {
|
||||
int status;
|
||||
char* line = NULL;
|
||||
debugger* d = new_debugger(pid);
|
||||
short quit = 0;
|
||||
|
||||
waitpid(pid, &status, 0);
|
||||
|
||||
while((line = readline("minidbg> ")) != NULL) {
|
||||
debug_loop(line, pid);
|
||||
while(!quit && (line = readline("minidbg> "))) {
|
||||
quit = debug_loop(line, d);
|
||||
add_history(line);
|
||||
free(line);
|
||||
}
|
||||
free_debugger(d);
|
||||
}
|
||||
|
||||
void debug(char* program) {
|
||||
|
@@ -1,17 +1,31 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <editline/readline.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define PTRACE_TRACEME PT_TRACE_ME
|
||||
#define PTRACE_CONT PT_CONTINUE
|
||||
#define DATA 0
|
||||
#define PTRACE_PEEKDATA PT_READ_D
|
||||
#define PTRACE_POKEDATA PT_WRITE_D
|
||||
#else
|
||||
#define DATA NULL
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
short enabled;
|
||||
uint8_t data;
|
||||
pid_t pid;
|
||||
void* addr;
|
||||
} breakpoint;
|
||||
|
||||
typedef struct {
|
||||
breakpoint** breakpoints;
|
||||
int n_breakpoints;
|
||||
pid_t pid;
|
||||
} debugger;
|
||||
|
||||
void debug(char*);
|
||||
|
37
src/util.c
Normal file
37
src/util.c
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "util.h"
|
||||
|
||||
char** split(char* inpt, char d) {
|
||||
char** res = NULL;
|
||||
size_t count = 0;
|
||||
char* tmp = inpt;
|
||||
char* last_comma = NULL;
|
||||
size_t idx = 0;
|
||||
char delim[2];
|
||||
delim[0] = d;
|
||||
delim[1] = '\0';
|
||||
char* tok;
|
||||
|
||||
while (*tmp) {
|
||||
if (d == *tmp) {
|
||||
count++;
|
||||
last_comma = tmp;
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
|
||||
count += last_comma < (inpt+strlen(inpt)-1);
|
||||
|
||||
res = malloc((++count)*sizeof(char*));
|
||||
|
||||
if (res) {
|
||||
tok = strsep(&inpt, delim);
|
||||
|
||||
while (tok) {
|
||||
res[idx++] = strdup(tok);
|
||||
tok = strsep(&inpt, delim);
|
||||
}
|
||||
res[idx] = NULL;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
4
src/util.h
Normal file
4
src/util.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char** split(char*, char);
|
Reference in New Issue
Block a user