diff options
Diffstat (limited to 'src/debug')
-rwxr-xr-x | src/debug/Makefile.am | 3 | ||||
-rw-r--r-- | src/debug/break.c | 440 | ||||
-rw-r--r-- | src/debug/break.h | 105 | ||||
-rw-r--r-- | src/debug/debugger-int.h | 4 | ||||
-rw-r--r-- | src/debug/debugger.c | 212 | ||||
-rw-r--r-- | src/debug/debugger.h | 92 | ||||
-rw-r--r-- | src/debug/debuggers.c | 197 | ||||
-rw-r--r-- | src/debug/debuggers.h | 91 | ||||
-rw-r--r-- | src/debug/ptrace/ptrace.h | 2 | ||||
-rw-r--r-- | src/debug/remgdb/Makefile.am | 1 | ||||
-rw-r--r-- | src/debug/remgdb/gdb.c | 179 | ||||
-rw-r--r-- | src/debug/remgdb/gdb.h | 12 | ||||
-rw-r--r-- | src/debug/remgdb/helpers.c | 139 | ||||
-rw-r--r-- | src/debug/remgdb/helpers.h | 61 | ||||
-rw-r--r-- | src/debug/remgdb/packet.c | 2 | ||||
-rw-r--r-- | src/debug/remgdb/packet.h | 2 | ||||
-rw-r--r-- | src/debug/remgdb/stream.c | 48 |
17 files changed, 1258 insertions, 332 deletions
diff --git a/src/debug/Makefile.am b/src/debug/Makefile.am index 7a19221..ec3dde7 100755 --- a/src/debug/Makefile.am +++ b/src/debug/Makefile.am @@ -2,7 +2,8 @@ noinst_LTLIBRARIES = libdebug.la libdebug_la_SOURCES = \ - debuggers.h debuggers.c + break.h break.c \ + debugger.h debugger.c libdebug_la_CFLAGS = $(AM_CFLAGS) diff --git a/src/debug/break.c b/src/debug/break.c new file mode 100644 index 0000000..4a19f25 --- /dev/null +++ b/src/debug/break.c @@ -0,0 +1,440 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * break.c - manipulation des points d'arrêt + * + * Copyright (C) 2010 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 "break.h" + + +#include <malloc.h> +#include <string.h> + + +#include "../common/dllist.h" + + + + +/* --------------------------- GESTION DES POINTS D'ARRET --------------------------- */ + + +/* Propriétés d'un point d'arrêt (instance) */ +struct _GBreakPoint +{ + GObject parent; /* A laisser en premier */ + + DL_LIST_ITEM(link); /* Maillon de liste chaînée */ + + vmpa_t address; /* Adresse où s'arrêter */ + + bool is_enabled; /* Statut d'activité */ + +}; + +/* Propriétés d'un point d'arrêt (classe) */ +struct _GBreakPointClass +{ + GObjectClass parent; /* A laisser en premier */ + + /* Signaux */ + + void (* changed) (GBreakPoint *); + +}; + + +#define bp_list_add_tail(new, head) dl_list_add_tail(new, head, GBreakPoint, link) +#define bp_list_del(item, head) dl_list_del(item, head, GBreakPoint, link) +#define bp_list_for_each(pos, head) dl_list_for_each(pos, head, GBreakPoint, link) +#define bp_list_for_each_safe(pos, head, next) dl_list_for_each_safe(pos, head, next, GBreakPoint, link) + + +/* Initialise la classe des propriétés d'un point d'arrêt. */ +static void g_break_point_class_init(GBreakPointClass *); + +/* Initialise des propriétés d'un point d'arrêt. */ +static void g_break_point_init(GBreakPoint *); + + + + + + +/* ---------------------------- GROUPE DE POINTS D'ARRET ---------------------------- */ + + +/* Propriétés d'un groupe de points d'arrêt (instance) */ +struct _GBreakGroup +{ + GObject parent; /* A laisser en premier */ + + char *name; /* Désignation humaine */ + + GBreakPoint *points; /* Liste de points d'arrêt */ + +}; + +/* Propriétés d'un groupe de points d'arrêt (classe) */ +struct _GBreakGroupClass +{ + GObjectClass parent; /* A laisser en premier */ + + /* Signaux */ + + void (* added) (GBreakGroup *, GBreakPoint *); + void (* removed) (GBreakGroup *, GBreakPoint *); + +}; + + +/* Initialise la classe des groupes de points d'arrêt. */ +static void g_break_group_class_init(GBreakGroupClass *); + +/* Initialise un groupe de points d'arrêt. */ +static void g_break_group_init(GBreakGroup *); + + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/* GESTION DES POINTS D'ARRET */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour des propriétés d'un point d'arrêt. */ +G_DEFINE_TYPE(GBreakPoint, g_break_point, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des propriétés d'un point d'arrêt. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_break_point_class_init(GBreakPointClass *klass) +{ + g_signal_new("changed", + G_TYPE_BREAK_POINT, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GBreakPointClass, changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + +} + + +/****************************************************************************** +* * +* Paramètres : point = instance à initialiser. * +* * +* Description : Initialise des propriétés d'un point d'arrêt. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_break_point_init(GBreakPoint *point) +{ + DL_LIST_ITEM_INIT(&point->link); + +} + + +/****************************************************************************** +* * +* Paramètres : address = adresse à laquelle s'arrêter. * +* * +* Description : Construit un nouveau point d'arrêt. * +* * +* Retour : Point d'arrêt mis en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBreakPoint *g_break_point_new(vmpa_t address) +{ + GBreakPoint *result; /* Adresse à retourner */ + + result = g_object_new(G_TYPE_BREAK_POINT, NULL); + + result->address = address; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : point = instance à consulter. * +* * +* Description : Fournit l'adresse associée à un point d'arrêt. * +* * +* Retour : Adresse associée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +vmpa_t g_break_point_get_address(const GBreakPoint *point) +{ + return point->address; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* GROUPE DE POINTS D'ARRET */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour les groupes de points d'errêt. */ +G_DEFINE_TYPE(GBreakGroup, g_break_group, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des groupes de points d'arrêt. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_break_group_class_init(GBreakGroupClass *klass) +{ + g_signal_new("added", + G_TYPE_BREAK_GROUP, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GBreakGroupClass, added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_BREAK_POINT); + + g_signal_new("removed", + G_TYPE_BREAK_GROUP, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GBreakGroupClass, removed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_BREAK_POINT); + +} + + +/****************************************************************************** +* * +* Paramètres : group = instance à initialiser. * +* * +* Description : Initialise un groupe de point d'arrêt. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_break_group_init(GBreakGroup *group) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Construit un nouveau groupe de points d'arrêt. * +* * +* Retour : Groupe de points d'arrêt mis en place ou NULL en cas d'échec.* +* * +* Remarques : - * +* * +******************************************************************************/ + +GBreakGroup *g_break_group_new(void) +{ + GBreakGroup *result; /* Adresse à retourner */ + + result = g_object_new(G_TYPE_BREAK_GROUP, NULL); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : group = groupe de points d'arrêt à consulter. * +* * +* Description : Fournit la désignation humaine associée à un groupe. * +* * +* Retour : Désignation humaine associée, jamais NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_break_group_get_name(const GBreakGroup *group) +{ + return group->name; + +} + + +/****************************************************************************** +* * +* Paramètres : group = groupe de points d'arrêt à modifier. * +* name = nouveau nom de scène. * +* * +* Description : Définit la désignation humaine à associer à un groupe. * +* * +* Retour : Désignation humaine associée, voire NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_break_group_set_name(GBreakGroup *group, const char *name) +{ + if (group->name != NULL) + free(group->name); + + if (name == NULL) + group->name = NULL; + + else + group->name = strdup(name); + +} + + +/****************************************************************************** +* * +* Paramètres : group = groupe de points d'arrêt à consulter. * +* addr = adresse recherchée dans les points d'arrêt. * +* * +* Description : Indique si une adresse donnée est gérée dans un groupe. * +* * +* Retour : true si l'adresse est gérée ici, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_break_group_has_address(const GBreakGroup *group, vmpa_t addr) +{ + GBreakPoint *iter; /* Boucle de parcours */ + + bp_list_for_each(iter, group->points) + if (g_break_point_get_address(iter) == addr) + return true; + + return false; + +} + + +/****************************************************************************** +* * +* Paramètres : group = groupe de points d'arrêt à modifier. * +* addr = adresse mémoire à faire basculer. * +* * +* Description : Ajoute ou supprime un point d'arrêt dans un groupe. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_break_group_toggle_breakpoint(GBreakGroup *group, vmpa_t addr) +{ + GBreakPoint *iter; /* Boucle de parcours */ + GBreakPoint *next; /* Prochain point de passage */ + + /* Suppression d'un éventuel existant */ + + bp_list_for_each_safe(iter, &group->points, next) + if (g_break_point_get_address(iter) == addr) + { + g_signal_emit_by_name(group, "removed", iter); + + bp_list_del(iter, &group->points); + g_object_unref(G_OBJECT(iter)); + + return; + + } + + /* Si non trouvé, ajout du nouveau point */ + + iter = g_break_point_new(addr); + + bp_list_add_tail(iter, &group->points); + + g_signal_emit_by_name(group, "added", iter); + +} + + +/****************************************************************************** +* * +* Paramètres : group = groupe de points d'arrêt à parcourir. * +* func = fonction à appeler à chaque point trouvé. * +* data = éventuelle donnée de l'utilisateur à joindre. * +* * +* Description : Parcourt l'ensemble des points d'arrêt d'un groupe donné. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_break_group_for_each(GBreakGroup *group, GExtFunc func, gpointer data) +{ + GBreakPoint *iter; /* Boucle de parcours */ + + /* Suppression d'un éventuel existant */ + + bp_list_for_each(iter, group->points) + func(group, iter, data); + +} diff --git a/src/debug/break.h b/src/debug/break.h new file mode 100644 index 0000000..76b537a --- /dev/null +++ b/src/debug/break.h @@ -0,0 +1,105 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * break.h - prototypes pour la manipulation des points d'arrêt + * + * Copyright (C) 2010 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_BREAK_H +#define _DEBUG_BREAK_H + + +#include <glib-object.h> +#include <stdbool.h> + + +#include "../arch/archbase.h" +#include "../glibext/proto.h" + + + +/* --------------------------- GESTION DES POINTS D'ARRET --------------------------- */ + + +#define G_TYPE_BREAK_POINT g_break_point_get_type() +#define G_BREAK_POINT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_break_point_get_type(), GBreakPoint)) +#define G_IS_BREAK_POINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_break_point_get_type())) +#define G_BREAK_POINT_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_break_point_get_type(), GBreakPointIface)) +#define G_BREAK_POINT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BREAK_POINT, GBreakPointClass)) + + +/* Propriétés d'un point d'arrêt (instance) */ +typedef struct _GBreakPoint GBreakPoint; + +/* Propriétés d'un point d'arrêt (classe) */ +typedef struct _GBreakPointClass GBreakPointClass; + + +/* Indique le type défini pour des propriétés d'un point d'arrêt. */ +GType g_break_point_get_type(void); + +/* Construit un nouveau point d'arrêt. */ +GBreakPoint *g_break_point_new(vmpa_t); + +/* Fournit l'adresse associée à un point d'arrêt. */ +vmpa_t g_break_point_get_address(const GBreakPoint *); + + + +/* ---------------------------- GROUPE DE POINTS D'ARRET ---------------------------- */ + + +#define G_TYPE_BREAK_GROUP g_break_group_get_type() +#define G_BREAK_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_break_group_get_type(), GBreakGroup)) +#define G_IS_BREAK_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_break_group_get_type())) +#define G_BREAK_GROUP_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_break_group_get_type(), GBreakGroupIface)) +#define G_BREAK_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BREAK_GROUP, GBreakGroupClass)) + + +/* Propriétés d'un groupe de points d'arrêt (instance) */ +typedef struct _GBreakGroup GBreakGroup; + +/* Propriétés d'un groupe de points d'arrêt (classe) */ +typedef struct _GBreakGroupClass GBreakGroupClass; + + +/* Indique le type défini pour les groupes de points d'errêt. */ +GType g_break_group_get_type(void); + +/* Construit un nouveau groupe de points d'arrêt. */ +GBreakGroup *g_break_group_new(void); + +/* Fournit la désignation humaine associée à un groupe. */ +const char *g_break_group_get_name(const GBreakGroup *); + +/* Définit la désignation humaine à associer à un groupe. */ +void g_break_group_set_name(GBreakGroup *, const char *); + +/* Indique si une adresse donnée est gérée dans un groupe. */ +bool g_break_group_has_address(const GBreakGroup *, vmpa_t); + +/* Ajoute ou supprime un point d'arrêt dans un groupe. */ +void g_break_group_toggle_breakpoint(GBreakGroup *, vmpa_t); + +/* Parcourt l'ensemble des points d'arrêt d'un groupe donné. */ +void g_break_group_for_each(GBreakGroup *, GExtFunc, gpointer); + + + +#endif /* _DEBUG_BREAK_H */ diff --git a/src/debug/debugger-int.h b/src/debug/debugger-int.h index 3ba594a..642efd7 100644 --- a/src/debug/debugger-int.h +++ b/src/debug/debugger-int.h @@ -25,7 +25,7 @@ #define _DEBUG_DEBUGGER_INT_H -#include "debuggers.h" +#include "debugger.h" #include <gtk/gtk.h> @@ -68,6 +68,8 @@ struct _GBinaryDebuggerClass void (* debugger_stopped) (GBinaryDebugger *, uint64_t, uint64_t); + void (* debugger_halted) (GBinaryDebugger *, int, vmpa_t, pid_t); + }; diff --git a/src/debug/debugger.c b/src/debug/debugger.c new file mode 100644 index 0000000..a7d7470 --- /dev/null +++ b/src/debug/debugger.c @@ -0,0 +1,212 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * debugger.c - gestion des différents débogueurs + * + * 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 "debugger.h" + +#include "debugger-int.h" +#include "remgdb/gdb.h" +#include "ptrace/ptrace.h" +#include "../gtkext/iodamarshal.h" + + + +/* Initialise la classe de base des débogueurs. */ +static void g_binary_debugger_class_init(GBinaryDebuggerClass *); + +/* Initialise une instance de base d'un débogueur. */ +static void g_binary_debugger_init(GBinaryDebugger *); + + + +/* Indique le type définit pour une ligne de représentation. */ +G_DEFINE_TYPE(GBinaryDebugger, g_binary_debugger, G_TYPE_OBJECT); + + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe de base des débogueurs. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_debugger_class_init(GBinaryDebuggerClass *klass) +{ + g_signal_new("debugger-stopped", + G_TYPE_BINARY_DEBUGGER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GBinaryDebuggerClass, debugger_stopped), + NULL, NULL, + g_cclosure_user_marshal_VOID__UINT64_UINT64, + G_TYPE_NONE, 2, G_TYPE_UINT64, G_TYPE_UINT64); + + g_signal_new("halted", + G_TYPE_BINARY_DEBUGGER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GBinaryDebuggerClass, debugger_halted), + NULL, NULL, + g_cclosure_user_marshal_VOID__INT_UINT64_INT, + G_TYPE_NONE, 3, G_TYPE_INT, G_TYPE_UINT64, G_TYPE_INT); + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = instance à initialiser. * +* * +* Description : Initialise une instance de base d'un débogueur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_debugger_init(GBinaryDebugger *debugger) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : type = type de débigueur choisi pour l'opération. * +* binary = binaire devant être débogué. * +* * +* Description : Crée un nouveau débogueur. * +* * +* Retour : Composant GObject mis en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinaryDebugger *g_new_binary_debugger(DebuggerType type, GOpenidaBinary *binary) +{ + GBinaryDebugger *result; + + switch (type) + { + case DGT_REMOTE_GDB: + result = g_gdb_debugger_new(binary, NULL); + break; + + case DGT_PTRACE: + result = g_object_new(G_TYPE_PTRACE_DEBUGGER, NULL); + break; + + default: + result = NULL; + break; + + } + + if (result != NULL) + result->binary = binary; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à manipuler ici. * +* * +* Description : Démarre une procédure de débogage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_debugger_run(GBinaryDebugger *debugger) +{ + debugger->run(debugger); + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à manipuler ici. * +* * +* Description : Reprend une procédure de débogage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_debugger_resume(GBinaryDebugger *debugger) +{ + debugger->resume(debugger); + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à manipuler ici. * +* * +* Description : Tue une procédure de débogage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_debugger_kill(GBinaryDebugger *debugger) +{ + debugger->kill(debugger); + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à manipuler ici. * +* 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 *g_binary_debugger_get_registers(GBinaryDebugger *debugger, size_t *count) +{ + return debugger->get_reg_values(debugger, count); + +} diff --git a/src/debug/debugger.h b/src/debug/debugger.h new file mode 100644 index 0000000..d6163cf --- /dev/null +++ b/src/debug/debugger.h @@ -0,0 +1,92 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * debugger.h - prototypes pour la gestion des différents débogueurs + * + * 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_DEBUGGER_H +#define _DEBUG_DEBUGGER_H + + +#include <glib-object.h> +#include <stdint.h> +#include <sys/types.h> + + +#include "../analysis/binary.h" + + + +/* Liste de tous les débogueurs */ +typedef enum _DebuggerType +{ + DGT_REMOTE_GDB, /* Utilisation de GDB */ + DGT_PTRACE, /* Utilisation de ptrace() */ + + DGT_COUNT + +} DebuggerType; + + +/* Transmission des valeurs des registres */ +typedef struct _register_value +{ + const char *name; /* Nom à ne pas libérer */ + uint64_t value; /* Valeur (taille maximale) */ + +} register_value; + + +#define G_TYPE_BINARY_DEBUGGER g_binary_debugger_get_type() +#define G_BINARY_DEBUGGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_binary_debugger_get_type(), GBinaryDebugger)) +#define G_IS_BINARY_DEBUGGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_binary_debugger_get_type())) +#define G_BINARY_DEBUGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BINARY_DEBUGGER, GGBinaryDebuggerClass)) +#define G_IS_BINARY_DEBUGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BINARY_DEBUGGER)) +#define G_BINARY_DEBUGGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BINARY_DEBUGGER, GGBinaryDebuggerClass)) + + +/* Définition des fonctionnalités d'un débogueur (instance) */ +typedef struct _GBinaryDebugger GBinaryDebugger; + +/* Définition des fonctionnalités d'un débogueur (classe) */ +typedef struct _GBinaryDebuggerClass GBinaryDebuggerClass; + + +/* Indique le type définit par la GLib pour le débogueur ptrace(). */ +GType g_binary_debugger_get_type(void); + +/* Crée un nouveau débogueur. */ +GBinaryDebugger *g_new_binary_debugger(DebuggerType, GOpenidaBinary *); + +/* Démarre une procédure de débogage. */ +void g_binary_debugger_run(GBinaryDebugger *); + +/* Reprend une procédure de débogage. */ +void g_binary_debugger_resume(GBinaryDebugger *); + +/* Tue une procédure de débogage. */ +void g_binary_debugger_kill(GBinaryDebugger *); + +/* Fournit la valeur des registres de l'architecture. */ +register_value *g_binary_debugger_get_registers(GBinaryDebugger *, size_t *); + + + +#endif /* _DEBUG_DEBUGGER_H */ diff --git a/src/debug/debuggers.c b/src/debug/debuggers.c index c9af67a..e69de29 100644 --- a/src/debug/debuggers.c +++ b/src/debug/debuggers.c @@ -1,197 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * debugger.sc - gestion des différents débogueurs - * - * 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 "debuggers.h" - -#include "debugger-int.h" -#include "ptrace/ptrace.h" -#include "../gtkext/iodamarshal.h" - - - -/* Initialise la classe de base des débogueurs. */ -static void g_binary_debugger_class_init(GBinaryDebuggerClass *); - -/* Initialise une instance de base d'un débogueur. */ -static void g_binary_debugger_init(GBinaryDebugger *); - - - -/* Indique le type définit pour une ligne de représentation. */ -G_DEFINE_TYPE(GBinaryDebugger, g_binary_debugger, G_TYPE_OBJECT); - - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe de base des débogueurs. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_binary_debugger_class_init(GBinaryDebuggerClass *klass) -{ - g_signal_new("debugger-stopped", - G_TYPE_BINARY_DEBUGGER, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GBinaryDebuggerClass, debugger_stopped), - NULL, NULL, - g_cclosure_user_marshal_VOID__UINT64_UINT64, - G_TYPE_NONE, 2, G_TYPE_UINT64, G_TYPE_UINT64); - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = instance à initialiser. * -* * -* Description : Initialise une instance de base d'un débogueur. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_binary_debugger_init(GBinaryDebugger *debugger) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : type = type de débigueur choisi pour l'opération. * -* binary = binaire devant être débogué. * -* * -* Description : Crée un nouveau débogueur. * -* * -* Retour : Composant GObject mis en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GBinaryDebugger *g_new_binary_debugger(DebuggerType type, GOpenidaBinary *binary) -{ - GBinaryDebugger *result; - - switch (type) - { - case DGT_PTRACE: - result = g_object_new(G_TYPE_PTRACE_DEBUGGER, NULL); - break; - default: - result = NULL; - break; - } - - if (result != NULL) - result->binary = binary; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à manipuler ici. * -* * -* Description : Démarre une procédure de débogage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_binary_debugger_run(GBinaryDebugger *debugger) -{ - debugger->run(debugger); - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à manipuler ici. * -* * -* Description : Reprend une procédure de débogage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_binary_debugger_resume(GBinaryDebugger *debugger) -{ - debugger->resume(debugger); - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à manipuler ici. * -* * -* Description : Tue une procédure de débogage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_binary_debugger_kill(GBinaryDebugger *debugger) -{ - debugger->kill(debugger); - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à manipuler ici. * -* 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 *g_binary_debugger_get_registers(GBinaryDebugger *debugger, size_t *count) -{ - return debugger->get_reg_values(debugger, count); - -} diff --git a/src/debug/debuggers.h b/src/debug/debuggers.h index 90db12f..e69de29 100644 --- a/src/debug/debuggers.h +++ b/src/debug/debuggers.h @@ -1,91 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * debuggers.h - prototypes pour la gestion des différents débogueurs - * - * 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_DEBUGGER_H -#define _DEBUG_DEBUGGER_H - - -#include <glib-object.h> -#include <stdint.h> -#include <sys/types.h> - - -#include "../analysis/binary.h" - - - -/* Liste de tous les débogueurs */ -typedef enum _DebuggerType -{ - DGT_PTRACE, /* Utilisation de ptrace() */ - - DGT_COUNT - -} DebuggerType; - - -/* Transmission des valeurs des registres */ -typedef struct _register_value -{ - const char *name; /* Nom à ne pas libérer */ - uint64_t value; /* Valeur (taille maximale) */ - -} register_value; - - -#define G_TYPE_BINARY_DEBUGGER g_binary_debugger_get_type() -#define G_BINARY_DEBUGGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_binary_debugger_get_type(), GBinaryDebugger)) -#define G_IS_BINARY_DEBUGGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_binary_debugger_get_type())) -#define G_BINARY_DEBUGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BINARY_DEBUGGER, GGBinaryDebuggerClass)) -#define G_IS_BINARY_DEBUGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BINARY_DEBUGGER)) -#define G_BINARY_DEBUGGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BINARY_DEBUGGER, GGBinaryDebuggerClass)) - - -/* Définition des fonctionnalités d'un débogueur (instance) */ -typedef struct _GBinaryDebugger GBinaryDebugger; - -/* Définition des fonctionnalités d'un débogueur (classe) */ -typedef struct _GBinaryDebuggerClass GBinaryDebuggerClass; - - -/* Indique le type définit par la GLib pour le débogueur ptrace(). */ -GType g_binary_debugger_get_type(void); - -/* Crée un nouveau débogueur. */ -GBinaryDebugger *g_new_binary_debugger(DebuggerType, GOpenidaBinary *); - -/* Démarre une procédure de débogage. */ -void g_binary_debugger_run(GBinaryDebugger *); - -/* Reprend une procédure de débogage. */ -void g_binary_debugger_resume(GBinaryDebugger *); - -/* Tue une procédure de débogage. */ -void g_binary_debugger_kill(GBinaryDebugger *); - -/* Fournit la valeur des registres de l'architecture. */ -register_value *g_binary_debugger_get_registers(GBinaryDebugger *, size_t *); - - - -#endif /* _DEBUG_DEBUGGER_H */ diff --git a/src/debug/ptrace/ptrace.h b/src/debug/ptrace/ptrace.h index f0e2c2b..e309fb2 100644 --- a/src/debug/ptrace/ptrace.h +++ b/src/debug/ptrace/ptrace.h @@ -28,7 +28,7 @@ #include <glib-object.h> -#include "../debuggers.h" +#include "../debugger.h" diff --git a/src/debug/remgdb/Makefile.am b/src/debug/remgdb/Makefile.am index b2829c9..7ed26b0 100644 --- a/src/debug/remgdb/Makefile.am +++ b/src/debug/remgdb/Makefile.am @@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libdebugremgdb.la libdebugremgdb_la_SOURCES = \ gdb.h gdb.c \ + helpers.h helpers.c \ packet.h packet.c \ stream-int.h \ stream.h stream.c \ diff --git a/src/debug/remgdb/gdb.c b/src/debug/remgdb/gdb.c index 068cf26..ea8e48e 100644 --- a/src/debug/remgdb/gdb.c +++ b/src/debug/remgdb/gdb.c @@ -23,7 +23,46 @@ #include "gdb.h" + +#include "../debugger-int.h" + + + +#include "helpers.h" +#include "tcp.h" + + + + +/* Débogueur utilisant un serveur GDB (instance) */ +struct _GGdbDebugger +{ + GBinaryDebugger parent; /* A laisser en premier */ + + GGdbStream *stream; /* Flux de communication */ + + #if 0 + 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 */ +#endif +}; + +/* Débogueur utilisant un serveur GDB (classe) */ +struct _GGdbDebuggerClass +{ + GBinaryDebuggerClass parent; /* A laisser en premier */ + +}; + + + /* Initialise la classe du débogueur utilisant gdb. */ @@ -33,6 +72,16 @@ static void g_gdb_debugger_class_init(GGdbDebuggerClass *); static void g_gdb_debugger_init(GGdbDebugger *); +/* Met en marche le débogueur utilisant un serveur GDB. */ +static bool g_gdb_debugger_run(GGdbDebugger *); + +/* Remet en marche le débogueur utilisant un serveur GDB. */ +static bool g_gdb_debugger_resume(GGdbDebugger *); + +/* Tue le débogueur utilisant un serveur GDB. */ +static bool g_gdb_debugger_kill(GGdbDebugger *); + + /* Indique le type défini par la GLib pour le débogueur gdb. */ G_DEFINE_TYPE(GGdbDebugger, g_gdb_debugger, G_TYPE_BINARY_DEBUGGER); @@ -79,19 +128,49 @@ static void g_gdb_debugger_init(GGdbDebugger *debugger) parent->resume = (resume_debugger_fc)g_gdb_debugger_resume; parent->kill = (basic_debugger_fc)g_gdb_debugger_kill; - parent->get_reg_values = (get_register_values_fc)get_register_values_using_gdb_debugger; + //parent->get_reg_values = (get_register_values_fc)get_register_values_using_gdb_debugger; - debugger->cond = g_cond_new(); - debugger->mutex = g_mutex_new(); + //debugger->cond = g_cond_new(); + //debugger->mutex = g_mutex_new(); } /****************************************************************************** * * +* Paramètres : binary = binaire représenter à déboguer. * +* options = paramètres destinés au débogage. * +* * +* Description : Crée un débogueur utilisant un serveur GDB distant. * +* * +* Retour : Instance de débogueur mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinaryDebugger *g_gdb_debugger_new(GOpenidaBinary *binary, void *options) +{ + GBinaryDebugger *result; /* Débogueur à retourner */ + + result = g_object_new(G_TYPE_GDB_DEBUGGER, NULL); + + return result; + +} + + + + + + + + +/****************************************************************************** +* * * Paramètres : debugger = débogueur à lancer. * * * -* Description : Met en marche le débogueur utilisant gdb. * +* Description : Met en marche le débogueur utilisant un serveur GDB. * * * * Retour : Bilan de l'opération. * * * @@ -99,30 +178,68 @@ static void g_gdb_debugger_init(GGdbDebugger *debugger) * * ******************************************************************************/ -bool g_gdb_debugger_run(GGdbDebugger *debugger) +static bool g_gdb_debugger_run(GGdbDebugger *debugger) { - GError *error; /* Bilan de création de thread */ - if (debugger->options == NULL) - debugger->options = create_gdb_options_from_binary(G_BINARY_DEBUGGER(debugger)->binary); - if (debugger->options == NULL) - return false; + GGdbPacket *packet; + bool test; + + const char *data; + size_t len; + + + int sig; + vmpa_t addr; + pid_t thread; + + + debugger->stream = g_gdb_tcp_client_new("127.0.0.1", "6666"); + if (debugger->stream == NULL) return false; + + + printf("Connection done !\n"); + + + + packet = g_gdb_stream_get_free_packet(debugger->stream); + + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, "?"); + + + test = g_gdb_stream_send_packet(debugger->stream, packet); + + + + printf(" >> Paquet '%s' bien envoyé ? %s\n", "?", test ? "oui" : "non"); + + + + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + + packet = g_gdb_stream_recv_packet(debugger->stream); + + g_gdb_packet_get_data(packet, &data, &len, NULL); + + printf(" << Réception de '%s'\n", data); + + + + + + get_stop_reply_sig_info(packet, &sig, &addr, &thread, SRE_LITTLE); + + g_signal_emit_by_name(debugger, "halted", sig, addr, thread); + + - if (!g_thread_create((GThreadFunc)gdb_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; } @@ -132,7 +249,7 @@ bool g_gdb_debugger_run(GGdbDebugger *debugger) * * * Paramètres : debugger = débogueur à relancer. * * * -* Description : Remet en marche le débogueur utilisant gdb(). * +* Description : Remet en marche le débogueur utilisant un serveur GDB. * * * * Retour : Bilan de l'opération. * * * @@ -140,13 +257,16 @@ bool g_gdb_debugger_run(GGdbDebugger *debugger) * * ******************************************************************************/ -bool g_gdb_debugger_resume(GGdbDebugger *debugger) +static bool g_gdb_debugger_resume(GGdbDebugger *debugger) { + + + /* g_mutex_lock(debugger->mutex); debugger->run_again = TRUE; g_cond_signal(debugger->cond); g_mutex_unlock(debugger->mutex); - + */ return true; } @@ -156,7 +276,7 @@ bool g_gdb_debugger_resume(GGdbDebugger *debugger) * * * Paramètres : debugger = débogueur à relancer. * * * -* Description : Tue le débogueur utilisant gdb(). * +* Description : Tue le débogueur utilisant un serveur GDB. * * * * Retour : Bilan de l'opération. * * * @@ -164,8 +284,11 @@ bool g_gdb_debugger_resume(GGdbDebugger *debugger) * * ******************************************************************************/ -bool g_gdb_debugger_kill(GGdbDebugger *debugger) +static bool g_gdb_debugger_kill(GGdbDebugger *debugger) { + + +#if 0 int ret; /* Bilan de l'appel système */ ret = kill(debugger->child, SIGKILL); @@ -177,19 +300,11 @@ bool g_gdb_debugger_kill(GGdbDebugger *debugger) debugger->run_again = TRUE; g_cond_signal(debugger->cond); g_mutex_unlock(debugger->mutex); - +#endif return true; } -#endif - - - - - - -#include "tcp.h" diff --git a/src/debug/remgdb/gdb.h b/src/debug/remgdb/gdb.h index 2812afd..dfd2f69 100644 --- a/src/debug/remgdb/gdb.h +++ b/src/debug/remgdb/gdb.h @@ -28,9 +28,9 @@ #include <glib-object.h> -#include "../debuggers.h" +#include "../debugger.h" + -#if 0 #define G_TYPE_GDB_DEBUGGER (g_gdb_debugger_get_type()) #define G_GDB_DEBUGGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_GDB_DEBUGGER, GGdbDebugger)) @@ -40,18 +40,18 @@ #define G_GDB_DEBUGGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_DEBUGGER, GGdbDebuggerClass)) -/* Débogueur utilisant gdb (instance) */ +/* Débogueur utilisant un serveur GDB (instance) */ typedef struct _GGdbDebugger GGdbDebugger; -/* Débogueur utilisant gdb (classe) */ +/* Débogueur utilisant un serveur GDB (classe) */ typedef struct _GGdbDebuggerClass GGdbDebuggerClass; /* Indique le type défini par la GLib pour le débogueur gdb. */ GType g_gdb_debugger_get_type(void); -#endif - +/* Crée un débogueur utilisant un serveur GDB distant. */ +GBinaryDebugger *g_gdb_debugger_new(GOpenidaBinary *, void *); void test_gdb(void); diff --git a/src/debug/remgdb/helpers.c b/src/debug/remgdb/helpers.c new file mode 100644 index 0000000..9451b08 --- /dev/null +++ b/src/debug/remgdb/helpers.c @@ -0,0 +1,139 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * helpers.c - assistanat dans la manipulation des paquets GDB + * + * Copyright (C) 2010 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 "helpers.h" + + +#include <regex.h> +#include <string.h> + + + + + + + + + + + + + + + + +/* -------------------------- PAQUETS DES REPONSES D'ARRET -------------------------- */ + + + + + + +/****************************************************************************** +* * +* Paramètres : packet = paquet de deonnées à interpréter. * +* sig = identifiant du signal source. [OUT] * +* addr = adresse de l'instruction courante. [OUT] * +* thread = identifiant du thread concerné. [OUT] * +* endian = boutisme de la plateforme ciblée. * +* * +* Description : Récupère les informations liées à un arrêt suite à signal. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : Les données sont la forme : * +* T0505:00000000;04:a08de6bf;08:505878b7;thread:50dc; * +* * +******************************************************************************/ + +bool get_stop_reply_sig_info(const GGdbPacket *packet, int *sig, vmpa_t *addr, pid_t *thread, SourceEndian endian) +{ + const char *data; /* Données brutes du paquet */ + size_t length; /* Quantité de ces données */ + uint8_t index; /* Indice de 8 bits quelconque */ + size_t pos; /* Tête de lecture courante */ + regex_t preg; /* Expression régulière */ + int ret; /* Bilan d'un appel */ + regmatch_t pmatch[3]; /* Zones remarquées */ + size_t key_len; /* Taille de l'indicatif */ + + *addr = 0ull; + + g_gdb_packet_get_data(packet, &data, &length, NULL); + + pos = 1; + + /* Lecture du numéro du signal */ + + if (!strtou8(&index, data, &pos, length, SRE_LITTLE)) + return false; + + *sig = index; + + /* Reste des informations */ + + ret = regcomp(&preg, "([^:]+):([^;]+);", REG_EXTENDED | REG_ICASE); + if (ret != 0) return false; + + for (ret = regexec(&preg, &data[pos], 3, pmatch, 0); + ret != REG_NOMATCH; + ret = regexec(&preg, &data[pos], 3, pmatch, 0)) + { + key_len = pmatch[1].rm_eo - pmatch[1].rm_so; + + /* Indication sur le thread */ + if (key_len == strlen("thread") + && strncmp(&data[pos + pmatch[1].rm_so], "thread", key_len) == 0) + { + + /* TODO printf("Thread found !\n"); */ + + } + + /* Valeur de registre ? */ + else if (key_len == 2) + { + if (!strtou8(&index, data, (size_t []) { pos + pmatch[1].rm_so }, length, SRE_LITTLE)) + return false; + + if (index != 8 /* FIXME */) + goto next_field; + + if (!strtou32(addr, data, (size_t []) { pos + pmatch[2].rm_so }, length, SRE_LITTLE/* FIXME */)) + return false; + + } + + next_field: + pos += pmatch[0].rm_eo; + + } + + regfree(&preg); + + return (*addr != 0ull); + +} + + + diff --git a/src/debug/remgdb/helpers.h b/src/debug/remgdb/helpers.h new file mode 100644 index 0000000..d6888d0 --- /dev/null +++ b/src/debug/remgdb/helpers.h @@ -0,0 +1,61 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * helpers.h - prototypes pour un assistanat dans la manipulation des paquets GDB + * + * Copyright (C) 2010 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_REMGDB_HELPERS_H +#define _DEBUG_REMGDB_HELPERS_H + + +#include "packet.h" + + +#include "../../arch/archbase.h" +#include "../../common/endianness.h" + + + + + + + +/* -------------------------- PAQUETS DES REPONSES D'ARRET -------------------------- */ + + +/* Récupère les informations liées à un arrêt suite à signal. */ +bool get_stop_reply_sig_info(const GGdbPacket *, int *, vmpa_t *, pid_t *, SourceEndian); + + + +/* ---------------------------------------------------------------------------------- */ +/* PAQUETS DES REPONSES D'ARRET */ +/* ---------------------------------------------------------------------------------- */ + + + + + + + + + + +#endif /* _DEBUG_REMGDB_HELPERS_H */ diff --git a/src/debug/remgdb/packet.c b/src/debug/remgdb/packet.c index 3fd3cba..acdec1d 100644 --- a/src/debug/remgdb/packet.c +++ b/src/debug/remgdb/packet.c @@ -333,7 +333,7 @@ bool g_gdb_packet_decode(GGdbPacket *packet) * * ******************************************************************************/ -void g_gdb_packet_get_data(GGdbPacket *packet, const char **data, size_t *len, uint8_t *checksum) +void g_gdb_packet_get_data(const GGdbPacket *packet, const char **data, size_t *len, uint8_t *checksum) { *data = packet->buffer; *len = packet->len; diff --git a/src/debug/remgdb/packet.h b/src/debug/remgdb/packet.h index 30be43e..9276e62 100644 --- a/src/debug/remgdb/packet.h +++ b/src/debug/remgdb/packet.h @@ -69,7 +69,7 @@ bool g_gdb_packet_verify_checksum(GGdbPacket *, uint8_t); bool g_gdb_packet_decode(GGdbPacket *); /* Fournit le contenu du paquet. */ -void g_gdb_packet_get_data(GGdbPacket *, const char **, size_t *, uint8_t *); +void g_gdb_packet_get_data(const GGdbPacket *, const char **, size_t *, uint8_t *); /* Ajoute un paquet à une liste de paquets. */ void g_gdb_packet_push(GGdbPacket **, GGdbPacket *); diff --git a/src/debug/remgdb/stream.c b/src/debug/remgdb/stream.c index 2b487ad..0f17930 100644 --- a/src/debug/remgdb/stream.c +++ b/src/debug/remgdb/stream.c @@ -41,6 +41,9 @@ static void g_gdb_stream_class_init(GGdbStreamClass *); /* Initialise une instance de flux de communication avec GDB. */ static void g_gdb_stream_init(GGdbStream *); +/* Envoie un acquittement pour la dernière réception. */ +static bool gdb_stream_ack(GGdbStream *); + /* Ecoute une connexion à un serveur GDB. */ static void *gdb_stream_thread(GGdbStream *); @@ -124,6 +127,37 @@ bool g_gdb_stream_listen(GGdbStream *stream) * * * Paramètres : stream = encadrement associée à l'opération. * * * +* Description : Envoie un acquittement pour la dernière réception. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool gdb_stream_ack(GGdbStream *stream) +{ + bool result; /* Bilan à retourner */ + GGdbPacket *packet; /* Paquet à envoyer */ + + packet = g_gdb_stream_get_free_packet(stream); + + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, "+"); + + result = g_gdb_stream_send_packet(stream, packet); + + g_gdb_stream_mark_packet_as_free(stream, packet); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : stream = encadrement associée à l'opération. * +* * * Description : Ecoute une connexion à un serveur GDB. * * * * Retour : ??? * @@ -145,6 +179,8 @@ static void *gdb_stream_thread(GGdbStream *stream) ret = select(stream->fd + 1, &rfds, NULL, NULL, NULL); + printf("ret :: %d\n", ret); + switch (ret) { case -1: @@ -162,6 +198,11 @@ static void *gdb_stream_thread(GGdbStream *stream) if (g_gdb_stream_read_packet(stream, packet)) { + /* Acquittement */ + if (!gdb_stream_ack(stream)) goto bad_recv; + + /* On conserve le résultat */ + g_mutex_lock(stream->recv_mutex); g_gdb_packet_push(&stream->recv_packets, packet); g_mutex_unlock(stream->recv_mutex); @@ -169,7 +210,12 @@ static void *gdb_stream_thread(GGdbStream *stream) g_cond_signal(stream->recv_cond); } - else g_gdb_stream_mark_packet_as_free(stream, packet); + + bad_recv: + + printf("bad things happend...\n"); + + g_gdb_stream_mark_packet_as_free(stream, packet); break; |