diff options
Diffstat (limited to 'src/debug/ptrace')
-rw-r--r-- | src/debug/ptrace/Makefile.am | 15 | ||||
-rw-r--r-- | src/debug/ptrace/options.c | 104 | ||||
-rw-r--r-- | src/debug/ptrace/options.h | 50 | ||||
-rw-r--r-- | src/debug/ptrace/ptrace.c | 449 | ||||
-rw-r--r-- | src/debug/ptrace/ptrace.h | 55 |
5 files changed, 673 insertions, 0 deletions
diff --git a/src/debug/ptrace/Makefile.am b/src/debug/ptrace/Makefile.am new file mode 100644 index 0000000..0512721 --- /dev/null +++ b/src/debug/ptrace/Makefile.am @@ -0,0 +1,15 @@ + +lib_LIBRARIES = libdebugptrace.a + +libdebugptrace_a_SOURCES = \ + options.h options.c \ + ptrace.h ptrace.c + +libdebugptrace_a_CFLAGS = $(AM_CFLAGS) + + +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CPPFLAGS = + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/src/debug/ptrace/options.c b/src/debug/ptrace/options.c new file mode 100644 index 0000000..6aa8a1c --- /dev/null +++ b/src/debug/ptrace/options.c @@ -0,0 +1,104 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * options.c - configuration du débogage ptrace() + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "options.h" + + +#include <libgen.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + + + +/* ---------------------- OPTIONS POUR LE DEBOGAGE AVEC PTRACE ---------------------- */ + + +/* Description des options */ +struct _ptrace_options +{ + char *filename; /* Fichier à exécuter */ + char **argv; /* Argument à fournir */ + +}; + + + + + + +/* ---------------------------------------------------------------------------------- */ +/* OPTIONS POUR LE DEBOGAGE AVEC PTRACE */ +/* ---------------------------------------------------------------------------------- */ + + + +/****************************************************************************** +* * +* Paramètres : binary = élément binaire ciblé par le débogage. * +* * +* Description : Etablit les options par défaut pour un binaire donné. * +* * +* Retour : Structure mise en place (ou NULL en cas d'échec). * +* * +* Remarques : - * +* * +******************************************************************************/ + +ptrace_options *create_ptrace_options_from_binary(const openida_binary *binary) +{ + ptrace_options *result; + + result = (ptrace_options *)calloc(1, sizeof(ptrace_options)); + + result->filename = strdup(openida_binary_get_filename(binary)); + + result->argv = (char **)calloc(2, sizeof(char *)); + + result->argv[0] = basename(result->filename); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : options = options du débogage à consulter. * +* * +* Description : Lance le processus à déboguer via ptrace(). * +* * +* Retour : false en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool run_ptrace_options_process(const ptrace_options *options) +{ + execv(options->filename, options->argv); + perror("execlp"); + + return false; + +} diff --git a/src/debug/ptrace/options.h b/src/debug/ptrace/options.h new file mode 100644 index 0000000..e49f87c --- /dev/null +++ b/src/debug/ptrace/options.h @@ -0,0 +1,50 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * options.h - prototypes pour la configuration du débogage ptrace() + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _DEBUG_PTRACE_OPTIONS_H +#define _DEBUG_PTRACE_OPTIONS_H + + +#include <stdbool.h> + + +#include "../../binary.h" + + + +/* ---------------------- OPTIONS POUR LE DEBOGAGE AVEC PTRACE ---------------------- */ + + +/* Description des options */ +typedef struct _ptrace_options ptrace_options; + + +/* Etablit les options par défaut pour un binaire donné. */ +ptrace_options *create_ptrace_options_from_binary(const openida_binary *); + +/* Lance le processus à déboguer via ptrace(). */ +bool run_ptrace_options_process(const ptrace_options *); + + + +#endif /* _DEBUG_PTRACE_OPTIONS_H */ diff --git a/src/debug/ptrace/ptrace.c b/src/debug/ptrace/ptrace.c new file mode 100644 index 0000000..8840ce6 --- /dev/null +++ b/src/debug/ptrace/ptrace.c @@ -0,0 +1,449 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * ptrace.c - débogage à l'aide de ptrace() + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "ptrace.h" + + +#include <malloc.h> +#include <unistd.h> +#include <signal.h> +#include <sys/types.h> + + +#include "options.h" +#include "../debugger-int.h" +#include "../../panel/log.h" + + + + +/** Partie ptrace() **/ +#include <sys/ptrace.h> +#include <sys/wait.h> +//#include <linux/user.h> +#include <sys/syscall.h> /* For SYS_write etc */ +#include <sys/reg.h> +/** Partie ptrace() **/ + + + + +#define _(str) str + + + + +/* Débogueur utilisant ptrace() (instance) */ +struct _GPtraceDebugger +{ + GBinaryDebugger parent; /* A laisser en premier */ + + GCond *cond; /* Poursuite du déroulement */ + GMutex *mutex; /* Accès à la condition */ + + ptrace_options *options; /* Configuration du débogage */ + + pid_t child; /* Processus suivi lancé */ + + gboolean run_again; /* Reprise du débogage */ + +}; + +/* Débogueur utilisant ptrace() (classe) */ +struct _GPtraceDebuggerClass +{ + GBinaryDebuggerClass parent; /* A laisser en premier */ + +}; + + +/* Met en marche le débogueur utilisant ptrace(). */ +bool g_ptrace_debugger_run(GPtraceDebugger *); + +/* Remet en marche le débogueur utilisant ptrace(). */ +bool g_ptrace_debugger_resume(GPtraceDebugger *); + +/* Tue le débogueur utilisant ptrace(). */ +bool g_ptrace_debugger_kill(GPtraceDebugger *); + +/* Procède à un débogage via ptrace(). */ +void *ptrace_thread(GPtraceDebugger *); + +/* Fournit la valeur des registres de l'architecture. */ +register_value *get_register_values_using_ptrace_debugger(GPtraceDebugger *, size_t *); + +/* Initialise la classe du débogueur utilisant ptrace(). */ +static void g_ptrace_debugger_class_init(GPtraceDebuggerClass *); + +/* Procède à l'initialisation du débogueur utilisant ptrace(). */ +static void g_ptrace_debugger_init(GPtraceDebugger *); + + + +/* Indique le type définit par la GLib pour le débogueur ptrace(). */ +G_DEFINE_TYPE(GPtraceDebugger, g_ptrace_debugger, G_TYPE_BINARY_DEBUGGER); + + + +/****************************************************************************** +* * +* Paramètres : klass = classe de débogueur à initialiser. * +* * +* Description : Initialise la classe du débogueur utilisant ptrace(). * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_ptrace_debugger_class_init(GPtraceDebuggerClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = instance de débogueur à préparer. * +* * +* Description : Procède à l'initialisation du débogueur utilisant ptrace(). * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_ptrace_debugger_init(GPtraceDebugger *debugger) +{ + GBinaryDebugger *parent; /* Instance parente */ + + parent = G_BINARY_DEBUGGER(debugger); + + parent->run = (basic_debugger_fc)g_ptrace_debugger_run; + parent->resume = (resume_debugger_fc)g_ptrace_debugger_resume; + parent->kill = (basic_debugger_fc)g_ptrace_debugger_kill; + + parent->get_reg_values = (get_register_values_fc)get_register_values_using_ptrace_debugger; + + debugger->cond = g_cond_new(); + debugger->mutex = g_mutex_new(); + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à lancer. * +* * +* Description : Met en marche le débogueur utilisant ptrace(). * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_ptrace_debugger_run(GPtraceDebugger *debugger) +{ + GError *error; /* Bilan de création de thread */ + + if (debugger->options == NULL) + debugger->options = create_ptrace_options_from_binary(G_BINARY_DEBUGGER(debugger)->binary); + + if (debugger->options == NULL) + return false; + + + + + if (!g_thread_create((GThreadFunc)ptrace_thread, debugger, FALSE, &error)) + { + printf ("Failed to create the thread: %s\n", error->message); + } + + + /* + printf("Start Debugger with bin :: %p\n", G_BINARY_DEBUGGER_GET_IFACE(debugger)->binary); + + g_signal_emit_by_name(debugger, "debugger-stopped", (uint64_t)0xdeadbeaf); + */ + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à relancer. * +* * +* Description : Remet en marche le débogueur utilisant ptrace(). * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_ptrace_debugger_resume(GPtraceDebugger *debugger) +{ + g_mutex_lock(debugger->mutex); + debugger->run_again = TRUE; + g_cond_signal(debugger->cond); + g_mutex_unlock(debugger->mutex); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à relancer. * +* * +* Description : Tue le débogueur utilisant ptrace(). * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_ptrace_debugger_kill(GPtraceDebugger *debugger) +{ + int ret; /* Bilan de l'appel système */ + + ret = kill(debugger->child, SIGKILL); + if (ret != 0) perror("kill"); + + debugger->child = 0; + + g_mutex_lock(debugger->mutex); + debugger->run_again = TRUE; + g_cond_signal(debugger->cond); + g_mutex_unlock(debugger->mutex); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = encadrement associée à l'opération. * +* * +* Description : Procède à un débogage via ptrace(). * +* * +* Retour : ??? * +* * +* Remarques : - * +* * +******************************************************************************/ + +void *ptrace_thread(GPtraceDebugger *debugger) +{ + + + + long last_eip; /* Ancien point d'arrêt */ + long cur_eip; /* Point d'arrêt courant */ + + + long orig_eax; + int status; + + + pid_t pid; + + + bool first_run; /* Premier passage ? */ + + + debugger->child = fork(); + + switch (debugger->child) + { + case -1: + perror("fork"); + exit(-1); + break; + + case 0: + ptrace(PTRACE_TRACEME, 0, NULL, NULL); + run_ptrace_options_process(debugger->options); + _exit(-1); + break; + + default: + + gdk_threads_enter(); + + log_variadic_message(LMT_PROCESS, _("Starting to debug %s..."), + openida_binary_get_filename(G_BINARY_DEBUGGER(debugger)->binary)); + + gdk_flush (); + gdk_threads_leave(); + + first_run = true; + + while(1) + { + + + + + pid = waitpid(debugger->child, &status, 0/*WNOHANG*/); + //wait(&status); + + printf("Status :: %d\n", WIFEXITED(status)); + + if(WIFEXITED(status)) + break; + + orig_eax = ptrace(PTRACE_PEEKUSER, + debugger->child, 4 * ORIG_EAX, NULL); + if (orig_eax == -1) + { + //printf("errno :: %d vs %d\n", errno, ESRCH); + perror("ptrace()"); + } + + /* get GTK thread lock */ + gdk_threads_enter(); + + + //gtk_text_buffer_insert_at_cursor (info->buffer, "Thread waiting for resume...\n", -1); + + //gdk_flush (); + + /* release GTK thread lock */ + //gdk_threads_leave(); + + + /* Notification du point d'arrêt */ + + cur_eip = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * EIP, NULL); + + if (first_run) + { + last_eip = cur_eip; + first_run = false; + } + + g_signal_emit_by_name(debugger, "debugger-stopped", + (uint64_t)last_eip, (uint64_t)cur_eip); + + last_eip = cur_eip; + + /* release GTK thread lock */ + gdk_flush (); + + gdk_threads_leave(); + + g_mutex_lock(debugger->mutex); + while (!debugger->run_again) + g_cond_wait(debugger->cond, debugger->mutex); + debugger->run_again = FALSE; + g_mutex_unlock(debugger->mutex); + + + if (debugger->child == 0) break; + + + ptrace(PTRACE_SYSCALL, debugger->child, NULL, NULL); + + } + + log_variadic_message(LMT_PROCESS, _("Finished to debug %s..."), + openida_binary_get_filename(G_BINARY_DEBUGGER(debugger)->binary)); + + break; + + } + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à utiliser. * +* count = nombre de transmissions effetuées. * +* * +* Description : Fournit la valeur des registres de l'architecture. * +* * +* Retour : Tableau de valeurs transmises à libérer de la mémoire / NULL.* +* * +* Remarques : - * +* * +******************************************************************************/ + +register_value *get_register_values_using_ptrace_debugger(GPtraceDebugger *debugger, size_t *count) +{ + register_value *result; /* Liste de valeurs renvoyées */ + long ret; /* Valeur de registre */ + + *count = 9; + result = (register_value *)calloc(*count, sizeof(register_value)); + + ret = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * EAX, NULL); + result[0].name = "eax"; + result[0].value = ret; + + ret = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * EBX, NULL); + result[1].name = "ebx"; + result[1].value = ret; + + ret = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * ECX, NULL); + result[2].name = "ecx"; + result[2].value = ret; + + ret = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * EDX, NULL); + result[3].name = "edx"; + result[3].value = ret; + + ret = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * ESI, NULL); + result[4].name = "esi"; + result[4].value = ret; + + ret = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * EDI, NULL); + result[5].name = "edi"; + result[5].value = ret; + + ret = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * EBP, NULL); + result[6].name = "ebp"; + result[6].value = ret; + + ret = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * UESP, NULL); + result[7].name = "esp"; + result[7].value = ret; + + ret = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * EIP, NULL); + result[8].name = "eip"; + result[8].value = ret; + + return result; + +} diff --git a/src/debug/ptrace/ptrace.h b/src/debug/ptrace/ptrace.h new file mode 100644 index 0000000..f0e2c2b --- /dev/null +++ b/src/debug/ptrace/ptrace.h @@ -0,0 +1,55 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * ptrace.h - prototypes pour le débogage à l'aide de ptrace() + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _DEBUG_PTRACE_PTRACE_H +#define _DEBUG_PTRACE_PTRACE_H + + +#include <glib-object.h> + + +#include "../debuggers.h" + + + +#define G_TYPE_PTRACE_DEBUGGER (g_ptrace_debugger_get_type()) +#define G_PTRACE_DEBUGGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PTRACE_DEBUGGER, GPtraceDebugger)) +#define G_IS_PTRACE_DEBUGGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PTRACE_DEBUGGER)) +#define G_PTRACE_DEBUGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PTRACE_DEBUGGER, GPtraceDebuggerClass)) +#define G_IS_PTRACE_DEBUGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PTRACE_DEBUGGER)) +#define G_PTRACE_DEBUGGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PTRACE_DEBUGGER, GPtraceDebuggerClass)) + + +/* Débogueur utilisant ptrace() (instance) */ +typedef struct _GPtraceDebugger GPtraceDebugger; + +/* Débogueur utilisant ptrace() (classe) */ +typedef struct _GPtraceDebuggerClass GPtraceDebuggerClass; + + +/* Indique le type définit par la GLib pour le débogueur ptrace(). */ +GType g_ptrace_debugger_get_type(void); + + + +#endif /* _DEBUG_PTRACE_PTRACE_H */ |