diff --git a/Info.plist b/Info.plist
new file mode 100644
index 0000000..2e4cc8f
--- /dev/null
+++ b/Info.plist
@@ -0,0 +1,11 @@
+
+
+
+
+ SecTaskAccess
+
+ allowed
+ debug
+
+
+
diff --git a/Makefile b/Makefile
index eabc434..509d36f 100644
--- a/Makefile
+++ b/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)
diff --git a/src/debugger.c b/src/debugger.c
index 025bc98..ec7dabb 100644
--- a/src/debugger.c
+++ b/src/debugger.c
@@ -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) {
diff --git a/src/debugger.h b/src/debugger.h
index 23fecea..8f3fa7e 100644
--- a/src/debugger.h
+++ b/src/debugger.h
@@ -1,17 +1,31 @@
-#include
-#include
+#include
#include
#include
#include
#include
+#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*);
diff --git a/src/util.c b/src/util.c
new file mode 100644
index 0000000..b80eeda
--- /dev/null
+++ b/src/util.c
@@ -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;
+}
diff --git a/src/util.h b/src/util.h
new file mode 100644
index 0000000..72d5032
--- /dev/null
+++ b/src/util.h
@@ -0,0 +1,4 @@
+#include
+#include
+
+char** split(char*, char);