diff options
34 files changed, 3006 insertions, 7 deletions
@@ -1,3 +1,60 @@ +10-12-31  Cyrille Bagard <nocbos@gmail.com> + +	* configure.ac: +	Add the new Makefiles from the 'src/debug/jdwp{,misc,sets}' directories +	to AC_CONFIG_FILES. + +	* src/common/endianness.c: +	* src/common/endianness.h: +	Write values using LE or BE encoding. + +	* src/common/Makefile.am: +	Add net.[ch] to libcommon_la_SOURCES. + +	* src/common/net.c: +	* src/common/net.h: +	Provide a generic way to connect to a server via TCP. + +	* src/debug/debugger.h: +	Rename DGT_COUNT into DGT_COUNT2. + +	* src/debug/jdwp/debugger.c: +	* src/debug/jdwp/debugger.h: +	* src/debug/jdwp/jdwp_def.h: +	* src/debug/jdwp/Makefile.am: +	* src/debug/jdwp/misc/header.c: +	* src/debug/jdwp/misc/header.h: +	* src/debug/jdwp/misc/Makefile.am: +	* src/debug/jdwp/misc/types.c: +	* src/debug/jdwp/misc/types.h: +	* src/debug/jdwp/packet.c: +	* src/debug/jdwp/packet.h: +	* src/debug/jdwp/sets/list.c: +	* src/debug/jdwp/sets/list.h: +	* src/debug/jdwp/sets/Makefile.am: +	* src/debug/jdwp/sets/vm.c: +	* src/debug/jdwp/sets/vm.h: +	* src/debug/jdwp/tcp.c: +	* src/debug/jdwp/tcp.h: +	New entries: support a first basic packet of the Java Debug Wire Protocol. + +	* src/debug/Makefile.am: +	Add the packet-int.h, packet.[ch], stream-int.h and stream.[ch] files +        to libdebug_la_SOURCES. Add jdwp/libdebugjdwp.la to libdebug_la_LIBADD. + +	* src/debug/packet.c: +	* src/debug/packet.h: +	* src/debug/packet-int.h: +	New entries: define a generic packet for debugging communications. + +	* src/debug/remgdb/tcp.c: +	Update code relative to connect_via_tcp(). + +	* src/debug/stream.c: +	* src/debug/stream.h: +	* src/debug/stream-int.h: +	New entries: define a generic handler for debugging communications. +  10-12-21  Cyrille Bagard <nocbos@gmail.com>  	* configure.ac: diff --git a/configure.ac b/configure.ac index fe2cc9f..da0e825 100644 --- a/configure.ac +++ b/configure.ac @@ -253,6 +253,9 @@ AC_CONFIG_FILES([Makefile                   src/arch/x86/Makefile                   src/common/Makefile                   src/debug/Makefile +                 src/debug/jdwp/Makefile +                 src/debug/jdwp/misc/Makefile +                 src/debug/jdwp/sets/Makefile                   src/debug/remgdb/Makefile                   src/decomp/Makefile                   src/decomp/expr/Makefile diff --git a/src/common/Makefile.am b/src/common/Makefile.am index c883e02..391f35a 100755 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -9,6 +9,7 @@ libcommon_la_SOURCES =					\  	extstr.h extstr.c					\  	leb128.h leb128.c					\  	macros.h							\ +	net.h net.c							\  	xml.h xml.c  libcommon_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBXML_LIBS) diff --git a/src/common/endianness.c b/src/common/endianness.c index 0b7e192..15ca52a 100755 --- a/src/common/endianness.c +++ b/src/common/endianness.c @@ -25,6 +25,7 @@  #include <stdarg.h> +#include <string.h> @@ -323,6 +324,94 @@ bool read_u64(uint64_t *target, const bin_t *data, off_t *pos, off_t len, Source  } + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : value  = source de la valeur à transcrire.                   * +*                size   = taille de cette source de données.                  * +*                data   = flux de données à modifier. [OUT]                   * +*                pos    = position courante dans ce flux. [OUT]               * +*                len    = taille totale des données à analyser.               * +*                endian = ordre des bits dans la source.                      * +*                                                                             * +*  Description : Ecrit un nombre non signé sur n octets.                      * +*                                                                             * +*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool _write_un(const bin_t *value, size_t size, bin_t *data, off_t *pos, off_t len, SourceEndian endian) +{ +    size_t i;                               /* Boucle de parcours          */ + +    if (*pos < 0) return false; +    if ((len - *pos) < size) return false; + +    switch (endian) +    { +        case SRE_LITTLE: + +#if __BYTE_ORDER == __LITTLE_ENDIAN + +            memcpy(&data[*pos], value, size); +            (*pos) += size; + +#elif __BYTE_ORDER == __BIG_ENDIAN + +            for (i = 0; i < size; i++, (*pos)++) +                *(data + *pos) = *(value + size - i - 1); + +#else + +#   error "TODO : PDP !" + +#endif + +            break; + +        case SRE_MIDDLE: +            return false;   /* TODO ! */ +            break; + +        case SRE_BIG: + +#if __BYTE_ORDER == __LITTLE_ENDIAN + +            for (i = 0; i < size; i++, (*pos)++) +                *(data + *pos) = *(value + size - i - 1); + +#elif __BYTE_ORDER == __BIG_ENDIAN + +            memcpy(&data[*pos], value, size); +            (*pos) += size; + +#else + +#   error "TODO : PDP !" + +#endif + +            break; + +    } + +    return true; + +} + + + + + + + +  /******************************************************************************  *                                                                             *  *  Paramètres  : target = lieu d'enregistrement de la lecture. [OUT]          * diff --git a/src/common/endianness.h b/src/common/endianness.h index 0664d6a..e4aca6e 100755 --- a/src/common/endianness.h +++ b/src/common/endianness.h @@ -65,6 +65,33 @@ bool read_u64(uint64_t *, const bin_t *, off_t *, off_t, SourceEndian);  #define read_s64(target, data, pos, len, endian) read_u64((uint64_t *)target, data, pos, len, endian) + +/* Ecrit un nombre non signé sur n octets. */ +bool _write_un(const bin_t *, size_t, bin_t *, off_t *, off_t, SourceEndian); + + +#define write_un(value, data, pos, len, endian, type)                       \ +    ({                                                                      \ +        type __tmp;                                                         \ +        (void)(value == &__tmp);                                            \ +        _write_un((bin_t *)value, sizeof(type), data, pos, len, endian);    \ +    }) + + +#define write_u8(value, data, pos, len, endian) write_un(value, data, pos, len, endian, uint8_t) +#define write_u16(value, data, pos, len, endian) write_un(value, data, pos, len, endian, uint16_t) +#define write_u32(value, data, pos, len, endian) write_un(value, data, pos, len, endian, uint32_t) +#define write_u64(value, data, pos, len, endian) write_un(value, data, pos, len, endian, uint64_t) + +#define write_s8(value, data, pos, len, endian) write_un(value, data, pos, len, endian, sint8_t) +#define write_s16(value, data, pos, len, endian) write_un(value, data, pos, len, endian, sint16_t) +#define write_s32(value, data, pos, len, endian) write_un(value, data, pos, len, endian, sint32_t) +#define write_s64(value, data, pos, len, endian) write_un(value, data, pos, len, endian, sint64_t) + + + + +  /* Lit un nombre hexadécimal non signé sur deux octets. */  bool strtou8(uint8_t *, const char *, size_t *, size_t, SourceEndian); diff --git a/src/common/net.c b/src/common/net.c new file mode 100644 index 0000000..79a5883 --- /dev/null +++ b/src/common/net.c @@ -0,0 +1,102 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * net.c - fonctions complémentaires liées au réseau + * + * 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 "net.h" + + +#include <stdio.h> +#include <string.h> +#include <unistd.h> + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : server = nom ou adresse du serveur à contacter.              * +*                port   = port de connexion.                                  * +*                addr   = éventuelle remontée d'informations. [OUT]           * +*                                                                             * +*  Description : Ouvre une connexion TCP à un serveur quelconque.             * +*                                                                             * +*  Retour      : Flux ouvert en lecture/écriture ou -1 en cas d'échec.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +int connect_via_tcp(const char *server, const char *port, struct sockaddr_in *addr) +{ +    int result;                             /* Bilan à retourner           */ +    struct addrinfo hints;                  /* Type de connexion souhaitée */ +    struct addrinfo *infos;                 /* Informations disponibles    */ +    int ret;                                /* Bilan d'un appel            */ +    struct addrinfo *iter;                  /* Boucle de parcours          */ + +    memset(&hints, 0, sizeof(struct addrinfo)); + +    hints.ai_family = AF_UNSPEC;        /* IPv4 ou IPv6 */ +    hints.ai_socktype = SOCK_STREAM; +    hints.ai_flags = 0; +    hints.ai_protocol = 0;              /* N'importe quel protocole */ + +    ret = getaddrinfo(server, port, &hints, &infos); +    if (ret != 0) +    { +        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret)); +        return -1; +    } + +    for (iter = infos; iter != NULL; iter = iter->ai_next) +    { +        result = socket(iter->ai_family, iter->ai_socktype, iter->ai_protocol); +        if (result == -1) continue; + +        ret = connect(result, iter->ai_addr, iter->ai_addrlen); +        if (ret == 0) break; + +        perror("connect"); +        close(result); + +    } + +    freeaddrinfo(infos); + +    if (iter == NULL) return -1; + +    if (addr != NULL) +    { +        ret = getpeername(result, (struct sockaddr *)addr, +                          (socklen_t []){ sizeof(struct sockaddr_in) }); + +        if (ret == -1) +        { +            perror("getpeername"); +            close(result); +            return -1; +        } + +    } + +    return result; + +} diff --git a/src/common/net.h b/src/common/net.h new file mode 100644 index 0000000..fbfe6e0 --- /dev/null +++ b/src/common/net.h @@ -0,0 +1,37 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * net.h - prototypes pour les fonctions complémentaires liées au réseau + * + * 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 _COMMON_NET_H +#define _COMMON_NET_H + + +#include <netdb.h> + + + +/* Ouvre une connexion TCP à un serveur quelconque. */ +int connect_via_tcp(const char *, const char *, struct sockaddr_in *); + + + +#endif  /* _COMMON_NET_H */ diff --git a/src/debug/Makefile.am b/src/debug/Makefile.am index 4369a69..e2e87b8 100755 --- a/src/debug/Makefile.am +++ b/src/debug/Makefile.am @@ -3,7 +3,14 @@ noinst_LTLIBRARIES = libdebug.la  libdebug_la_SOURCES =					\  	break.h break.c						\ -	debugger.h debugger.c +	debugger.h debugger.c				\ +	packet-int.h						\ +	packet.h packet.c					\ +	stream-int.h						\ +	stream.h stream.c + +libdebug_la_LIBADD =					\ +	jdwp/libdebugjdwp.la  libdebug_la_CFLAGS = $(AM_CFLAGS) @@ -14,4 +21,4 @@ AM_CPPFLAGS =  AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = remgdb +SUBDIRS = jdwp remgdb diff --git a/src/debug/debugger.h b/src/debug/debugger.h index d6163cf..521d346 100644 --- a/src/debug/debugger.h +++ b/src/debug/debugger.h @@ -40,7 +40,7 @@ typedef enum _DebuggerType      DGT_REMOTE_GDB,                         /* Utilisation de GDB          */      DGT_PTRACE,                             /* Utilisation de ptrace()     */ -    DGT_COUNT +    DGT_COUNT2/* FIXME */  } DebuggerType; diff --git a/src/debug/jdwp/Makefile.am b/src/debug/jdwp/Makefile.am new file mode 100644 index 0000000..a9b9c81 --- /dev/null +++ b/src/debug/jdwp/Makefile.am @@ -0,0 +1,23 @@ + +noinst_LTLIBRARIES = libdebugjdwp.la + +libdebugjdwp_la_SOURCES =				\ +	debugger.h debugger.c				\ +	jdwp_def.h							\ +	packet.h packet.c					\ +	tcp.h tcp.c + +libdebugjdwp_la_LIBADD =				\ +	misc/libdebugjdwpmisc.la			\ +	sets/libdebugjdwpsets.la + +libdebugjdwp_la_LDFLAGS =  + + +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CPPFLAGS =  + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +SUBDIRS = misc sets diff --git a/src/debug/jdwp/debugger.c b/src/debug/jdwp/debugger.c new file mode 100644 index 0000000..a99c6d0 --- /dev/null +++ b/src/debug/jdwp/debugger.c @@ -0,0 +1,204 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * debugger.c - débogage d'une cible en Java. + * + * 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 "debugger.h" + + +#include "packet.h" +#include "tcp.h" + + +#include "../debugger-int.h" +#include "../stream.h" + + + + + +/* Débogueur utilisant un serveur JAVA (instance) */ +struct _GJavaDebugger +{ +    GBinaryDebugger parent;                 /* A laisser en premier        */ + +    GDebugStream *stream; + +}; + +/* Débogueur utilisant un serveur JAVA (classe) */ +struct _GJavaDebuggerClass +{ +    GBinaryDebuggerClass parent;            /* A laisser en premier        */ + +}; + + + + + +/* Initialise la classe du débogueur utilisant Java. */ +static void g_java_debugger_class_init(GJavaDebuggerClass *); + +/* Procède à l'initialisation du débogueur utilisant Java. */ +static void g_java_debugger_init(GJavaDebugger *); + + + +/* Indique le type défini par la GLib pour le débogueur java. */ +G_DEFINE_TYPE(GJavaDebugger, g_java_debugger, G_TYPE_BINARY_DEBUGGER); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe de débogueur à initialiser.                   * +*                                                                             * +*  Description : Initialise la classe du débogueur utilisant Java.            * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_java_debugger_class_init(GJavaDebuggerClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : debugger = instance de débogueur à préparer.                 * +*                                                                             * +*  Description : Procède à l'initialisation du débogueur utilisant Java.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_java_debugger_init(GJavaDebugger *debugger) +{ +    GBinaryDebugger *parent;                /* Instance parente            */ + +    parent = G_BINARY_DEBUGGER(debugger); +#if 0 +    parent->run = (basic_debugger_fc)g_java_debugger_run; +    parent->resume = (resume_debugger_fc)g_java_debugger_resume; +    parent->kill = (basic_debugger_fc)g_java_debugger_kill; +#endif + + +} + + +/****************************************************************************** +*                                                                             * +*  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 JAVA distant.          * +*                                                                             * +*  Retour      : Instance de débogueur mise en place ou NULL.                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GBinaryDebugger *g_java_debugger_new(GOpenidaBinary *binary, void *options) +{ +    GBinaryDebugger *result;                /* Débogueur à retourner       */ + +    result = g_object_new(G_TYPE_JAVA_DEBUGGER, NULL); + + +    G_JAVA_DEBUGGER(result)->stream = g_jdwp_tcp_client_new("localhost", "9000"); + +    return result; + +} + + + + + + + +void test_java(void) +{ +    GBinaryDebugger *debugger; +    GDebugPacket *packet; +    GDebugPacket *packet2; +    jdwp_payload *payload; + +    printf("JDWP-start !!!!\n"); + +    printf("size == %d\n", sizeof(jdwp_header)); + + +    debugger = g_java_debugger_new(NULL, NULL); + + +    g_debug_stream_connect(G_JAVA_DEBUGGER(debugger)->stream); + + +    packet = g_debug_stream_get_free_packet(G_JAVA_DEBUGGER(debugger)->stream); + + +    g_jdwp_packet_set_request_header(G_JDWP_PACKET(packet), JDWP_CST_VIRTUAL_MACHINE, JDWP_CMD_VM_VERSION); + +    if (!g_debug_stream_send_packet(G_JAVA_DEBUGGER(debugger)->stream, packet)) +        printf("erreur envoi\n"); + +    packet2 = g_debug_stream_recv_packet(G_JAVA_DEBUGGER(debugger)->stream, (filter_packet_fc)g_jdwp_packet_is_reply, packet); + +    if (!packet2) +        printf("erreur réception\n"); + +    if (!g_jdwp_packet_parse_payload(G_JDWP_PACKET(packet2), JDWP_CST_VIRTUAL_MACHINE, JDWP_CMD_VM_VERSION)) +        printf("erreur de décodage\n"); + +    payload = g_jdwp_packet_get_payload(G_JDWP_PACKET(packet2)); + + + +    printf("-----------\n"); + +    printf("desc :: '%s'\n", payload->vs_reply.description.value); + +    printf("version :: %d.%d\n", payload->vs_reply.jdwp_major, payload->vs_reply.jdwp_minor); + +    printf("version :: '%s'\n", payload->vs_reply.vm_version.value); +    printf("name :: '%s'\n", payload->vs_reply.vm_name.value); + +    printf("-----------\n"); + + + +    g_jdwp_packet_free_payload(G_JDWP_PACKET(packet2), JDWP_CST_VIRTUAL_MACHINE, JDWP_CMD_VM_VERSION); + + +    printf("JDWP-end !!!!\n"); + +} diff --git a/src/debug/jdwp/debugger.h b/src/debug/jdwp/debugger.h new file mode 100644 index 0000000..c19a415 --- /dev/null +++ b/src/debug/jdwp/debugger.h @@ -0,0 +1,61 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * debugger.h - prototypes pour le débogage d'une cible en Java. + * + * 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_JDWP_DEBUGGER_H +#define _DEBUG_JDWP_DEBUGGER_H + + +#include <glib-object.h> + + +#include "../debugger.h" + + + +#define G_TYPE_JAVA_DEBUGGER            (g_java_debugger_get_type()) +#define G_JAVA_DEBUGGER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_JAVA_DEBUGGER, GJavaDebugger)) +#define G_IS_JAVA_DEBUGGER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_JAVA_DEBUGGER)) +#define G_JAVA_DEBUGGER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_JAVA_DEBUGGER, GJavaDebuggerClass)) +#define G_IS_JAVA_DEBUGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_JAVA_DEBUGGER)) +#define G_JAVA_DEBUGGER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_JAVA_DEBUGGER, GJavaDebuggerClass)) + + +/* Débogueur utilisant un serveur Java (instance) */ +typedef struct _GJavaDebugger GJavaDebugger; + +/* Débogueur utilisant un serveur Java (classe) */ +typedef struct _GJavaDebuggerClass GJavaDebuggerClass; + + +/* Indique le type défini par la GLib pour le débogueur Java. */ +GType g_java_debugger_get_type(void); + +/* Crée un débogueur utilisant un serveur Java distant. */ +GBinaryDebugger *g_java_debugger_new(GOpenidaBinary *, void *); + + +void test_java(void); + + + +#endif  /* _DEBUG_JDWP_DEBUGGER_H */ diff --git a/src/debug/jdwp/jdwp_def.h b/src/debug/jdwp/jdwp_def.h new file mode 100644 index 0000000..fc5a8fe --- /dev/null +++ b/src/debug/jdwp/jdwp_def.h @@ -0,0 +1,131 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * jdwp_def.h - transcription du protocole Java Debug Wire Protocol + * + * 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_JDWP_JDWP_DEF_H +#define _DEBUG_JDWP_JDWP_DEF_H + + +#include <stdint.h> + + + +/** + * Les définitions ci-dessous sont issues des pages Web suivantes : + *  - http://download.oracle.com/javase/1.4.2/docs/guide/jpda/jdwp-spec.html + *  - http://download.oracle.com/javase/1.4.2/docs/guide/jpda/jdwp/jdwp-protocol.html + */ + + + +/* ---------------------------------------------------------------------------------- */ +/*                              EN-TETES DE PAQUETS JDWP                              */ +/* ---------------------------------------------------------------------------------- */ + + +/* En-tête générique */ +typedef struct __attribute__((__packed__)) _jdwp_header +{ +    uint32_t length;                        /* Taille totale du paquet     */ +    uint32_t id;                            /* Numéro de séquence          */ +    uint8_t flags;                          /* Options diverses            */ + +    union +    { +        /* Requête */ +        struct +        { +            uint8_t set;                    /* Jeu de commandes            */ +            uint8_t command;                /* Identifiant de commande     */ +        }; + +        /* Réponse */ +        uint16_t error;                     /* Numéro d'erreur             */ + +    }; + +} jdwp_header; + + +#define JDWP_FLAGS_NONE     0x00 +#define JDWP_FLAGS_REPLY    0x80 + + + +/* ---------------------------------------------------------------------------------- */ +/*                           TYPES DE BASE DIVERS POUR JDWP                           */ +/* ---------------------------------------------------------------------------------- */ + + + + +/* "string" */ +typedef struct _jdwp_string +{ +    uint32_t length;                        /* Taille de la chaîne         */ +    char *value;                            /* Chaîne encodée en UTF-8     */ + +} jdwp_string; + + + + + + +/** + * Jeux de commandes. + */ + +#define JDWP_CST_VIRTUAL_MACHINE    1 + + +/** + * Sous-commandes d'un jeu. + */ + +/* VirtualMachine Command Set */ + +#define JDWP_CMD_VM_VERSION         1 + + +/** + * Charges utiles des paquets. + */ + +/* JDWP_CMD_VM_VERSION */ + +typedef struct _jdwp_cmd_vm_version_reply +{ +    jdwp_string description;                /* Infos sur la VM             */ +    uint32_t jdwp_major;                    /* Numéro majeur de JDWP       */ +    uint32_t jdwp_minor;                    /* Numéro mineur de JDWP       */ +    jdwp_string vm_version;                 /* Version JRE de la VM ciblée */ +    jdwp_string vm_name;                    /* Nom de la VM                */ + +} jdwp_cmd_vm_version_reply; + + + + + + +#endif  /* _DEBUG_JDWP_JDWP_DEF_H */ diff --git a/src/debug/jdwp/misc/Makefile.am b/src/debug/jdwp/misc/Makefile.am new file mode 100644 index 0000000..cfb4a06 --- /dev/null +++ b/src/debug/jdwp/misc/Makefile.am @@ -0,0 +1,15 @@ + +noinst_LTLIBRARIES = libdebugjdwpmisc.la + +libdebugjdwpmisc_la_SOURCES =			\ +	header.h header.c					\ +	types.h types.c + +libdebugjdwpmisc_la_LDFLAGS =  + + +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CPPFLAGS =  + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/src/debug/jdwp/misc/header.c b/src/debug/jdwp/misc/header.c new file mode 100644 index 0000000..ad41c90 --- /dev/null +++ b/src/debug/jdwp/misc/header.c @@ -0,0 +1,172 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * header.c - constitution des deux types d'en-têtes JDWP + * + * 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 "header.h" + + +#include <string.h> + + +#include "../../../common/endianness.h" + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : header  = en-tête logicielle au format local à constituer.   * +*                blob    = en-tête en gros boutiste du paquet à constituer.   * +*                length  = taille totale du paquet.                           * +*                set     = jeu de commandes de la requête.                    * +*                command = commande proprement dite.                          * +*                                                                             * +*  Description : Définit une en-tête de requête au format JDWP.               * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void set_jdwp_request_header(jdwp_header *header, bin_t *blob, uint32_t length, uint8_t set, uint8_t command) +{ +    off_t pos;                              /* Tête d'écriture             */ + +    pos = 0; + +    length += sizeof(jdwp_header); + +    /* Encodage local */ + +    header->length = length; +    header->id = 1; +    header->flags = JDWP_FLAGS_NONE; + +    header->set = set; +    header->command = command; + +    /* Encodage gros boutiste */ + +    write_u32(&length, blob, &pos, sizeof(jdwp_header), SRE_BIG); +    write_u32((uint32_t []) { 1 }, blob, &pos, sizeof(jdwp_header), SRE_BIG); +    write_u8((uint8_t []) { JDWP_FLAGS_NONE }, blob, &pos, sizeof(jdwp_header), SRE_BIG); + +    write_u8(&set, blob, &pos, sizeof(jdwp_header), SRE_BIG); +    write_u8(&command, blob, &pos, sizeof(jdwp_header), SRE_BIG); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : header = en-tête logicielle au format local à constituer.    * +*                blob   = en-tête en gros boutiste du paquet à constituer.    * +*                length = taille totale du paquet.                            * +*                lastid = jeton du paquet à l'origine du besoin de réponse.   * +*                error  = éventuelle indication d'erreur.                     * +*                                                                             * +*  Description : Définit une en-tête de réponse au format JDWP.               * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void set_jdwp_reply_header(jdwp_header *header, bin_t *blob, uint32_t length, uint32_t lastid, uint16_t error) +{ +    off_t pos;                              /* Tête d'écriture             */ + +    pos = 0; + +    length += sizeof(jdwp_header); + +    /* Encodage local */ + +    header->length = length; +    header->id = 1; +    header->flags = JDWP_FLAGS_REPLY; + +    header->error = error; + +    /* Encodage gros boutiste */ + +    write_u32(&length, blob, &pos, sizeof(jdwp_header), SRE_BIG); +    write_u32((uint32_t []) { 1 }, blob, &pos, sizeof(jdwp_header), SRE_BIG); +    write_u8((uint8_t []) { JDWP_FLAGS_REPLY }, blob, &pos, sizeof(jdwp_header), SRE_BIG); + +    write_u16(&error, blob, &pos, sizeof(jdwp_header), SRE_BIG); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : blob   = flux de données à analyser.                         * +*                header = en-tête de paquet JDWP reconstituée. [OUT]          * +*                                                                             * +*  Description : Lit une en-tête de paquet au format JDWP.                    * +*                                                                             * +*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool get_jdwp_header(const bin_t *blob, jdwp_header *header) +{ +    off_t pos;                              /* Tête de lecture             */ +    off_t len;                              /* Taille standard d'en-tête   */ + +    pos = 0; +    len = sizeof(jdwp_header); + +    if (!read_u32(&header->length, blob, &pos, len, SRE_BIG)) +        return false; + +    if (!read_u32(&header->id, blob, &pos, len, SRE_BIG)) +        return false; + +    if (!read_u8(&header->flags, blob, &pos, len, SRE_BIG)) +        return false; + +    /* Réponse ? */ +    if (header->flags & JDWP_FLAGS_REPLY) +    { +        if (!read_u16(&header->error, blob, &pos, len, SRE_BIG)) +            return false; +    } + +    /* Requête ! */ +    else +    { +        if (!read_u8(&header->set, blob, &pos, len, SRE_BIG)) +            return false; + +        if (!read_u8(&header->command, blob, &pos, len, SRE_BIG)) +            return false; + +    } + +    return true; + +} diff --git a/src/debug/jdwp/misc/header.h b/src/debug/jdwp/misc/header.h new file mode 100644 index 0000000..d8fa845 --- /dev/null +++ b/src/debug/jdwp/misc/header.h @@ -0,0 +1,47 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * header.h - prototypes pour la constitution des deux types d'en-têtes JDWP + * + * 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_JDWP_MISC_HEADER_H +#define _DEBUG_JDWP_MISC_HEADER_H + + +#include <stdbool.h> + + +#include "../jdwp_def.h" +#include "../../../arch/archbase.h" + + + +/* Définit une en-tête de requête au format JDWP. */ +void set_jdwp_request_header(jdwp_header *, bin_t *, uint32_t, uint8_t, uint8_t); + +/* Définit une en-tête de réponse au format JDWP. */ +void set_jdwp_reply_header(jdwp_header *, bin_t *, uint32_t, uint32_t, uint16_t); + +/* Lit une en-tête de paquet au format JDWP. */ +bool get_jdwp_header(const bin_t *, jdwp_header *); + + + +#endif  /* _DEBUG_JDWP_MISC_HEADER_H */ diff --git a/src/debug/jdwp/misc/types.c b/src/debug/jdwp/misc/types.c new file mode 100644 index 0000000..4eca44c --- /dev/null +++ b/src/debug/jdwp/misc/types.c @@ -0,0 +1,85 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * types.c - constitution des types communs de JDWP + * + * 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 "types.h" + + +#include <malloc.h> +#include <string.h> + + +#include "../../../common/endianness.h" + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : blob = flux de données à analyser.                           * +*                pos  = position courante dans ce flux. [OUT]                 * +*                len  = taille totale des données à analyser.                 * +*                str  = chaîne de caractères à la sauce JDWP. [OUT]           * +*                                                                             * +*  Description : Lit une chaîne de caractères UTF-8 au format JDWP.           * +*                                                                             * +*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool get_jdwp_string(const bin_t *blob, off_t *pos, off_t len, jdwp_string *str) +{ +    if (!read_u32(&str->length, blob, pos, len, SRE_BIG)) +        return false; + +    if ((*pos + str->length) > len) +        return false; + +    str->value = (char *)calloc(str->length + 1, sizeof(char)); +    memcpy(str->value, &blob[*pos], str->length); + +    *pos += str->length; + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : str = chaîne de caractères à la sauce JDWP.                  * +*                                                                             * +*  Description : Libère de la mémoire une chaîne de caractères UTF-8 JDWP.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void free_jdwp_string(jdwp_string *str) +{ +    if (str->value != NULL) +        free(str->value); + +} diff --git a/src/debug/jdwp/misc/types.h b/src/debug/jdwp/misc/types.h new file mode 100644 index 0000000..1c285ff --- /dev/null +++ b/src/debug/jdwp/misc/types.h @@ -0,0 +1,44 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * types.h - prototypes pour la constitution des types communs de JDWP + * + * 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_JDWP_MISC_TYPES_H +#define _DEBUG_JDWP_MISC_TYPES_H + + +#include <stdbool.h> + + +#include "../jdwp_def.h" +#include "../../../arch/archbase.h" + + + +/* Lit une chaîne de caractères UTF-8 au format JDWP. */ +bool get_jdwp_string(const bin_t *, off_t *, off_t, jdwp_string *); + +/* Libère de la mémoire une chaîne de caractères UTF-8 JDWP. */ +void free_jdwp_string(jdwp_string *); + + + +#endif  /* _DEBUG_JDWP_MISC_TYPES_H */ diff --git a/src/debug/jdwp/packet.c b/src/debug/jdwp/packet.c new file mode 100644 index 0000000..8afaeb4 --- /dev/null +++ b/src/debug/jdwp/packet.c @@ -0,0 +1,348 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * packet.c - définition des paquets destiné au protocole JDWP + * + * 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 "packet.h" + + +#include "misc/header.h" +#include "../packet-int.h" +#include "../../arch/archbase.h" +#include "../../common/endianness.h" + + + +/* Répresentation d'un paquet de débogage JDWP (instance) */ +struct _GJdwpPacket +{ +    GDebugPacket parent;                    /* A laisser en premier        */ + +    jdwp_header header;                     /* En-tête du paquet JDWP      */ +    bin_t hblob[sizeof(jdwp_header)];       /* Contenu encodé en B.E.      */ + +    jdwp_payload payload;                   /* Charge utile du paquet      */ +    bin_t pblob[sizeof(jdwp_payload)];      /* Contenu encodé en B.E.      */ + +}; + + +/* Répresentation d'un paquet de débogage JDWP (classe) */ +struct _GJdwpPacketClass +{ +    GDebugPacketClass parent;               /* A laisser en premier        */ + +}; + + +/* Initialise la classe des paquets de débogage JDWP. */ +static void g_jdwp_packet_class_init(GJdwpPacketClass *); + +/* Initialise une instance de paquet de débogage JDWP. */ +static void g_jdwp_packet_init(GJdwpPacket *); + +/* Précise les zones mémoires correspondant au contenu. */ +static void g_jdwp_packet_vectorize(GJdwpPacket *, struct iovec [UIO_MAXIOV], int *); + + + +/* Indique le type défini pour un paquet de débogage JDWP. */ +G_DEFINE_TYPE(GJdwpPacket, g_jdwp_packet, G_TYPE_DEBUG_PACKET); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des paquets de débogage JDWP.           * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_jdwp_packet_class_init(GJdwpPacketClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : packet = instance à initialiser.                             * +*                                                                             * +*  Description : Initialise une instance de paquet de débogage JDWP.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_jdwp_packet_init(GJdwpPacket *packet) +{ +    GDebugPacket *dpkt;                     /* Version parente             */ + +    dpkt = G_DEBUG_PACKET(packet); + +    dpkt->vectorize = (debug_vectorize_fc)g_jdwp_packet_vectorize; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : packet = instance à convertir.                               * +*                iov    = table de vecteurs. [OUT]                            * +*                iovcnt = quantité de champs renseignés. [OUT]                * +*                                                                             * +*  Description : Précise les zones mémoires correspondant au contenu.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_jdwp_packet_vectorize(GJdwpPacket *packet, struct iovec iov[UIO_MAXIOV], int *iovcnt) +{ +    uint32_t length;                        /* Quantité de données         */ +    bool empty;                             /* Présence d'une charge utile */ + +    read_u32(&length, packet->hblob, (off_t []) { 0 }, sizeof(jdwp_header), SRE_BIG); + +    iov[0].iov_base = packet->hblob; +    iov[0].iov_len = sizeof(jdwp_header); + +    empty = (length == sizeof(jdwp_header)); + +    if (!empty) +    { +        iov[1].iov_base = packet->pblob; +        iov[1].iov_len = length - sizeof(jdwp_header); +    } + +    *iovcnt = (empty ? 1 : 2); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : packet = instance à consulter.                               * +*                                                                             * +*  Description : Fournit l'adresse des données de l'en-tête d'un paquet JDWP. * +*                                                                             * +*  Retour      : Adresse des données de l'en-tête (à priori de requête).      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +jdwp_header *g_jdwp_packet_get_header(GJdwpPacket *packet) +{ +    return &packet->header; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : packet = instance à consulter.                               * +*                                                                             * +*  Description : Fournit l'adresse des données de l'en-tête d'un paquet JDWP. * +*                                                                             * +*  Retour      : Adresse des données de l'en-tête (à priori de requête).      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bin_t *g_jdwp_packet_get_hblob(GJdwpPacket *packet) +{ +    return packet->hblob; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : packet = instance à mettre à jour.                           * +*                                                                             * +*  Description : Recompose l'en-tête d'un paquet à partir de données brutes.  * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_jdwp_packet_parse_header(GJdwpPacket *packet) +{ +    return get_jdwp_header(packet->hblob, &packet->header); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : packet  = paquet à mettre à jour.                            * +*                set     = jeu de commandes de la requête.                    * +*                command = commande proprement dite.                          * +*                                                                             * +*  Description : Définit l'en-tête du paquet pour une requête au format JDWP. * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_jdwp_packet_set_request_header(GJdwpPacket *packet, uint8_t set, uint8_t command) +{ +    set_jdwp_request_header(&packet->header, packet->hblob, +                            0 /* FIXME */, set, command); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : packet  = paquet à mettre à jour.                            * +*                lastid = jeton du paquet à l'origine du besoin de réponse.   * +*                error  = éventuelle indication d'erreur.                     * +*                                                                             * +*  Description : Définit l'en-tête du paquet pour une réponse au format JDWP. * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_jdwp_packet_set_reply_header(GJdwpPacket *packet, uint32_t lastid, uint16_t error) +{ +    set_jdwp_reply_header(&packet->header, packet->hblob, +                          0 /* FIXME */, lastid, error); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : packet = instance à consulter.                               * +*                                                                             * +*  Description : Fournit l'adresse des charges utiles d'un paquet JDWP.       * +*                                                                             * +*  Retour      : Adresse des données d'une charge utile.                      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +jdwp_payload *g_jdwp_packet_get_payload(GJdwpPacket *packet) +{ +    return &packet->payload; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : packet = instance à consulter.                               * +*                                                                             * +*  Description : Fournit l'adresse des charges utiles d'un paquet JDWP.       * +*                                                                             * +*  Retour      : Adresse des données d'une charge utile.                      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bin_t *g_jdwp_packet_get_pblob(GJdwpPacket *packet) +{ +    return packet->pblob; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : packet = instance à mettre à jour.                           * +*                set    = jeu de commandes concerné.                          * +*                cmd    = identifiant d'une commande donnée.                  * +*                                                                             * +*  Description : Recompose une charge utile à partir de ses données brutes.   * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_jdwp_packet_parse_payload(GJdwpPacket *packet, uint8_t set, uint8_t cmd) +{ +    return get_jdwp_payload(packet->pblob, packet->header.length - sizeof(jdwp_header)/* FIXME */, set, cmd, &packet->payload); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : packet = instance à mettre à jour.                           * +*                set    = jeu de commandes concerné.                          * +*                cmd    = identifiant d'une commande donnée.                  * +*                                                                             * +*  Description : Libère la mémoire occupée par une charge utile de paquet.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_jdwp_packet_free_payload(GJdwpPacket *packet, uint8_t set, uint8_t cmd) +{ +    free_jdwp_payload(&packet->payload, set, cmd); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : reply  = instance de paquet à analyser.                      * +*                packet = instance de paquet de référence.                    * +*                                                                             * +*  Description : Détermine si un paquet est une réponse à un premier paquet.  * +*                                                                             * +*  Retour      : true si le paquet correspond à la réponse attendue.          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_jdwp_packet_is_reply(const GJdwpPacket *reply, const GJdwpPacket *packet) +{ +    return (reply->header.id == packet->header.id +            && reply->header.flags & JDWP_FLAGS_REPLY); + +} diff --git a/src/debug/jdwp/packet.h b/src/debug/jdwp/packet.h new file mode 100644 index 0000000..fda9faf --- /dev/null +++ b/src/debug/jdwp/packet.h @@ -0,0 +1,87 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * packet.h - prototypes pour la définition des paquets destiné au protocole JDWP + * + * 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_JDWP_PACKET_H +#define _DEBUG_JDWP_PACKET_H + + +#include <glib-object.h> + + +#include "jdwp_def.h" +#include "sets/list.h" + + + +#define G_TYPE_JDWP_PACKET               g_jdwp_packet_get_type() +#define G_JDWP_PACKET(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_jdwp_packet_get_type(), GJdwpPacket)) +#define G_IS_JDWP_PACKET(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_jdwp_packet_get_type())) +#define G_JDWP_PACKET_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_JDWP_PACKET, GJdwpPacketClass)) +#define G_IS_JDWP_PACKET_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_JDWP_PACKET)) +#define G_JDWP_PACKET_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_JDWP_PACKET, GJdwpPacketClass)) + + +/* Répresentation d'un paquet de débogage JDWP (instance) */ +typedef struct _GJdwpPacket GJdwpPacket; + +/* Répresentation d'un paquet de débogage JDWP (classe) */ +typedef struct _GJdwpPacketClass GJdwpPacketClass; + + + +/* Indique le type défini pour un paquet de débogage JDWP. */ +GType g_jdwp_packet_get_type(void); + +/* Fournit l'adresse des données de l'en-tête d'un paquet JDWP. */ +jdwp_header *g_jdwp_packet_get_header(GJdwpPacket *); + +/* Fournit l'adresse des données de l'en-tête d'un paquet JDWP. */ +bin_t *g_jdwp_packet_get_hblob(GJdwpPacket *); + +/* Recompose l'en-tête d'un paquet à partir de données brutes. */ +bool g_jdwp_packet_parse_header(GJdwpPacket *); + +/* Définit l'en-tête du paquet pour une requête au format JDWP. */ +void g_jdwp_packet_set_request_header(GJdwpPacket *, uint8_t, uint8_t); + +/* Définit l'en-tête du paquet pour une réponse au format JDWP. */ +void g_jdwp_packet_set_reply_header(GJdwpPacket *, uint32_t, uint16_t); + +/* Fournit l'adresse des charges utiles d'un paquet JDWP. */ +jdwp_payload *g_jdwp_packet_get_payload(GJdwpPacket *); + +/* Fournit l'adresse des charges utiles d'un paquet JDWP. */ +bin_t *g_jdwp_packet_get_pblob(GJdwpPacket *); + +/* Recompose une charge utile à partir de ses données brutes. */ +bool g_jdwp_packet_parse_payload(GJdwpPacket *, uint8_t, uint8_t); + +/* Libère la mémoire occupée par une charge utile de paquet. */ +void g_jdwp_packet_free_payload(GJdwpPacket *, uint8_t, uint8_t); + +/* Détermine si un paquet est une réponse à un premier paquet. */ +bool g_jdwp_packet_is_reply(const GJdwpPacket *, const GJdwpPacket *); + + + +#endif  /* _DEBUG_JDWP_PACKET_H */ diff --git a/src/debug/jdwp/sets/Makefile.am b/src/debug/jdwp/sets/Makefile.am new file mode 100644 index 0000000..98a76b4 --- /dev/null +++ b/src/debug/jdwp/sets/Makefile.am @@ -0,0 +1,15 @@ + +noinst_LTLIBRARIES = libdebugjdwpsets.la + +libdebugjdwpsets_la_SOURCES =			\ +	list.h list.c						\ +	vm.h vm.c + +libdebugjdwpsets_la_LDFLAGS =  + + +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CPPFLAGS =  + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/src/debug/jdwp/sets/list.c b/src/debug/jdwp/sets/list.c new file mode 100644 index 0000000..0dad1e8 --- /dev/null +++ b/src/debug/jdwp/sets/list.c @@ -0,0 +1,118 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * list.c - ensemble des jeux de commandes de JDWP + * + * 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 "list.h" + + +#include <stddef.h> + + +#include "vm.h" + + + +/* Reconstitue une charge utile à partir d'un contenu binaire. */ +typedef bool (* get_jdwp_payload_fc) (const bin_t *, off_t, jdwp_payload *); + +/* Libère le contenu d'une charge utile. */ +typedef void (* free_jdwp_payload_fc) (jdwp_payload *); + + +/* Commandes JDWP */ +typedef struct _jdwp_command +{ +    get_jdwp_payload_fc get_payload;        /* Constitution de la charge   */ +    free_jdwp_payload_fc free_payload;      /* Libération de la mémoire    */ + +} jdwp_command; + + +/* Energistrement des différents jeux */ +static jdwp_command _commands[][256] = { + +    [JDWP_CST_VIRTUAL_MACHINE] = { + +        [JDWP_CMD_VM_VERSION] = { +            .get_payload = (get_jdwp_payload_fc)get_jdwp_vm_version, +            .free_payload = (free_jdwp_payload_fc)free_jdwp_vm_version +        }, + + + + +    }, + + + +}; + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : blob    = ensemble de données binaires brutes.               * +*                len     = quantité de données valides.                       * +*                set     = jeu de commandes concerné.                         * +*                cmd     = identifiant d'une commande donnée.                 * +*                payload = charge utile à reconstituer. [OUT]                 * +*                                                                             * +*  Description : Reconstitue une charge utile à partir d'un contenu binaire.  * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool get_jdwp_payload(const bin_t *blob, off_t len, uint8_t set, uint8_t cmd, jdwp_payload *payload) +{ +    bool result;                            /* Bilan à retourner           */ + +    if (_commands[set][cmd].get_payload == NULL) result = false; +    else result = _commands[set][cmd].get_payload(blob, len, payload); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : payload = charge utile à supprimer de la mémoire.            * +*                set     = jeu de commandes concerné.                         * +*                cmd     = identifiant d'une commande donnée.                 * +*                                                                             * +*  Description : Libère le contenu d'une charge utile.                        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void free_jdwp_payload(jdwp_payload *payload, uint8_t set, uint8_t cmd) +{ +    if (_commands[set][cmd].free_payload != NULL) +        _commands[set][cmd].free_payload(payload); + +} diff --git a/src/debug/jdwp/sets/list.h b/src/debug/jdwp/sets/list.h new file mode 100644 index 0000000..2fb135e --- /dev/null +++ b/src/debug/jdwp/sets/list.h @@ -0,0 +1,54 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * list.h - prototypes pour l'ensemble des jeux de commandes de JDWP + * + * 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_JDWP_SETS_LIST_H +#define _DEBUG_JDWP_SETS_LIST_H + + +#include <stdbool.h> + + +#include "../jdwp_def.h" +#include "../../../arch/archbase.h" + + + +/* Ensemble des contenus pris en compte */ +typedef union _jdwp_payload +{ +    jdwp_cmd_vm_version_reply vs_reply;     /* Infos. sur la version       */ + +    bin_t padding[500]; + +} jdwp_payload; + + +/* Reconstitue une charge utile à partir d'un contenu binaire. */ +bool get_jdwp_payload(const bin_t *, off_t, uint8_t, uint8_t, jdwp_payload *); + +/* Libère le contenu d'une charge utile. */ +void free_jdwp_payload(jdwp_payload *, uint8_t, uint8_t); + + + +#endif  /* _DEBUG_JDWP_SETS_LIST_H */ diff --git a/src/debug/jdwp/sets/vm.c b/src/debug/jdwp/sets/vm.c new file mode 100644 index 0000000..fdb1ec0 --- /dev/null +++ b/src/debug/jdwp/sets/vm.c @@ -0,0 +1,97 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * vm.c - constitution des charges utiles liées à la VM + * + * 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 "vm.h" + + +#include <string.h> + + +#include "../misc/types.h" +#include "../../../common/endianness.h" + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : blob  = ensemble de données binaires brutes.                 * +*                len   = quantité de données valides.                         * +*                reply = structure de réponse à constituer. [OUT]             * +*                                                                             * +*  Description : Reconstitue une réponse quant à une version de serveur.      * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool get_jdwp_vm_version(const bin_t *blob, off_t len, jdwp_cmd_vm_version_reply *reply) +{ +    bool result;                            /* Bilan à retourner           */ +    off_t pos;                              /* Tête de lecture             */ + +    pos = 0; +    memset(reply, 0, sizeof(jdwp_cmd_vm_version_reply)); + +    result = get_jdwp_string(blob, &pos, len, &reply->description); +    if (!result) return false; + +    result = read_u32(&reply->jdwp_major, blob, &pos, len, SRE_BIG); +    if (!result) return false; + +    result = read_u32(&reply->jdwp_minor, blob, &pos, len, SRE_BIG); +    if (!result) return false; + +    result = get_jdwp_string(blob, &pos, len, &reply->vm_version); +    if (!result) return false; + +    result = get_jdwp_string(blob, &pos, len, &reply->vm_name); +    if (!result) return false; + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : reply = structure de réponse à supprimer de la mémoire.      * +*                                                                             * +*  Description : Libère le contenu d'une réponse quant à une version.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void free_jdwp_vm_version(jdwp_cmd_vm_version_reply *reply) +{ +    free_jdwp_string(&reply->description); + +    free_jdwp_string(&reply->vm_version); + +    free_jdwp_string(&reply->vm_name); + +} diff --git a/src/debug/jdwp/sets/vm.h b/src/debug/jdwp/sets/vm.h new file mode 100644 index 0000000..de2c7db --- /dev/null +++ b/src/debug/jdwp/sets/vm.h @@ -0,0 +1,44 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * vm.h - prototypes pour la constitution des charges utiles liées à la VM + * + * 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_JDWP_SETS_VM_H +#define _DEBUG_JDWP_SETS_VM_H + + +#include <stdbool.h> + + +#include "../jdwp_def.h" +#include "../../../arch/archbase.h" + + + +/* Reconstitue une réponse quant à une version de serveur. */ +bool get_jdwp_vm_version(const bin_t *, off_t, jdwp_cmd_vm_version_reply *); + +/* Libère le contenu d'une réponse quant à une version. */ +void free_jdwp_vm_version(jdwp_cmd_vm_version_reply *); + + + +#endif  /* _DEBUG_JDWP_SETS_VM_H */ diff --git a/src/debug/jdwp/tcp.c b/src/debug/jdwp/tcp.c new file mode 100644 index 0000000..38acd29 --- /dev/null +++ b/src/debug/jdwp/tcp.c @@ -0,0 +1,328 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * tcp.c - gestion des connexions TCP aux serveurs JDWP. + * + * 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 "tcp.h" + + +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/select.h> +#include <sys/socket.h> +#include <sys/types.h> + + +#include "packet.h" +#include "misc/header.h" +#include "sets/list.h" +#include "../stream-int.h" +#include "../../common/net.h" + + + +/* Flux de communication TCP avec un serveur JDWP (instance) */ +struct _GJdwpTcpClient +{ +    GDebugStream parent;                    /* A laisser en premier        */ + +    char *server;                           /* Serveur à contacter         */ +    char *port;                             /* Port de connexion           */ +    int fd;                                 /* Flux ouvert en L./E.        */ + +}; + + +/* Flux de communication TCP avec un serveur JDWP (classe) */ +struct _GJdwpTcpClientClass +{ +    GDebugStreamClass parent;               /* A laisser en premier        */ + +}; + + +/* Initialise la classe des flux de communication JDWP over TCP. */ +static void g_jdwp_tcp_client_class_init(GJdwpTcpClientClass *); + +/* Initialise une instance de flux de communication avec JDWP. */ +static void g_jdwp_tcp_client_init(GJdwpTcpClient *); + +/* Etablit de façon effective une connexion à la cible. */ +static bool g_jdwp_tcp_client_connect(GJdwpTcpClient *); + +/* Attend le signalement de données à traiter. */ +static bool g_jdwp_tcp_client_poll(GJdwpTcpClient *); + +/* Envoie un paquet de données à un serveur de débogage. */ +static bool g_jdwp_tcp_client_send_packet(GJdwpTcpClient *, const GJdwpPacket *); + +/* Réceptionne un paquet de données d'un serveur de débogage. */ +static bool g_jdwp_tcp_client_recv_packet(GJdwpTcpClient *, GJdwpPacket *); + + + +/* Indique le type défini pour un flux de communication TCP avec un serveur JDWP. */ +G_DEFINE_TYPE(GJdwpTcpClient, g_jdwp_tcp_client, G_TYPE_DEBUG_STREAM); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des flux de communication JVDP over TCP.* +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_jdwp_tcp_client_class_init(GJdwpTcpClientClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : client = instance à initialiser.                             * +*                                                                             * +*  Description : Initialise une instance de flux de communication avec JDWP.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_jdwp_tcp_client_init(GJdwpTcpClient *client) +{ +    GDebugStream *stream;                   /* Version parente             */ + +    stream = G_DEBUG_STREAM(client); + +    stream->connect = (debug_connect_fc)g_jdwp_tcp_client_connect; + +    stream->poll = (debug_poll_fc)g_jdwp_tcp_client_poll; +    stream->send_packet = (debug_pkt_op_fc)g_jdwp_tcp_client_send_packet; +    stream->recv_packet = (debug_pkt_op_fc)g_jdwp_tcp_client_recv_packet; + +    stream->pkt_type = G_TYPE_JDWP_PACKET; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : server = nom ou adresse du serveur à contacter.              * +*                port   = port de connexion.                                  * +*                                                                             * +*  Description : Crée une nouvelle connexion TCP à un serveur JDWP.           * +*                                                                             * +*  Retour      : Adresse de la structure mise en place.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GDebugStream *g_jdwp_tcp_client_new(const char *server, const char *port) +{ +    GJdwpTcpClient *result;                 /* Structure à retourner       */ + +    result = g_object_new(G_TYPE_JDWP_TCP_CLIENT, NULL); + +    result->server = strdup(server); +    result->port = strdup(port); +    result->fd = -1; + +    return G_DEBUG_STREAM(result); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : client = paramètres de connexion au serveur JDWP.            * +*                                                                             * +*  Description : Etablit de façon effective une connexion à la cible.         * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_jdwp_tcp_client_connect(GJdwpTcpClient *client) +{ +    struct sockaddr_in addr;                /* Infos de connexion distante */ +    int sock;                               /* Flux ouvert à construire    */ +    char handshake[15];                     /* Poignée de main chaleureuse */ + +    sock = connect_via_tcp(client->server, client->port, &addr); +    if (sock == -1) +    { +        printf("Echec de connexion au serveur JDWP sur %s:%s\n", +               client->server, client->port); +        return false; +    } + +    printf("Connecté à %s:%hd\n", client->server, ntohs(addr.sin_port)); + +    if (send(sock, "JDWP-Handshake", 14, 0) != 14) +        goto gjtcc_error; + +    if (recv(sock, handshake, 14, 0) != 14) +        goto gjtcc_error; + +    if (strncmp(handshake, "JDWP-Handshake", 14) != 0) +        goto gjtcc_error; + +    client->fd = sock; + +    return true; + + gjtcc_error: + +    printf("Echec des premiers échanges !\n"); + +    close(sock); + +    return false; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : client = paramètres de connexion au serveur JDWP.            * +*                                                                             * +*  Description : Attend le signalement de données à traiter.                  * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_jdwp_tcp_client_poll(GJdwpTcpClient *client) +{ +    bool result;                            /* Statut à faire remonter     */ +    fd_set rfds;                            /* Liste des flux à surveiller */ +    int ret;                                /* Bilan d'un appel            */ + +    result = false; + +    FD_ZERO(&rfds); +    FD_SET(client->fd, &rfds); + +    ret = select(client->fd + 1, &rfds, NULL, NULL, NULL); + +    switch (ret) +    { +            case -1: +                perror("select()"); +                break; + +            case 0: +                /* ?! */ +                break; + +            default: +                result = true; +                break; + +    } + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : client = flux ouvert en écriture à utiliser.                 * +*                packet = zone mémoire à parcourir.                           * +*                                                                             * +*  Description : Envoie un paquet de données à un serveur de débogage.        * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_jdwp_tcp_client_send_packet(GJdwpTcpClient *client, const GJdwpPacket *packet) +{ +    struct iovec iov[UIO_MAXIOV];           /* Table de vecteurs à écrire  */ +    int iovcnt;                             /* Quantité de champs valides  */ +    int i;                                  /* Boucle de parcours          */ + +    g_debug_packet_vectorize(G_DEBUG_PACKET(packet), iov, &iovcnt); + +    for (i = 0; i < iovcnt; i++) +        if (send(client->fd, iov[i].iov_base, iov[i].iov_len, 0) != iov[i].iov_len) +            return false; + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : client = flux ouvert en lecture à utiliser.                  * +*                packet = zone mémoire à remplir. [OUT]                       * +*                                                                             * +*  Description : Réceptionne un paquet de données d'un serveur de débogage.   * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_jdwp_tcp_client_recv_packet(GJdwpTcpClient *client, GJdwpPacket *packet) +{ +    bin_t *hblob;                           /* Contenu encodé en B.E.      */ +    jdwp_header *header;                    /* En-tête à reconstituer      */ +    uint32_t length;                        /* Taille de la charge utile   */ +    bin_t *pblob;                           /* Contenu encodé en B.E.      */ + +    hblob = g_jdwp_packet_get_hblob(packet); + +    if (recv(client->fd, hblob, sizeof(jdwp_header), 0) != sizeof(jdwp_header)) +        return false; + +    if (!g_jdwp_packet_parse_header(packet)) +        return false; + +    header = g_jdwp_packet_get_header(packet); +    length = header->length - sizeof(jdwp_header); + +    pblob = g_jdwp_packet_get_pblob(packet); + +    if (recv(client->fd, pblob, length, 0) != length) +        return false; + +    return true; + +} diff --git a/src/debug/jdwp/tcp.h b/src/debug/jdwp/tcp.h new file mode 100644 index 0000000..74487d6 --- /dev/null +++ b/src/debug/jdwp/tcp.h @@ -0,0 +1,56 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * tcp.h - prototypes pour la gestion des connexions TCP aux serveurs JDWP. + * + * 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_JDWP_TCP_H +#define _DEBUG_JDWP_TCP_H + + +#include "../stream.h" + + + +#define G_TYPE_JDWP_TCP_CLIENT               g_jdwp_tcp_client_get_type() +#define G_JDWP_TCP_CLIENT(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_jdwp_tcp_client_get_type(), GJdwpTcpClient)) +#define G_IS_JDWP_TCP_CLIENT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_jdwp_tcp_client_get_type())) +#define G_JDWP_TCP_CLIENT_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_JDWP_TCP_CLIENT, GJdwpTcpClientClass)) +#define G_IS_JDWP_TCP_CLIENT_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_JDWP_TCP_CLIENT)) +#define G_JDWP_TCP_CLIENT_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_JDWP_TCP_CLIENT, GJdwpTcpClientClass)) + + +/* Flux de communication TCP avec un serveur JDWP (instance) */ +typedef struct _GJdwpTcpClient GJdwpTcpClient; + +/* Flux de communication TCP avec un serveur JDWP (classe) */ +typedef struct _GJdwpTcpClientClass GJdwpTcpClientClass; + + + +/* Indique le type défini pour un flux de communication TCP avec un serveur JDWP. */ +GType g_jdwp_tcp_client_get_type(void); + +/* Crée une nouvelle connexion TCP à un serveur JDWP. */ +GDebugStream *g_jdwp_tcp_client_new(const char *, const char *); + + + +#endif  /* _DEBUG_JDWP_TCP_H */ diff --git a/src/debug/packet-int.h b/src/debug/packet-int.h new file mode 100644 index 0000000..016b5d3 --- /dev/null +++ b/src/debug/packet-int.h @@ -0,0 +1,60 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * packet.h - prototypes pour la définition interne des paquets utiles au débogage + * + * 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_PACKET_INT_H +#define _DEBUG_PACKET_INT_H + + +#include "packet.h" + + +#include "../common/dllist.h" + + + +/* Précise les zones mémoires correspondant au contenu. */ +typedef void (* debug_vectorize_fc) (GDebugPacket *, struct iovec [UIO_MAXIOV], int *); + + +/* Répresentation d'un paquet de débogage (instance) */ +struct _GDebugPacket +{ +    GObject parent;                         /* A laisser en premier        */ + +    DL_LIST_ITEM(link);                     /* Lien vers les autres        */ + +    debug_vectorize_fc vectorize;           /* Découpage des données       */ + +}; + + +/* Répresentation d'un paquet de débogage (classe) */ +struct _GDebugPacketClass +{ +    GObjectClass parent;                    /* A laisser en premier        */ + +}; + + + +#endif  /* _DEBUG_PACKET_INT_H */ diff --git a/src/debug/packet.c b/src/debug/packet.c new file mode 100644 index 0000000..9a7df58 --- /dev/null +++ b/src/debug/packet.c @@ -0,0 +1,161 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * packet.c - définition des paquets issus des protocoles de débogage + * + * 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 "packet.h" + + +#include "packet-int.h" + + + +/* Initialise la classe des paquets de débogage. */ +static void g_debug_packet_class_init(GDebugPacketClass *); + +/* Initialise une instance de paquet de débogage. */ +static void g_debug_packet_init(GDebugPacket *); + + + +/* Indique le type défini pour un paquet de débogage. */ +G_DEFINE_TYPE(GDebugPacket, g_debug_packet, G_TYPE_OBJECT); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des paquets de débogage.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_debug_packet_class_init(GDebugPacketClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : packet = instance à initialiser.                             * +*                                                                             * +*  Description : Initialise une instance de paquet de débogage.               * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_debug_packet_init(GDebugPacket *packet) +{ +    DL_LIST_ITEM_INIT(&packet->link); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : packet = instance à convertir.                               * +*                iov    = table de vecteurs. [OUT]                            * +*                iovcnt = quantité de champs renseignés. [OUT]                * +*                                                                             * +*  Description : Précise les zones mémoires correspondant au contenu.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_debug_packet_vectorize(GDebugPacket *packet, struct iovec iov[UIO_MAXIOV], int *iovcnt) +{ +    packet->vectorize(packet, iov, iovcnt); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : list = liste de paquets à consulter.                         * +*              : iter = position actuelle dans la liste.                      * +*                                                                             * +*  Description : Fournit l'élement suivant un autre pour un parcours.         * +*                                                                             * +*  Retour      : Elément suivant ou NULL si aucun.                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GDebugPacket *g_debug_packet_get_next_iter(const GDebugPacket *list, const GDebugPacket *iter) +{ +    GDebugPacket *result;                   /* Elément suivant à renvoyer  */ + +    result = dl_list_next_iter(iter, list, GDebugPacket, link); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : list = liste de paquets à compléter.                         * +*                item = paquet à ajouter à la liste.                          * +*                                                                             * +*  Description : Ajoute un paquet à une liste de paquets.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_debug_packet_push(GDebugPacket **list, GDebugPacket *item) +{ +    dl_list_push(item, list, GDebugPacket, link); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : list = liste de paquets à consulter.                         * +*                                                                             * +*  Description : Retire et fournit le premier élément d'une liste de paquets. * +*                                                                             * +*  Retour      : Elément dépilé de la liste de paquets.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GDebugPacket *g_debug_packet_pop(GDebugPacket **list) +{ +    return dl_list_pop(list, GDebugPacket, link); + +} diff --git a/src/debug/packet.h b/src/debug/packet.h new file mode 100644 index 0000000..c3d45a5 --- /dev/null +++ b/src/debug/packet.h @@ -0,0 +1,66 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * packet.h - prototypes pour la définition des paquets issus des protocoles de débogage + * + * 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_PACKET_H +#define _DEBUG_PACKET_H + + +#include <glib-object.h> +#include <sys/uio.h> + + + +#define G_TYPE_DEBUG_PACKET               g_debug_packet_get_type() +#define G_DEBUG_PACKET(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_debug_packet_get_type(), GDebugPacket)) +#define G_IS_DEBUG_PACKET(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_debug_packet_get_type())) +#define G_DEBUG_PACKET_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DEBUG_PACKET, GDebugPacketClass)) +#define G_IS_DEBUG_PACKET_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DEBUG_PACKET)) +#define G_DEBUG_PACKET_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DEBUG_PACKET, GDebugPacketClass)) + + +/* Répresentation d'un paquet de débogage (instance) */ +typedef struct _GDebugPacket GDebugPacket; + +/* Répresentation d'un paquet de débogage (classe) */ +typedef struct _GDebugPacketClass GDebugPacketClass; + + + +/* Indique le type défini pour un paquet de débogage. */ +GType g_debug_packet_get_type(void); + +/* Précise les zones mémoires correspondant au contenu. */ +void g_debug_packet_vectorize(GDebugPacket *, struct iovec [UIO_MAXIOV], int *); + +/* Fournit l'élement suivant un autre pour un parcours. */ +GDebugPacket *g_debug_packet_get_next_iter(const GDebugPacket *, const GDebugPacket *); + +/* Ajoute un paquet à une liste de paquets. */ +void g_debug_packet_push(GDebugPacket **, GDebugPacket *); + +/* Retire et fournit le premier élément d'une liste de paquets. */ +GDebugPacket *g_debug_packet_pop(GDebugPacket **); + + + +#endif  /* _DEBUG_PACKET_H */ diff --git a/src/debug/remgdb/tcp.c b/src/debug/remgdb/tcp.c index fa97f8c..6c6b78b 100644 --- a/src/debug/remgdb/tcp.c +++ b/src/debug/remgdb/tcp.c @@ -35,6 +35,8 @@  #include "stream-int.h" +#include "../../common/net.h" +  /* Flux de communication TCP avec un serveur GDB (instance) */  struct _GGdbTcpClient @@ -59,7 +61,7 @@ static void g_gdb_tcp_client_class_init(GGdbTcpClientClass *);  static void g_gdb_tcp_client_init(GGdbTcpClient *);  /* Ouvre une connexion TCP à un serveur GDB. */ -static int connect_via_tcp(const char *, const char *); +//static int connect_via_tcp(const char *, const char *);  /* Envoie des données à un serveur GDB. */  static bool g_gdb_tcp_client_send_data(GGdbTcpClient *, const char *, size_t); @@ -127,7 +129,7 @@ static void g_gdb_tcp_client_init(GGdbTcpClient *client)  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ - +#if 0  static int connect_via_tcp(const char *server, const char *port)  {      int result;                             /* Bilan à retourner           */ @@ -181,7 +183,7 @@ static int connect_via_tcp(const char *server, const char *port)      return result;  } - +#endif  /******************************************************************************  *                                                                             * @@ -201,7 +203,7 @@ GGdbStream *g_gdb_tcp_client_new(const char *server, const char *port)      GGdbTcpClient *result;                  /* Structure à retourner       */      int sock;                               /* Flux ouvert à construire    */ -    sock = connect_via_tcp(server, port); +    sock = connect_via_tcp(server, port, NULL);      if (sock == -1) return NULL;      result = g_object_new(G_TYPE_GDB_TCP_CLIENT, NULL); diff --git a/src/debug/stream-int.h b/src/debug/stream-int.h new file mode 100644 index 0000000..6250522 --- /dev/null +++ b/src/debug/stream-int.h @@ -0,0 +1,86 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * stream-int.h - prototypes internes pour la gestion des connexions liées aux débogages. + * + * 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_STREAM_INT_H +#define _DEBUG_STREAM_INT_H + + +#include "stream.h" + + + +/* Etablit de façon effective une connexion à la cible. */ +typedef bool (* debug_connect_fc) (GDebugStream *); + + + +/* Attend le signalement de données à traiter. */ +typedef bool (* debug_poll_fc) (GDebugStream *); + +/* Réceptionne un paquet de données d'un serveur de débogage. */ +typedef bool (* debug_pkt_op_fc) (GDebugStream *, GDebugPacket *); + + + + +/* Envoie des données à un serveur de débogage. */ +typedef bool (* send_debug_data_fc) (GDebugStream *, const char *, size_t); + +/* Réceptionne un octet de donnée d'un serveur de débogage. */ +typedef bool (* recv_debug_byte_fc) (GDebugStream *, char *); + + +/* Flux de communication avec un serveur de débogage (instance) */ +struct _GDebugStream +{ +    GObject parent;                         /* A laisser en premier        */ + +    debug_connect_fc connect;               /* Connexion distante          */ + +    debug_poll_fc poll;                     /* Attente de traitements      */ +    debug_pkt_op_fc send_packet;            /* Emission d'un paquet        */ +    debug_pkt_op_fc recv_packet;            /* Réception d'un paquet       */ + +    GThread *listening;                     /* Thread pour les réceptions  */ + +    GType pkt_type;                         /* Type des paquets traités    */ +    GDebugPacket *free_packets;             /* Liste des disponibles       */ +    GMutex *free_mutex;                     /* Accès à la liste            */ + +    GDebugPacket *recv_packets;             /* Liste des paquets reçus     */ +    GCond *recv_cond;                       /* Attente de disponibilité    */ +    GMutex *recv_mutex;                     /* Accès à la liste            */ + +}; + + +/* Flux de communication avec un serveur de débogage (classe) */ +struct _GDebugStreamClass +{ +    GObjectClass parent;                    /* A laisser en premier        */ + +}; + + + +#endif  /* _DEBUG_STREAM_INT_H */ diff --git a/src/debug/stream.c b/src/debug/stream.c new file mode 100644 index 0000000..4c4767a --- /dev/null +++ b/src/debug/stream.c @@ -0,0 +1,298 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * stream.c - gestion des connexions aux serveurs de débogage. + * + * 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 "stream.h" + + +#include <stdio.h> +#include <stdlib.h> +#include <glib/gthread.h> + + +#include "stream-int.h" +#include "../common/dllist.h"   /* FIXME : remme ! */ + + + +/* Initialise la classe des flux de communication de débogage. */ +static void g_debug_stream_class_init(GDebugStreamClass *); + +/* Initialise une instance de flux de communication de débogage. */ +static void g_debug_stream_init(GDebugStream *); + +/* Ecoute une connexion à un serveur de débogage. */ +static void *debug_stream_thread(GDebugStream *); + +/* Réceptionne un paquet d'un serveur de débogage. */ +static bool g_debug_stream_read_packet(GDebugStream *, GDebugPacket *); + + + +/* Indique le type défini pour un flux de communication avec un serveur de débogage. */ +G_DEFINE_TYPE(GDebugStream, g_debug_stream, G_TYPE_OBJECT); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des flux de communication de débogage.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_debug_stream_class_init(GDebugStreamClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : stream = instance à initialiser.                             * +*                                                                             * +*  Description : Initialise une instance de flux de communication de débogage.* +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_debug_stream_init(GDebugStream *stream) +{ +    stream->free_mutex = g_mutex_new(); + +    stream->recv_cond = g_cond_new(); +    stream->recv_mutex = g_mutex_new(); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : stream = paramètres de connexion distante.                   * +*                                                                             * +*  Description : Etablit de façon effective une connexion à la cible.         * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_debug_stream_connect(GDebugStream *stream) +{ +    GError *error;                          /* Bilan de création de thread */ + +    if (stream->connect == NULL || !stream->connect(stream)) +        return false; + +    if (!g_thread_create((GThreadFunc)debug_stream_thread, stream, FALSE, &error)) +    { +        /* TODO : disconnect ! */ +        return false; +    } + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : stream = encadrement associée à l'opération.                 * +*                                                                             * +*  Description : Ecoute une connexion à un serveur de débogage.               * +*                                                                             * +*  Retour      : ???                                                          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void *debug_stream_thread(GDebugStream *stream) +{ +    bool status;                            /* Bilan d'évolution           */ +    GDebugPacket *packet;                   /* Nouveau paquet reçu         */ + +    while (1) +    { +        status = stream->poll(stream); +        if (!status) break; + +        packet = g_debug_stream_get_free_packet(stream); + +        if (stream->recv_packet(stream, packet)) +        { +            g_mutex_lock(stream->recv_mutex); +            g_debug_packet_push(&stream->recv_packets, packet); +            g_mutex_unlock(stream->recv_mutex); + +            g_cond_signal(stream->recv_cond); + +        } +        else g_debug_stream_mark_packet_as_free(stream, packet); + +    } + +    return NULL; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : stream = flux de communication de débogage à consulter.      * +*                                                                             * +*  Description : Fournit un paquet prêt à emploi.                             * +*                                                                             * +*  Retour      : Paquet prêt à emploi.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GDebugPacket *g_debug_stream_get_free_packet(GDebugStream *stream) +{ +    GDebugPacket *result;                   /* Paquet à retourner          */ + +    g_mutex_lock(stream->free_mutex); + +    if (dl_list_empty(stream->free_packets)) +        result = g_object_new(stream->pkt_type, NULL); + +    else +        result = g_debug_packet_pop(&stream->free_packets); + +    g_mutex_unlock(stream->free_mutex); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : stream = flux de communication de débogage à mettre à jour.  * +*                packet = paquet à considérer comme disponible.               * +*                                                                             * +*  Description : Place un paquet en attente d'une future utilisation.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_debug_stream_mark_packet_as_free(GDebugStream *stream, GDebugPacket *packet) +{ +    g_mutex_lock(stream->free_mutex); + +    g_debug_packet_push(&stream->free_packets, packet); + +    g_mutex_unlock(stream->free_mutex); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : stream = flux ouvert en écriture à mettre à jour.            * +*                packet = données à transmettre.                              * +*                                                                             * +*  Description : Envoie un paquet à un serveur de débogage.                   * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_debug_stream_send_packet(GDebugStream *stream, GDebugPacket *packet) +{ +    bool result;                            /* Bilan à retourner           */ + +    result = stream->send_packet(stream, packet); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : stream = flux de communication de débogage à consulter.      * +*                filter = éventuelle fonction de sélection du paquet.         * +*                data   = éventuelle donnée à associer au filtrage.           * +*                                                                             * +*  Description : Fournit un paquet reçu d'un serveur de débogage.             * +*                                                                             * +*  Retour      : Paquet de débogage.                                          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GDebugPacket *g_debug_stream_recv_packet(GDebugStream *stream, filter_packet_fc filter, void *data) +{ +    GDebugPacket *result;                   /* Paquet à retourner          */ + +    g_mutex_lock(stream->recv_mutex); + +    if (filter != NULL) +    { + gdsrp_try_again: + +        for (result = stream->recv_packets; +             result != NULL; +             result = g_debug_packet_get_next_iter(stream->recv_packets, result)) +        { +            if (filter(result, data)) +                break; +        } + +        if (result == NULL) +        { +            g_cond_wait(stream->recv_cond, stream->recv_mutex); +            goto gdsrp_try_again; +        } + +    } +    else +    { +        if (dl_list_empty(stream->recv_packets)) +            g_cond_wait(stream->recv_cond, stream->recv_mutex); + +        result = g_debug_packet_pop(&stream->recv_packets); + +    } + +    g_mutex_unlock(stream->recv_mutex); + +    return result; + +} diff --git a/src/debug/stream.h b/src/debug/stream.h new file mode 100644 index 0000000..c0d342d --- /dev/null +++ b/src/debug/stream.h @@ -0,0 +1,74 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * stream.h - prototypes pour la gestion des connexions aux serveurs de débogage. + * + * 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_STREAM_H +#define _DEBUG_STREAM_H + + +#include <stdbool.h> + + +#include "packet.h" + + + +#define G_TYPE_DEBUG_STREAM               g_debug_stream_get_type() +#define G_DEBUG_STREAM(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_debug_stream_get_type(), GDebugStream)) +#define G_IS_DEBUG_STREAM(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_debug_stream_get_type())) +#define G_DEBUG_STREAM_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DEBUG_STREAM, GDebugStreamClass)) +#define G_IS_DEBUG_STREAM_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DEBUG_STREAM)) +#define G_DEBUG_STREAM_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DEBUG_STREAM, GDebugStreamClass)) + + +/* Flux de communication avec un serveur de débogage (instance) */ +typedef struct _GDebugStream GDebugStream; + +/* Flux de communication avec un serveur de débogage (classe) */ +typedef struct _GDebugStreamClass GDebugStreamClass; + + +/* Filtre la récupération de paquet */ +typedef bool (* filter_packet_fc) (const GDebugPacket *, void *); + + +/* Indique le type défini pour un flux de communication avec un serveur de débogage. */ +GType g_debug_stream_get_type(void); + +/* Etablit de façon effective une connexion à la cible. */ +bool g_debug_stream_connect(GDebugStream *); + +/* Fournit un paquet prêt à emploi. */ +GDebugPacket *g_debug_stream_get_free_packet(GDebugStream *); + +/* Place un paquet en attente d'une future utilisation. */ +void g_debug_stream_mark_packet_as_free(GDebugStream *, GDebugPacket *); + +/* Envoie un paquet à un serveur de débogage. */ +bool g_debug_stream_send_packet(GDebugStream *, GDebugPacket *); + +/* Fournit un paquet reçu d'un serveur de débogage. */ +GDebugPacket *g_debug_stream_recv_packet(GDebugStream *, filter_packet_fc, void *); + + + +#endif  /* _DEBUG_STREAM_H */  | 
