diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2010-12-31 11:49:34 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2010-12-31 11:49:34 (GMT) |
commit | 651c94450df8619c26e26a133289dbaa197616f4 (patch) | |
tree | 1a81a2625687116d205cb5c6583497cb657f8460 /src/debug/jdwp | |
parent | dbec8e8af5f296f0b95cd9c07e7d96b1a4277137 (diff) |
Supported a first basic packet of the Java Debug Wire Protocol.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@204 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/debug/jdwp')
-rw-r--r-- | src/debug/jdwp/Makefile.am | 23 | ||||
-rw-r--r-- | src/debug/jdwp/debugger.c | 204 | ||||
-rw-r--r-- | src/debug/jdwp/debugger.h | 61 | ||||
-rw-r--r-- | src/debug/jdwp/jdwp_def.h | 131 | ||||
-rw-r--r-- | src/debug/jdwp/misc/Makefile.am | 15 | ||||
-rw-r--r-- | src/debug/jdwp/misc/header.c | 172 | ||||
-rw-r--r-- | src/debug/jdwp/misc/header.h | 47 | ||||
-rw-r--r-- | src/debug/jdwp/misc/types.c | 85 | ||||
-rw-r--r-- | src/debug/jdwp/misc/types.h | 44 | ||||
-rw-r--r-- | src/debug/jdwp/packet.c | 348 | ||||
-rw-r--r-- | src/debug/jdwp/packet.h | 87 | ||||
-rw-r--r-- | src/debug/jdwp/sets/Makefile.am | 15 | ||||
-rw-r--r-- | src/debug/jdwp/sets/list.c | 118 | ||||
-rw-r--r-- | src/debug/jdwp/sets/list.h | 54 | ||||
-rw-r--r-- | src/debug/jdwp/sets/vm.c | 97 | ||||
-rw-r--r-- | src/debug/jdwp/sets/vm.h | 44 | ||||
-rw-r--r-- | src/debug/jdwp/tcp.c | 328 | ||||
-rw-r--r-- | src/debug/jdwp/tcp.h | 56 |
18 files changed, 1929 insertions, 0 deletions
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 */ |