/* OpenIDA - Outil d'analyse de fichiers binaires * gdb.c - débogage à l'aide de gdb. * * Copyright (C) 2009-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 . */ #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. */ static void g_gdb_debugger_class_init(GGdbDebuggerClass *); /* Procède à l'initialisation du débogueur utilisant gdb. */ 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); /****************************************************************************** * * * Paramètres : klass = classe de débogueur à initialiser. * * * * Description : Initialise la classe du débogueur utilisant gdb. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_gdb_debugger_class_init(GGdbDebuggerClass *klass) { } /****************************************************************************** * * * Paramètres : debugger = instance de débogueur à préparer. * * * * Description : Procède à l'initialisation du débogueur utilisant gdb. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_gdb_debugger_init(GGdbDebugger *debugger) { GBinaryDebugger *parent; /* Instance parente */ parent = G_BINARY_DEBUGGER(debugger); parent->run = (basic_debugger_fc)g_gdb_debugger_run; 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; //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 un serveur GDB. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ static bool g_gdb_debugger_run(GGdbDebugger *debugger) { 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); return true; } /****************************************************************************** * * * Paramètres : debugger = débogueur à relancer. * * * * Description : Remet en marche le débogueur utilisant un serveur GDB. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ 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; } /****************************************************************************** * * * Paramètres : debugger = débogueur à relancer. * * * * Description : Tue le débogueur utilisant un serveur GDB. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ static bool g_gdb_debugger_kill(GGdbDebugger *debugger) { #if 0 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); #endif return true; } void test_gdb(void) { GGdbStream *stream; GGdbPacket *packet; bool test; const char *data; size_t len; printf("GDB !!!!\n"); stream = g_gdb_tcp_client_new("192.168.100.141", "6666"); packet = g_gdb_stream_get_free_packet(stream); g_gdb_packet_start_new_command(packet); g_gdb_packet_append(packet, "g"); test = g_gdb_stream_send_packet(stream, packet); printf(" >> Paquet '%s' bien envoyé ? %s\n", "g", test ? "oui" : "non"); g_gdb_stream_mark_packet_as_free(stream, packet); packet = g_gdb_stream_recv_packet(stream); g_gdb_packet_get_data(packet, &data, &len, NULL); printf(" << Réception de '%s'\n", data); }