From 648bf475951e6d588d13539441d8a0e54eab2706 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 7 Dec 2018 22:04:46 +0100 Subject: Moved some core features into plugins. --- configure.ac | 6 +- plugins/gdbrsp/Makefile.am | 29 + plugins/gdbrsp/aops.h | 57 + plugins/gdbrsp/gdb-int.h | 116 ++ plugins/gdbrsp/gdb.c | 1524 +++++++++++++++++++++++++ plugins/gdbrsp/gdb.h | 61 + plugins/gdbrsp/helpers.c | 224 ++++ plugins/gdbrsp/helpers.h | 62 + plugins/gdbrsp/helpers_arm.c | 252 ++++ plugins/gdbrsp/helpers_arm.h | 37 + plugins/gdbrsp/helpers_arm64.c | 97 ++ plugins/gdbrsp/helpers_arm64.h | 40 + plugins/gdbrsp/packet.c | 389 +++++++ plugins/gdbrsp/packet.h | 82 ++ plugins/gdbrsp/python/Makefile.am | 19 + plugins/gdbrsp/python/gdb.c | 173 +++ plugins/gdbrsp/python/gdb.h | 42 + plugins/gdbrsp/python/module.c | 94 ++ plugins/gdbrsp/python/module.h | 42 + plugins/gdbrsp/stream-int.h | 89 ++ plugins/gdbrsp/stream.c | 696 +++++++++++ plugins/gdbrsp/stream.h | 68 ++ plugins/gdbrsp/support.c | 598 ++++++++++ plugins/gdbrsp/support.h | 73 ++ plugins/gdbrsp/target.c | 950 +++++++++++++++ plugins/gdbrsp/target.h | 72 ++ plugins/gdbrsp/tcp.c | 280 +++++ plugins/gdbrsp/tcp.h | 57 + plugins/gdbrsp/utils.c | 354 ++++++ plugins/gdbrsp/utils.h | 58 + plugins/java/Makefile.am | 29 + plugins/java/attribute.c | 717 ++++++++++++ plugins/java/attribute.h | 40 + plugins/java/e_java.c | 284 +++++ plugins/java/e_java.h | 49 + plugins/java/field.c | 158 +++ plugins/java/field.h | 40 + plugins/java/java-int.c | 92 ++ plugins/java/java-int.h | 66 ++ plugins/java/java.c | 508 +++++++++ plugins/java/java.h | 63 + plugins/java/java_def.h | 418 +++++++ plugins/java/method.c | 187 +++ plugins/java/method.h | 44 + plugins/java/pool.c | 474 ++++++++ plugins/java/pool.h | 56 + plugins/jvm/Makefile.am | 35 + plugins/jvm/instruction.c | 299 +++++ plugins/jvm/instruction.h | 151 +++ plugins/jvm/op_add.c | 55 + plugins/jvm/op_const.c | 87 ++ plugins/jvm/op_convert.c | 433 +++++++ plugins/jvm/op_dup.c | 190 +++ plugins/jvm/op_getput.c | 62 + plugins/jvm/op_invoke.c | 128 +++ plugins/jvm/op_load.c | 92 ++ plugins/jvm/op_monitor.c | 82 ++ plugins/jvm/op_nop.c | 55 + plugins/jvm/op_pop.c | 82 ++ plugins/jvm/op_ret.c | 184 +++ plugins/jvm/op_store.c | 60 + plugins/jvm/opcodes.h | 160 +++ plugins/jvm/operand.c | 325 ++++++ plugins/jvm/operand.h | 109 ++ plugins/jvm/processor.c | 400 +++++++ plugins/jvm/processor.h | 55 + plugins/pychrysalide/debug/Makefile.am | 5 +- plugins/pychrysalide/debug/gdbrsp/Makefile.am | 19 - plugins/pychrysalide/debug/gdbrsp/gdb.c | 173 --- plugins/pychrysalide/debug/gdbrsp/gdb.h | 42 - plugins/pychrysalide/debug/gdbrsp/module.c | 94 -- plugins/pychrysalide/debug/gdbrsp/module.h | 42 - plugins/pychrysalide/debug/module.c | 5 - src/arch/Makefile.am | 8 - src/arch/jvm/Makefile.am | 35 - src/arch/jvm/instruction.c | 299 ----- src/arch/jvm/instruction.h | 151 --- src/arch/jvm/op_add.c | 55 - src/arch/jvm/op_const.c | 87 -- src/arch/jvm/op_convert.c | 433 ------- src/arch/jvm/op_dup.c | 190 --- src/arch/jvm/op_getput.c | 62 - src/arch/jvm/op_invoke.c | 128 --- src/arch/jvm/op_load.c | 92 -- src/arch/jvm/op_monitor.c | 82 -- src/arch/jvm/op_nop.c | 55 - src/arch/jvm/op_pop.c | 82 -- src/arch/jvm/op_ret.c | 184 --- src/arch/jvm/op_store.c | 60 - src/arch/jvm/opcodes.h | 160 --- src/arch/jvm/operand.c | 325 ------ src/arch/jvm/operand.h | 109 -- src/arch/jvm/processor.c | 400 ------- src/arch/jvm/processor.h | 55 - src/debug/Makefile.am | 5 +- src/debug/gdbrsp/Makefile.am | 29 - src/debug/gdbrsp/aops.h | 57 - src/debug/gdbrsp/gdb-int.h | 116 -- src/debug/gdbrsp/gdb.c | 1524 ------------------------- src/debug/gdbrsp/gdb.h | 61 - src/debug/gdbrsp/helpers.c | 224 ---- src/debug/gdbrsp/helpers.h | 62 - src/debug/gdbrsp/helpers_arm.c | 252 ---- src/debug/gdbrsp/helpers_arm.h | 37 - src/debug/gdbrsp/helpers_arm64.c | 97 -- src/debug/gdbrsp/helpers_arm64.h | 40 - src/debug/gdbrsp/packet.c | 389 ------- src/debug/gdbrsp/packet.h | 82 -- src/debug/gdbrsp/stream-int.h | 89 -- src/debug/gdbrsp/stream.c | 696 ----------- src/debug/gdbrsp/stream.h | 68 -- src/debug/gdbrsp/support.c | 598 ---------- src/debug/gdbrsp/support.h | 73 -- src/debug/gdbrsp/target.c | 950 --------------- src/debug/gdbrsp/target.h | 72 -- src/debug/gdbrsp/tcp.c | 280 ----- src/debug/gdbrsp/tcp.h | 57 - src/debug/gdbrsp/utils.c | 354 ------ src/debug/gdbrsp/utils.h | 58 - src/format/Makefile.am | 2 +- src/format/java/Makefile.am | 29 - src/format/java/attribute.c | 717 ------------ src/format/java/attribute.h | 40 - src/format/java/e_java.c | 284 ----- src/format/java/e_java.h | 49 - src/format/java/field.c | 158 --- src/format/java/field.h | 40 - src/format/java/java-int.c | 92 -- src/format/java/java-int.h | 66 -- src/format/java/java.c | 508 --------- src/format/java/java.h | 63 - src/format/java/java_def.h | 418 ------- src/format/java/method.c | 187 --- src/format/java/method.h | 44 - src/format/java/pool.c | 474 -------- src/format/java/pool.h | 56 - 136 files changed, 12912 insertions(+), 12927 deletions(-) create mode 100644 plugins/gdbrsp/Makefile.am create mode 100644 plugins/gdbrsp/aops.h create mode 100644 plugins/gdbrsp/gdb-int.h create mode 100644 plugins/gdbrsp/gdb.c create mode 100644 plugins/gdbrsp/gdb.h create mode 100644 plugins/gdbrsp/helpers.c create mode 100644 plugins/gdbrsp/helpers.h create mode 100644 plugins/gdbrsp/helpers_arm.c create mode 100644 plugins/gdbrsp/helpers_arm.h create mode 100644 plugins/gdbrsp/helpers_arm64.c create mode 100644 plugins/gdbrsp/helpers_arm64.h create mode 100644 plugins/gdbrsp/packet.c create mode 100644 plugins/gdbrsp/packet.h create mode 100644 plugins/gdbrsp/python/Makefile.am create mode 100644 plugins/gdbrsp/python/gdb.c create mode 100644 plugins/gdbrsp/python/gdb.h create mode 100644 plugins/gdbrsp/python/module.c create mode 100644 plugins/gdbrsp/python/module.h create mode 100644 plugins/gdbrsp/stream-int.h create mode 100644 plugins/gdbrsp/stream.c create mode 100644 plugins/gdbrsp/stream.h create mode 100644 plugins/gdbrsp/support.c create mode 100644 plugins/gdbrsp/support.h create mode 100644 plugins/gdbrsp/target.c create mode 100644 plugins/gdbrsp/target.h create mode 100644 plugins/gdbrsp/tcp.c create mode 100644 plugins/gdbrsp/tcp.h create mode 100644 plugins/gdbrsp/utils.c create mode 100644 plugins/gdbrsp/utils.h create mode 100644 plugins/java/Makefile.am create mode 100644 plugins/java/attribute.c create mode 100644 plugins/java/attribute.h create mode 100644 plugins/java/e_java.c create mode 100644 plugins/java/e_java.h create mode 100644 plugins/java/field.c create mode 100644 plugins/java/field.h create mode 100644 plugins/java/java-int.c create mode 100644 plugins/java/java-int.h create mode 100644 plugins/java/java.c create mode 100644 plugins/java/java.h create mode 100644 plugins/java/java_def.h create mode 100644 plugins/java/method.c create mode 100644 plugins/java/method.h create mode 100644 plugins/java/pool.c create mode 100644 plugins/java/pool.h create mode 100644 plugins/jvm/Makefile.am create mode 100644 plugins/jvm/instruction.c create mode 100644 plugins/jvm/instruction.h create mode 100644 plugins/jvm/op_add.c create mode 100644 plugins/jvm/op_const.c create mode 100644 plugins/jvm/op_convert.c create mode 100644 plugins/jvm/op_dup.c create mode 100644 plugins/jvm/op_getput.c create mode 100644 plugins/jvm/op_invoke.c create mode 100644 plugins/jvm/op_load.c create mode 100644 plugins/jvm/op_monitor.c create mode 100644 plugins/jvm/op_nop.c create mode 100644 plugins/jvm/op_pop.c create mode 100644 plugins/jvm/op_ret.c create mode 100644 plugins/jvm/op_store.c create mode 100644 plugins/jvm/opcodes.h create mode 100644 plugins/jvm/operand.c create mode 100644 plugins/jvm/operand.h create mode 100644 plugins/jvm/processor.c create mode 100644 plugins/jvm/processor.h delete mode 100644 plugins/pychrysalide/debug/gdbrsp/Makefile.am delete mode 100644 plugins/pychrysalide/debug/gdbrsp/gdb.c delete mode 100644 plugins/pychrysalide/debug/gdbrsp/gdb.h delete mode 100644 plugins/pychrysalide/debug/gdbrsp/module.c delete mode 100644 plugins/pychrysalide/debug/gdbrsp/module.h delete mode 100644 src/arch/jvm/Makefile.am delete mode 100644 src/arch/jvm/instruction.c delete mode 100644 src/arch/jvm/instruction.h delete mode 100644 src/arch/jvm/op_add.c delete mode 100644 src/arch/jvm/op_const.c delete mode 100644 src/arch/jvm/op_convert.c delete mode 100644 src/arch/jvm/op_dup.c delete mode 100644 src/arch/jvm/op_getput.c delete mode 100644 src/arch/jvm/op_invoke.c delete mode 100644 src/arch/jvm/op_load.c delete mode 100644 src/arch/jvm/op_monitor.c delete mode 100644 src/arch/jvm/op_nop.c delete mode 100644 src/arch/jvm/op_pop.c delete mode 100644 src/arch/jvm/op_ret.c delete mode 100644 src/arch/jvm/op_store.c delete mode 100644 src/arch/jvm/opcodes.h delete mode 100644 src/arch/jvm/operand.c delete mode 100644 src/arch/jvm/operand.h delete mode 100644 src/arch/jvm/processor.c delete mode 100644 src/arch/jvm/processor.h delete mode 100644 src/debug/gdbrsp/Makefile.am delete mode 100644 src/debug/gdbrsp/aops.h delete mode 100644 src/debug/gdbrsp/gdb-int.h delete mode 100644 src/debug/gdbrsp/gdb.c delete mode 100644 src/debug/gdbrsp/gdb.h delete mode 100644 src/debug/gdbrsp/helpers.c delete mode 100644 src/debug/gdbrsp/helpers.h delete mode 100644 src/debug/gdbrsp/helpers_arm.c delete mode 100644 src/debug/gdbrsp/helpers_arm.h delete mode 100644 src/debug/gdbrsp/helpers_arm64.c delete mode 100644 src/debug/gdbrsp/helpers_arm64.h delete mode 100644 src/debug/gdbrsp/packet.c delete mode 100644 src/debug/gdbrsp/packet.h delete mode 100644 src/debug/gdbrsp/stream-int.h delete mode 100644 src/debug/gdbrsp/stream.c delete mode 100644 src/debug/gdbrsp/stream.h delete mode 100644 src/debug/gdbrsp/support.c delete mode 100644 src/debug/gdbrsp/support.h delete mode 100644 src/debug/gdbrsp/target.c delete mode 100644 src/debug/gdbrsp/target.h delete mode 100644 src/debug/gdbrsp/tcp.c delete mode 100644 src/debug/gdbrsp/tcp.h delete mode 100644 src/debug/gdbrsp/utils.c delete mode 100644 src/debug/gdbrsp/utils.h delete mode 100644 src/format/java/Makefile.am delete mode 100644 src/format/java/attribute.c delete mode 100644 src/format/java/attribute.h delete mode 100644 src/format/java/e_java.c delete mode 100644 src/format/java/e_java.h delete mode 100644 src/format/java/field.c delete mode 100644 src/format/java/field.h delete mode 100644 src/format/java/java-int.c delete mode 100644 src/format/java/java-int.h delete mode 100644 src/format/java/java.c delete mode 100644 src/format/java/java.h delete mode 100644 src/format/java/java_def.h delete mode 100644 src/format/java/method.c delete mode 100644 src/format/java/method.h delete mode 100644 src/format/java/pool.c delete mode 100644 src/format/java/pool.h diff --git a/configure.ac b/configure.ac index 8450923..3943a2f 100644 --- a/configure.ac +++ b/configure.ac @@ -364,8 +364,11 @@ AC_CONFIG_FILES([Makefile plugins/elf/Makefile plugins/elf/python/Makefile plugins/fmtp/Makefile + plugins/gdbrsp/Makefile + plugins/gdbrsp/python/Makefile plugins/itanium/Makefile plugins/itanium/python/Makefile + plugins/java/Makefile plugins/javadesc/Makefile plugins/javadesc/python/Makefile plugins/libcsem/Makefile @@ -382,7 +385,6 @@ AC_CONFIG_FILES([Makefile plugins/pychrysalide/common/Makefile plugins/pychrysalide/core/Makefile plugins/pychrysalide/debug/Makefile - plugins/pychrysalide/debug/gdbrsp/Makefile plugins/pychrysalide/format/Makefile plugins/pychrysalide/glibext/Makefile plugins/pychrysalide/gtkext/Makefile @@ -411,9 +413,7 @@ AC_CONFIG_FILES([Makefile src/common/Makefile src/core/Makefile src/debug/Makefile - src/debug/gdbrsp/Makefile src/format/Makefile - src/format/java/Makefile src/glibext/Makefile src/glibext/generators/Makefile src/gtkext/Makefile diff --git a/plugins/gdbrsp/Makefile.am b/plugins/gdbrsp/Makefile.am new file mode 100644 index 0000000..5ee8df6 --- /dev/null +++ b/plugins/gdbrsp/Makefile.am @@ -0,0 +1,29 @@ + +noinst_LTLIBRARIES = libdebuggdbrsp.la + +libdebuggdbrsp_la_SOURCES = \ + aops.h \ + gdb-int.h \ + gdb.h gdb.c \ + helpers.h helpers.c \ + helpers_arm.h helpers_arm.c \ + helpers_arm64.h helpers_arm64.c \ + packet.h packet.c \ + stream-int.h \ + stream.h stream.c \ + support.h support.c \ + target.h target.c \ + tcp.h tcp.c \ + utils.h utils.c + +libdebuggdbrsp_la_CFLAGS = $(AM_CFLAGS) + + +devdir = $(includedir)/chrysalide/$(subdir:src/%=%) + +dev_HEADERS = $(libdebuggdbrsp_la_SOURCES:%c=) + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/gdbrsp/aops.h b/plugins/gdbrsp/aops.h new file mode 100644 index 0000000..1599615 --- /dev/null +++ b/plugins/gdbrsp/aops.h @@ -0,0 +1,57 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * aops.h - prototypes pour les compléments utiles à GDB pour l'architecture ARM + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _DEBUG_GDBRSP_AOPS_H +#define _DEBUG_GDBRSP_AOPS_H + + +#include "gdb.h" + + + +/* Détermine le point d'exécution courant. */ +typedef bool (* get_pc_fc) (GGdbDebugger *, virt_t *); + +/* Remonte la pile d'appels jusqu'au point courant. */ +typedef bool (* compute_call_stack_fc) (const GGdbDebugger *, virt_t **, size_t *); + +/* Complète la commande manipulant des points d'arrêt. */ +typedef const char * (* get_bp_kind_fc) (const GGdbDebugger *, virt_t); + +/* Construit une instruction provoquant un arrêt d'exécution. */ +typedef const uint8_t * (* get_bp_data_fc) (const GGdbDebugger *, virt_t, size_t *); + + +/* Procédures spécifiques pour une architecture */ +typedef struct _gdb_arch_ops +{ + get_pc_fc get_pc; /* Obtention du point d'exéc. */ + compute_call_stack_fc compute_cstack; /* Calcule la pile d'appels */ + get_bp_kind_fc get_bp_kind; /* Fournit le type d'un point */ + get_bp_data_fc get_bp_data; /* Code d'un point d'arrêt */ + +} gdb_arch_ops; + + + +#endif /* _DEBUG_GDBRSP_AOPS_H */ diff --git a/plugins/gdbrsp/gdb-int.h b/plugins/gdbrsp/gdb-int.h new file mode 100644 index 0000000..11b4753 --- /dev/null +++ b/plugins/gdbrsp/gdb-int.h @@ -0,0 +1,116 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gdb.h - prototypes pour le débogage à l'aide de gdb. + * + * Copyright (C) 2009-2012 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _DEBUG_GDBRSP_GDB_INT_H +#define _DEBUG_GDBRSP_GDB_INT_H + + +#include "aops.h" +#include "gdb.h" +#include "stream.h" +#include "support.h" +#include "target.h" +#include "../break-int.h" +#include "../debugger-int.h" + + + + + + + + + + +/* Définition d'un point d'arrêt appliqué */ +typedef struct _gdb_breakpoint +{ + raw_breakpoint raw; /* A laisser en premier */ + + bool is_z; /* Usage de commande dédiée ? */ + + union + { + const char *kind; /* Précision de taille */ + + struct + { + uint8_t memory[16]; /* Données d'origine remplacées*/ + size_t len; /* Quantité de ces données */ + }; + + }; + +} gdb_breakpoint; + + + + + + + + + + + + + + +/* Débogueur utilisant un serveur GDB (instance) */ +struct _GGdbDebugger +{ + GBinaryDebugger parent; /* A laisser en premier */ + + SourceEndian endian; /* Boutisme du format */ + MemoryDataSize msize; /* Taille des adresses */ + + const gdb_arch_ops *ops; /* Opérations spécifiques */ + + GGdbStream *stream; /* Flux de communication */ + GGdbSupport *support; /* Configuration à adopter */ + GGdbTarget *target; /* Architecture ciblée par GDB */ + +}; + + +/* Débogueur utilisant un serveur GDB (classe) */ +struct _GGdbDebuggerClass +{ + GBinaryDebuggerClass parent; /* A laisser en premier */ + +}; + + + +/* ------------------------ ACCUEIL D'EVENEMENTS ASYNCHRONES ------------------------ */ + + +/* Réagit à la réception d'un signal par le programme étudié. */ +void g_gdb_debugger_receive_signal_reply(GGdbDebugger *, int); + +/* Réagit à la sortie d'exécution d'un programme étudié. */ +void g_gdb_debugger_receive_exit_reply(GGdbDebugger *, int, pid_t); + + + +#endif /* _DEBUG_GDBRSP_GDB_INT_H */ diff --git a/plugins/gdbrsp/gdb.c b/plugins/gdbrsp/gdb.c new file mode 100644 index 0000000..1d0ffe5 --- /dev/null +++ b/plugins/gdbrsp/gdb.c @@ -0,0 +1,1524 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gdb.c - débogage à l'aide de gdb. + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "gdb.h" + + + +#include +#include +#include +#include +#include + + +#include "gdb-int.h" +#include "helpers.h" +#include "helpers_arm.h" +#include "helpers_arm64.h" +#include "tcp.h" +#include "utils.h" +#include "../../common/cpp.h" +#include "../../format/format.h" + + + + + + + + +/* Initialise la classe du débogueur utilisant gdb. */ +static void g_gdb_debugger_class_init(GGdbDebuggerClass *); + +/* Procède à l'initialisation du débogueur utilisant gdb. */ +static void g_gdb_debugger_init(GGdbDebugger *); + +/* Supprime toutes les références externes. */ +static void g_gdb_debugger_dispose(GGdbDebugger *); + +/* Procède à la libération totale de la mémoire. */ +static void g_gdb_debugger_finalize(GGdbDebugger *); + + +/* Met en marche le débogueur utilisant un serveur GDB. */ +static bool g_gdb_debugger_run(GGdbDebugger *); + +/* Remet en marche le débogueur utilisant un serveur GDB. */ +//static bool g_gdb_debugger_resume(GGdbDebugger *); + +/* Tue le débogueur utilisant un serveur GDB. */ +static bool g_gdb_debugger_kill(GGdbDebugger *); + + + + + + +/* --------------------------- ENTREES / SORTIES BASIQUES --------------------------- */ + + +/* Lit une valeur quelconque à une adresse arbitraire. */ +static bool g_gdb_debugger_read_memory(GGdbDebugger *, virt_t, size_t, ...); + +/* Ecrit une valeur quelconque à une adresse arbitraire. */ +static bool g_gdb_debugger_write_memory(GGdbDebugger *, virt_t, size_t, ...); + +/* Liste l'ensemble des registres appartenant à un groupe. */ +static char **g_gdb_debugger_get_register_names(const GGdbDebugger *, const char *, size_t *); + +/* Indique la taille associée à un registre donné. */ +static unsigned int g_gdb_debugger_get_register_size(const GGdbDebugger *, const char *); + +/* Effectue la lecture d'un registre donné. */ +static bool g_gdb_debugger_read_register(GGdbDebugger *, const char *, size_t, ...); + +/* Effectue l'écriture d'un registre donné. */ +static bool g_gdb_debugger_write_register(GGdbDebugger *, const char *, size_t, ...); + + + +/* ------------------------- MANIPULATION DE L'ETAT COURANT ------------------------- */ + + +/* Détermine le point d'exécution courant. */ +static bool g_gdb_debugger_get_current_pc(GGdbDebugger *, virt_t *); + +/* Remonte la pile d'appels jusqu'au point courant. */ +static bool g_gdb_debugger_compute_call_stack(GGdbDebugger *, virt_t **, size_t *); + + + +/* --------------------------- GESTION DES POINTS D'ARRET --------------------------- */ + + +/* Ajoute un point d'arrêt basique en mémoire. */ +static gdb_breakpoint *g_gdb_debugger_enable_memory_breakpoint(GGdbDebugger *, virt_t); + +/* Retire un point d'arrêt basique en mémoire. */ +static bool g_gdb_debugger_disable_memory_breakpoint(GGdbDebugger *, gdb_breakpoint *); + + + +/* -------------------------- CONTROLE DU FLOT D'EXECUTION -------------------------- */ + + +/* Redémarre le processus de débogage lié à un serveur GDB. */ +static bool g_gdb_debugger_restart(GGdbDebugger *); + +/* Remet en marche le débogueur utilisant un serveur GDB. */ +static bool g_gdb_debugger_resume(GGdbDebugger *); + + + + + + + + + + + + +/* Détermine l'identifiant du thread principal courant. */ +static char *g_gdb_debugger_get_active_thread(GGdbDebugger *); + + + + + + +/* ------------------------ ACCUEIL D'EVENEMENTS ASYNCHRONES ------------------------ */ + + + + + + + + +/* Indique le type défini par la GLib pour le débogueur gdb. */ +G_DEFINE_TYPE(GGdbDebugger, g_gdb_debugger, G_TYPE_BINARY_DEBUGGER); + + +/****************************************************************************** +* * +* Paramètres : klass = classe de débogueur à initialiser. * +* * +* Description : Initialise la classe du débogueur utilisant gdb. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_debugger_class_init(GGdbDebuggerClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GBinaryDebuggerClass *parent; /* Version en classe parente */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_gdb_debugger_dispose; + object->finalize = (GObjectFinalizeFunc)g_gdb_debugger_finalize; + + parent = G_BINARY_DEBUGGER_CLASS(klass); + + parent->read_mem = (read_mem_any_fc)g_gdb_debugger_read_memory; + parent->write_mem = (write_mem_any_fc)g_gdb_debugger_write_memory; + parent->get_reg_names = (get_reg_names_fc)g_gdb_debugger_get_register_names; + parent->get_reg_size = (get_reg_size_fc)g_gdb_debugger_get_register_size; + parent->read_reg = (read_write_reg_any_fc)g_gdb_debugger_read_register; + parent->write_reg = (read_write_reg_any_fc)g_gdb_debugger_write_register; + + parent->get_current_pc = (get_current_pc_fc)g_gdb_debugger_get_current_pc; + parent->get_call_stack = (get_call_stack_fc)g_gdb_debugger_compute_call_stack; + + parent->enable_bp = (enable_mem_bp_fc)g_gdb_debugger_enable_memory_breakpoint; + parent->disable_bp = (disable_mem_bp_fc)g_gdb_debugger_disable_memory_breakpoint; + + parent->restart = (restart_debugger_fc)g_gdb_debugger_restart; + parent->resume = (resume_debugger_fc)g_gdb_debugger_resume; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = instance de débogueur à préparer. * +* * +* Description : Procède à l'initialisation du débogueur utilisant gdb. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_debugger_init(GGdbDebugger *debugger) +{ + GBinaryDebugger *parent; /* Instance parente */ + + parent = G_BINARY_DEBUGGER(debugger); + + parent->run = (basic_debugger_fc)g_gdb_debugger_run; + //parent->resume = (resume_debugger_fc)g_gdb_debugger_resume; + parent->kill = (basic_debugger_fc)g_gdb_debugger_kill; + + //parent->get_reg_values = (get_register_values_fc)get_register_values_using_gdb_debugger; + + //debugger->cond = g_cond_new(); + //debugger->mutex = g_mutex_new(); + + + // FIXME + //debugger->compute_cstack = compute_call_stack_for_arm64; + //debugger->fill_mem_bp = fill_memory_breakpoint_cmd_for_arm64; + + + + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_debugger_dispose(GGdbDebugger *debugger) +{ + if (debugger->stream != NULL) + g_object_unref(G_OBJECT(debugger->stream)); + + if (debugger->support != NULL) + g_object_unref(G_OBJECT(debugger->support)); + + if (debugger->target != NULL) + g_object_unref(G_OBJECT(debugger->target)); + + G_OBJECT_CLASS(g_gdb_debugger_parent_class)->dispose(G_OBJECT(debugger)); + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_debugger_finalize(GGdbDebugger *debugger) +{ + G_OBJECT_CLASS(g_gdb_debugger_parent_class)->finalize(G_OBJECT(debugger)); + +} + + +/****************************************************************************** +* * +* Paramètres : binary = binaire représenter à déboguer. * +* server = nom ou adresse du serveur à contacter. * +* port = port de connexion. * +* * +* Description : Crée un débogueur utilisant un serveur GDB distant. * +* * +* Retour : Instance de débogueur mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinaryDebugger *g_gdb_debugger_new(GLoadedBinary *binary, const char *server, unsigned short port) +{ + GGdbDebugger *result; /* Débogueur à retourner */ + GExeFormat *format; /* Format du binaire chargé */ + const char *arch; /* Architecture d'exécution */ + GArchProcessor *proc; /* Processeur lié au binaire */ + char service[sizeof(XSTR(UINT16_MAX)) + 1]; /* Conversion requise */ + + result = g_object_new(G_TYPE_GDB_DEBUGGER, NULL); + + G_BINARY_DEBUGGER(result)->binary = binary; + g_object_ref(G_OBJECT(binary)); + + /* Propriétés de la cible */ + + format = g_loaded_binary_get_format(binary); + + result->endian = g_binary_format_get_endianness(G_BIN_FORMAT(format)); + + arch = g_exe_format_get_target_machine(format); + + if (strcmp(arch, "armv7") == 0) + result->ops = get_arm_operations(); + else + result->ops = NULL; + + g_object_unref(G_OBJECT(format)); + + if (result->ops == NULL) + goto ggdn_error; + + proc = g_loaded_binary_get_processor(binary); + + result->msize = g_arch_processor_get_memory_size(proc); + + g_object_unref(G_OBJECT(proc)); + + /* Mise en place des modules auxialiaires */ + + snprintf(service, sizeof(service), "%hu", port); + + result->stream = g_gdb_tcp_client_new(server, service, result); + if (result->stream == NULL) goto ggdn_error; + + result->support = g_gdb_support_new(result->stream); + + result->target = g_gdb_target_new(result->stream); + if (result->target == NULL) goto ggdn_error; + + return G_BINARY_DEBUGGER(result); + + ggdn_error: + + g_object_unref(G_OBJECT(result)); + + return NULL; + +} + + + + + + + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à lancer. * +* * +* Description : Met en marche le débogueur utilisant un serveur GDB. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_debugger_run(GGdbDebugger *debugger) +{ + + + + GGdbPacket *packet; + + bool test; + + const char *data; + size_t len; + + + int sig; + vmpa_t addr; + pid_t thread; + + + debugger->stream = g_gdb_tcp_client_new("127.0.0.1", "6666", NULL); + if (debugger->stream == NULL) return false; + + + printf("Connection done !\n"); + + + + packet = g_gdb_stream_get_free_packet(debugger->stream); + + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, "?"); + + + test = g_gdb_stream_send_packet(debugger->stream, packet); + + + + printf(" >> Paquet '%s' bien envoyé ? %s\n", "?", test ? "oui" : "non"); + + + + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + + packet = g_gdb_stream_recv_packet(debugger->stream); + + g_gdb_packet_get_data(packet, &data, &len, NULL); + + printf(" << Réception de '%s'\n", data); + + + + + + get_stop_reply_sig_info(packet, &sig, &addr, &thread, SRE_LITTLE); + + g_signal_emit_by_name(debugger, "halted", sig, addr, thread); + + + + return true; + +} + + + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à relancer. * +* * +* Description : Tue le débogueur utilisant un serveur GDB. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_debugger_kill(GGdbDebugger *debugger) +{ + + +#if 0 + int ret; /* Bilan de l'appel système */ + + ret = kill(debugger->child, SIGKILL); + if (ret != 0) perror("kill"); + + debugger->child = 0; + + g_mutex_lock(debugger->mutex); + debugger->run_again = TRUE; + g_cond_signal(debugger->cond); + g_mutex_unlock(debugger->mutex); +#endif + return true; + +} + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à consulter. * +* * +* Description : Détermine l'identifiant du thread principal courant. * +* * +* Retour : Identifiant du thread actif principal ou NULL en cas d'échec.* +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_gdb_debugger_get_active_thread(GGdbDebugger *debugger) +{ + char *result; /* Identifiant à renvoyer */ + GGdbPacket *packet; /* Paquet de communication */ + bool status; /* Bilan d'une communication */ + const char *data; /* Données reçues à analyser */ + const char *start; /* Début d'identification */ + const char *end; /* Fin d'identification */ + + result = NULL; + + /* Envoi de la requête */ + + packet = g_gdb_stream_get_free_packet(debugger->stream); + + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, "?"); + + status = g_gdb_stream_send_packet(debugger->stream, packet); + + if (!status) + goto ggdgat_exit; + + /* Réception de la réponse */ + + packet = g_gdb_stream_recv_packet(debugger->stream); + + g_gdb_packet_get_data(packet, &data, NULL, NULL); + + start = strstr(data, "thread:"); + if (start == NULL) goto ggdgat_exit; + + start += sizeof("thread:") - 1 /* '\0' */; + + end = strstr(start, ";"); + if (end == NULL) goto ggdgat_exit; + + result = strndup(start, end - start); + + ggdgat_exit: + + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + + return result; + +} + + + + + + + + + + + + + + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/* ENTREES / SORTIES BASIQUES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à consulter. * +* addr = emplacement en mémoire à venir consulter. * +* size = taille des données mises en jeu. * +* ... = emplacement de la valeur lue à conserver. [OUT] * +* * +* Description : Lit une valeur quelconque à une adresse arbitraire. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_debugger_read_memory(GGdbDebugger *debugger, virt_t addr, size_t size, ...) +{ + bool result; /* Bilan d'opération à renvoyer*/ + char cmd[1 + VMPA_MAX_LEN + 3]; /* Commande à émettre */ + GGdbPacket *packet; /* Paquet de communication */ + const char *data; /* Données reçues à analyser */ + size_t len; /* Quantité de données reçues */ + va_list ap; /* Liste variable d'arguments */ + uint8_t *val8; /* Valeur sur 8 bits */ + uint16_t *val16; /* Valeur sur 16 bits */ + uint16_t conv16; /* Valeur adaptée sur 16 bits */ + uint32_t *val32; /* Valeur sur 32 bits */ + uint32_t conv32; /* Valeur adaptée sur 32 bits */ + uint64_t *val64; /* Valeur sur 64 bits */ + uint64_t conv64; /* Valeur adaptée sur 64 bits */ + + /* Envoi de la requête */ + + cmd[0] = 'm'; + + result = translate_virt_to_hex(debugger, addr, &cmd[1]); + + switch (size) + { + case 8: + strcat(cmd, ",1"); + break; + + case 16: + strcat(cmd, ",2"); + break; + + case 32: + strcat(cmd, ",4"); + break; + + case 64: + strcat(cmd, ",8"); + break; + + default: + assert(false); + result = false; + goto ggdrm_exit; + break; + + } + + packet = g_gdb_stream_get_free_packet(debugger->stream); + + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, cmd); + + result = g_gdb_stream_send_packet(debugger->stream, packet); + + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + + if (!result) + goto ggdrm_exit; + + /* Réception de la réponse */ + + packet = g_gdb_stream_recv_packet(debugger->stream); + + g_gdb_packet_get_data(packet, &data, &len, NULL); + + if (is_error_code(data, len)) + { + result = false; + goto ggdrm_error; + } + + va_start(ap, size); + + switch (size) + { + case 8: + val8 = va_arg(ap, uint8_t *); + result = hex_to_u8(data, val8); + break; + + case 16: + val16 = va_arg(ap, uint16_t *); + result = hex_to_u16(data, &conv16); + *val16 = from_u16(&conv16, debugger->endian); + break; + + case 32: + val32 = va_arg(ap, uint32_t *); + result = hex_to_u32(data, &conv32); + *val32 = from_u32(&conv32, debugger->endian); + break; + + case 64: + val64 = va_arg(ap, uint64_t *); + result = hex_to_u64(data, &conv64); + *val64 = from_u64(&conv64, debugger->endian); + break; + + default: + assert(false); + result = false; + break; + + } + + va_end(ap); + + ggdrm_error: + + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + + ggdrm_exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à manipuler. * +* addr = emplacement en mémoire à venir consulter. * +* size = taille des données mises en jeu. * +* ... = emplacement de la valeur lue à conserver. [OUT] * +* * +* Description : Lit une valeur quelconque à une adresse arbitraire. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_debugger_write_memory(GGdbDebugger *debugger, virt_t addr, size_t size, ...) +{ + bool result; /* Bilan d'opération à renvoyer*/ + char cmd[1 + 3 * VMPA_MAX_LEN + 3]; /* Commande à émettre */ + va_list ap; /* Liste variable d'arguments */ + const uint8_t *val8; /* Valeur sur 8 bits */ + const uint16_t *val16; /* Valeur sur 16 bits */ + uint16_t conv16; /* Valeur adaptée sur 16 bits */ + const uint32_t *val32; /* Valeur sur 32 bits */ + uint32_t conv32; /* Valeur adaptée sur 32 bits */ + const uint64_t *val64; /* Valeur sur 64 bits */ + uint64_t conv64; /* Valeur adaptée sur 64 bits */ + char hexval[17]; /* Valeur sous forme hexa */ + GGdbPacket *packet; /* Paquet de communication */ + const char *data; /* Données reçues à analyser */ + size_t len; /* Quantité de données reçues */ + + /* Envoi de la requête */ + + cmd[0] = 'M'; + + result = translate_virt_to_hex(debugger, addr, &cmd[1]); + + va_start(ap, size); + + switch (size) + { + case 8: + val8 = va_arg(ap, uint8_t *); + result = u8_to_hex(val8, hexval); + + strcat(cmd, ",1:"); + strcat(cmd, hexval); + break; + + case 16: + val16 = va_arg(ap, uint16_t *); + conv16 = to_u16(val16, debugger->endian); + result = u16_to_hex(&conv16, hexval); + + strcat(cmd, ",2:"); + strcat(cmd, hexval); + break; + + case 32: + val32 = va_arg(ap, uint32_t *); + conv32 = to_u32(val32, debugger->endian); + result = u32_to_hex(&conv32, hexval); + + strcat(cmd, ",4:"); + strcat(cmd, hexval); + break; + + case 64: + val64 = va_arg(ap, uint64_t *); + conv64 = to_u64(val64, debugger->endian); + result = u16_to_hex(&conv64, hexval); + + strcat(cmd, ",8:"); + strcat(cmd, hexval); + break; + + default: + assert(false); + result = false; + break; + + } + + if (!result) + goto ggdwm_exit; + + packet = g_gdb_stream_get_free_packet(debugger->stream); + + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, cmd); + + result = g_gdb_stream_send_packet(debugger->stream, packet); + + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + + if (!result) + goto ggdwm_exit; + + /* Réception de la réponse */ + + packet = g_gdb_stream_recv_packet(debugger->stream); + + g_gdb_packet_get_data(packet, &data, &len, NULL); + + if (len == 3 && data[0] == 'E') + { + result = false; + goto ggdrm_error; + } + + ggdrm_error: + + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + + ggdwm_exit: + + va_end(ap); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à consulter. * +* group = éventuel groupe de registres ciblé ou NULL. * +* count = nombre d'éléments dans la liste de noms. [OUT] * +* * +* Description : Liste l'ensemble des registres appartenant à un groupe. * +* * +* Retour : Liste de noms à libérer de la mémoire après utilisation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char **g_gdb_debugger_get_register_names(const GGdbDebugger *debugger, const char *group, size_t *count) +{ + return g_gdb_target_get_register_names(debugger->target, group, count); + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à consulter. * +* name = désignation du registre visé. * +* * +* Description : Indique la taille associée à un registre donné. * +* * +* Retour : Taille en bits, ou 0 si le registre n'a pas été trouvé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static unsigned int g_gdb_debugger_get_register_size(const GGdbDebugger *debugger, const char *name) +{ + return g_gdb_target_get_register_size(debugger->target, name); + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à consulter. * +* reg = désignation humaine du register à consulter. * +* size = taille des données mises en jeu. * +* ... = emplacement de la valeur lue à conserver. [OUT] * +* * +* Description : Effectue la lecture d'un registre donné. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_debugger_read_register(GGdbDebugger *debugger, const char *reg, size_t size, ...) +{ + bool result; /* Bilan d'opération à renvoyer*/ + va_list ap; /* Liste variable d'arguments */ + uint8_t *val8; /* Valeur sur 8 bits */ + uint16_t *val16; /* Valeur sur 16 bits */ + uint32_t *val32; /* Valeur sur 32 bits */ + uint64_t *val64; /* Valeur sur 64 bits */ + + va_start(ap, size); + + switch (size) + { + case 8: + val8 = va_arg(ap, uint8_t *); + result = g_gdb_target_read_register(debugger->target, debugger->stream, debugger->endian, + reg, 8, val8); + break; + + case 16: + val16 = va_arg(ap, uint16_t *); + result = g_gdb_target_read_register(debugger->target, debugger->stream, debugger->endian, + reg, 16, val16); + break; + + case 32: + val32 = va_arg(ap, uint32_t *); + result = g_gdb_target_read_register(debugger->target, debugger->stream, debugger->endian, + reg, 32, val32); + break; + + case 64: + val64 = va_arg(ap, uint64_t *); + result = g_gdb_target_read_register(debugger->target, debugger->stream, debugger->endian, + reg, 64, val64); + break; + + default: + assert(false); + result = false; + break; + + } + + va_end(ap); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à manipuler. * +* reg = désignation humaine du register à consulter. * +* size = taille des données mises en jeu. * +* ... = emplacement de la valeur à écrire. * +* * +* Description : Effectue l'écriture d'un registre donné. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_debugger_write_register(GGdbDebugger *debugger, const char *reg, size_t size, ...) +{ + bool result; /* Bilan d'opération à renvoyer*/ + va_list ap; /* Liste variable d'arguments */ + const uint8_t *val8; /* Valeur sur 8 bits */ + const uint16_t *val16; /* Valeur sur 16 bits */ + const uint32_t *val32; /* Valeur sur 32 bits */ + const uint64_t *val64; /* Valeur sur 64 bits */ + + va_start(ap, size); + + switch (size) + { + case 8: + val8 = va_arg(ap, const uint8_t *); + result = g_gdb_target_write_register(debugger->target, debugger->stream, debugger->endian, + reg, 8, val8); + break; + + case 16: + val16 = va_arg(ap, const uint16_t *); + result = g_gdb_target_write_register(debugger->target, debugger->stream, debugger->endian, + reg, 16, val16); + break; + + case 32: + val32 = va_arg(ap, const uint32_t *); + result = g_gdb_target_write_register(debugger->target, debugger->stream, debugger->endian, + reg, 32, val32); + break; + + case 64: + val64 = va_arg(ap, const uint64_t *); + result = g_gdb_target_write_register(debugger->target, debugger->stream, debugger->endian, + reg, 64, val64); + break; + + default: + assert(false); + result = false; + break; + + } + + va_end(ap); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* MANIPULATION DE L'ETAT COURANT */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à consulter. * +* pc = adresse de l'instruction courante. [OUT] * +* * +* Description : Détermine le point d'exécution courant. * +* * +* Retour : Bilan de la récupération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_debugger_get_current_pc(GGdbDebugger *debugger, virt_t *pc) +{ + bool result; /* Bilan à retourner */ + + result = debugger->ops->get_pc(debugger, pc); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à consulter. * +* callstack = pile d'appels reconstituée. [OUT] * +* size = taille de cette pile. [OUT] * +* * +* Description : Remonte la pile d'appels jusqu'au point courant. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_debugger_compute_call_stack(GGdbDebugger *debugger, virt_t **callstack, size_t *size) +{ + bool result; /* Bilan global à retourner */ + + if (debugger->ops->compute_cstack != NULL) + result = debugger->ops->compute_cstack(debugger, callstack, size); + + else + result = false; + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* GESTION DES POINTS D'ARRET */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à manipuler ici. * +* addr = emplacement du point mémoire à traiter. * +* * +* Description : Ajoute un point d'arrêt basique en mémoire. * +* * +* Retour : Structure de suivi mise en place pour l'occasion, voire NULL.* +* * +* Remarques : - * +* * +******************************************************************************/ + +static gdb_breakpoint *g_gdb_debugger_enable_memory_breakpoint(GGdbDebugger *debugger, virt_t addr) +{ + gdb_breakpoint *result; /* Nouveau suivi à retourner */ + char cmd[3 + VMPA_MAX_LEN + 3]; /* Commande à émettre */ + bool status; /* Bilan d'une opération */ + const char *kind; /* Taille spécifique du point */ + GGdbPacket *packet; /* Paquet de communication */ + const char *data; /* Données reçues à analyser */ + size_t len; /* Quantité de données reçues */ + GBinaryDebugger *dbg; /* Autre version du débogueur */ + const uint8_t *bp; /* Données du point d'arrêt */ + size_t bp_len; /* Quantité de ces données */ + uint8_t memory[16]; /* Sauvegarde de la mémoire */ + + result = NULL; + + /* Si l'utilisation de la commande dédiée est possible */ + if (1) //////// TODO + { + /* Envoi de la requête */ + + strcpy(cmd, "Z0,"); + + status = translate_virt_to_hex(debugger, addr, &cmd[3]); + + if (!status) + goto ggdemb_exit; + + kind = debugger->ops->get_bp_kind(debugger, addr); + + if (kind == NULL) + goto ggdemb_exit; + + strcat(cmd, kind); + + packet = g_gdb_stream_get_free_packet(debugger->stream); + + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, cmd); + + status = g_gdb_stream_send_packet(debugger->stream, packet); + + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + + if (!status) + goto ggdemb_exit; + + /* Réception de la réponse */ + + packet = g_gdb_stream_recv_packet(debugger->stream); + + g_gdb_packet_get_data(packet, &data, &len, NULL); + + if (is_error_code(data, len)) + { + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + goto ggdemb_fallback; + } + + if (strcmp(data, "OK") != 0) + { + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + goto ggdemb_fallback; + } + + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + + /* Constitution d'un dossier de suivi */ + + result = (gdb_breakpoint *)malloc(sizeof(gdb_breakpoint)); + + result->is_z = true; + + result->kind = kind; + + } + + else + { + + ggdemb_fallback: + + dbg = G_BINARY_DEBUGGER(debugger); + + /* Détermination du point d'arrêt */ + + bp = debugger->ops->get_bp_data(debugger, addr, &bp_len); + + assert(bp_len <= 16); + + /* Sauvegarde de la mémoire courante */ + + status = g_binary_debugger_read_memory_data(dbg, addr, memory, bp_len); + + if (!status) goto ggdemb_exit; + + /* Application du point d'arrêt */ + + status = g_binary_debugger_write_memory_data(dbg, addr, bp, bp_len); + + if (!status) goto ggdemb_exit; + + /* Constitution d'un dossier de suivi */ + + result = (gdb_breakpoint *)malloc(sizeof(gdb_breakpoint)); + + result->is_z = false; + + memcpy(result->memory, memory, bp_len); + result->len = bp_len; + + } + + init_raw_breakpoint((raw_breakpoint *)result, addr); + + ggdemb_exit: + + return result; +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à manipuler ici. * +* bp = point d'arrêt à traiter. * +* * +* Description : Retire un point d'arrêt basique de la mémoire ciblée. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_debugger_disable_memory_breakpoint(GGdbDebugger *debugger, gdb_breakpoint *bp) +{ + bool result; /* Bilan à retourner */ + char cmd[3 + VMPA_MAX_LEN + 3]; /* Commande à émettre */ + bool status; /* Bilan d'une opération */ + GGdbPacket *packet; /* Paquet de communication */ + const char *data; /* Données reçues à analyser */ + size_t len; /* Quantité de données reçues */ + GBinaryDebugger *dbg; /* Autre version du débogueur */ + + result = false; + + /* Si l'utilisation de la commande dédiée est requise */ + if (bp->is_z) + { + /* Envoi de la requête */ + + strcpy(cmd, "z0,"); + + status = translate_virt_to_hex(debugger, bp->raw.addr, &cmd[3]); + + if (!status) + goto ggddmb_exit; + + strcat(cmd, bp->kind); + + packet = g_gdb_stream_get_free_packet(debugger->stream); + + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, cmd); + + status = g_gdb_stream_send_packet(debugger->stream, packet); + + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + + if (!status) + goto ggddmb_exit; + + /* Réception de la réponse */ + + packet = g_gdb_stream_recv_packet(debugger->stream); + + g_gdb_packet_get_data(packet, &data, &len, NULL); + + if (is_error_code(data, len)) + { + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + goto ggddmb_exit; + } + + if (strcmp(data, "OK") != 0) + { + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + goto ggddmb_exit; + } + + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + + result = true; + + } + + else + { + dbg = G_BINARY_DEBUGGER(debugger); + + result = g_binary_debugger_write_memory_data(dbg, bp->raw.addr, bp->memory, bp->len); + + } + + ggddmb_exit: + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* CONTROLE DU FLOT D'EXECUTION */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à redémarrer. * +* * +* Description : Redémarre le processus de débogage lié à un serveur GDB. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_debugger_restart(GGdbDebugger *debugger) +{ + bool result; /* Bilan à retourner */ + GGdbPacket *packet; /* Paquet de communication */ + return true; + /* Envoi de la requête */ + + packet = g_gdb_stream_get_free_packet(debugger->stream); + + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, "R00"); + + result = g_gdb_stream_send_packet(debugger->stream, packet); + + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à relancer. * +* * +* Description : Remet en marche le débogueur utilisant un serveur GDB. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_debugger_resume(GGdbDebugger *debugger) +{ + bool result; /* Bilan à retourner */ + //char *id; /* Identifiant de thread */ + GGdbPacket *packet; /* Paquet de communication */ + //const char *data; /* Données reçues à analyser */ + + static bool _twice = false; + + + if (!_twice && 0) + { + + packet = g_gdb_stream_get_free_packet(debugger->stream); + + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, "$QPassSignals:e;10;14;17;1a;1b;1c;21;24;25;2c;4c;"); + + result = g_gdb_stream_send_packet(debugger->stream, packet); + + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + + if (!result) + goto ggdhmb_exit; + + } + + + + + + + /* Envoi de la requête */ + + /* + id = g_gdb_debugger_get_active_thread(debugger); + if (id == NULL) return false; + + printf("ID : %s\n", id); + */ + + /* + id = g_gdb_support_get_id(debugger->support); + if (id == NULL) return false; + + printf("ID : %s\n", id); + */ + + packet = g_gdb_stream_get_free_packet(debugger->stream); + + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, "vCont;c:-1"); + //g_gdb_packet_append(packet, "vCont;c:p256f.-1"); + + + /* + if (_twice) + { + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, "vCont;c:p"); + g_gdb_packet_append(packet, id); + g_gdb_packet_append(packet, "."); + g_gdb_packet_append(packet, id); + } + else + { + _twice = true; + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, "vCont;c:p"); + g_gdb_packet_append(packet, id); + g_gdb_packet_append(packet, ".-1"); + } + */ + + + + + + result = g_gdb_stream_send_packet(debugger->stream, packet); + + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + + if (!result) + goto ggdhmb_exit; + + /* Réception de la réponse */ + /* + packet = g_gdb_stream_recv_packet(debugger->stream); + + g_gdb_packet_get_data(packet, &data, NULL, NULL); + + printf("Ack cont...\n"); + + //result = (strcmp(data, "OK") == 0); + + g_gdb_stream_mark_packet_as_free(debugger->stream, packet); + */ + ggdhmb_exit: + + _twice = true; + + return result; + +} + + + + + + + + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/* ACCUEIL D'EVENEMENTS ASYNCHRONES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : debugger = instance liée à un débogueur GDB à manipuler. * +* signum = indentifiant du signal concerné. * +* * +* Description : Réagit à la réception d'un signal par le programme étudié. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_gdb_debugger_receive_signal_reply(GGdbDebugger *debugger, int signum) +{ + virt_t pc; /* Position courante du CPU */ + bool status; /* Bilan d'une opération */ + GBinaryDebugger *base; /* Version basique du débogueur*/ + + base = G_BINARY_DEBUGGER(debugger); + + status = g_binary_debugger_get_current_pc(base, &pc); + + if (!status) + pc = VMPA_NO_VIRTUAL; + + on_binary_debugger_stopped(base, pc); + + g_signal_emit_by_name(debugger, "signaled", signum); + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = instance liée à un débogueur GDB à manipuler. * +* status = indication d'état à la sortie. * +* pid = éventuel identifiant de processus concerné ou -1. * +* * +* Description : Réagit à la sortie d'exécution d'un programme étudié. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_gdb_debugger_receive_exit_reply(GGdbDebugger *debugger, int status, pid_t pid) +{ + GBinaryDebugger *base; /* Version basique du débogueur*/ + + base = G_BINARY_DEBUGGER(debugger); + + on_binary_debugger_finished(base, pid); + + g_signal_emit_by_name(debugger, "exited", status, pid); + +} diff --git a/plugins/gdbrsp/gdb.h b/plugins/gdbrsp/gdb.h new file mode 100644 index 0000000..a338f98 --- /dev/null +++ b/plugins/gdbrsp/gdb.h @@ -0,0 +1,61 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gdb.h - prototypes pour le débogage à l'aide de gdb. + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _DEBUG_GDBRSP_GDB_H +#define _DEBUG_GDBRSP_GDB_H + + +#include + + +#include "../debugger.h" + + + +#define G_TYPE_GDB_DEBUGGER (g_gdb_debugger_get_type()) +#define G_GDB_DEBUGGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_GDB_DEBUGGER, GGdbDebugger)) +#define G_IS_GDB_DEBUGGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_GDB_DEBUGGER)) +#define G_GDB_DEBUGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_DEBUGGER, GGdbDebuggerClass)) +#define G_IS_GDB_DEBUGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_DEBUGGER)) +#define G_GDB_DEBUGGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_DEBUGGER, GGdbDebuggerClass)) + + +/* Débogueur utilisant un serveur GDB (instance) */ +typedef struct _GGdbDebugger GGdbDebugger; + +/* Débogueur utilisant un serveur GDB (classe) */ +typedef struct _GGdbDebuggerClass GGdbDebuggerClass; + + +/* Indique le type défini par la GLib pour le débogueur gdb. */ +GType g_gdb_debugger_get_type(void); + +/* Crée un débogueur utilisant un serveur GDB distant. */ +GBinaryDebugger *g_gdb_debugger_new(GLoadedBinary *, const char *, unsigned short); + + +void test_gdb(void); + + + +#endif /* _DEBUG_GDBRSP_GDB_H */ diff --git a/plugins/gdbrsp/helpers.c b/plugins/gdbrsp/helpers.c new file mode 100644 index 0000000..1bdf6f7 --- /dev/null +++ b/plugins/gdbrsp/helpers.c @@ -0,0 +1,224 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * helpers.c - assistanat dans la manipulation des paquets GDB + * + * Copyright (C) 2010-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "helpers.h" + + +#include +#include + + +#include "gdb-int.h" +#include "utils.h" + + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à consulter. * +* addr = emplacement en mémoire à venir consulter. * +* out = zone d'impression en hexadécimal. [OUT] * +* * +* Description : Traduit une adresse en chaîne hexadécimale pour GDB. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool translate_virt_to_hex(const GGdbDebugger *debugger, virt_t addr, char *out) +{ + bool result; /* Bilan d'opération à renvoyer*/ + uint8_t conv8; /* Valeur adaptée sur 8 bits */ + uint16_t conv16; /* Valeur adaptée sur 16 bits */ + uint32_t conv32; /* Valeur adaptée sur 32 bits */ + uint64_t conv64; /* Valeur adaptée sur 64 bits */ + char hexval[17]; /* Valeur sous forme hexa */ + bool got_msn; /* Obtention d'un quartet ? */ + size_t i; /* Boucle de parcours */ + + /* Conversion */ + + switch (debugger->msize) + { + case MDS_8_BITS: + conv8 = addr; + result = u8_to_hex(&conv8, hexval); + break; + + case MDS_16_BITS: + conv16 = addr; + conv16 = to_u16(&conv16, SRE_BIG); + result = u16_to_hex(&conv16, hexval); + break; + + case MDS_32_BITS: + conv32 = addr; + conv32 = to_u32(&conv32, SRE_BIG); + result = u32_to_hex(&conv32, hexval); + break; + + case MDS_64_BITS: + conv64 = addr; + conv64 = to_u64(&conv64, SRE_BIG); + result = u64_to_hex(&conv64, hexval); + break; + + default: + result = false; + break; + + } + + /* On saute les zéros préliminaires... */ + + if (result) + { + got_msn = false; + + for (i = 0; i < 17; i++) + { + if (!got_msn) + { + if (hexval[i] == '0') + continue; + else + got_msn = true; + } + + *out = hexval[i]; + out++; + + } + + *out = '\0'; + + } + + return result; + +} + + + + + + + + +/* -------------------------- PAQUETS DES REPONSES D'ARRET -------------------------- */ + + + + + + +/****************************************************************************** +* * +* Paramètres : packet = paquet de deonnées à interpréter. * +* sig = identifiant du signal source. [OUT] * +* addr = adresse de l'instruction courante. [OUT] * +* thread = identifiant du thread concerné. [OUT] * +* endian = boutisme de la plateforme ciblée. * +* * +* Description : Récupère les informations liées à un arrêt suite à signal. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : Les données sont la forme : * +* T0505:00000000;04:a08de6bf;08:505878b7;thread:50dc; * +* * +******************************************************************************/ + +bool get_stop_reply_sig_info(const GGdbPacket *packet, int *sig, vmpa_t *addr, pid_t *thread, SourceEndian endian) +{ + const char *data; /* Données brutes du paquet */ + size_t length; /* Quantité de ces données */ + uint8_t index; /* Indice de 8 bits quelconque */ + size_t pos; /* Tête de lecture courante */ + regex_t preg; /* Expression régulière */ + int ret; /* Bilan d'un appel */ + regmatch_t pmatch[3]; /* Zones remarquées */ + size_t key_len; /* Taille de l'indicatif */ + + *addr = 0ull; + + g_gdb_packet_get_data(packet, &data, &length, NULL); + + pos = 1; + + /* Lecture du numéro du signal */ + + if (!strtou8(&index, data, &pos, length, SRE_LITTLE)) + return false; + + *sig = index; + + /* Reste des informations */ + + ret = regcomp(&preg, "([^:]+):([^;]+);", REG_EXTENDED | REG_ICASE); + if (ret != 0) return false; + + for (ret = regexec(&preg, &data[pos], 3, pmatch, 0); + ret != REG_NOMATCH; + ret = regexec(&preg, &data[pos], 3, pmatch, 0)) + { + key_len = pmatch[1].rm_eo - pmatch[1].rm_so; + + /* Indication sur le thread */ + if (key_len == strlen("thread") + && strncmp(&data[pos + pmatch[1].rm_so], "thread", key_len) == 0) + { + + /* TODO printf("Thread found !\n"); */ + + } + + /* Valeur de registre ? */ + else if (key_len == 2) + { + if (!strtou8(&index, data, (size_t []) { pos + pmatch[1].rm_so }, length, SRE_LITTLE)) + return false; + + if (index != 8 /* FIXME */) + goto next_field; + + if (!strtou32(addr, data, (size_t []) { pos + pmatch[2].rm_so }, length, SRE_LITTLE/* FIXME */)) + return false; + + } + + next_field: + pos += pmatch[0].rm_eo; + + } + + regfree(&preg); + + return (*addr != 0ull); + +} + + + diff --git a/plugins/gdbrsp/helpers.h b/plugins/gdbrsp/helpers.h new file mode 100644 index 0000000..0492ea3 --- /dev/null +++ b/plugins/gdbrsp/helpers.h @@ -0,0 +1,62 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * helpers.h - prototypes pour un assistanat dans la manipulation des paquets GDB + * + * Copyright (C) 2010-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _DEBUG_GDBRSP_HELPERS_H +#define _DEBUG_GDBRSP_HELPERS_H + + +#include "gdb.h" +#include "packet.h" + + + +/* Traduit une adresse en chaîne hexadécimale pour GDB. */ +bool translate_virt_to_hex(const GGdbDebugger *, virt_t, char *); + + + + + + +/* -------------------------- PAQUETS DES REPONSES D'ARRET -------------------------- */ + + +/* Récupère les informations liées à un arrêt suite à signal. */ +bool get_stop_reply_sig_info(const GGdbPacket *, int *, vmpa_t *, pid_t *, SourceEndian); + + + +/* ---------------------------------------------------------------------------------- */ +/* PAQUETS DES REPONSES D'ARRET */ +/* ---------------------------------------------------------------------------------- */ + + + + + + + + + + +#endif /* _DEBUG_GDBRSP_HELPERS_H */ diff --git a/plugins/gdbrsp/helpers_arm.c b/plugins/gdbrsp/helpers_arm.c new file mode 100644 index 0000000..4b486d4 --- /dev/null +++ b/plugins/gdbrsp/helpers_arm.c @@ -0,0 +1,252 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * helpers_arm.c - compléments utiles à GDB pour l'architecture ARM + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "helpers_arm.h" + + +#include +#include + + +#include "gdb-int.h" + + + +/* Détermine le point d'exécution courant. */ +static bool get_arm_pc(GGdbDebugger *, virt_t *); + +/* Remonte la pile d'appels jusqu'au point courant. */ +static bool compute_call_stack_for_arm(const GGdbDebugger *, virt_t **, size_t *); + +/* Complète la commande manipulant des points d'arrêt. */ +static const char *get_breakpoint_kind_for_arm(const GGdbDebugger *, virt_t); + +/* Construit une instruction provoquant un arrêt d'exécution. */ +static const uint8_t *get_arm_breakpoint_data(const GGdbDebugger *, virt_t, size_t *); + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit les fonctions adaptées aux opérations pour ARM. * +* * +* Retour : Opérations spécifiques adaptées à ARM. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const gdb_arch_ops *get_arm_operations(void) +{ + static const gdb_arch_ops arm_ops = { + + .get_pc = get_arm_pc, + .compute_cstack = compute_call_stack_for_arm, + .get_bp_kind = get_breakpoint_kind_for_arm, + .get_bp_data = get_arm_breakpoint_data + + }; + + return &arm_ops; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à consulter. * +* pc = adresse de l'instruction courante. [OUT] * +* * +* Description : Détermine le point d'exécution courant. * +* * +* Retour : Bilan de la récupération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool get_arm_pc(GGdbDebugger *debugger, virt_t *pc) +{ + bool result; /* Bilan à retourner */ + uint32_t value; + + result = g_binary_debugger_read_register_u32(G_BINARY_DEBUGGER(debugger), "pc", &value); + + if (result) + *pc = value; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à consulter. * +* callstack = pile d'appels reconstituée. [OUT] * +* size = taille de cette pile. [OUT] * +* * +* Description : Remonte la pile d'appels jusqu'au point courant. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool compute_call_stack_for_arm(const GGdbDebugger *debugger, virt_t **callstack, size_t *size) +{ + bool result; /* Bilan global à retourner */ + GBinaryDebugger *base; /* Version basique d'instance */ + uint32_t lr; /* Retour de fonction */ + uint32_t fp; /* Pointeur de cadre à suivre */ + + base = G_BINARY_DEBUGGER(debugger); + + result = g_binary_debugger_read_register_u32(base, "lr", &lr); + + if (result && lr != 0) + { + *callstack = (virt_t *)realloc(*callstack, ++(*size) * sizeof(virt_t)); + + (*callstack)[*size - 1] = lr; + + } + + result &= g_binary_debugger_read_register_u32(base, "r11", &fp); + + while (result && fp != 0) + { + /** + * fp[-0] : pc sauvegardé + * fp[-1] : lr sauvegardé + * fp[-2] : sp précédent + * fp[-3] : fp précédent + */ + + result = g_binary_debugger_read_memory_u32(base, fp - 2 * sizeof(uint32_t), &lr); + if (!result) break; + + if (lr != 0) + { + *callstack = (virt_t *)realloc(*callstack, ++(*size) * sizeof(virt_t)); + + (*callstack)[*size - 1] = lr; + + } + + result = g_binary_debugger_read_memory_u32(base, fp - 4 * sizeof(uint32_t), &fp); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à manipuler ici. * +* virt = emplacement du point mémoire à traiter. * +* * +* Description : Complète la commande manipulant des points d'arrêt. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const char *get_breakpoint_kind_for_arm(const GGdbDebugger *debugger, virt_t virt) +{ + const char *result; /* Indication à retourner */ + GArchProcessor *proc; /* Processeur lié au binaire */ + vmpa2t addr; /* Format d'adresse complet */ + GArchInstruction *instr; /* Instruction ciblée */ + const char *encoding; /* Encodage de l'instruction */ + + proc = g_loaded_binary_get_processor(G_BINARY_DEBUGGER(debugger)->binary); + + init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); + instr = g_arch_processor_find_instr_by_address(proc, &addr); + + if (instr == NULL) + result = NULL; + + else + { + encoding = g_arch_instruction_get_encoding(instr); + + if (strcmp(encoding, "Thumb/16") == 0) + result = ",2"; + + if (strcmp(encoding, "Thumb/32") == 0) + result = ",3"; + + if (strcmp(encoding, "ARM") == 0) + result = ",4"; + + else + result = NULL; + + g_object_unref(G_OBJECT(instr)); + + } + + g_object_unref(G_OBJECT(proc)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à manipuler ici. * +* addr = emplacement du point mémoire à traiter. * +* len = quantité de mémoire à remplacer. [OUT] * +* * +* Description : Construit une instruction provoquant un arrêt d'exécution. * +* * +* Retour : Définition du point d'arrêt à placer à l'adresse donnée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const uint8_t *get_arm_breakpoint_data(const GGdbDebugger *debugger, virt_t addr, size_t *len) +{ + const uint8_t *result; /* Données à placer en mémoire */ + + /* Version point d'arrêt */ + static const uint32_t bkpt_code[] = { 0xe1200070 }; + + *len = sizeof(bkpt_code);; + + result = (const uint8_t *)bkpt_code; + + return result; + +} diff --git a/plugins/gdbrsp/helpers_arm.h b/plugins/gdbrsp/helpers_arm.h new file mode 100644 index 0000000..ec82b27 --- /dev/null +++ b/plugins/gdbrsp/helpers_arm.h @@ -0,0 +1,37 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * helpers_arm.h - prototypes pour les compléments utiles à GDB pour l'architecture ARM + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _DEBUG_GDBRSP_HELPERS_ARM_H +#define _DEBUG_GDBRSP_HELPERS_ARM_H + + +#include "aops.h" + + + +/* Fournit les fonctions adaptées aux opérations pour ARM. */ +const gdb_arch_ops *get_arm_operations(void); + + + +#endif /* _DEBUG_GDBRSP_HELPERS_ARM_H */ diff --git a/plugins/gdbrsp/helpers_arm64.c b/plugins/gdbrsp/helpers_arm64.c new file mode 100644 index 0000000..810c8b3 --- /dev/null +++ b/plugins/gdbrsp/helpers_arm64.c @@ -0,0 +1,97 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * helpers_arm64.c - compléments utiles à GDB pour l'architecture AArch64 + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "helpers_arm64.h" + + +#include + + +#include "gdb-int.h" + + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à consulter. * +* callstack = pile d'appels reconstituée. [OUT] * +* size = taille de cette pile. [OUT] * +* * +* Description : Remonte la pile d'appels jusqu'au point courant. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool compute_call_stack_for_arm64(GGdbDebugger *debugger, virt_t **callstack, size_t *size) +{ + bool result; /* Bilan global à retourner */ + GBinaryDebugger *base; /* Version basique d'instance */ + uint64_t fp; /* Pointeur de cadre à suivre */ + uint64_t previous; /* Appel de fonction précédent */ + + base = G_BINARY_DEBUGGER(debugger); + + result = g_binary_debugger_read_register_u64(base, "x29", &fp); + + while (result && fp != 0) + { + result = g_binary_debugger_read_memory_u64(base, fp + sizeof(uint64_t), &previous); + if (!result) break; + + *callstack = (virt_t *)realloc(*callstack, ++(*size) * sizeof(virt_t)); + + (*callstack)[*size - 1] = previous; + + result = g_binary_debugger_read_memory_u64(base, fp, &fp); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à manipuler ici. * +* addr = emplacement du point mémoire à traiter. * +* cmd = commande en cours de constitution. [OUT] * +* * +* Description : Complète la commande manipulant des points d'arrêt. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool fill_memory_breakpoint_cmd_for_arm64(GGdbDebugger *debugger, virt_t addr, char *cmd) +{ + strcat(cmd, ",4"); + + return true; + +} diff --git a/plugins/gdbrsp/helpers_arm64.h b/plugins/gdbrsp/helpers_arm64.h new file mode 100644 index 0000000..5e89deb --- /dev/null +++ b/plugins/gdbrsp/helpers_arm64.h @@ -0,0 +1,40 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * helpers_arm64.h - prototypes pour les compléments utiles à GDB pour l'architecture AArch64 + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _DEBUG_GDBRSP_HELPERS_ARM64_H +#define _DEBUG_GDBRSP_HELPERS_ARM64_H + + +#include "gdb.h" + + + +/* Remonte la pile d'appels jusqu'au point courant. */ +bool compute_call_stack_for_arm64(GGdbDebugger *, virt_t **, size_t *); + +/* Complète la commande manipulant des points d'arrêt. */ +bool fill_memory_breakpoint_cmd_for_arm64(GGdbDebugger *, virt_t, char *); + + + +#endif /* _DEBUG_GDBRSP_HELPERS_ARM64_H */ diff --git a/plugins/gdbrsp/packet.c b/plugins/gdbrsp/packet.c new file mode 100644 index 0000000..806c6b0 --- /dev/null +++ b/plugins/gdbrsp/packet.c @@ -0,0 +1,389 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * packet.c - manipulation des paquets de données GDB. + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "packet.h" + + +#include +#include + + +#include "../../common/dllist.h" + + + +/* Répresentation d'un paquet GDB (instance) */ +struct _GGdbPacket +{ + GObject parent; /* A laisser en premier */ + + DL_LIST_ITEM(link); /* Lien vers les autres */ + + char *buffer; /* Données à traiter */ + size_t len; /* Quantité de ces données */ + size_t allocated; /* Taille du tampon */ + + uint8_t checksum; /* Empreinte de contrôle */ + +}; + + +/* Répresentation d'un paquet GDB (classe) */ +struct _GGdbPacketClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des représentations des paquets GDB. */ +static void g_gdb_packet_class_init(GGdbPacketClass *); + +/* Initialise une instance de représentation de paquet GDB. */ +static void g_gdb_packet_init(GGdbPacket *); + + + +/* Indique le type défini pour une répresentation de paquet GDB. */ +G_DEFINE_TYPE(GGdbPacket, g_gdb_packet, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des représentations des paquets GDB. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_packet_class_init(GGdbPacketClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : packet = instance à initialiser. * +* * +* Description : Initialise une instance de représentation de paquet GDB. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_packet_init(GGdbPacket *packet) +{ + DL_LIST_ITEM_INIT(&packet->link); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée une représentation de paquet GDB. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GGdbPacket *g_gdb_packet_new(void) +{ + GGdbPacket *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_GDB_PACKET, NULL); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : packet = paquet à préparer pour une émission. * +* * +* Description : Prépare un paquet pour un envoi prochain. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_gdb_packet_start_new_command(GGdbPacket *packet) +{ + if (packet->allocated == 0) + { + packet->allocated = 1; + packet->buffer = (char *)calloc(packet->allocated, sizeof(char)); + } + + packet->buffer[0] = '\0'; + packet->len = 0; + +} + + +/****************************************************************************** +* * +* Paramètres : packet = paquet à préparer pour une émission. * +* string = chaîne à inclure dans le paquet. * +* * +* Description : Complète un paquet pour un envoi prochain. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_gdb_packet_append(GGdbPacket *packet, const char *string) +{ + size_t len; /* Taille de la chaîne donnée */ + + len = strlen(string); + + /* Si la place n'est pas assez grande */ + if ((packet->len + len + 1) > packet->allocated) + { + packet->buffer = (char *)realloc(packet->buffer, (packet->len + len + 1) * sizeof(char)); + packet->allocated = packet->len + len + 1; + } + + + memcpy(packet->buffer + packet->len, string, len + 1); + //strcat(packet->buffer, string); + + packet->len += len; + +} + + +/****************************************************************************** +* * +* Paramètres : packet = paquet à analyser. * +* * +* Description : Détermine l'empreinte des données d'un paquet GDB. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_gdb_packet_compute_checksum(GGdbPacket *packet) +{ + int sum; /* Valeur cumulée des données */ + size_t i; /* Boucle de parcours */ + + sum = 0; + + for (i = 0; i < packet->len; i++) + sum += packet->buffer[i]; + + packet->checksum = sum % 256; + +} + + +/****************************************************************************** +* * +* Paramètres : packet = paquet à analyser. * +* checksum = contrôle d'intégrité à retrouver. * +* * +* Description : Contrôle l'intégrité des données d'un paquet GDB. * +* * +* Retour : Bilan de la vérification. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_gdb_packet_verify_checksum(GGdbPacket *packet, uint8_t checksum) +{ + g_gdb_packet_compute_checksum(packet); + + return checksum == packet->checksum; + +} + + +/****************************************************************************** +* * +* Paramètres : packet = paquet à décoder et/ou décompresser. * +* * +* Description : Décode et/ou décompresse un paquet GDB. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_gdb_packet_decode(GGdbPacket *packet) +{ + bool result; /* Bilan à retourner */ + char *buffer; /* Données transcrites */ + size_t allocated; /* Quantité de données gérées */ + size_t i; /* Boucle de parcours */ + size_t k; /* Point d'insertion */ + size_t repeat; /* Nombre de répétitions */ + + result = true; + + allocated = packet->len + 1; + buffer = (char *)calloc(allocated, sizeof(char)); + + for (i = 0, k = 0; i < packet->len && result; i++) + switch (packet->buffer[i]) + { + case '#': + case '$': + result = false; + break; + + case '*': + + if (++i == packet->len || k == 0) + { + result = false; + break; + } + + repeat = packet->buffer[i] - ' ' + 3; + + allocated += repeat; + buffer = (char *)realloc(buffer, allocated * sizeof(char)); + + memset(&buffer[k], buffer[k - 1], repeat); + k += repeat; + + break; + + case '}': + + if (++i == packet->len) + { + result = false; + break; + } + + buffer[k++] = packet->buffer[i] ^ 0x20; + + break; + + default: + buffer[k++] = packet->buffer[i]; + break; + + } + + if (packet->buffer != NULL) + free(packet->buffer); + + buffer[k] = '\0'; + + packet->buffer = buffer; + packet->len = k; + packet->allocated = allocated; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : packet = paquet à analyser. * +* data = données contenues dans le paquet. [OUT] * +* len = quantité de ces données ou NULL. [OUT] * +* checksum = contrôle d'intégrité des données ou NULL. [OUT] * +* * +* Description : Fournit le contenu du paquet. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_gdb_packet_get_data(const GGdbPacket *packet, const char **data, size_t *len, uint8_t *checksum) +{ + *data = packet->buffer; + + if (len != NULL) + *len = packet->len; + + if (checksum != NULL) + *checksum = packet->checksum; + +} + + +/****************************************************************************** +* * +* 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_gdb_packet_push(GGdbPacket **list, GGdbPacket *item) +{ + dl_list_push(item, list, GGdbPacket, 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 : - * +* * +******************************************************************************/ + +GGdbPacket *g_gdb_packet_pop(GGdbPacket **list) +{ + return dl_list_pop(list, GGdbPacket, link); + +} diff --git a/plugins/gdbrsp/packet.h b/plugins/gdbrsp/packet.h new file mode 100644 index 0000000..7f362bd --- /dev/null +++ b/plugins/gdbrsp/packet.h @@ -0,0 +1,82 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * packet.h - prototypes pour la manipulation des paquets de données GDB. + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _DEBUG_GDBRSP_PACKET_H +#define _DEBUG_GDBRSP_PACKET_H + + +#include +#include +#include + + + +#define G_TYPE_GDB_PACKET g_gdb_packet_get_type() +#define G_GDB_PACKET(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_gdb_packet_get_type(), GGdbPacket)) +#define G_IS_GDB_PACKET(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_gdb_packet_get_type())) +#define G_GDB_PACKET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_PACKET, GGdbPacketClass)) +#define G_IS_GDB_PACKET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_PACKET)) +#define G_GDB_PACKET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_PACKET, GGdbPacketClass)) + + +/* Répresentation d'un paquet GDB (instance) */ +typedef struct _GGdbPacket GGdbPacket; + +/* Répresentation d'un paquet GDB (classe) */ +typedef struct _GGdbPacketClass GGdbPacketClass; + + + +/* Indique le type défini pour une répresentation de paquet GDB. */ +GType g_gdb_packet_get_type(void); + +/* Crée une représentation de paquet GDB. */ +GGdbPacket *g_gdb_packet_new(void); + +/* Prépare un paquet pour un envoi prochain. */ +void g_gdb_packet_start_new_command(GGdbPacket *); + +/* Complète un paquet pour un envoi prochain. */ +void g_gdb_packet_append(GGdbPacket *, const char *); + +/* Détermine l'empreinte des données d'un paquet GDB. */ +void g_gdb_packet_compute_checksum(GGdbPacket *); + +/* Contrôle l'intégrité des données d'un paquet GDB. */ +bool g_gdb_packet_verify_checksum(GGdbPacket *, uint8_t); + +/* Décode et/ou décompresse un paquet GDB. */ +bool g_gdb_packet_decode(GGdbPacket *); + +/* Fournit le contenu du paquet. */ +void g_gdb_packet_get_data(const GGdbPacket *, const char **, size_t *, uint8_t *); + +/* Ajoute un paquet à une liste de paquets. */ +void g_gdb_packet_push(GGdbPacket **, GGdbPacket *); + +/* Retire et fournit le premier élément d'une liste de paquets. */ +GGdbPacket *g_gdb_packet_pop(GGdbPacket **); + + + +#endif /* _DEBUG_GDBRSP_PACKET_H */ diff --git a/plugins/gdbrsp/python/Makefile.am b/plugins/gdbrsp/python/Makefile.am new file mode 100644 index 0000000..8ece12b --- /dev/null +++ b/plugins/gdbrsp/python/Makefile.am @@ -0,0 +1,19 @@ + +noinst_LTLIBRARIES = libpychrysadebuggdbrsp.la + +libpychrysadebuggdbrsp_la_SOURCES = \ + gdb.h gdb.c \ + module.h module.c + +libpychrysadebuggdbrsp_la_LDFLAGS = + + +devdir = $(includedir)/chrysalide-$(subdir) + +dev_HEADERS = $(libpychrysadebuggdbrsp_la_SOURCES:%c=) + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ + -I$(top_srcdir)/src + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/gdbrsp/python/gdb.c b/plugins/gdbrsp/python/gdb.c new file mode 100644 index 0000000..77b72b0 --- /dev/null +++ b/plugins/gdbrsp/python/gdb.c @@ -0,0 +1,173 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gdb.c - équivalent Python du fichier "debug/gdbrsp/gdb.c" + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "gdb.h" + + +#include + + +#include + + +#include + + +#include "../debugger.h" +#include "../../access.h" +#include "../../helpers.h" +#include "../../analysis/binary.h" + + + +/* Crée un nouvel objet Python de type 'GdbDebugger'. */ +static PyObject *py_gdb_debugger_new(PyTypeObject *, PyObject *, PyObject *); + + + +/****************************************************************************** +* * +* Paramètres : type = type de l'objet à instancier. * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Crée un nouvel objet Python de type 'GdbDebugger'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_gdb_debugger_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *result; /* Instance à retourner */ + PyObject *binary_obj; /* Objet pour le binaire lié */ + const char *server; /* Nom du serveur à contacter */ + unsigned short port; /* Port de connexion */ + int ret; /* Bilan de lecture des args. */ + GLoadedBinary *binary; /* Binaire chargé en mémoire */ + GBinaryDebugger *debugger; /* Création GLib à transmettre */ + + ret = PyArg_ParseTuple(args, "OsH", &binary_obj, &server, &port); + if (!ret) return NULL; + + ret = PyObject_IsInstance(binary_obj, (PyObject *)get_python_loaded_binary_type()); + if (!ret) + { + PyErr_SetString(PyExc_TypeError, _("The first argument must be an instance of LoadedBinary.")); + return NULL; + } + + binary = G_LOADED_BINARY(pygobject_get(binary_obj)); + + debugger = g_gdb_debugger_new(binary, server, port); + + result = pygobject_new(G_OBJECT(debugger)); + + g_object_unref(debugger); + + return (PyObject *)result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_gdb_debugger_type(void) +{ + static PyMethodDef py_gdb_debugger_methods[] = { + { NULL } + }; + + static PyGetSetDef py_gdb_debugger_getseters[] = { + { NULL } + }; + + static PyTypeObject py_gdb_debugger_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.debug.gdbrsp.GdbDebugger", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "PyChrysalide GDB debugger", + + .tp_methods = py_gdb_debugger_methods, + .tp_getset = py_gdb_debugger_getseters, + .tp_new = py_gdb_debugger_new + + }; + + return &py_gdb_debugger_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide....gdbrsp.GdbDebugger'.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool ensure_python_gdb_debugger_is_registered(void) +{ + PyTypeObject *type; /* Type Python 'GdbDebugger' */ + PyObject *module; /* Module à recompléter */ + PyObject *dict; /* Dictionnaire du module */ + + type = get_python_gdb_debugger_type(); + + if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) + { + module = get_access_to_python_module("pychrysalide.debug.gdbrsp"); + + dict = PyModule_GetDict(module); + + if (!register_class_for_pygobject(dict, G_TYPE_GDB_DEBUGGER, type, get_python_binary_debugger_type())) + return false; + + } + + return true; + +} diff --git a/plugins/gdbrsp/python/gdb.h b/plugins/gdbrsp/python/gdb.h new file mode 100644 index 0000000..057a38d --- /dev/null +++ b/plugins/gdbrsp/python/gdb.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gdb.h - prototypes pour l'équivalent Python du fichier "debug/gdbrsp/gdb.h" + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSALIDE_DEBUG_GDBRSP_DEBUGGER_H +#define _PLUGINS_PYCHRYSALIDE_DEBUG_GDBRSP_DEBUGGER_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_gdb_debugger_type(void); + +/* Prend en charge l'objet 'pychrysalide.debug.gdbrsp.GdbDebugger'. */ +bool ensure_python_gdb_debugger_is_registered(void); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_DEBUG_GDBRSP_DEBUGGER_H */ diff --git a/plugins/gdbrsp/python/module.c b/plugins/gdbrsp/python/module.c new file mode 100644 index 0000000..c077aa7 --- /dev/null +++ b/plugins/gdbrsp/python/module.c @@ -0,0 +1,94 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * module.c - intégration du répertoire gdbrsp en tant que module + * + * Copyright (C) 2012 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "module.h" + + +#include "gdb.h" +#include "../../helpers.h" + + + +/****************************************************************************** +* * +* Paramètres : super = module dont la définition est à compléter. * +* * +* Description : Ajoute le module 'debug.gdbresp' à un module Python. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_debug_gdbresp_module(PyObject *super) +{ + bool result; /* Bilan à retourner */ + PyObject *module; /* Sous-module mis en place */ + + static PyModuleDef py_chrysalide_debug_gdbresp_module = { + + .m_base = PyModuleDef_HEAD_INIT, + + .m_name = "pychrysalide.debug.gdbrsp", + .m_doc = "Python module for Chrysalide.debug.gdbrsp", + + .m_size = -1, + + }; + + module = build_python_module(super, &py_chrysalide_debug_gdbresp_module); + + result = (module != NULL); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Intègre les objets du module 'debug.gdbresp'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool populate_debug_gdbresp_module(void) +{ + bool result; /* Bilan à retourner */ + + result = true; + + if (result) result = ensure_python_gdb_debugger_is_registered(); + + assert(result); + + return result; + +} diff --git a/plugins/gdbrsp/python/module.h b/plugins/gdbrsp/python/module.h new file mode 100644 index 0000000..0ed3719 --- /dev/null +++ b/plugins/gdbrsp/python/module.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * module.h - prototypes pour l'intégration du répertoire gdbrsp en tant que module + * + * Copyright (C) 2012-2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYCHRYSALIDE_DEBUG_GDBRSP_MODULE_H +#define _PLUGINS_PYCHRYSALIDE_DEBUG_GDBRSP_MODULE_H + + +#include +#include + + + +/* Ajoute le module 'debug.gdbresp' à un module Python. */ +bool add_debug_gdbresp_module(PyObject *); + +/* Intègre les objets du module 'debug.gdbresp'. */ +bool populate_debug_gdbresp_module(void); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_DEBUG_GDBRSP_MODULE_H */ diff --git a/plugins/gdbrsp/stream-int.h b/plugins/gdbrsp/stream-int.h new file mode 100644 index 0000000..ab26dc2 --- /dev/null +++ b/plugins/gdbrsp/stream-int.h @@ -0,0 +1,89 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * stream-int.h - prototypes internes pour la gestion des connexions aux serveurs GDB. + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _DEBUG_GDBRSP_STREAM_INT_H +#define _DEBUG_GDBRSP_STREAM_INT_H + + +#include "gdb.h" +#include "stream.h" + + + +/* Envoie des données à un serveur GDB. */ +typedef bool (* send_gdb_data_fc) (GGdbStream *, const char *, size_t); + +/* Réceptionne un octet de donnée d'un serveur GDB. */ +typedef bool (* recv_gdb_byte_fc) (GGdbStream *, char *); + + +/* Flux de communication avec un serveur GDB (instance) */ +struct _GGdbStream +{ + GObject parent; /* A laisser en premier */ + + int fd; /* Flux ouvert en L./E. */ + + GGdbDebugger *owner; /* Propriétaire du flux */ + + send_gdb_data_fc send_data; /* Envoi d'un paquet GDB */ + recv_gdb_byte_fc recv_byte; /* Réception d'un paquet GDB */ + + GThread *listening; /* Thread pour les réceptions */ + + GGdbPacket *free_packets; /* Liste des disponibles */ + GMutex free_mutex; /* Accès à la liste */ + + GGdbPacket *recv_packets; /* Liste des paquets reçus */ + GCond recv_cond; /* Attente de disponibilité */ + GMutex recv_mutex; /* Accès à la liste */ + + GGdbPacket *status_packets; /* Liste des paquets d'état */ + GCond status_cond; /* Attente de disponibilité */ + GMutex status_mutex; /* Accès à la liste */ + + + + + bool skip_ack; + + bool want_status; + + +}; + + +/* Flux de communication avec un serveur GDB (classe) */ +struct _GGdbStreamClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +/* Lance l'écoute d'un flux de communication avec GDB. */ +bool g_gdb_stream_listen(GGdbStream *); + + + +#endif /* _DEBUG_GDBRSP_STREAM_INT_H */ diff --git a/plugins/gdbrsp/stream.c b/plugins/gdbrsp/stream.c new file mode 100644 index 0000000..f86f630 --- /dev/null +++ b/plugins/gdbrsp/stream.c @@ -0,0 +1,696 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * stream.c - gestion des connexions aux serveurs GDB. + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "stream.h" + + +#include +#include +#include +#include +#include +#include + + +#include "gdb-int.h" +#include "stream-int.h" +#include "utils.h" +#include "../../common/dllist.h" +#include "../../core/logs.h" + + + +/* Initialise la classe des flux de communication avec GDB. */ +static void g_gdb_stream_class_init(GGdbStreamClass *); + +/* Initialise une instance de flux de communication avec GDB. */ +static void g_gdb_stream_init(GGdbStream *); + +/* Supprime toutes les références externes. */ +static void g_gdb_stream_dispose(GGdbStream *); + +/* Procède à la libération totale de la mémoire. */ +static void g_gdb_stream_finalize(GGdbStream *); + +/* Envoie un acquittement pour la dernière réception. */ +static bool gdb_stream_ack(GGdbStream *); + +/* Ecoute une connexion à un serveur GDB. */ +static void *gdb_stream_thread(GGdbStream *); + +/* Reste en alerte quant au changement de statut de l'exécution. */ +static void *gdb_stream_status_thread(GGdbStream *); + +/* Réceptionne un paquet d'un serveur GDB. */ +static bool g_gdb_stream_read_packet(GGdbStream *, GGdbPacket *); + + + +/* Indique le type défini pour un flux de communication avec un serveur GDB. */ +G_DEFINE_TYPE(GGdbStream, g_gdb_stream, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des flux de communication avec GDB. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_stream_class_init(GGdbStreamClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_gdb_stream_dispose; + object->finalize = (GObjectFinalizeFunc)g_gdb_stream_finalize; + +} + + +/****************************************************************************** +* * +* Paramètres : stream = instance à initialiser. * +* * +* Description : Initialise une instance de flux de communication avec GDB. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_stream_init(GGdbStream *stream) +{ + g_mutex_init(&stream->free_mutex); + + g_cond_init(&stream->recv_cond); + g_mutex_init(&stream->recv_mutex); + + g_cond_init(&stream->status_cond); + g_mutex_init(&stream->status_mutex); + + stream->skip_ack = false; + + stream->want_status = false; + +} + + +/****************************************************************************** +* * +* Paramètres : stream = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_stream_dispose(GGdbStream *stream) +{ + g_object_unref(G_OBJECT(stream->owner)); + + + /* TODO... */ + + + G_OBJECT_CLASS(g_gdb_stream_parent_class)->dispose(G_OBJECT(stream)); + +} + + +/****************************************************************************** +* * +* Paramètres : stream = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_stream_finalize(GGdbStream *stream) +{ + + /* TODO */ + + + G_OBJECT_CLASS(g_gdb_stream_parent_class)->finalize(G_OBJECT(stream)); + +} + + +/****************************************************************************** +* * +* Paramètres : stream = instance à modifier. * +* * +* Description : Ne participe plus aux acquitements de paquets. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_gdb_stream_do_not_ack(GGdbStream *stream) +{ + stream->skip_ack = true; + +} + + + +/****************************************************************************** +* * +* Paramètres : stream = instance à réellement lancer. * +* * +* Description : Lance l'écoute d'un flux de communication avec GDB. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_gdb_stream_listen(GGdbStream *stream) +{ + bool result; /* Bilan final à retourner */ + + result = true; + + if (!g_thread_new("chrysalide_gdb_stream", (GThreadFunc)gdb_stream_thread, stream)) + result = false; + + if (!g_thread_new("chrysalide_gdb_status", (GThreadFunc)gdb_stream_status_thread, stream)) + result = false; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : stream = encadrement associée à l'opération. * +* * +* Description : Envoie un acquittement pour la dernière réception. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool gdb_stream_ack(GGdbStream *stream) +{ + /// + //return true; + + bool result; /* Bilan à retourner */ + GGdbPacket *packet; /* Paquet à envoyer */ + + packet = g_gdb_stream_get_free_packet(stream); + + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, "+"); + + result = g_gdb_stream_send_packet(stream, packet); + + g_gdb_stream_mark_packet_as_free(stream, packet); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : stream = encadrement associée à l'opération. * +* * +* Description : Ecoute une connexion à un serveur GDB. * +* * +* Retour : ??? * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void *gdb_stream_thread(GGdbStream *stream) +{ + fd_set rfds; /* Liste des flux à surveiller */ + int ret; /* Bilan d'un appel */ + GGdbPacket *packet; /* Nouveau paquet reçu */ + + + const char *data; /* Données reçues à analyser */ + size_t len; /* Quantité de ces données */ + + + + while (1) + { + FD_ZERO(&rfds); + FD_SET(stream->fd, &rfds); + + ret = select(stream->fd + 1, &rfds, NULL, NULL, NULL); + + switch (ret) + { + case -1: + perror("select()"); + break; + + case 0: + break; + + default: + + packet = g_gdb_stream_get_free_packet(stream); + + g_gdb_packet_start_new_command(packet); + + if (g_gdb_stream_read_packet(stream, packet)) + { + /* Acquittement ? */ + if (!stream->skip_ack) + { + if (!gdb_stream_ack(stream)) goto bad_recv; + } + + + /* On conserve le résultat ? */ + + + g_gdb_packet_get_data(packet, &data, &len, NULL); + + + //printf("---------------------------\n"); + //printf(">> want status ? %d\n", stream->want_status); + //printf(">> got '%s'\n", data); + + + if (len >= 1) + { + if (stream->want_status) + stream->want_status = false; + + else if (index("STWX", data[0]) != NULL) + { + g_mutex_lock(&stream->status_mutex); + g_gdb_packet_push(&stream->status_packets, packet); + g_mutex_unlock(&stream->status_mutex); + + g_cond_signal(&stream->status_cond); + + break; + } + + // else message inconnu -> log_message() ! + + } + + + + + g_mutex_lock(&stream->recv_mutex); + g_gdb_packet_push(&stream->recv_packets, packet); + g_mutex_unlock(&stream->recv_mutex); + + g_cond_signal(&stream->recv_cond); + + } + + else + g_gdb_stream_mark_packet_as_free(stream, packet); + + break; + + bad_recv: + + printf("bad things happend...\n"); + + g_gdb_stream_mark_packet_as_free(stream, packet); + + break; + + } + + } + + + printf("Oh noes....\n"); + + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : stream = encadrement associée à l'opération. * +* * +* Description : Reste en alerte quant au changement de statut de l'exécution.* +* * +* Retour : ??? * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void *gdb_stream_status_thread(GGdbStream *stream) +{ + GGdbPacket *packet; /* Nouveau paquet reçu */ + const char *data; /* Données reçues à analyser */ + size_t len; /* Quantité de ces données */ + bool malformed; /* Echec d'interprétation */ + uint8_t byte; /* Valeur quelconque sur 8 bits*/ + bool ret; /* Bilan d'un appel */ + + while (1) + { + /* Réception d'un nouveau paquet de statut */ + + g_mutex_lock(&stream->status_mutex); + + if (dl_list_empty(stream->status_packets)) + g_cond_wait(&stream->status_cond, &stream->status_mutex); + + packet = g_gdb_packet_pop(&stream->status_packets); + + g_mutex_unlock(&stream->status_mutex); + + /* Traitement du paquet reçu */ + + g_gdb_packet_get_data(packet, &data, &len, NULL); + + malformed = false; + + switch (data[0]) + { + case 'S': + + ret = read_fixed_byte(data + 1, len - 1, &byte); + + if (!ret) + { + malformed = true; + goto gsst_processed; + } + + g_gdb_debugger_receive_signal_reply(stream->owner, byte); + break; + + case 'T': + assert(false); // TODO + break; + + case 'W': + + ret = read_fixed_byte(data + 1, len - 1, &byte); + + if (!ret) + { + malformed = true; + goto gsst_processed; + } + + + // TODO : ";process:pid" + + + printf("Program exited (status=%hhu)\n", byte); + + + g_gdb_debugger_receive_exit_reply(stream->owner, byte, -1); + + + // log_message en cas de mauvais format... + + + break; + + + default: + assert(false); + break; + + } + + gsst_processed: + + if (malformed && true/* TODO : config->show_... */) + log_variadic_message(LMT_WARNING, "Malformed GDB status reply: '%s'", data); + + g_gdb_stream_mark_packet_as_free(stream, packet); + + } + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : stream = flux de communication avec GDB à consulter. * +* * +* Description : Fournit un paquet prêt à emploi. * +* * +* Retour : Paquet prêt à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GGdbPacket *g_gdb_stream_get_free_packet(GGdbStream *stream) +{ + GGdbPacket *result; /* Paquet à retourner */ + + g_mutex_lock(&stream->free_mutex); + + if (dl_list_empty(stream->free_packets)) + result = g_gdb_packet_new(); + + else + result = g_gdb_packet_pop(&stream->free_packets); + + g_mutex_unlock(&stream->free_mutex); + + // ??? + //g_gdb_packet_start_new_command(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : stream = flux de communication avec GDB à mettre à jour. * +* packet = paquet à considérer comme disponible. * +* * +* Description : Place un paquet en attente d'une future utilisation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_gdb_stream_mark_packet_as_free(GGdbStream *stream, GGdbPacket *packet) +{ + //// Utile ? + g_gdb_packet_start_new_command(packet); + + + g_mutex_lock(&stream->free_mutex); + + g_gdb_packet_push(&stream->free_packets, packet); + + g_mutex_unlock(&stream->free_mutex); + +} + + +/****************************************************************************** +* * +* Paramètres : stream = flux ouvert en lecture à utiliser. * +* packet = données à recevoir. * +* * +* Description : Réceptionne un paquet d'un serveur GDB. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_stream_read_packet(GGdbStream *stream, GGdbPacket *packet) +{ + bool result; /* Bilan à renvoyer */ + char tmp[3]; /* Tampon de réception */ + uint8_t checksum; /* Contrôle d'intégrité */ + + do + { + result = stream->recv_byte(stream, tmp); + if (tmp[0] != '+') break; + } + while (0); + + if (tmp[0] != '$') return false; + + tmp[1] = '\0'; + + while ((result = stream->recv_byte(stream, tmp))) + { + //printf(" .. '%c'\n", tmp[0]); + + if (tmp[0] == '#') break; + else g_gdb_packet_append(packet, tmp); + } + + if (result) + { + result = stream->recv_byte(stream, &tmp[0]); + result &= stream->recv_byte(stream, &tmp[1]); + + tmp[2] = 0; + checksum = strtol(tmp, NULL, 16); + + } + + if (result) + result = g_gdb_packet_verify_checksum(packet, checksum); + + if (result) + result = g_gdb_packet_decode(packet); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : stream = flux ouvert en écriture à mettre à jour. * +* packet = données à transmettre. * +* * +* Description : Envoie un paquet à un serveur GDB. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ +#include +bool g_gdb_stream_send_packet(GGdbStream *stream, GGdbPacket *packet) +{ + bool result; /* Bilan à renvoyer */ + const char *data; /* Données à envoyer */ + size_t len; /* Quantité de ces données */ + uint8_t checksum; /* Contrôle d'intégrité */ + char tmp[3]; /* Impression du checksum */ + + g_gdb_packet_get_data(packet, &data, &len, NULL); + +#if 1 + /* Ack ? */ + if (len == 1 && data[0] == '+') + result = stream->send_data(stream, "+", 1); + + else +#endif + { + + result = stream->send_data(stream, "$", 1); + //result = stream->send_data(stream, "+$", 2); + + g_gdb_packet_compute_checksum(packet); + g_gdb_packet_get_data(packet, &data, &len, &checksum); + + + if (len == 1 && data[0] == '?') + stream->want_status = true; + + /* + if (memcmp(data, "vCont;c", strlen("vCont;c")) == 0) + stream->want_status = true; + */ + + + + result &= stream->send_data(stream, data, len); + + result = stream->send_data(stream, "#", 1); + + snprintf(tmp, 3, "%02hhx", checksum); + result &= stream->send_data(stream, tmp, 2); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : stream = flux de communication avec GDB à consulter. * +* * +* Description : Fournit un paquet reçu d'un serveur GDB. * +* * +* Retour : Paquet GDB. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GGdbPacket *g_gdb_stream_recv_packet(GGdbStream *stream) +{ + GGdbPacket *result; /* Paquet à retourner */ + + g_mutex_lock(&stream->recv_mutex); + + if (dl_list_empty(stream->recv_packets)) + g_cond_wait(&stream->recv_cond, &stream->recv_mutex); + + result = g_gdb_packet_pop(&stream->recv_packets); + + g_mutex_unlock(&stream->recv_mutex); + + return result; + +} diff --git a/plugins/gdbrsp/stream.h b/plugins/gdbrsp/stream.h new file mode 100644 index 0000000..a64485a --- /dev/null +++ b/plugins/gdbrsp/stream.h @@ -0,0 +1,68 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * stream.h - prototypes pour la gestion des connexions aux serveurs GDB. + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _DEBUG_GDBRSP_STREAM_H +#define _DEBUG_GDBRSP_STREAM_H + + +#include "packet.h" + + + +#define G_TYPE_GDB_STREAM g_gdb_stream_get_type() +#define G_GDB_STREAM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_gdb_stream_get_type(), GGdbStream)) +#define G_IS_GDB_STREAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_gdb_stream_get_type())) +#define G_GDB_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_STREAM, GGdbStreamClass)) +#define G_IS_GDB_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_STREAM)) +#define G_GDB_STREAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_STREAM, GGdbStreamClass)) + + +/* Flux de communication avec un serveur GDB (instance) */ +typedef struct _GGdbStream GGdbStream; + +/* Flux de communication avec un serveur GDB (classe) */ +typedef struct _GGdbStreamClass GGdbStreamClass; + + + +/* Indique le type défini pour un flux de communication avec un serveur GDB. */ +GType g_gdb_stream_get_type(void); + +/* Ne participe plus aux acquitements de paquets. */ +void g_gdb_stream_do_not_ack(GGdbStream *); + +/* Fournit un paquet prêt à emploi. */ +GGdbPacket *g_gdb_stream_get_free_packet(GGdbStream *); + +/* Place un paquet en attente d'une future utilisation. */ +void g_gdb_stream_mark_packet_as_free(GGdbStream *, GGdbPacket *); + +/* Envoie un paquet à un serveur GDB. */ +bool g_gdb_stream_send_packet(GGdbStream *, GGdbPacket *); + +/* Fournit un paquet reçu d'un serveur GDB. */ +GGdbPacket *g_gdb_stream_recv_packet(GGdbStream *); + + + +#endif /* _DEBUG_GDBRSP_STREAM_H */ diff --git a/plugins/gdbrsp/support.c b/plugins/gdbrsp/support.c new file mode 100644 index 0000000..3d27c06 --- /dev/null +++ b/plugins/gdbrsp/support.c @@ -0,0 +1,598 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * support.c - conformité dans l'interfaçage client/serveur + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "support.h" + + +#include +#include + + + +/* Indications quant à l'interfaçage client/serveur GDB (instance) */ +struct _GGdbSupport +{ + GObject parent; /* A laisser en premier */ + + unsigned long packet_size; /* Taille maximale d'un paquet */ + + bool os_data; + + + bool extended_mode; /* Mode étendu présent & actif */ + + + char *id; + +}; + +/* Indications quant à l'interfaçage client/serveur GDB (classe) */ +struct _GGdbSupportClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des détails d'interfaçage GDB. */ +static void g_gdb_support_class_init(GGdbSupportClass *); + +/* Procède à l'initialisation des détails d'interfaçage GDB. */ +static void g_gdb_support_init(GGdbSupport *); + +/* Supprime toutes les références externes. */ +static void g_gdb_support_dispose(GGdbSupport *); + +/* Procède à la libération totale de la mémoire. */ +static void g_gdb_support_finalize(GGdbSupport *); + +/* Lit une valeur booléenne à partir des détails du serveur. */ +static bool g_gdb_support_read_bool(GGdbSupport *, const char *, const char *, bool *); + +/* Lit une valeur longue à partir des détails du serveur. */ +static bool g_gdb_support_read_ulong(GGdbSupport *, const char *, const char *, unsigned long *); + + + +/* Indique le type défini par la GLib pour les détails d'interfaçage GDB. */ +G_DEFINE_TYPE(GGdbSupport, g_gdb_support, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe de débogueur à initialiser. * +* * +* Description : Initialise la classe des détails d'interfaçage GDB. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_support_class_init(GGdbSupportClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_gdb_support_dispose; + object->finalize = (GObjectFinalizeFunc)g_gdb_support_finalize; + +} + + +/****************************************************************************** +* * +* Paramètres : support = instance de débogueur à préparer. * +* * +* Description : Procède à l'initialisation des détails d'interfaçage GDB. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_support_init(GGdbSupport *support) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : support = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_support_dispose(GGdbSupport *support) +{ + G_OBJECT_CLASS(g_gdb_support_parent_class)->dispose(G_OBJECT(support)); + +} + + +/****************************************************************************** +* * +* Paramètres : support = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_support_finalize(GGdbSupport *support) +{ + G_OBJECT_CLASS(g_gdb_support_parent_class)->finalize(G_OBJECT(support)); + +} + + + + + + + + + + + + + + +#include + +static char *build_id(GGdbStream *stream) +{ + char *result; /* Identifiant à renvoyer */ + GGdbPacket *packet; /* Paquet de communication */ + bool status; /* Bilan d'une communication */ + const char *data; /* Données reçues à analyser */ + const char *start; /* Début d'identification */ + const char *end; /* Fin d'identification */ + + result = NULL; + + /* Envoi de la requête */ + + packet = g_gdb_stream_get_free_packet(stream); + + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, "?"); + + status = g_gdb_stream_send_packet(stream, packet); + + if (!status) + goto ggdgat_exit; + + /* Réception de la réponse */ + + packet = g_gdb_stream_recv_packet(stream); + + g_gdb_packet_get_data(packet, &data, NULL, NULL); + + start = strstr(data, "thread:"); + if (start == NULL) goto ggdgat_exit; + + start += sizeof("thread:") - 1 /* '\0' */; + + end = strstr(start, ";"); + if (end == NULL) goto ggdgat_exit; + + result = strndup(start, end - start); + + ggdgat_exit: + + g_gdb_stream_mark_packet_as_free(stream, packet); + + return result; + +} + + + + + + + +/****************************************************************************** +* * +* Paramètres : stream = flux de communication ouvert avec le débogueur. * +* * +* Description : Crée une définition des détails d'interfaçage GDB. * +* * +* Retour : Instance de détails mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GGdbSupport *g_gdb_support_new(GGdbStream *stream) +{ + GGdbSupport *result; /* Débogueur à retourner */ + GGdbPacket *packet; /* Paquet de communication GDB */ + + + //goto end; + + //goto skip; + + packet = g_gdb_stream_get_free_packet(stream); + + g_gdb_packet_start_new_command(packet); + //g_gdb_packet_append(packet, "qSupported:multiprocess+;xmlRegisters"); + g_gdb_packet_append(packet, "qSupported"); + + g_gdb_packet_append(packet, "qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+"); + + + bool test; + + const char *data; /* Données reçues à analyser */ + size_t len; + + test = g_gdb_stream_send_packet(stream, packet); + + + + printf(" >> Paquet '%s' bien envoyé ? %s\n", "qSupported", test ? "oui" : "non"); + + + + g_gdb_stream_mark_packet_as_free(stream, packet); + + packet = g_gdb_stream_recv_packet(stream); + + g_gdb_packet_get_data(packet, &data, &len, NULL); + + printf(" << Réception de '%s'\n", data); + + + + + result = g_object_new(G_TYPE_GDB_SUPPORT, NULL); + + + + /* Découpage des éléments de réponse */ + + char *answer; /* Réponse modifiable */ + char *save; /* Sauvegarde de position */ + char *token; /* Elément de réponse cerné */ + + answer = strdup(data); + + for (token = strtok_r(answer, ";", &save); + token != NULL; + token = strtok_r(NULL, ";", &save)) + { + + + printf("TOKEN :: %s\n", token); + + if (g_gdb_support_read_ulong(result, token, "PacketSize", &result->packet_size)) + continue; + + if (g_gdb_support_read_bool(result, token, "qXfer:osdata:read", &result->os_data)) + { + printf(" -->> %d\n", result->os_data); + continue; + } + + + + + } + + free(answer); + + + + /** + * Première chose : plus d'acquitement ! + * + * Dans les faits, c'est impossible à gérer en asynchrone. Par exemple : + * + * C> vCont;c + * C> g Txx... extended_mode = (strcmp(data, "OK") == 0); + + g_gdb_stream_mark_packet_as_free(stream, packet); + + + + + result->id = build_id(stream); + + + +#if 0 + //end: + +#define CMD "?" + + + packet = g_gdb_stream_get_free_packet(stream); + + g_gdb_packet_start_new_command(packet); + //g_gdb_packet_append(packet, "qSupported:multiprocess+;xmlRegisters"); + g_gdb_packet_append(packet, CMD); + + + test = g_gdb_stream_send_packet(stream, packet); + + + + printf(" >> Paquet '%s' bien envoyé ? %s\n", CMD, test ? "oui" : "non"); + + + + g_gdb_stream_mark_packet_as_free(stream, packet); + + packet = g_gdb_stream_recv_packet(stream); + + g_gdb_packet_get_data(packet, &data, &len, NULL); + + printf(" << [pkt = %p ] Réception de '%s' (len=%d)\n", packet, data, (int)len); + + +#endif + + + + // qfThreadInfo + + +#undef CMD + + //#define CMD "qXfer:threads:read::0,1fff" + //#define CMD "qXfer:btrace:read:all:0,1fff" + //#define CMD "g" + //#define CMD "m400000,8" +#define CMD "qsThreadInfo" + + packet = g_gdb_stream_get_free_packet(stream); + + g_gdb_packet_start_new_command(packet); + //g_gdb_packet_append(packet, "qSupported:multiprocess+;xmlRegisters"); + g_gdb_packet_append(packet, CMD); + + + test = g_gdb_stream_send_packet(stream, packet); + + + + printf(" >> Paquet '%s' bien envoyé ? %s\n", CMD, test ? "oui" : "non"); + + + + g_gdb_stream_mark_packet_as_free(stream, packet); + + packet = g_gdb_stream_recv_packet(stream); + + g_gdb_packet_get_data(packet, &data, &len, NULL); + + printf(" << [pkt = %p ] Réception de '%s' (len=%d)\n", packet, data, (int)len); + + + + + + + + + + + + return result; + + ggsn_error: + + + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : support = ensemble de détails à préciser. * +* raw = données brutes à parcourir. * +* name = désignation de la valeur recherchée. * +* value = emplacement de la valeur à inscrire. * +* * +* Description : Lit une valeur booléenne à partir des détails du serveur. * +* * +* Retour : true en cas d'affectation, false dans tous les autres cas. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_support_read_bool(GGdbSupport *support, const char *raw, const char *name, bool *value) +{ + bool result; /* Bilan à retourner */ + size_t rlen; /* Taille de l'ensemble */ + size_t nlen; /* Taille du nom */ + + rlen = strlen(raw); + nlen = strlen(name); + + if ((nlen + 1) != rlen) + return false; + + if (strncmp(raw, name, nlen) != 0) + return false; + + switch (raw[nlen]) + { + case '+': + *value = true; + result = true; + break; + + case '-': + case '?': + *value = false; + result = true; + break; + + default: + result = false; + break; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : support = ensemble de détails à préciser. * +* raw = données brutes à parcourir. * +* name = désignation de la valeur recherchée. * +* value = emplacement de la valeur à inscrire. * +* * +* Description : Lit une valeur longue à partir des détails du serveur. * +* * +* Retour : true en cas d'affectation, false dans tous les autres cas. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_support_read_ulong(GGdbSupport *support, const char *raw, const char *name, unsigned long *value) +{ + size_t rlen; /* Taille de l'ensemble */ + size_t nlen; /* Taille du nom */ + unsigned long v; /* Valeur récupérée à assigner */ + + rlen = strlen(raw); + nlen = strlen(name); + + if (strncmp(raw, name, nlen) != 0) + return false; + + if (raw[nlen] != '=') + return false; + + v = strtoul(raw + nlen + 1, NULL, 16); + + if (v == ULONG_MAX/* && errno == ERANGE*/) + return false; + + *value = v; + + return true; + +} + + + + + + +char *g_gdb_support_get_id(const GGdbSupport *support) +{ + return support->id; + +} + + + + + diff --git a/plugins/gdbrsp/support.h b/plugins/gdbrsp/support.h new file mode 100644 index 0000000..2f6259c --- /dev/null +++ b/plugins/gdbrsp/support.h @@ -0,0 +1,73 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * support.h - prototypes pour la conformité dans l'interfaçage client/serveur + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _DEBUG_GDBRSP_SUPPORT_H +#define _DEBUG_GDBRSP_SUPPORT_H + + +#include +#include + + +#include "stream.h" + + + +#define G_TYPE_GDB_SUPPORT (g_gdb_support_get_type()) +#define G_GDB_SUPPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_GDB_SUPPORT, GGdbSupport)) +#define G_IS_GDB_SUPPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_GDB_SUPPORT)) +#define G_GDB_SUPPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_SUPPORT, GGdbSupportClass)) +#define G_IS_GDB_SUPPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_SUPPORT)) +#define G_GDB_SUPPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_SUPPORT, GGdbSupportClass)) + + +/* Indications quant à l'interfaçage client/serveur GDB (instance) */ +typedef struct _GGdbSupport GGdbSupport; + +/* Indications quant à l'interfaçage client/serveur GDB (classe) */ +typedef struct _GGdbSupportClass GGdbSupportClass; + + +/* Indique le type défini par la GLib pour les détails d'interfaçage GDB. */ +GType g_gdb_support_get_type(void); + +/* Crée une définition des détails d'interfaçage GDB. */ +GGdbSupport *g_gdb_support_new(GGdbStream *); + + + + + + + +char *g_gdb_support_get_id(const GGdbSupport *support); + + + + + + + + + +#endif /* _DEBUG_GDBRSP_SUPPORT_H */ diff --git a/plugins/gdbrsp/target.c b/plugins/gdbrsp/target.c new file mode 100644 index 0000000..cf28a49 --- /dev/null +++ b/plugins/gdbrsp/target.c @@ -0,0 +1,950 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * target.c - gestion des éléments propres à l'architecture reconnue par GDB + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "target.h" + + +#include +#include +#include +#include +#include + + +#include "utils.h" +#include "../../common/cpp.h" +#include "../../common/extstr.h" +#include "../../common/xml.h" + + + +/* Définitions de registres */ + +typedef struct _arch_register_t +{ + char *name; /* Nom de registre */ + unsigned int size; /* Taille en bits */ + +} arch_register_t; + +typedef struct _target_cpu_t +{ + char *label; /* Désignation de l'ensemble */ + + arch_register_t *regs; /* Définition des registres */ + unsigned int count; /* Quantité de ces définitions */ + +} target_cpu_t; + + +/* Indications quant à l'interfaçage client/serveur GDB (instance) */ +struct _GGdbTarget +{ + GObject parent; /* A laisser en premier */ + + target_cpu_t **defs; /* Liste de définitions */ + size_t count; /* Taille de cette même liste */ + + bool read_single_register; /* Lecture spécifique permise ?*/ + bool write_single_register; /* Ecriture spécifique valide ?*/ + +}; + +/* Indications quant à l'interfaçage client/serveur GDB (classe) */ +struct _GGdbTargetClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des détails d'interfaçage GDB. */ +static void g_gdb_target_class_init(GGdbTargetClass *); + +/* Procède à l'initialisation des détails d'interfaçage GDB. */ +static void g_gdb_target_init(GGdbTarget *); + +/* Supprime toutes les références externes. */ +static void g_gdb_target_dispose(GGdbTarget *); + +/* Procède à la libération totale de la mémoire. */ +static void g_gdb_target_finalize(GGdbTarget *); + +/* Charge la définition d'un groupe de registres. */ +static bool g_gdb_target_load_register_definition(GGdbTarget *, GGdbStream *, const char *); + +/* Recherche l'indice correspondant à un registre donné. */ +static bool g_gdb_target_find_register_index(const GGdbTarget *, const char *, unsigned int *); + +/* Recherche la position correspondant à un registre donné. */ +static bool g_gdb_target_find_register_offset(const GGdbTarget *, unsigned int, size_t *); + + + +/* Indique le type défini par la GLib pour les détails d'interfaçage GDB. */ +G_DEFINE_TYPE(GGdbTarget, g_gdb_target, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe de débogueur à initialiser. * +* * +* Description : Initialise la classe des détails d'interfaçage GDB. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_target_class_init(GGdbTargetClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_gdb_target_dispose; + object->finalize = (GObjectFinalizeFunc)g_gdb_target_finalize; + +} + + +/****************************************************************************** +* * +* Paramètres : target = instance de débogueur à préparer. * +* * +* Description : Procède à l'initialisation des détails d'interfaçage GDB. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_target_init(GGdbTarget *target) +{ + target->defs = NULL; + target->count = 0; + + target->read_single_register = true; + target->write_single_register = true; + +} + + +/****************************************************************************** +* * +* Paramètres : target = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_target_dispose(GGdbTarget *target) +{ + G_OBJECT_CLASS(g_gdb_target_parent_class)->dispose(G_OBJECT(target)); + +} + + +/****************************************************************************** +* * +* Paramètres : target = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_target_finalize(GGdbTarget *target) +{ + G_OBJECT_CLASS(g_gdb_target_parent_class)->finalize(G_OBJECT(target)); + +} + + +/****************************************************************************** +* * +* Paramètres : stream = flux de communication ouvert avec le débogueur. * +* * +* Description : Crée une définition des détails d'interfaçage GDB. * +* * +* Retour : Instance de détails mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GGdbTarget *g_gdb_target_new(GGdbStream *stream) +{ + GGdbTarget *result; /* Débogueur à retourner */ + GGdbPacket *packet; /* Paquet de communication GDB */ + bool status; /* Bilan d'une communication */ + + const char *data; /* Données reçues du serveur */ + size_t len; /* Quantité de ces données */ + char *xmldata; /* Données modifiables */ + xmlDocPtr xdoc; /* Document XML récupéré */ + xmlXPathContextPtr context; /* Contexte d'analyse associé */ + xmlXPathObjectPtr xobject; /* Cible d'une recherche */ + unsigned int i; /* Boucle de parcours */ + char *access; /* Chemin d'accès à un élément */ + char *xmlref; /* Référence de définitions */ + + + + + result = NULL; + + + //goto end; + + //goto skip; + + + packet = g_gdb_stream_get_free_packet(stream); + + g_gdb_packet_start_new_command(packet); + //g_gdb_packet_append(packet, "qTargeted:multiprocess+;xmlRegisters"); + g_gdb_packet_append(packet, "qXfer:features:read:target.xml:0,3fff"); + + //g_gdb_packet_append(packet, "qTargeted:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContTargeted+;QThreadEvents+;no-resumed+"); + + + + status = g_gdb_stream_send_packet(stream, packet); + if (!status) goto ggtn_failed; + + + + + g_gdb_stream_mark_packet_as_free(stream, packet); + + packet = g_gdb_stream_recv_packet(stream); + + g_gdb_packet_get_data(packet, &data, &len, NULL); + + printf(" << Réception de '%s'\n", data); + + /* Marqueur de fin placé au début ?! */ + if (data[0] != 'l') + goto ggtn_failed; + + xmldata = strdup(data + 1); + + /** + * On cherche à éviter la déconvenue suivante avec la libxml2 : + * + * noname.xml:12: namespace error : Namespace prefix xi on include is not defined + * + */ + + xmldata = strrpl(xmldata, "xi:include", "include"); + + if (!load_xml_from_memory(xmldata, len - 1, &xdoc, &context)) + goto ggtn_failed; + + + result = g_object_new(G_TYPE_GDB_TARGET, NULL); + + + xobject = get_node_xpath_object(context, "/target/include"); + + for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobject); i++) + { + asprintf(&access, "/target/include[position()=%u]", i + 1); + + xmlref = get_node_prop_value(context, access, "href"); + + free(access); + + if (xmlref != NULL) + { + printf("REF>> %s\n", xmlref); + /*static bool */g_gdb_target_load_register_definition(result, stream, xmlref); + + free(xmlref); + + } + + } + + if(xobject != NULL) + xmlXPathFreeObject(xobject); + + close_xml_file(xdoc, context); + + free(xmldata); + + + + + + + + + + + //result = g_object_new(G_TYPE_GDB_TARGET, NULL); + + + ggtn_failed: + + g_gdb_stream_mark_packet_as_free(stream, packet); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : target = ensemble d'informations liées à l'architecture. * +* stream = flux de communication ouvert avec le débogueur. * +* name = désignation des définitions de registres à charger. * +* * +* Description : Charge la définition d'un groupe de registres. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_target_load_register_definition(GGdbTarget *target, GGdbStream *stream, const char *name) +{ + bool result; /* Bilan à retourner */ + GGdbPacket *packet; /* Paquet de communication GDB */ + bool status; /* Bilan d'une communication */ + const char *data; /* Données reçues du serveur */ + size_t len; /* Quantité de ces données */ + xmlDocPtr xdoc; /* Document XML récupéré */ + xmlXPathContextPtr context; /* Contexte d'analyse associé */ + xmlXPathObjectPtr xobject; /* Cible d'une recherche */ + target_cpu_t *def; /* Nouvelle définition à lire */ + unsigned int i; /* Boucle de parcours */ + char *access; /* Chemin d'accès à un élément */ + char *type; /* Espèce de définition */ + + result = false; + + /* Envoi de la requête */ + + packet = g_gdb_stream_get_free_packet(stream); + + g_gdb_packet_start_new_command(packet); + + g_gdb_packet_append(packet, "qXfer:features:read:"); + g_gdb_packet_append(packet, name); + g_gdb_packet_append(packet, ":0,3fff"); + + status = g_gdb_stream_send_packet(stream, packet); + if (!status) goto ggtlrd_failed; + + g_gdb_stream_mark_packet_as_free(stream, packet); + + /* Réception de la réponse */ + + packet = g_gdb_stream_recv_packet(stream); + + g_gdb_packet_get_data(packet, &data, &len, NULL); + + //printf(">>>> '%s'\n", data); + + /* Marqueur de fin placé au début ?! */ + if (data[0] != 'l') + goto ggtlrd_failed; + + if (!load_xml_from_memory(data + 1, len - 1, &xdoc, &context)) + goto ggtlrd_failed; + + /* Chargement des définitions */ + + xobject = get_node_xpath_object(context, "/feature/*"); + + def = (target_cpu_t *)calloc(1, sizeof(target_cpu_t)); + + def->count = XPATH_OBJ_NODES_COUNT(xobject); + def->regs = (arch_register_t *)calloc(def->count, sizeof(arch_register_t)); + + for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobject); i++) + { + asprintf(&access, "/feature/*[position()=%u]", i + 1); + + type = get_node_name(context, access); + + if (strcmp(type, "reg") == 0) + { + def->regs[i].name = get_node_prop_value(context, access, "name"); + def->regs[i].size = atoi(get_node_prop_value(context, access, "bitsize")); + + //printf("load reg '%s' (%u)\n", def->regs[i].name, def->regs[i].size); + + } + + free(type); + + free(access); + + } + + if(xobject != NULL) + xmlXPathFreeObject(xobject); + + close_xml_file(xdoc, context); + + /* Intégration finale */ + + target->defs = (target_cpu_t **)realloc(target->defs, ++target->count * sizeof(target_cpu_t *)); + + target->defs[target->count - 1] = def; + + ggtlrd_failed: + + g_gdb_stream_mark_packet_as_free(stream, packet); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : target = ensemble d'informations liées à l'architecture. * +* group = éventuel groupe de registres ciblé ou NULL. * +* count = nombre d'éléments dans la liste de noms. [OUT] * +* * +* Description : Liste l'ensemble des registres appartenant à un groupe. * +* * +* Retour : Liste de noms à libérer de la mémoire après utilisation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char **g_gdb_target_get_register_names(const GGdbTarget *target, const char *group, size_t *count) +{ + char **result; /* Désignations à retourner */ + unsigned int i; /* Boucle de parcours #1 */ + const target_cpu_t *rgrp; /* Groupe de registres */ + unsigned int j; /* Boucle de parcours #2 */ + + result = NULL; + + for (i = 0; i < target->count && result == NULL; i++) + { + rgrp = target->defs[i]; + + if (group != NULL) + { + if (strcmp(rgrp->label, group) != 0) + continue; + } + + *count = rgrp->count; + + result = (char **)calloc(*count, sizeof(char *)); + + for (j = 0; j < *count; j++) + result[j] = strdup(rgrp->regs[j].name); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : target = ensemble d'informations liées à l'architecture. * +* name = désignation du registre visé. * +* * +* Description : Indique la taille associée à un registre donné. * +* * +* Retour : Taille en bits, ou 0 si le registre n'a pas été trouvé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +unsigned int g_gdb_target_get_register_size(const GGdbTarget *target, const char *name) +{ + unsigned int result; /* Taille en bits à retourner */ + unsigned int i; /* Boucle de parcours #1 */ + const target_cpu_t *rgrp; /* Groupe de registres */ + unsigned int j; /* Boucle de parcours #2 */ + + result = 0; + + for (i = 0; i < target->count && result == 0; i++) + { + rgrp = target->defs[i]; + + for (j = 0; j < rgrp->count; j++) + if (strcmp(rgrp->regs[j].name, name) == 0) + result = rgrp->regs[j].size; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : target = ensemble d'informations liées à l'architecture. * +* reg = désignation humaine du register à consulter. * +* index = indice correspondant au registre pour GDB. [OUT] * +* * +* Description : Recherche l'indice correspondant à un registre donné. * +* * +* Retour : Bilan de l'opération : trouvaille ou échec ? * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_target_find_register_index(const GGdbTarget *target, const char *reg, unsigned int *index) +{ + bool result; /* Bilan à retourner */ + unsigned int i; /* Boucle de parcours #1 */ + unsigned int j; /* Boucle de parcours #2 */ + + result = false; + + *index = 0; + + for (i = 0; i < target->count && !result; i++) + for (j = 0; j < target->defs[i]->count && !result; j++) + { + if (strcmp(target->defs[i]->regs[j].name, reg) == 0) + result = true; + else + (*index)++; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : target = ensemble d'informations liées à l'architecture. * +* index = indice correspondant au registre pour GDB. * +* offset = position de valeur du registre dans du texte. [OUT] * +* * +* Description : Recherche la position correspondant à un registre donné. * +* * +* Retour : Bilan de l'opération : trouvaille ou échec ? * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_target_find_register_offset(const GGdbTarget *target, unsigned int index, size_t *offset) +{ + unsigned int i; /* Boucle de parcours #1 */ + unsigned int j; /* Boucle de parcours #2 */ + + *offset = 0; + + for (i = 0; i < target->count && index > 0; i++) + for (j = 0; j < target->defs[i]->count && index > 0; j++) + { + assert(target->defs[i]->regs[j].size % 4 == 0); + + *offset += target->defs[i]->regs[j].size / 4; + + index--; + + } + + return (index == 0); + +} + + +/****************************************************************************** +* * +* Paramètres : target = ensemble d'informations liées à l'architecture. * +* stream = flux de communication ouvert avec le débogueur. * +* endian = boutisme de la cible. * +* reg = désignation humaine du register à consulter. * +* size = taille des données mises en jeu. * +* ... = emplacement de la valeur lue à conserver. [OUT] * +* * +* Description : Effectue la lecture d'un registre donné. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_gdb_target_read_register(GGdbTarget *target, GGdbStream *stream, SourceEndian endian, const char *reg, size_t size, ...) +{ + bool result; /* Bilan à retourner */ + unsigned int index; /* Indice du registre ciblé */ + GGdbPacket *packet; /* Paquet de communication */ + char cmd[sizeof(XSTR(UINT_MAX)) + 1]; /* Elément de requête */ + const char *data; /* Données reçues à analyser */ + size_t len; /* Quantité de ces données */ + const char *raw; /* Début de zone à relire */ + size_t offset; /* Position dans la masse */ + va_list ap; /* Liste variable d'arguments */ + uint8_t *val8; /* Valeur sur 8 bits */ + uint16_t *val16; /* Valeur sur 16 bits */ + uint16_t conv16; /* Valeur adaptée sur 16 bits */ + uint32_t *val32; /* Valeur sur 32 bits */ + uint32_t conv32; /* Valeur adaptée sur 32 bits */ + uint64_t *val64; /* Valeur sur 64 bits */ + uint64_t conv64; /* Valeur adaptée sur 64 bits */ + + result = g_gdb_target_find_register_index(target, reg, &index); + if (!result) goto ggtrr_error; + + /** + * Essai avec la méthode précise. + */ + + if (!target->read_single_register) + goto read_all_register_fallback; + + packet = g_gdb_stream_get_free_packet(stream); + + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, "p"); + + snprintf(cmd, sizeof(cmd), "%x", index); + g_gdb_packet_append(packet, cmd); + + result = g_gdb_stream_send_packet(stream, packet); + + g_gdb_stream_mark_packet_as_free(stream, packet); + + if (!result) + goto ggtrr_error; + + /* Réception de la réponse */ + + packet = g_gdb_stream_recv_packet(stream); + + g_gdb_packet_get_data(packet, &data, &len, NULL); + + if (len != 0 && !is_error_code(data, len)) + raw = data; + + else + { + target->read_single_register = false; + + g_gdb_stream_mark_packet_as_free(stream, packet); + + read_all_register_fallback: + + /** + * Utilisation de la méthode de masse au besoin... + */ + + packet = g_gdb_stream_get_free_packet(stream); + + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, "g"); + + result = g_gdb_stream_send_packet(stream, packet); + + g_gdb_stream_mark_packet_as_free(stream, packet); + + if (!result) + goto ggtrr_error; + + /* Réception de la réponse */ + + packet = g_gdb_stream_recv_packet(stream); + + g_gdb_packet_get_data(packet, &data, &len, NULL); + + result = g_gdb_target_find_register_offset(target, index, &offset); + + if (!result || offset > len) + goto ggtrr_exit; + + raw = data + offset; + len -= offset; + + } + + /* Lecture finale de la valeur recherchée */ + + va_start(ap, size); + + switch (size) + { + case 8: + val8 = va_arg(ap, uint8_t *); + result = hex_to_u8(raw, val8); + break; + + case 16: + val16 = va_arg(ap, uint16_t *); + result = hex_to_u16(raw, &conv16); + *val16 = from_u16(&conv16, endian); + break; + + case 32: + val32 = va_arg(ap, uint32_t *); + result = hex_to_u32(raw, &conv32); + *val32 = from_u32(&conv32, endian); + break; + + case 64: + val64 = va_arg(ap, uint64_t *); + result = hex_to_u64(raw, &conv64); + *val64 = from_u64(&conv64, endian); + break; + + default: + assert(false); + result = false; + break; + + } + + va_end(ap); + + ggtrr_exit: + + g_gdb_stream_mark_packet_as_free(stream, packet); + + ggtrr_error: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : target = ensemble d'informations liées à l'architecture. * +* stream = flux de communication ouvert avec le débogueur. * +* endian = boutisme de la cible. * +* reg = désignation humaine du register à consulter. * +* size = taille des données mises en jeu. * +* ... = emplacement de la valeur à écrire. * +* * +* Description : Effectue l'écriture d'un registre donné. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_gdb_target_write_register(GGdbTarget *target, GGdbStream *stream, SourceEndian endian, const char *reg, size_t size, ...) +{ + bool result; /* Bilan d'opération à renvoyer*/ + va_list ap; /* Liste variable d'arguments */ + const uint8_t *val8; /* Valeur sur 8 bits */ + const uint16_t *val16; /* Valeur sur 16 bits */ + uint16_t conv16; /* Valeur adaptée sur 16 bits */ + const uint32_t *val32; /* Valeur sur 32 bits */ + uint32_t conv32; /* Valeur adaptée sur 32 bits */ + const uint64_t *val64; /* Valeur sur 64 bits */ + uint64_t conv64; /* Valeur adaptée sur 64 bits */ + char hexval[17]; /* Valeur sous forme hexa */ + unsigned int index; /* Indice du registre ciblé */ + GGdbPacket *packet; /* Paquet de communication */ + char cmd[sizeof(XSTR(UINT_MAX)) + 1]; /* Elément de requête */ + const char *data; /* Données reçues à analyser */ + size_t len; /* Quantité de ces données */ + char *new; /* Nouvelles valeurs générales */ + size_t offset; /* Position dans la masse */ + + /* Tronc commun : récupération de la valeur */ + + va_start(ap, size); + + switch (size) + { + case 8: + val8 = va_arg(ap, uint8_t *); + result = u8_to_hex(val8, hexval); + break; + + case 16: + val16 = va_arg(ap, uint16_t *); + conv16 = to_u16(val16, endian); + result = u16_to_hex(&conv16, hexval); + break; + + case 32: + val32 = va_arg(ap, uint32_t *); + conv32 = to_u32(val32, endian); + result = u32_to_hex(&conv32, hexval); + break; + + case 64: + val64 = va_arg(ap, uint64_t *); + conv64 = to_u64(val64, endian); + result = u16_to_hex(&conv64, hexval); + break; + + default: + assert(false); + result = false; + break; + + } + + va_end(ap); + + if (!result) + goto ggtwr_error; + + /* Préparation de la suite */ + + result = g_gdb_target_find_register_index(target, reg, &index); + if (!result) goto ggtwr_error; + + /** + * Essai avec la méthode précise. + */ + + if (!target->write_single_register) + goto write_all_register_fallback; + + packet = g_gdb_stream_get_free_packet(stream); + + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, "P"); + + snprintf(cmd, sizeof(cmd), "%x", index); + g_gdb_packet_append(packet, cmd); + + g_gdb_packet_append(packet, "="); + + g_gdb_packet_append(packet, hexval); + + result = g_gdb_stream_send_packet(stream, packet); + + g_gdb_stream_mark_packet_as_free(stream, packet); + + if (!result) + goto ggtwr_error; + + /* Réception de la réponse */ + + packet = g_gdb_stream_recv_packet(stream); + + g_gdb_packet_get_data(packet, &data, &len, NULL); + + if (is_error_code(data, len) || strcmp(data, "OK") != 0) + { + target->write_single_register = false; + + g_gdb_stream_mark_packet_as_free(stream, packet); + + write_all_register_fallback: + + /** + * Utilisation de la méthode de masse au besoin... + */ + + /* Lecture de l'ensemble des registres */ + + packet = g_gdb_stream_get_free_packet(stream); + + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, "g"); + + result = g_gdb_stream_send_packet(stream, packet); + + g_gdb_stream_mark_packet_as_free(stream, packet); + + if (!result) + goto ggtwr_error; + + /* Réception de la réponse et mise à jour */ + + packet = g_gdb_stream_recv_packet(stream); + + g_gdb_packet_get_data(packet, &data, &len, NULL); + + result = g_gdb_target_find_register_offset(target, index, &offset); + + if (!result || offset > len) + goto ggtwr_exit; + + new = (char *)malloc(len); + + memcpy(new, data, len); + memcpy(new + offset, hexval, strlen(hexval)); + + g_gdb_stream_mark_packet_as_free(stream, packet); + + /* Ecrasement de tous les registres */ + + packet = g_gdb_stream_get_free_packet(stream); + + g_gdb_packet_start_new_command(packet); + g_gdb_packet_append(packet, "G"); + + g_gdb_packet_append(packet, new); + free(new); + + result = g_gdb_stream_send_packet(stream, packet); + + g_gdb_stream_mark_packet_as_free(stream, packet); + + if (!result) + goto ggtwr_error; + + /* Réception de la réponse */ + + packet = g_gdb_stream_recv_packet(stream); + + g_gdb_packet_get_data(packet, &data, &len, NULL); + + result = (!is_error_code(data, len) && strcmp(data, "OK") == 0); + + } + + ggtwr_exit: + + g_gdb_stream_mark_packet_as_free(stream, packet); + + ggtwr_error: + + return result; + +} diff --git a/plugins/gdbrsp/target.h b/plugins/gdbrsp/target.h new file mode 100644 index 0000000..bbdbec1 --- /dev/null +++ b/plugins/gdbrsp/target.h @@ -0,0 +1,72 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * target.h - prototypes pour la gestion des éléments propres à l'architecture reconnue par GDB + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _DEBUG_GDBRSP_TARGET_H +#define _DEBUG_GDBRSP_TARGET_H + + +#include +#include + + +#include "stream.h" +#include "../../common/endianness.h" + + + +#define G_TYPE_GDB_TARGET (g_gdb_target_get_type()) +#define G_GDB_TARGET(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_GDB_TARGET, GGdbTarget)) +#define G_IS_GDB_TARGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_GDB_TARGET)) +#define G_GDB_TARGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_TARGET, GGdbTargetClass)) +#define G_IS_GDB_TARGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_TARGET)) +#define G_GDB_TARGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_TARGET, GGdbTargetClass)) + + +/* Indications quant à l'interfaçage client/serveur GDB (instance) */ +typedef struct _GGdbTarget GGdbTarget; + +/* Indications quant à l'interfaçage client/serveur GDB (classe) */ +typedef struct _GGdbTargetClass GGdbTargetClass; + + +/* Indique le type défini par la GLib pour les détails d'interfaçage GDB. */ +GType g_gdb_target_get_type(void); + +/* Crée une définition des détails d'interfaçage GDB. */ +GGdbTarget *g_gdb_target_new(GGdbStream *); + +/* Liste l'ensemble des registres appartenant à un groupe. */ +char **g_gdb_target_get_register_names(const GGdbTarget *, const char *, size_t *); + +/* Indique la taille associée à un registre donné. */ +unsigned int g_gdb_target_get_register_size(const GGdbTarget *, const char *); + +/* Effectue la lecture d'un registre donné. */ +bool g_gdb_target_read_register(GGdbTarget *, GGdbStream *, SourceEndian, const char *, size_t, ...); + +/* Effectue l'écriture d'un registre donné. */ +bool g_gdb_target_write_register(GGdbTarget *, GGdbStream *, SourceEndian, const char *, size_t, ...); + + + +#endif /* _DEBUG_GDBRSP_TARGET_H */ diff --git a/plugins/gdbrsp/tcp.c b/plugins/gdbrsp/tcp.c new file mode 100644 index 0000000..8458dc6 --- /dev/null +++ b/plugins/gdbrsp/tcp.c @@ -0,0 +1,280 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * tcp.c - gestion des connexions TCP aux serveurs GDB. + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "tcp.h" + + +#include +#include +#include +#include +#include +#include + + +#include "stream-int.h" + + +#include "../../common/net.h" + + +/* Flux de communication TCP avec un serveur GDB (instance) */ +struct _GGdbTcpClient +{ + GGdbStream parent; /* A laisser en premier */ + +}; + + +/* Flux de communication TCP avec un serveur GDB (classe) */ +struct _GGdbTcpClientClass +{ + GGdbStreamClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des flux de communication TCP avec GDB. */ +static void g_gdb_tcp_client_class_init(GGdbTcpClientClass *); + +/* Initialise une instance de flux de communication avec GDB. */ +static void g_gdb_tcp_client_init(GGdbTcpClient *); + +/* Ouvre une connexion TCP à un serveur GDB. */ +//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); + +/* Réceptionne un octet de donnée d'un serveur GDB. */ +static bool g_gdb_tcp_client_recv_byte(GGdbTcpClient *, char *); + + + +/* Indique le type défini pour un flux de communication TCP avec un serveur GDB. */ +G_DEFINE_TYPE(GGdbTcpClient, g_gdb_tcp_client, G_TYPE_GDB_STREAM); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des flux de communication TCP avec GDB. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_tcp_client_class_init(GGdbTcpClientClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : client = instance à initialiser. * +* * +* Description : Initialise une instance de flux de communication avec GDB. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_gdb_tcp_client_init(GGdbTcpClient *client) +{ + GGdbStream *stream; /* Version parente */ + + stream = G_GDB_STREAM(client); + + stream->send_data = (send_gdb_data_fc)g_gdb_tcp_client_send_data; + stream->recv_byte = (recv_gdb_byte_fc)g_gdb_tcp_client_recv_byte; + +} + + +/****************************************************************************** +* * +* Paramètres : server = nom ou adresse du serveur à contacter. * +* port = port de connexion. * +* * +* Description : Ouvre une connexion TCP à un serveur GDB. * +* * +* Retour : Flux ouvert en lecture/écriture ou -1 en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ +#if 0 +static int connect_via_tcp(const char *server, const char *port) +{ + 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 */ + struct sockaddr_in addr; /* Infos de connexion distante */ + + 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; + + ret = getpeername(result, (struct sockaddr *)&addr, (socklen_t []){ sizeof(struct sockaddr_in) }); + if (ret == -1) + { + perror("getpeername"); + close(result); + return -1; + } + + printf("Connecté à %s:%hd\n", server, ntohs(addr.sin_port)); + + return result; + +} +#endif + +/****************************************************************************** +* * +* Paramètres : server = nom ou adresse du serveur à contacter. * +* port = port de connexion. * +* owner = débogueur tributaire du canal de communication. * +* * +* Description : Crée une nouvelle connexion TCP à un serveur GDB. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GGdbStream *g_gdb_tcp_client_new(const char *server, const char *port, GGdbDebugger *owner) +{ + GGdbTcpClient *result; /* Structure à retourner */ + int sock; /* Flux ouvert à construire */ + + sock = connect_via_tcp(server, port, NULL); + if (sock == -1) return NULL; + + result = g_object_new(G_TYPE_GDB_TCP_CLIENT, NULL); + + G_GDB_STREAM(result)->fd = sock; + + G_GDB_STREAM(result)->owner = owner; + g_object_ref(G_OBJECT(owner)); + + if (!g_gdb_stream_listen(G_GDB_STREAM(result))) + goto ggtcn_error; + + return G_GDB_STREAM(result); + + ggtcn_error: + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : client = flux ouvert en écriture à utiliser. * +* data = données à envoyer. * +* len = quantité de ces données. * +* * +* Description : Envoie des données à un serveur GDB. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_tcp_client_send_data(GGdbTcpClient *client, const char *data, size_t len) +{ + ssize_t sent; /* Quantité de données envoyée */ + + sent = send(G_GDB_STREAM(client)->fd, data, len, 0); + + //printf(" sent '%s'\n", data); + //printf(" sent ? %d vs %d\n", (int)sent, (int)len); + + return (sent == len); + +} + + +/****************************************************************************** +* * +* Paramètres : client = flux ouvert en lecture à utiliser. * +* data = donnée à recevoir. * +* * +* Description : Réceptionne un octet de donnée d'un serveur GDB. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_gdb_tcp_client_recv_byte(GGdbTcpClient *client, char *data) +{ + ssize_t got; /* Quantité de données reçue */ + + got = recv(G_GDB_STREAM(client)->fd, data, 1, 0); + + //printf(" got ? %d vs %d -> %c (0x%02hhx\n", (int)got, (int)1, *data, *data); + + return (got == 1); + +} diff --git a/plugins/gdbrsp/tcp.h b/plugins/gdbrsp/tcp.h new file mode 100644 index 0000000..3472fd2 --- /dev/null +++ b/plugins/gdbrsp/tcp.h @@ -0,0 +1,57 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * tcp.h - prototypes pour la gestion des connexions TCP aux serveurs GDB. + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _DEBUG_GDBRSP_TCP_H +#define _DEBUG_GDBRSP_TCP_H + + +#include "gdb.h" +#include "stream.h" + + + +#define G_TYPE_GDB_TCP_CLIENT g_gdb_tcp_client_get_type() +#define G_GDB_TCP_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_gdb_tcp_client_get_type(), GGdbTcpClient)) +#define G_IS_GDB_TCP_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_gdb_tcp_client_get_type())) +#define G_GDB_TCP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_TCP_CLIENT, GGdbTcpClientClass)) +#define G_IS_GDB_TCP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_TCP_CLIENT)) +#define G_GDB_TCP_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_TCP_CLIENT, GGdbTcpClientClass)) + + +/* Flux de communication TCP avec un serveur GDB (instance) */ +typedef struct _GGdbTcpClient GGdbTcpClient; + +/* Flux de communication TCP avec un serveur GDB (classe) */ +typedef struct _GGdbTcpClientClass GGdbTcpClientClass; + + + +/* Indique le type défini pour un flux de communication TCP avec un serveur GDB. */ +GType g_gdb_tcp_client_get_type(void); + +/* Crée une nouvelle connexion TCP à un serveur GDB. */ +GGdbStream *g_gdb_tcp_client_new(const char *, const char *, GGdbDebugger *); + + + +#endif /* _DEBUG_GDBRSP_TCP_H */ diff --git a/plugins/gdbrsp/utils.c b/plugins/gdbrsp/utils.c new file mode 100644 index 0000000..1088e51 --- /dev/null +++ b/plugins/gdbrsp/utils.c @@ -0,0 +1,354 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * utils.h - fonctions qui simplifient la vie dans les interactions avec un serveur GDB + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "utils.h" + + +#include +#include +#include +#include +#include +#include + + + +/****************************************************************************** +* * +* Paramètres : data = données à inspecter. * +* len = quantité de ces données. * +* * +* Description : Indique si les données correspondent à un code d'erreur. * +* * +* Retour : Bilan de l'analyse. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool is_error_code(const char *data, size_t len) +{ + bool result; /* Bilan à retourner */ + + result = (len == 3); + + if (result) + result = (data[0] == 'E' && isdigit(data[1]) && isdigit(data[2])); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = données à analyser. * +* size = taille de ces données. * +* byte = statut de sortie d'un programme. [OUT] * +* * +* Description : Relit une valeur sur 8 bits et deux lettres. * +* * +* Retour : Bilan de la lecture. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_fixed_byte(const char *data, size_t len, uint8_t *byte) +{ + bool result; /* Bilan à retourner */ + const char *iter; /* Boucle de parcours #1 */ + size_t i; /* Boucle de parcours #2 */ + uint8_t nibble; /* Valeur affichée */ + + result = true; + + len = MIN(2, len); + + for (i = 0, iter = data; i < len; i++, iter++) + { + switch (*iter) + { + case '0' ... '9': + nibble = *iter - '0'; + break; + + case 'a' ... 'f': + nibble = *iter - 'a' + 10; + break; + + case 'A' ... 'F': + nibble = *iter - 'A' + 10; + break; + + default: + result = false; + break; + + } + + if (!result) + break; + + if (i == 0) + *byte = (nibble << 4); + else + *byte |= nibble; + + } + + if (result) + result = (i == 2); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : hex = tampon d'origine assez grand. * +* size = taille de la valeur à considérer pour les travaux. * +* value = valeur sur XX bits à transcrire. [OUT] * +* * +* Description : Traduit en valeur sur XX bits une forme textuelle. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool hex_to_any_u(const char *hex, size_t size, ...) +{ + bool result; /* Bilan à retourner */ + va_list ap; /* Gestion de l'inconnue */ + uint8_t *value8; /* Valeur sur 8 bits */ + uint16_t *value16; /* Valeur sur 16 bits */ + uint32_t *value32; /* Valeur sur 32 bits */ + uint64_t *value64; /* Valeur sur 64 bits */ + uint8_t *iter; /* Boucle de parcours #1 */ + size_t i; /* Boucle de parcours #2 */ + char nibble; /* Valeur à afficher */ + + result = false; + + /* Récupération de la destination */ + + va_start(ap, size); + + switch (size) + { + case 1: + value8 = va_arg(ap, uint8_t *); + iter = value8; + break; + + case 2: + value16 = va_arg(ap, uint16_t *); + iter = (uint8_t *)value16; + break; + + case 4: + value32 = va_arg(ap, uint32_t *); + iter = (uint8_t *)value32; + break; + + case 8: + value64 = va_arg(ap, uint64_t *); + iter = (uint8_t *)value64; + break; + + default: + goto done; + break; + + } + + /* Lecture de la valeur */ + + for (i = 0; i < size; i++, iter++) + { + *iter = 0; + + nibble = hex[i * 2]; + + switch (nibble) + { + case '0' ... '9': + *iter = (nibble - '0') << 4; + break; + + case 'a' ... 'f': + *iter = (nibble - 'a' + 0xa) << 4; + break; + + case 'A' ... 'F': + *iter = (nibble - 'A' + 0xa) << 4; + break; + + default: + goto done; + break; + + } + + nibble = hex[i * 2 + 1]; + + switch (nibble) + { + case '0' ... '9': + *iter |= (nibble - '0'); + break; + + case 'a' ... 'f': + *iter |= (nibble - 'a' + 0xa); + break; + + case 'A' ... 'F': + *iter |= (nibble - 'A' + 0xa); + break; + + default: + goto done; + break; + + } + + } + + result = (i == size); + + done: + + va_end(ap); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : size = taille de la valeur à considérer pour les travaux. * +* hex = tampon de destination assez grand. * +* value = valeur sur XX bits à transcrire. [OUT] * +* * +* Description : Traduit une valeur sur XX bits en forme textuelle. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool any_u_to_hex(size_t size, char hex[17], ...) +{ + bool result; /* Bilan à retourner */ + va_list ap; /* Gestion de l'inconnue */ + uint8_t *value8; /* Valeur sur 8 bits */ + uint16_t *value16; /* Valeur sur 16 bits */ + uint32_t *value32; /* Valeur sur 32 bits */ + uint64_t *value64; /* Valeur sur 64 bits */ + size_t i; /* Boucle de parcours #1 */ + const uint8_t *iter; /* Boucle de parcours #2 */ + uint8_t nibble; /* Valeur à retenir */ + + result = true; + + /* Récupération de la destination */ + + va_start(ap, hex); + + switch (size) + { + case 1: + value8 = va_arg(ap, uint8_t *); + iter = (const uint8_t *)value8; + break; + + case 2: + value16 = va_arg(ap, uint16_t *); + iter = (const uint8_t *)value16; + break; + + case 4: + value32 = va_arg(ap, uint32_t *); + iter = (const uint8_t *)value32; + break; + + case 8: + value64 = va_arg(ap, uint64_t *); + iter = (const uint8_t *)value64; + break; + + default: + result = false; + goto done; + break; + + } + + /* Lecture de la valeur */ + + for (i = 0; i < size; i++, iter++) + { + nibble = (*iter & 0xf0) >> 4; + + switch (nibble) + { + case 0x0 ... 0x9: + hex[i * 2] = '0' + nibble; + break; + + case 0xa ... 0xf: + hex[i * 2] = 'A' + nibble - 0xa; + break; + + } + + nibble = (*iter & 0x0f); + + switch (nibble) + { + case 0x0 ... 0x9: + hex[i * 2 + 1] = '0' + nibble; + break; + + case 0xa ... 0xf: + hex[i * 2 + 1] = 'A' + nibble - 0xa; + break; + + } + + } + + hex[size * 2] = '\0'; + + done: + + va_end(ap); + + return result; + +} diff --git a/plugins/gdbrsp/utils.h b/plugins/gdbrsp/utils.h new file mode 100644 index 0000000..833fe69 --- /dev/null +++ b/plugins/gdbrsp/utils.h @@ -0,0 +1,58 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * utils.h - prototypes pour les fonctions qui simplifient la vie dans les interactions avec un serveur GDB + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _DEBUG_GDBRSP_UTILS_H +#define _DEBUG_GDBRSP_UTILS_H + + +#include +#include +#include + + + +/* Indique si les données correspondent à un code d'erreur. */ +bool is_error_code(const char *, size_t); + +/* Relit une valeur sur 8 bits et deux lettres. */ +bool read_fixed_byte(const char *, size_t, uint8_t *); + +/* Traduit en valeur sur XX bits une forme textuelle. */ +bool hex_to_any_u(const char *, size_t, ...); + +#define hex_to_u8(h, v) hex_to_any_u(h, 1, v) +#define hex_to_u16(h, v) hex_to_any_u(h, 2, v) +#define hex_to_u32(h, v) hex_to_any_u(h, 4, v) +#define hex_to_u64(h, v) hex_to_any_u(h, 8, v) + +/* Traduit une valeur sur XX bits en forme textuelle. */ +bool any_u_to_hex(size_t, char [17], ...); + +#define u8_to_hex(v, h) any_u_to_hex(1, h, v) +#define u16_to_hex(v, h) any_u_to_hex(2, h, v) +#define u32_to_hex(v, h) any_u_to_hex(4, h, v) +#define u64_to_hex(v, h) any_u_to_hex(8, h, v) + + + +#endif /* _DEBUG_GDBRSP_UTILS_H */ diff --git a/plugins/java/Makefile.am b/plugins/java/Makefile.am new file mode 100644 index 0000000..0e40bfa --- /dev/null +++ b/plugins/java/Makefile.am @@ -0,0 +1,29 @@ + +noinst_LTLIBRARIES = libformatjava.la + +libformatjava_la_SOURCES = \ + java-int.h java-int.c \ + java.h java.c \ + java_def.h \ + pool.h pool.c + + +# libformatjava_la_SOURCES = \ +# attribute.h attribute.c \ +# e_java.h e_java.c \ +# field.h field.c \ +# java-int.h \ +# method.h method.c \ +# pool.h pool.c + +libformatjava_la_LDFLAGS = + + +devdir = $(includedir)/chrysalide/$(subdir:src/%=%) + +dev_HEADERS = $(libformatjava_la_SOURCES:%c=) + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/java/attribute.c b/plugins/java/attribute.c new file mode 100644 index 0000000..3e04ea9 --- /dev/null +++ b/plugins/java/attribute.c @@ -0,0 +1,717 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * attribute.c - manipulation des attributs Java + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "attribute.h" + + +#include +#include + + +#include "java-int.h" +#include "pool.h" +#include "../../common/endianness.h" +#include "../../panel/log.h" + + + +#define _(str) str + + + +/* Charge les propriétés d'un attribut quelconque. */ +bool load_java_attribute(java_format *, java_attribute *, off_t *); + +/* Décharge les propriétés d'un attribut quelconque. */ +void unload_java_attribute(java_format *, java_attribute *); + +/* Charge les propriétés d'un attribut de valeur constante. */ +bool load_java_const_value_attribute(java_format *, const_value_attrib *, off_t *); + +/* Charge les propriétés d'un attribut de code. */ +bool load_java_code_attribute(java_format *, code_attrib *, off_t *); + +/* Décharge les propriétés d'un attribut de code. */ +void unload_java_code_attribute(java_format *, code_attrib *); + +/*Charge les propriétés d'un attribut d'exceptions lançables. */ +bool load_java_exceptions_attribute(java_format *, exceptions_attrib *, off_t *); + +/* Décharge les propriétés d'un attribut d'exceptions lançables. */ +void unload_java_exceptions_attribute(java_format *, exceptions_attrib *); + +/* Charge les propriétés d'un attribut de classes internes. */ +bool load_java_inner_classes_attribute(java_format *, inner_classes_attrib *, off_t *); + +/* Décharge les propriétés d'un attribut de classes internes. */ +void unload_java_inner_classes_attribute(java_format *, inner_classes_attrib *); + +/* Charge les propriétés d'un attribut de fichier source. */ +bool load_java_source_file_attribute(java_format *, source_file_attrib *, off_t *); + +/* Charge les propriétés d'un attribut de correspondance. */ +bool load_java_line_number_attribute(java_format *, line_number_attrib *, off_t *); + +/* Décharge les propriétés d'un attribut de correspondance. */ +void unload_java_line_number_attribute(java_format *, line_number_attrib *); + +/* Charge les propriétés d'un attribut de variables locales. */ +bool load_java_local_variables_attribute(java_format *, local_variables_attrib *, off_t *); + +/* Décharge les propriétés d'un attribut de variables locales. */ +void unload_java_local_variables_attribute(java_format *, local_variables_attrib *); + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* pos = point de lecture à faire évoluer. [OUT] * +* attributes = tableau des attributs chargés. [OUT] * +* count = nombre d'éléments à charger. [OUT] * +* * +* Description : Charge les attribus d'un élément d'un binaire Java. * +* * +* Retour : true si l'opération s'est bien déroulée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_java_attributes(java_format *format, off_t *pos, java_attribute **attributes, uint16_t *count) +{ + bool result; /* Bilan à remonter */ + uint16_t i; /* Boucle de parcours */ + + result = read_u16(count, EXE_FORMAT(format)->content, pos, + EXE_FORMAT(format)->length, SRE_BIG); + + if (!result) return false; + + if (*count > 0) + { + *attributes = (java_attribute *)calloc(*count, sizeof(java_attribute)); + + for (i = 0; i < *count && result; i++) + result = load_java_attribute(format, &(*attributes)[i], pos); + + if (!result) + unload_java_attributes(format, *attributes, *count); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à libérer. * +* attributes = tableau des attributs à décharger. * +* count = nombre d'éléments à décharger. * +* * +* Description : Décharge les attribus d'un élément d'un binaire Java. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_java_attributes(java_format *format, java_attribute *attributes, uint16_t count) +{ + uint16_t i; /* Boucle de parcours */ + + for (i = 0; i < count; i++) + unload_java_attribute(format, &attributes[i]); + + free(attributes); + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* attrib = élément à spécifier. [OUT] * +* pos = point de lecture à faire évoluer. [OUT] * +* * +* Description : Charge les propriétés d'un attribut quelconque. * +* * +* Retour : true si l'opération s'est bien déroulée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_java_attribute(java_format *format, java_attribute *attrib, off_t *pos) +{ + bool result; /* Bilan à retourner */ + uint16_t index; /* Indice du nom assimilé */ + const char *name; /* Version humainement lisible */ + uint32_t attrib_length; /* Taille de la charge utile */ + off_t saved_pos; /* Conservation de la position */ + + result = read_u16(&index, EXE_FORMAT(format)->content, pos, + EXE_FORMAT(format)->length, SRE_BIG); + + result &= get_java_pool_ut8_string(format, index, &name); + + if (result) + { + result = read_u32(&attrib_length, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + saved_pos = *pos; + + if (result && strcmp("ConstantValue", name) == 0) + { + attrib->type = JAT_CONSTANT_VALUE; + result = load_java_const_value_attribute(format, &attrib->info.const_value, pos); + } + + else if (result && strcmp("Code", name) == 0) + { + attrib->type = JAT_CODE; + result = load_java_code_attribute(format, &attrib->info.code, pos); + } + + else if (result && strcmp("Exceptions", name) == 0) + { + attrib->type = JAT_EXCEPTIONS; + result = load_java_exceptions_attribute(format, &attrib->info.exceptions, pos); + } + + else if (result && strcmp("InnerClasses", name) == 0) + { + attrib->type = JAT_INNER_CLASSES; + result = load_java_inner_classes_attribute(format, &attrib->info.inner_classes, pos); + } + + else if (result && strcmp("Synthetic", name) == 0) + attrib->type = JAT_SYNTHETIC; + + else if (result && strcmp("SourceFile", name) == 0) + { + attrib->type = JAT_LINE_NUMBER; + result = load_java_source_file_attribute(format, &attrib->info.source_file, pos); + } + + else if (result && strcmp("LineNumberTable", name) == 0) + { + attrib->type = JAT_SOURCE_FILE; + result = load_java_line_number_attribute(format, &attrib->info.line_number, pos); + } + + else if (result && strcmp("LocalVariableTable", name) == 0) + { + attrib->type = JAT_LOCAL_VARIABLES; + result = load_java_local_variables_attribute(format, &attrib->info.local_vars, pos); + } + + else if (result && strcmp("Deprecated", name) == 0) + attrib->type = JAT_DEPRECATED; + + else if (result) + { + result = false; + log_variadic_message(LMT_BAD_BINARY, _("Attribute name not supported: '%s'"), name); + } + + if (result && attrib_length != (*pos - saved_pos)) + log_variadic_message(LMT_BAD_BINARY, _("Size indication of the attribute '%s' not verified: %d vs %d"), + name, attrib_length, *pos - saved_pos); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* attrib = élément à libérer. * +* * +* Description : Décharge les propriétés d'un attribut quelconque. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_java_attribute(java_format *format, java_attribute *attrib) +{ + switch (attrib->type) + { + case JAT_NONE: + break; + + case JAT_CONSTANT_VALUE: + break; + + case JAT_CODE: + unload_java_code_attribute(format, &attrib->info.code); + break; + + case JAT_EXCEPTIONS: + unload_java_exceptions_attribute(format, &attrib->info.exceptions); + break; + + case JAT_INNER_CLASSES: + unload_java_inner_classes_attribute(format, &attrib->info.inner_classes); + break; + + case JAT_SYNTHETIC: + break; + + case JAT_SOURCE_FILE: + break; + + case JAT_LINE_NUMBER: + unload_java_line_number_attribute(format, &attrib->info.line_number); + break; + + case JAT_LOCAL_VARIABLES: + unload_java_local_variables_attribute(format, &attrib->info.local_vars); + break; + + case JAT_DEPRECATED: + break; + + } + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* attrib = élément à spécifier. [OUT] * +* pos = point de lecture à faire évoluer. [OUT] * +* * +* Description : Charge les propriétés d'un attribut de valeur constante. * +* * +* Retour : true si l'opération s'est bien déroulée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_java_const_value_attribute(java_format *format, const_value_attrib *attrib, off_t *pos) +{ + bool result; /* Bilan à retourner */ + + result = read_u16(&attrib->const_value_index, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* attrib = élément à spécifier. [OUT] * +* pos = point de lecture à faire évoluer. [OUT] * +* * +* Description : Charge les propriétés d'un attribut de code. * +* * +* Retour : true si l'opération s'est bien déroulée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_java_code_attribute(java_format *format, code_attrib *attrib, off_t *pos) +{ + bool result; /* Bilan à retourner */ + uint16_t i; /* Boucle de parcours */ + + result = read_u16(&attrib->max_stack, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + result &= read_u16(&attrib->max_locals, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + result &= read_u32(&attrib->code_length, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + result &= ((*pos + attrib->code_length) <= EXE_FORMAT(format)->length); + + if (result) + { + attrib->content = *pos; + *pos += attrib->code_length; + } + + result &= read_u16(&attrib->exceptions_count, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + if (result && attrib->exceptions_count > 0) + { + attrib->exceptions = (code_exception *)calloc(attrib->exceptions_count, sizeof(code_exception)); + + for (i = 0; i < attrib->exceptions_count && result; i++) + { + result &= read_u16(&attrib->exceptions[i].start_pc, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + result &= read_u16(&attrib->exceptions[i].end_pc, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + result &= read_u16(&attrib->exceptions[i].handler_pc, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + result &= read_u16(&attrib->exceptions[i].catch_type, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + } + + } + + result &= load_java_attributes(format, pos, &attrib->attributes, &attrib->attributes_count); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* attrib = élément à libérer de la mémoire. * +* * +* Description : Décharge les propriétés d'un attribut de code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_java_code_attribute(java_format *format, code_attrib *attrib) +{ + if (attrib->exceptions != NULL) + free(attrib->exceptions); + + if (attrib->attributes != NULL) + unload_java_attributes(format, attrib->attributes, attrib->attributes_count); + +} + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* attrib = élément à spécifier. [OUT] * +* pos = point de lecture à faire évoluer. [OUT] * +* * +* Description : Charge les propriétés d'un attribut d'exceptions lançables. * +* * +* Retour : true si l'opération s'est bien déroulée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_java_exceptions_attribute(java_format *format, exceptions_attrib *attrib, off_t *pos) +{ + bool result; /* Bilan à retourner */ + uint16_t i; /* Boucle de parcours */ + + result = read_u16(&attrib->throw_count, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + if (result && attrib->throw_count > 0) + { + attrib->throw = (uint16_t *)calloc(attrib->throw_count, sizeof(uint16_t)); + + for (i = 0; i < attrib->throw_count && result; i++) + result &= read_u16(&attrib->throw[i], EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* attrib = élément à libérer de la mémoire. * +* * +* Description : Décharge les propriétés d'un attribut d'exceptions lançables.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_java_exceptions_attribute(java_format *format, exceptions_attrib *attrib) +{ + if (attrib->throw != NULL) + free(attrib->throw); + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* attrib = élément à spécifier. [OUT] * +* pos = point de lecture à faire évoluer. [OUT] * +* * +* Description : Charge les propriétés d'un attribut de classes internes. * +* * +* Retour : true si l'opération s'est bien déroulée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_java_inner_classes_attribute(java_format *format, inner_classes_attrib *attrib, off_t *pos) +{ + bool result; /* Bilan à retourner */ + uint16_t i; /* Boucle de parcours */ + + result = read_u16(&attrib->classes_count, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + if (result && attrib->classes_count > 0) + { + attrib->classes = (inner_class *)calloc(attrib->classes_count, sizeof(inner_class)); + + for (i = 0; i < attrib->classes_count && result; i++) + { + result &= read_u16(&attrib->classes[i].inner_class_info_index, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + result &= read_u16(&attrib->classes[i].outer_class_info_index, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + result &= read_u16(&attrib->classes[i].inner_name_index, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + result &= read_u16((uint16_t *)&attrib->classes[i].access, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + } + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* attrib = élément à libérer de la mémoire. * +* * +* Description : Décharge les propriétés d'un attribut de classes internes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_java_inner_classes_attribute(java_format *format, inner_classes_attrib *attrib) +{ + if (attrib->classes != NULL) + free(attrib->classes); + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* attrib = élément à spécifier. [OUT] * +* pos = point de lecture à faire évoluer. [OUT] * +* * +* Description : Charge les propriétés d'un attribut de fichier source. * +* * +* Retour : true si l'opération s'est bien déroulée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_java_source_file_attribute(java_format *format, source_file_attrib *attrib, off_t *pos) +{ + bool result; /* Bilan à retourner */ + + result = read_u16(&attrib->source_file_index, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* attrib = élément à spécifier. [OUT] * +* pos = point de lecture à faire évoluer. [OUT] * +* * +* Description : Charge les propriétés d'un attribut de correspondance. * +* * +* Retour : true si l'opération s'est bien déroulée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_java_line_number_attribute(java_format *format, line_number_attrib *attrib, off_t *pos) +{ + bool result; /* Bilan à retourner */ + uint16_t i; /* Boucle de parcours */ + + result = read_u16(&attrib->lines_count, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + if (result && attrib->lines_count > 0) + { + attrib->lines = (pc_and_line *)calloc(attrib->lines_count, sizeof(pc_and_line)); + + for (i = 0; i < attrib->lines_count && result; i++) + { + result &= read_u16(&attrib->lines[i].start_pc, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + result &= read_u16(&attrib->lines[i].number, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + } + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* attrib = élément à libérer de la mémoire. * +* * +* Description : Décharge les propriétés d'un attribut de correspondance. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_java_line_number_attribute(java_format *format, line_number_attrib *attrib) +{ + if (attrib->lines != NULL) + free(attrib->lines); + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* attrib = élément à spécifier. [OUT] * +* pos = point de lecture à faire évoluer. [OUT] * +* * +* Description : Charge les propriétés d'un attribut de variables locales. * +* * +* Retour : true si l'opération s'est bien déroulée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_java_local_variables_attribute(java_format *format, local_variables_attrib *attrib, off_t *pos) +{ + bool result; /* Bilan à retourner */ + uint16_t i; /* Boucle de parcours */ + + result = read_u16(&attrib->vars_count, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + if (result && attrib->vars_count > 0) + { + attrib->vars = (local_variable *)calloc(attrib->vars_count, sizeof(local_variable)); + + for (i = 0; i < attrib->vars_count && result; i++) + { + result &= read_u16(&attrib->vars[i].start_pc, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + result &= read_u16(&attrib->vars[i].length, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + result &= read_u16(&attrib->vars[i].name_index, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + result &= read_u16(&attrib->vars[i].descriptor_index, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + result &= read_u16(&attrib->vars[i].index, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + } + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* attrib = élément à libérer de la mémoire. * +* * +* Description : Décharge les propriétés d'un attribut de variables locales. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_java_local_variables_attribute(java_format *format, local_variables_attrib *attrib) +{ + if (attrib->vars != NULL) + free(attrib->vars); + +} diff --git a/plugins/java/attribute.h b/plugins/java/attribute.h new file mode 100644 index 0000000..155aa7e --- /dev/null +++ b/plugins/java/attribute.h @@ -0,0 +1,40 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * attribute.h - prototypes pour la manipulation des attributs Java + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _FORMAT_JAVA_ATTRIBUTE_H +#define _FORMAT_JAVA_ATTRIBUTE_H + + +#include "e_java.h" + + + +/* Charge les attribus d'un élément d'un binaire Java. */ +bool load_java_attributes(java_format *, off_t *, java_attribute **, uint16_t *); + +/* Décharge les attribus d'un élément d'un binaire Java. */ +void unload_java_attributes(java_format *, java_attribute *, uint16_t); + + + +#endif /* _FORMAT_JAVA_ATTRIBUTE_H */ diff --git a/plugins/java/e_java.c b/plugins/java/e_java.c new file mode 100644 index 0000000..7d05fa9 --- /dev/null +++ b/plugins/java/e_java.c @@ -0,0 +1,284 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * e_java.c - support du format Java + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "e_java.h" + + +#include +#include + + +#include "attribute.h" +#include "field.h" +#include "java-int.h" +#include "method.h" +#include "pool.h" +#include "../../common/endianness.h" + + + + +/* Indique le type d'architecture visée par le format. */ +FormatTargetMachine get_java_target_machine(const java_format *); + + + +/* Fournit les références aux zones de code à analyser. */ +bin_part **get_java_default_code_parts(const java_format *, size_t *); + + +/* Fournit le prototype de toutes les routines détectées. */ +GBinRoutine **get_all_java_routines(const java_format *, size_t *); + + + + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à parcourir. * +* length = taille du contenu en question. * +* * +* Description : Indique si le format peut être pris en charge ici. * +* * +* Retour : true si la réponse est positive, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool java_is_matching(const uint8_t *content, off_t length) +{ + bool result; /* Bilan à faire connaître */ + + result = false; + + if (length >= 4) + result = (strncmp((const char *)content, "\xca\xfe\xba\xbe", 4) == 0); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à parcourir. * +* length = taille du contenu en question. * +* * +* Description : Prend en charge une nouvelle classe Java. * +* * +* Retour : Adresse de la structure mise en place ou NULL en cas d'échec.* +* * +* Remarques : - * +* * +******************************************************************************/ + +exe_format *load_java(const uint8_t *content, off_t length) +{ + java_format *result; /* Adresse à retourner */ + off_t pos; /* Point d'analyse */ + uint32_t magic; /* Identifiant Java */ + uint16_t i; /* Boucle de parcours */ + + result = (java_format *)calloc(1, sizeof(java_format)); + + EXE_FORMAT(result)->content = content; + EXE_FORMAT(result)->length = length; + + EXE_FORMAT(result)->get_target_machine = (get_target_machine_fc)get_java_target_machine; + EXE_FORMAT(result)->get_def_parts = (get_def_parts_fc)get_java_default_code_parts; + EXE_FORMAT(result)->get_all_routines = (get_all_routines_fc)get_all_java_routines; + + pos = 0; + + if (!read_u32(&magic, content, &pos, length, SRE_BIG)) + goto ldj_error; + + if (!read_u16(&result->minor_version, content, &pos, length, SRE_BIG)) + goto ldj_error; + + if (!read_u16(&result->major_version, content, &pos, length, SRE_BIG)) + goto ldj_error; + + if (!load_java_pool(result, &pos)) + goto ldj_error; + + if (!read_u16((uint16_t *)&result->access, content, &pos, length, SRE_BIG)) + goto ldj_error; + + if (!read_u16(&result->this_class, content, &pos, length, SRE_BIG)) + goto ldj_error; + + if (!read_u16(&result->super_class, content, &pos, length, SRE_BIG)) + goto ldj_error; + + if (!read_u16(&result->interfaces_count, content, &pos, length, SRE_BIG)) + goto ldj_error; + + for (i = 0; i < result->interfaces_count; i++) + if (!read_u16(&result->interfaces[i], content, &pos, length, SRE_BIG)) + goto ldj_error; + + if (!load_java_fields(result, &pos)) + goto ldj_error; + + if (!load_java_methods(result, &pos)) + goto ldj_error; + + if (!load_java_attributes(result, &pos, &result->attributes, &result->attributes_count)) + goto ldj_error; + + return EXE_FORMAT(result); + + ldj_error: + + unload_java(result); + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à supprimer. * +* * +* Description : Efface la prise en charge une nouvelle classe Java. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_java(java_format *format) +{ + if (format->pool_len > 0) + unload_java_pool(format); + + if (format->interfaces_count > 0) + free(format->interfaces); + + if (format->fields_count > 0) + unload_java_fields(format); + + if (format->methods_count > 0) + unload_java_methods(format); + + if (format->attributes_count > 0) + unload_java_attributes(format, format->attributes, format->attributes_count); + + free(format); + +} + + + + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* * +* Description : Indique le type d'architecture visée par le format. * +* * +* Retour : Identifiant de l'architecture ciblée par le format. * +* * +* Remarques : - * +* * +******************************************************************************/ + +FormatTargetMachine get_java_target_machine(const java_format *format) +{ + return FTM_JVM; + +} + + + + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* count = quantité de zones listées. [OUT] * +* * +* Description : Fournit les références aux zones de code à analyser. * +* * +* Retour : Zones de code à analyser. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bin_part **get_java_default_code_parts(const java_format *format, size_t *count) +{ + bin_part **result; /* Tableau à retourner */ + uint16_t i; /* Boucle de parcours */ + off_t offset; /* Position physique */ + off_t size; /* Taille de la partie */ + bin_part *part; /* Partie à intégrer à la liste*/ + + result = NULL; + *count = 0; + + for (i = 0; i < format->methods_count; i++) + if (find_java_method_code_part(&format->methods[i], &offset, &size)) + { + part = create_bin_part(); + + set_bin_part_values(part, offset, size, offset); + + result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *)); + result[*count - 1] = part; + + } + + return result; + +} + + + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* count = taille du tableau créé. [OUT] * +* * +* Description : Fournit le prototype de toutes les routines détectées. * +* * +* Retour : Tableau créé ou NULL si aucun symbole de routine trouvé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinRoutine **get_all_java_routines(const java_format *format, size_t *count) +{ + *count = 0; + + return NULL; + +} diff --git a/plugins/java/e_java.h b/plugins/java/e_java.h new file mode 100644 index 0000000..65befbd --- /dev/null +++ b/plugins/java/e_java.h @@ -0,0 +1,49 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * e_java.h - prototypes pour le support du format Java + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _FORMAT_JAVA_E_JAVA_H +#define _FORMAT_JAVA_E_JAVA_H + + +#include "../exe_format.h" + + +/* Description des attributs Java */ +typedef struct _java_attribute java_attribute; + +/* Description du format Java */ +typedef struct _java_format java_format; + + +/* Indique si le format peut être pris en charge ici. */ +bool java_is_matching(const uint8_t *, off_t); + +/* Prend en charge une nouvelle classe Java. */ +exe_format *load_java(const uint8_t *, off_t); + +/* Efface la prise en charge une nouvelle classe Java. */ +void unload_java(java_format *); + + + +#endif /* _FORMAT_JAVA_E_JAVA_H */ diff --git a/plugins/java/field.c b/plugins/java/field.c new file mode 100644 index 0000000..e7df342 --- /dev/null +++ b/plugins/java/field.c @@ -0,0 +1,158 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * field.c - gestion des champs Java + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "field.h" + + +#include + + +#include "attribute.h" +#include "java-int.h" +#include "../../common/endianness.h" + + + +/* Charge les propriétés d'un champ de classe. */ +bool load_java_field(java_format *, java_field *, off_t *); + +/* Décharge les propriétés d'un champ de classe. */ +void unload_java_field(java_format *, java_field *); + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* pos = point de lecture à faire évoluer. [OUT] * +* * +* Description : Charge les champs d'un binaire Java. * +* * +* Retour : true si l'opération s'est bien déroulée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_java_fields(java_format *format, off_t *pos) +{ + bool result; /* Bilan à remonter */ + uint16_t i; /* Boucle de parcours */ + + result = read_u16(&format->fields_count, EXE_FORMAT(format)->content, pos, + EXE_FORMAT(format)->length, SRE_BIG); + + if (!result) return false; + + if (format->fields_count > 0) + { + format->fields = (java_field *)calloc(format->fields_count, sizeof(java_field)); + + for (i = 0; i < format->fields_count && result; i++) + result = load_java_field(format, &format->fields[i], pos); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à vider. * +* * +* Description : Décharge les champs d'un binaire Java. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_java_fields(java_format *format) +{ + uint16_t i; /* Boucle de parcours */ + + for (i = 0; i < format->fields_count; i++) + unload_java_field(format, &format->fields[i]); + + free(format->fields); + + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* field = élément à spécifier. [OUT] * +* pos = point de lecture à faire évoluer. [OUT] * +* * +* Description : Charge les propriétés d'un champ de classe. * +* * +* Retour : true si l'opération s'est bien déroulée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_java_field(java_format *format, java_field *field, off_t *pos) +{ + bool result; /* Bilan à retourner */ + + result = read_u16((uint16_t *)&field->access, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + result &= read_u16(&field->name_index, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + result &= read_u16(&field->descriptor_index, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + result &= load_java_attributes(format, pos, + &field->attributes, &field->attributes_count); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* field = élément à libérer. * +* * +* Description : Décharge les propriétés d'un champ de classe. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_java_field(java_format *format, java_field *field) +{ + if (field->attributes_count > 0) + unload_java_attributes(format, field->attributes, field->attributes_count); + +} diff --git a/plugins/java/field.h b/plugins/java/field.h new file mode 100644 index 0000000..686c13f --- /dev/null +++ b/plugins/java/field.h @@ -0,0 +1,40 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * field.h - prototypes pour la gestion des champs Java + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _FORMAT_JAVA_FIELD_H +#define _FORMAT_JAVA_FIELD_H + + +#include "e_java.h" + + + +/* Charge les champs d'un binaire Java. */ +bool load_java_fields(java_format *, off_t *); + +/* Décharge les champs d'un binaire Java. */ +void unload_java_fields(java_format *); + + + +#endif /* _FORMAT_JAVA_FIELD_H */ diff --git a/plugins/java/java-int.c b/plugins/java/java-int.c new file mode 100644 index 0000000..c1c8aa5 --- /dev/null +++ b/plugins/java/java-int.c @@ -0,0 +1,92 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * java-int.c - structures internes du format Java + * + * Copyright (C) 2010-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "java-int.h" + + +#include "pool.h" +#include "../../common/endianness.h" + + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* pos = position de début de lecture. [OUT] * +* header = structure lue à retourner. [OUT] * +* * +* Description : Procède à la lecture d'une en-tête de programme Java. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_java_header(const GJavaFormat *format, off_t *pos, java_header *header) +{ + bool result; /* Bilan à retourner */ + const bin_t *content; /* Contenu binaire à lire */ + off_t length; /* Taille totale du contenu */ + uint32_t magic; /* Identifiant Java */ + size_t i; /* Boucle de parcours */ + + result = true; + + content = NULL; //G_BIN_FORMAT(format)->content; + length = 0; //G_BIN_FORMAT(format)->length; + + result &= read_u32(&magic, content, pos, length, SRE_BIG); + printf("magic :: 0x%08x\n", magic); + result &= read_u16(&header->minor_version, content, pos, length, SRE_BIG); + result &= read_u16(&header->major_version, content, pos, length, SRE_BIG); + + printf("avant :: %d\n", result); + + result &= load_java_pool(format, pos); + + printf("après :: %d\n", result); + + result &= read_u16((uint16_t *)&header->access, content, pos, length, SRE_BIG); + result &= read_u16(&header->this_class, content, pos, length, SRE_BIG); + result &= read_u16(&header->super_class, content, pos, length, SRE_BIG); + result &= read_u16(&header->interfaces_count, content, pos, length, SRE_BIG); + +/* for (i = 0; i < header->interfaces_count; i++) */ +/* result &= read_u16(&header->interfaces[i], content, pos, length, SRE_BIG)) */ +/* goto ldj_error; */ + +/* result &= load_java_fields(result, pos); */ + +/* result &= load_java_methods(result, pos); */ + +/* result &= load_java_attributes(result, pos, &header->attributes, &header->attributes_count); */ + + return result; + +} + + + + + diff --git a/plugins/java/java-int.h b/plugins/java/java-int.h new file mode 100644 index 0000000..1636d1e --- /dev/null +++ b/plugins/java/java-int.h @@ -0,0 +1,66 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * java-int.h - prototypes pour les structures internes du format Java + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _FORMAT_JAVA_JAVA_INT_H +#define _FORMAT_JAVA_JAVA_INT_H + + +#include "java.h" +#include "java_def.h" +#include "../executable-int.h" + + + + + +/* Format d'exécutable Java (instance) */ +struct _GJavaFormat +{ + GExeFormat parent; /* A laisser en premier */ + + java_header header; /* En-tête du programme */ + +}; + +/* Format d'exécutable Java (classe) */ +struct _GJavaFormatClass +{ + GExeFormatClass parent; /* A laisser en premier */ + +}; + + + + + +/* Procède à la lecture d'une en-tête de programme Java. */ +bool read_java_header(const GJavaFormat *, off_t *, java_header *); + + + + + + + + +#endif /* _FORMAT_JAVA_JAVA_INT_H */ diff --git a/plugins/java/java.c b/plugins/java/java.c new file mode 100644 index 0000000..dcd8299 --- /dev/null +++ b/plugins/java/java.c @@ -0,0 +1,508 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * java.c - support du format Java + * + * Copyright (C) 2010-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "java.h" + + +#include + + +#include "java-int.h" + + + + + + + + + + + +/* Initialise la classe des formats d'exécutables Java. */ +static void g_java_format_class_init(GJavaFormatClass *); + +/* Initialise une instance de format d'exécutable Java. */ +static void g_java_format_init(GJavaFormat *); + +/* Supprime toutes les références externes. */ +static void g_java_format_dispose(GJavaFormat *); + +/* Procède à la libération totale de la mémoire. */ +static void g_java_format_finalize(GJavaFormat *); + +/* Indique le type d'architecture visée par le format. */ +static const char *g_java_format_get_target_machine(const GJavaFormat *); + + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à parcourir. * +* * +* Description : Indique si le format peut être pris en charge ici. * +* * +* Retour : true si la réponse est positive, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool java_is_matching(GBinContent *content) +{ + bool result; /* Bilan à faire connaître */ + vmpa2t addr; /* Tête de lecture initiale */ + char magic[4]; /* Idenfiant standard */ + + init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); + + result = g_binary_content_read_raw(content, &addr, 4, (bin_t *)magic); + + result &= (memcmp(magic, "\xca\xfe\xba\xbe", 4) == 0); + + return result; + +} + + +/* Indique le type défini pour un format d'exécutable Java. */ +G_DEFINE_TYPE(GJavaFormat, g_java_format, G_TYPE_EXE_FORMAT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des formats d'exécutables Java. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_java_format_class_init(GJavaFormatClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GExeFormatClass *exe; /* Version en exécutable */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_java_format_dispose; + object->finalize = (GObjectFinalizeFunc)g_java_format_finalize; + + exe = G_EXE_FORMAT_CLASS(klass); + + exe->get_machine = (get_target_machine_fc)g_java_format_get_target_machine; + //exe->refine_portions = (refine_portions_fc)g_java_format_refine_portions; + + exe->translate_phys = (translate_phys_fc)g_exe_format_without_virt_translate_offset_into_vmpa; + exe->translate_virt = (translate_virt_fc)g_exe_format_without_virt_translate_address_into_vmpa; + +} + + +/****************************************************************************** +* * +* Paramètres : format = instance à initialiser. * +* * +* Description : Initialise une instance de format d'exécutable Java. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_java_format_init(GJavaFormat *format) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : format = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_java_format_dispose(GJavaFormat *format) +{ + G_OBJECT_CLASS(g_java_format_parent_class)->dispose(G_OBJECT(format)); + +} + + +/****************************************************************************** +* * +* Paramètres : format = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_java_format_finalize(GJavaFormat *format) +{ + G_OBJECT_CLASS(g_java_format_parent_class)->finalize(G_OBJECT(format)); + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à parcourir. * +* length = taille du contenu en question. * +* * +* Description : Prend en charge un nouveau format Java. * +* * +* Retour : Adresse de la structure mise en place ou NULL en cas d'échec.* +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinFormat *g_java_format_new(const bin_t *content, off_t length) +{ + GJavaFormat *result; /* Structure à retourner */ + off_t offset; /* Tête de lecture */ + + result = g_object_new(G_TYPE_JAVA_FORMAT, NULL); + + //g_binary_format_set_content(G_BIN_FORMAT(result), content, length); + + + offset = 0; + + if (!read_java_header(result, &offset, &result->header)) + { + /* TODO */ + return NULL; + } + + + return G_BIN_FORMAT(result); + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* * +* Description : Indique le type d'architecture visée par le format. * +* * +* Retour : Identifiant de l'architecture ciblée par le format. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const char *g_java_format_get_target_machine(const GJavaFormat *format) +{ + return "jvm"; + +} + + + + + + + + + + + + +#if 0 + +#include +#include + + +#include "attribute.h" +#include "field.h" +#include "java-int.h" +#include "method.h" +#include "pool.h" +#include "../../common/endianness.h" + + + + +/* Indique le type d'architecture visée par le format. */ +FormatTargetMachine get_java_target_machine(const java_format *); + + + +/* Fournit les références aux zones de code à analyser. */ +bin_part **get_java_default_code_parts(const java_format *, size_t *); + + +/* Fournit le prototype de toutes les routines détectées. */ +GBinRoutine **get_all_java_routines(const java_format *, size_t *); + + + + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à parcourir. * +* length = taille du contenu en question. * +* * +* Description : Indique si le format peut être pris en charge ici. * +* * +* Retour : true si la réponse est positive, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool java_is_matching(const uint8_t *content, off_t length) +{ + bool result; /* Bilan à faire connaître */ + + result = false; + + if (length >= 4) + result = (strncmp((const char *)content, "\xca\xfe\xba\xbe", 4) == 0); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à parcourir. * +* length = taille du contenu en question. * +* * +* Description : Prend en charge une nouvelle classe Java. * +* * +* Retour : Adresse de la structure mise en place ou NULL en cas d'échec.* +* * +* Remarques : - * +* * +******************************************************************************/ + +exe_format *load_java(const uint8_t *content, off_t length) +{ + java_format *result; /* Adresse à retourner */ + off_t pos; /* Point d'analyse */ + uint32_t magic; /* Identifiant Java */ + uint16_t i; /* Boucle de parcours */ + + result = (java_format *)calloc(1, sizeof(java_format)); + + EXE_FORMAT(result)->content = content; + EXE_FORMAT(result)->length = length; + + EXE_FORMAT(result)->get_target_machine = (get_target_machine_fc)get_java_target_machine; + EXE_FORMAT(result)->get_def_parts = (get_def_parts_fc)get_java_default_code_parts; + EXE_FORMAT(result)->get_all_routines = (get_all_routines_fc)get_all_java_routines; + + pos = 0; + + if (!read_u32(&magic, content, &pos, length, SRE_BIG)) + goto ldj_error; + + if (!read_u16(&result->minor_version, content, &pos, length, SRE_BIG)) + goto ldj_error; + + if (!read_u16(&result->major_version, content, &pos, length, SRE_BIG)) + goto ldj_error; + + if (!load_java_pool(result, &pos)) + goto ldj_error; + + if (!read_u16((uint16_t *)&result->access, content, &pos, length, SRE_BIG)) + goto ldj_error; + + if (!read_u16(&result->this_class, content, &pos, length, SRE_BIG)) + goto ldj_error; + + if (!read_u16(&result->super_class, content, &pos, length, SRE_BIG)) + goto ldj_error; + + if (!read_u16(&result->interfaces_count, content, &pos, length, SRE_BIG)) + goto ldj_error; + + for (i = 0; i < result->interfaces_count; i++) + if (!read_u16(&result->interfaces[i], content, &pos, length, SRE_BIG)) + goto ldj_error; + + if (!load_java_fields(result, &pos)) + goto ldj_error; + + if (!load_java_methods(result, &pos)) + goto ldj_error; + + if (!load_java_attributes(result, &pos, &result->attributes, &result->attributes_count)) + goto ldj_error; + + return EXE_FORMAT(result); + + ldj_error: + + unload_java(result); + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à supprimer. * +* * +* Description : Efface la prise en charge une nouvelle classe Java. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_java(java_format *format) +{ + if (format->pool_len > 0) + unload_java_pool(format); + + if (format->interfaces_count > 0) + free(format->interfaces); + + if (format->fields_count > 0) + unload_java_fields(format); + + if (format->methods_count > 0) + unload_java_methods(format); + + if (format->attributes_count > 0) + unload_java_attributes(format, format->attributes, format->attributes_count); + + free(format); + +} + + + + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* * +* Description : Indique le type d'architecture visée par le format. * +* * +* Retour : Identifiant de l'architecture ciblée par le format. * +* * +* Remarques : - * +* * +******************************************************************************/ + +FormatTargetMachine get_java_target_machine(const java_format *format) +{ + return FTM_JVM; + +} + + + + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* count = quantité de zones listées. [OUT] * +* * +* Description : Fournit les références aux zones de code à analyser. * +* * +* Retour : Zones de code à analyser. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bin_part **get_java_default_code_parts(const java_format *format, size_t *count) +{ + bin_part **result; /* Tableau à retourner */ + uint16_t i; /* Boucle de parcours */ + off_t offset; /* Position physique */ + off_t size; /* Taille de la partie */ + bin_part *part; /* Partie à intégrer à la liste*/ + + result = NULL; + *count = 0; + + for (i = 0; i < format->methods_count; i++) + if (find_java_method_code_part(&format->methods[i], &offset, &size)) + { + part = create_bin_part(); + + set_bin_part_values(part, offset, size, offset); + + result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *)); + result[*count - 1] = part; + + } + + return result; + +} + + + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* count = taille du tableau créé. [OUT] * +* * +* Description : Fournit le prototype de toutes les routines détectées. * +* * +* Retour : Tableau créé ou NULL si aucun symbole de routine trouvé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinRoutine **get_all_java_routines(const java_format *format, size_t *count) +{ + *count = 0; + + return NULL; + +} + +#endif diff --git a/plugins/java/java.h b/plugins/java/java.h new file mode 100644 index 0000000..ad70e43 --- /dev/null +++ b/plugins/java/java.h @@ -0,0 +1,63 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * java.h - prototypes pour le support du format Java + * + * Copyright (C) 2010-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _FORMAT_JAVA_JAVA_H +#define _FORMAT_JAVA_JAVA_H + + +#include +#include +#include + + +#include "../../core/formats.h" + + + +#define G_TYPE_JAVA_FORMAT g_java_format_get_type() +#define G_JAVA_FORMAT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_JAVA_FORMAT, GJavaFormat)) +#define G_IS_JAVA_FORMAT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_JAVA_FORMAT)) +#define G_JAVA_FORMAT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_JAVA_FORMAT, GJavaFormatClass)) +#define G_IS_JAVA_FORMAT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_JAVA_FORMAT)) +#define G_JAVA_FORMAT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_JAVA_FORMAT, GJavaFormatClass)) + + +/* Format d'exécutable Java (instance) */ +typedef struct _GJavaFormat GJavaFormat; + +/* Format d'exécutable Java (classe) */ +typedef struct _GJavaFormatClass GJavaFormatClass; + + +/* Indique si le format peut être pris en charge ici. */ +bool java_is_matching(GBinContent *); + +/* Indique le type défini pour un format d'exécutable Java. */ +GType g_java_format_get_type(void); + +/* Prend en charge un nouveau format Java. */ +GBinFormat *g_java_format_new(const bin_t *, off_t); + + + +#endif /* _FORMAT_JAVA_JAVA_H */ diff --git a/plugins/java/java_def.h b/plugins/java/java_def.h new file mode 100644 index 0000000..2b1da67 --- /dev/null +++ b/plugins/java/java_def.h @@ -0,0 +1,418 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * java_def.h - liste des structures et constantes utilisées par le format Java + * + * Copyright (C) 2010-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _FORMAT_JAVA_JAVA_DEF_H +#define _FORMAT_JAVA_JAVA_DEF_H + + +#include + + + +/* Description des attributs Java */ +typedef struct _java_attribute java_attribute; + + + +/* ----------------------- ELEMENTS DU RESERVOIR A CONSTANTES ----------------------- */ + + +/* Types de données dans le réservoir (§4.4) */ +typedef enum _ConstantPoolTag +{ + CONSTANT_EMPTY = 0, /* Non initialisé ou sur 2 */ + + CONSTANT_CLASS = 7, /* Classe ou interface */ + CONSTANT_FIELD_REF = 9, /* Champ ou méthode */ + CONSTANT_METHOD_REF = 10, /* Champ ou méthode */ + CONSTANT_INTERFACE_METHOD_REF = 11, /* Champ ou méthode */ + CONSTANT_STRING = 8, /* Chaîne constante */ + CONSTANT_INTEGER = 3, /* Valeur entière */ + CONSTANT_FLOAT = 4, /* Valeur flottante */ + CONSTANT_LONG = 5, /* Valeur longue */ + CONSTANT_DOUBLE = 6, /* Valeur double */ + CONSTANT_NAME_AND_TYPE = 12, /* Prototype complet */ + CONSTANT_UTF8 = 1 /* Chaîne codée en UTF8 */ + +} ConstantPoolTag; + + +/* Représentation d'une classe ou d'une interface */ +typedef struct _class_info +{ + uint16_t name_index; /* Indice pour le nom */ + +} class_info; + +/* Représentation d'un champ ou d'une méthode */ +typedef struct _ref_info +{ + uint16_t class_index; /* Indice de la classe */ + uint16_t name_and_type_index; /* Prototype associé */ + +} ref_info; + +/* Représentation d'une chaîne constante */ +typedef struct _string_info +{ + uint16_t string_index; /* Indice de la valeur UTF8 */ + +} string_info; + +/* Représentation d'une valeur 'int' */ +typedef struct _integer_info +{ + uint32_t val; /* Valeur au format 'int' */ + +} integer_info; + +/* Représentation d'une valeur 'float' */ +typedef struct _float_info +{ + float val; /* Valeur au format 'float' */ + +} float_info; + +/* Représentation d'une valeur 'long' */ +typedef struct _long_info +{ + long val; /* Valeur au format 'long' */ + +} long_info; + +/* Représentation d'une valeur 'double' */ +typedef struct _double_info +{ + double val; /* Valeur au format 'double' */ + +} double_info; + +/* Représentation brève d'un champ ou d'une méthode */ +typedef struct _name_and_type_info +{ + uint16_t name_index; /* Indice du nom correspondant */ + uint16_t descriptor_index; /* Prototype associé */ + +} name_and_type_info; + +/* Représentation d'une chaîne codée en UTF8 */ +typedef struct _utf8_info +{ + char *bytes; /* Valeur de la chaîne */ + +} utf8_info; + + +/* Entrée du réservoir */ +typedef struct _constant_pool_entry +{ + ConstantPoolTag tag; /* Type d'entrée présente */ + + union + { + class_info class; + ref_info ref; + string_info string; + integer_info int_val; + float_info float_val; + long_info long_val; + double_info double_val; + name_and_type_info name_type; + utf8_info utf8; + + } info; /* Infos portées par l'entrée */ + +} constant_pool_entry; + + + +/* ------------------------ ATTRIBUTS POUR DES ELEMENTS JAVA ------------------------ */ + + +/* Types des attributs reconnus */ +typedef enum _JavaAttributeType +{ + JAT_NONE = 0, /* Attribu non chargé */ + + JAT_CONSTANT_VALUE, /* Valeur constante */ + JAT_CODE, /* Code exécutable */ + JAT_EXCEPTIONS, /* Exceptions remontables */ + JAT_INNER_CLASSES, /* Classes internes */ + JAT_SYNTHETIC, /* Membre non présent */ + JAT_SOURCE_FILE, /* Fichier source du code */ + JAT_LINE_NUMBER, /* Correspondances de débogage */ + JAT_LOCAL_VARIABLES, /* Variable(s) locale(s) */ + JAT_DEPRECATED /* Elément vieillot à oublier */ + +} JavaAttributeType; + +/* Représentation d'un attribut à valeur constante (§4.7.2) */ +typedef struct _const_value_attrib +{ + uint16_t const_value_index; /* Indice dans le réservoir */ + +} const_value_attrib; + +/* Représentation d'un attribut de code (§4.7.3) */ + +typedef struct _code_exception +{ + uint16_t start_pc; /* Début de la zone couverte */ + uint16_t end_pc; /* Fin de la zone couverte */ + uint16_t handler_pc; /* Début du gestionnaire */ + uint16_t catch_type; /* Indice du type d'exception */ + +} code_exception; + +typedef struct _code_attrib +{ + uint16_t max_stack; /* Taille maximale de la pile */ + uint16_t max_locals; /* Nombre de variables (!) */ + uint32_t code_length; /* Taille du code référencé */ + + off_t content; /* Début du code exécutable */ + + code_exception *exceptions; /* Exceptions gérées */ + uint16_t exceptions_count; /* Nombre de ces exceptions */ + + java_attribute *attributes; /* Attributs liés au code */ + uint16_t attributes_count; /* Nombre de ces attributs */ + +} code_attrib; + +/* Représentation d'un attribut fixant les exceptions remontables (§4.7.4) */ + +typedef struct _exceptions_attrib +{ + uint16_t *throw; /* Exceptions remontées */ + uint16_t throw_count; /* Nombre de ces exceptions */ + +} exceptions_attrib; + +/* Représentation d'un attribut présentant les classes internes (§4.7.5) */ + +typedef enum _InnerClassAccessFlags +{ + ICA_PUBLIC = 0x0001, /* Elément public */ + ICA_PRIVATE = 0x0002, /* Elément privé */ + ICA_PROTECTED = 0x0004, /* Elément sous protection */ + ICA_STATIC = 0x0008, /* Elément statique */ + ICA_FINAL = 0x0010, /* Elément défini un seule fois*/ + ICA_INTERFACE = 0x0200, /* Déclaration d'interface */ + ICA_ABSTRACT = 0x0400 /* Déclaré comme abstrait */ + +} InnerClassAccessFlags; + +typedef struct _inner_class +{ + uint16_t inner_class_info_index; /* Propriétés de la classe */ + uint16_t outer_class_info_index; /* Propriétés de la parente */ + uint16_t inner_name_index; /* Nom de la classe */ + InnerClassAccessFlags access; /* Droits d'accès */ + +} inner_class; + +typedef struct _inner_classes_attrib +{ + inner_class *classes; /* Classes internes */ + uint16_t classes_count; /* Nombre de ces classe */ + +} inner_classes_attrib; + +/* Représentation d'un fichier source (§4.7.7) */ +typedef struct _source_file_attrib +{ + uint16_t source_file_index; /* Indice dans le réservoir */ + +} source_file_attrib; + +/* Représentation des correspondances entre lignes et code (§4.7.8) */ + +typedef struct _pc_and_line +{ + uint16_t start_pc; /* Début de la zone visée */ + uint16_t number; /* Numéro de ligne du code */ + +} pc_and_line; + +typedef struct _line_number_attrib +{ + pc_and_line *lines; /* Correspondances code/source */ + uint16_t lines_count; /* Nombre de correspondances */ + +} line_number_attrib; + +/* Représentation des variables locales (§4.7.9) */ + +typedef struct _local_variable +{ + uint16_t start_pc; /* Position dans le code */ + uint16_t length; /* Taille de la variable */ + uint16_t name_index; /* Indice nominal de réservoir */ + uint16_t descriptor_index; /* Type de la variable */ + uint16_t index; /* Place dans la liste complète*/ + +} local_variable; + +typedef struct _local_variables_attrib +{ + local_variable *vars; /* Variables locales */ + uint16_t vars_count; /* Nombre de ces variables */ + +} local_variables_attrib; + +/* Description des attributs Java */ +struct _java_attribute +{ + JavaAttributeType type; /* Type d'attribut représenté */ + + union + { + const_value_attrib const_value; + code_attrib code; + exceptions_attrib exceptions; + inner_classes_attrib inner_classes; + source_file_attrib source_file; + line_number_attrib line_number; + local_variables_attrib local_vars; + + } info; /* Infos portées par l'attribut*/ + +}; + + + +/* ---------------------------- CHAMPS POUR CLASSES JAVA ---------------------------- */ + + +/* Types d'accès aux champs (§4.5) */ +typedef enum _FieldAccessFlags +{ + FAC_PUBLIC = 0x0001, /* Elément public */ + FAC_PRIVATE = 0x0002, /* Elément privé */ + FAC_PROTECTED = 0x0004, /* Elément sous protection */ + FAC_STATIC = 0x0008, /* Elément statique */ + FAC_FINAL = 0x0010, /* Elément défini un seule fois*/ + FAC_VOLATILE = 0x0040, /* Elément sans cache */ + FAC_TRANSIENT = 0x0080 /* Elément ni lu ni écrit... */ + +} FieldAccessFlags; + +/* Description d'un champ Java */ +typedef struct _java_field +{ + FieldAccessFlags access; /* Droits d'accès */ + + uint16_t name_index; /* Nom dans le réservoir */ + uint16_t descriptor_index; /* Prototype au même endroit */ + + java_attribute *attributes; /* Attributs liés au champ */ + uint16_t attributes_count; /* Nombre de ces attributs */ + +} java_field; + + + +/* --------------------------- METHODES POUR CLASSES JAVA --------------------------- */ + + +/* Types d'accès aux champs (§4.6) */ +typedef enum _MethodAccessFlags +{ + MAC_PUBLIC = 0x0001, /* Elément public */ + MAC_PRIVATE = 0x0002, /* Elément privé */ + MAC_PROTECTED = 0x0004, /* Elément sous protection */ + MAC_STATIC = 0x0008, /* Elément statique */ + MAC_FINAL = 0x0010, /* Elément défini un seule fois*/ + MAC_SYNCHRONIZED = 0x0020, /* Elément avec mutex natif */ + MAC_NATIVE = 0x0100, /* Elément conçu sans Java */ + MAC_ABSTRACT = 0x0400, /* Elément sans implantation */ + MAC_STRICT = 0x0800 /* Elément déclaré stricte FP */ + +} MethodAccessFlags; + +/* Description d'une méthode Java */ +typedef struct _java_method +{ + MethodAccessFlags access; /* Droits d'accès */ + + uint16_t name_index; /* Nom dans le réservoir */ + uint16_t descriptor_index; /* Prototype au même endroit */ + + java_attribute *attributes; /* Attributs liés à la méthode */ + uint16_t attributes_count; /* Nombre de ces attributs */ + +} java_method; + + + +/* ---------------------------- LISTE DES DROITS D'ACCES ---------------------------- */ + + +/* Types d'accès (§4.1) */ +typedef enum _ClassAccessFlags +{ + CAC_PUBLIC = 0x0001, /* Elément public */ + CAC_FINAL = 0x0010, /* Déclaré comme final */ + CAC_SUPER = 0x0020, /* Traitement spécial */ + CAC_INTERFACE = 0x0200, /* Déclaration d'interface */ + CAC_ABSTRACT = 0x0400 /* Déclaré comme abstrait */ + +} ClassAccessFlags; + + + +/* --------------------------- DESCRIPTION DU FORMAT JAVA --------------------------- */ + + +/* En-tête de tout programe Java */ +typedef struct _java_header +{ + uint16_t minor_version; /* Numéro de révision mineur */ + uint16_t major_version; /* Numéro de révision majeur */ + + constant_pool_entry *pool; /* Réservoir de constantes */ + uint16_t pool_len; /* Quantité de ces éléments */ + + ClassAccessFlags access; /* Type de classe/interface */ + + uint16_t this_class; /* Infos sur la classe */ + uint16_t super_class; /* Infos sur la classe parente */ + + uint16_t *interfaces; /* Interfaces intégrées */ + uint16_t interfaces_count; /* Nombre de ces interfaces */ + + java_field *fields; /* Champs de la classe */ + uint16_t fields_count; /* Nombre de champs présents */ + + java_method *methods; /* Méthodes de la classe */ + uint16_t methods_count; /* Nombre de méthodes listées */ + + java_attribute *attributes; /* Attributs liés à la classe */ + uint16_t attributes_count; /* Nombre de ces attributs */ + +} java_header; + + + +#endif /* _FORMAT_JAVA_JAVA_DEF_H */ diff --git a/plugins/java/method.c b/plugins/java/method.c new file mode 100644 index 0000000..371ba8c --- /dev/null +++ b/plugins/java/method.c @@ -0,0 +1,187 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * method.c - gestion des méthodes Java + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "method.h" + + +#include + + +#include "attribute.h" +#include "../../common/endianness.h" + + + +/* Charge les propriétés d'une méthode de classe. */ +bool load_java_method(java_format *, java_method *, off_t *); + +/* Décharge les propriétés d'une méthode de classe. */ +void unload_java_method(java_format *, java_method *); + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* pos = point de lecture à faire évoluer. [OUT] * +* * +* Description : Charge les méthodes d'un binaire Java. * +* * +* Retour : true si l'opération s'est bien déroulée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_java_methods(java_format *format, off_t *pos) +{ + bool result; /* Bilan à remonter */ + uint16_t i; /* Boucle de parcours */ + + result = read_u16(&format->methods_count, EXE_FORMAT(format)->content, pos, + EXE_FORMAT(format)->length, SRE_BIG); + + if (!result) return false; + + if (format->methods_count > 0) + { + format->methods = (java_method *)calloc(format->methods_count, sizeof(java_method)); + + for (i = 0; i < format->methods_count && result; i++) + result = load_java_method(format, &format->methods[i], pos); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à vider. * +* * +* Description : Décharge les méthodes d'un binaire Java. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_java_methods(java_format *format) +{ + uint16_t i; /* Boucle de parcours */ + + for (i = 0; i < format->methods_count; i++) + unload_java_method(format, &format->methods[i]); + + free(format->methods); + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* method = élément à spécifier. [OUT] * +* pos = point de lecture à faire évoluer. [OUT] * +* * +* Description : Charge les propriétés d'une méthode de classe. * +* * +* Retour : true si l'opération s'est bien déroulée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_java_method(java_format *format, java_method *method, off_t *pos) +{ + bool result; /* Bilan à retourner */ + + result = read_u16((uint16_t *)&method->access, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + result &= read_u16(&method->name_index, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + result &= read_u16(&method->descriptor_index, EXE_FORMAT(format)->content, + pos, EXE_FORMAT(format)->length, SRE_BIG); + + result &= load_java_attributes(format, pos, + &method->attributes, &method->attributes_count); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* method = élément à libérer. * +* * +* Description : Décharge les propriétés d'une méthode de classe. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_java_method(java_format *format, java_method *method) +{ + if (method->attributes_count > 0) + unload_java_attributes(format, method->attributes, method->attributes_count); + +} + + +/****************************************************************************** +* * +* Paramètres : method = élément à traiter. * +* offset = position physique du code de la méthode. [OUT] * +* size = taille du code de la méthode. [OUT] * +* * +* Description : Retrouve le code binaire correspondant à une méthode. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool find_java_method_code_part(const java_method *method, off_t *offset, off_t *size) +{ + uint16_t i; /* Boucle de parcours */ + + for (i = 0; i < method->attributes_count; i++) + if (method->attributes[i].type == JAT_CODE) + { + *offset = method->attributes[i].info.code.content; + *size = method->attributes[i].info.code.code_length; + break; + } + + return (i < method->attributes_count); + +} diff --git a/plugins/java/method.h b/plugins/java/method.h new file mode 100644 index 0000000..35b04e1 --- /dev/null +++ b/plugins/java/method.h @@ -0,0 +1,44 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * method.h - prototypes pour la gestion des méthodes Java + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _FORMAT_JAVA_METHOD_H +#define _FORMAT_JAVA_METHOD_H + + +#include "e_java.h" +#include "java-int.h" + + + +/* Charge les méthodes d'un binaire Java. */ +bool load_java_methods(java_format *, off_t *); + +/* Décharge les méthodes d'un binaire Java. */ +void unload_java_methods(java_format *); + +/* Retrouve le code binaire correspondant à une méthode. */ +bool find_java_method_code_part(const java_method *method, off_t *, off_t *); + + + +#endif /* _FORMAT_JAVA_METHOD_H */ diff --git a/plugins/java/pool.c b/plugins/java/pool.c new file mode 100644 index 0000000..625e9cc --- /dev/null +++ b/plugins/java/pool.c @@ -0,0 +1,474 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pool.c - lecture du réservoir de constantes + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "pool.h" + + +#include +#include +#include + +#include "java-int.h" +#include "../../common/endianness.h" +#include "../../common/extstr.h" + + + +/* Charge les propriétés d'une constante du réservoir. */ +bool load_java_pool_entry(GJavaFormat *, constant_pool_entry *, off_t *); + +/* Fournit une entrée donnée du réservoir de constantes. */ +const constant_pool_entry *get_java_pool_entry(const GJavaFormat *, uint16_t, ConstantPoolTag); + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* pos = point de lecture à faire évoluer. [OUT] * +* * +* Description : Charge le réservoir de constantes d'un binaire Java. * +* * +* Retour : true si l'opération s'est bien déroulée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_java_pool(GJavaFormat *format, off_t *pos) +{ + bool result; /* Bilan à remonter */ + uint16_t count; /* Nombre d'éléments présents */ + uint16_t i; /* Boucle de parcours */ + + result = false/*read_u16(&count, G_BIN_FORMAT(format)->content, pos, + G_BIN_FORMAT(format)->length, SRE_BIG)*/; +#if 0 + printf("Alloc %hu entries (result=%d)\n", count, result); + + format->header.pool_len = count - 1; + format->header.pool = (constant_pool_entry *)calloc(count - 1, sizeof(constant_pool_entry)); + + for (i = 1; i < count && result; i++) + { + result = load_java_pool_entry(format, &format->header.pool[i - 1], pos); + + if (format->header.pool[i - 1].tag == CONSTANT_LONG + || format->header.pool[i - 1].tag == CONSTANT_DOUBLE) + { + i++; + + /* On n'est jamais trop prudent */ + if (i < count) + format->header.pool[i - 1].tag = CONSTANT_EMPTY; + + } + + } +#endif + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à vider. * +* * +* Description : Décharge le réservoir de constantes d'un binaire Java. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_java_pool(GJavaFormat *format) +{ + uint16_t i; /* Boucle de parcours */ + + for (i = 0; i < format->header.pool_len; i++) + switch (format->header.pool[i].tag) + { + case CONSTANT_EMPTY: + case CONSTANT_CLASS: + case CONSTANT_FIELD_REF: + case CONSTANT_METHOD_REF: + case CONSTANT_INTERFACE_METHOD_REF: + case CONSTANT_STRING: + case CONSTANT_INTEGER: + case CONSTANT_FLOAT: + case CONSTANT_LONG: + case CONSTANT_DOUBLE: + case CONSTANT_NAME_AND_TYPE: + break; + + case CONSTANT_UTF8: + free(format->header.pool[i].info.utf8.bytes); + break; + + } + + free(format->header.pool); + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* entry = élément à spécifier. [OUT] * +* pos = point de lecture à faire évoluer. [OUT] * +* * +* Description : Charge les propriétés d'une constante du réservoir. * +* * +* Retour : true si l'opération s'est bien déroulée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_java_pool_entry(GJavaFormat *format, constant_pool_entry *entry, off_t *pos) +{ + bool result; /* Bilan à retourner */ + uint8_t tag; /* Type de l'élément */ + uint32_t low_bytes; /* Octets de poids faible */ + uint32_t high_bytes; /* Octets de poids fort */ + uint64_t bits; /* Nombre lu sur 64 bits */ + int sign; /* Signe du nombre lu */ + int exponent; /* Exposant du nombre lu */ + uint64_t mantissa32; /* Mantisse du nombre lu 32b */ + uint64_t mantissa64; /* Mantisse du nombre lu 64b */ + uint16_t length; /* Taille d'une chaîne */ + + result = false/*read_u8(&tag, G_BIN_FORMAT(format)->content, pos, + G_BIN_FORMAT(format)->length, SRE_BIG)*/; +#if 0 + entry->tag = tag; + + switch (entry->tag) + { + case CONSTANT_CLASS: + result = read_u16(&entry->info.class.name_index, G_BIN_FORMAT(format)->content, + pos, G_BIN_FORMAT(format)->length, SRE_BIG); + break; + + case CONSTANT_FIELD_REF: + case CONSTANT_METHOD_REF: + case CONSTANT_INTERFACE_METHOD_REF: + + result = read_u16(&entry->info.ref.class_index, G_BIN_FORMAT(format)->content, + pos, G_BIN_FORMAT(format)->length, SRE_BIG); + result &= read_u16(&entry->info.ref.name_and_type_index, G_BIN_FORMAT(format)->content, + pos, G_BIN_FORMAT(format)->length, SRE_BIG); + + break; + + case CONSTANT_STRING: + result = read_u16(&entry->info.string.string_index, G_BIN_FORMAT(format)->content, + pos, G_BIN_FORMAT(format)->length, SRE_BIG); + break; + + case CONSTANT_INTEGER: + result = read_u32(&entry->info.int_val.val, G_BIN_FORMAT(format)->content, + pos, G_BIN_FORMAT(format)->length, SRE_BIG); + break; + + case CONSTANT_FLOAT: + + result = read_u32(&low_bytes, G_BIN_FORMAT(format)->content, + pos, G_BIN_FORMAT(format)->length, SRE_BIG); + + if (result) + { + if (low_bytes == 0x7f800000) + entry->info.float_val.val = INFINITY; + + else if (low_bytes == 0xff800000) + entry->info.float_val.val = /* -1* */INFINITY; + + else if ((low_bytes >= 0x7f800001 && low_bytes <= 0x7fffffff) + || (low_bytes >= 0xff800001 && low_bytes <= 0xffffffff)) + entry->info.float_val.val = NAN; + + else if (low_bytes == 0x00000000 || low_bytes == 0x80000000) + entry->info.float_val.val = 0; + + else + { + sign = (low_bytes & 0x80000000) ? -1 : 1; + exponent = (low_bytes >> 23) & 0xff; + mantissa32 = (exponent == 0 ? + (low_bytes & 0x7fffff) << 1 : + (low_bytes & 0x7fffff) | 0x800000); + + entry->info.float_val.val = pow(2, (exponent - 150)); + entry->info.float_val.val *= mantissa32; + entry->info.float_val.val *= sign; + + } + + } + + break; + + case CONSTANT_LONG: + + result = read_u32(&high_bytes, G_BIN_FORMAT(format)->content, + pos, G_BIN_FORMAT(format)->length, SRE_BIG); + result &= read_u32(&low_bytes, G_BIN_FORMAT(format)->content, + pos, G_BIN_FORMAT(format)->length, SRE_BIG); + + if (result) + { + entry->info.double_val.val = (uint64_t)high_bytes << 32; + entry->info.double_val.val += low_bytes; + } + + break; + + case CONSTANT_DOUBLE: + + result = read_u32(&high_bytes, G_BIN_FORMAT(format)->content, + pos, G_BIN_FORMAT(format)->length, SRE_BIG); + result &= read_u32(&low_bytes, G_BIN_FORMAT(format)->content, + pos, G_BIN_FORMAT(format)->length, SRE_BIG); + + if (result) + { + bits = (uint64_t)high_bytes << 32 | (uint64_t)low_bytes; + + if (bits == 0x7ff0000000000000ll) + entry->info.double_val.val = INFINITY; + + else if (bits == 0xfff0000000000000ll) + entry->info.double_val.val = /* -1* */INFINITY; + + else if ((bits >= 0x7ff0000000000001ll && bits <= 0x7fffffffffffffffll) + || (bits >= 0xfff0000000000001ll && bits <= 0xffffffffffffffffll)) + entry->info.double_val.val = NAN; + + else if (bits == 0x0000000000000000ll || bits == 0x8000000000000000ll) + entry->info.double_val.val = 0; + + else + { + sign = ((bits >> 63) == 0) ? 1 : -1; + exponent = (bits >> 52) & 0x7ffl; + mantissa64 = (exponent == 0 ? + (bits & 0xfffffffffffffll) << 1 : + (bits & 0xfffffffffffffll) | 0x10000000000000ll); + + entry->info.double_val.val = pow(2, (exponent - 1075)); + entry->info.double_val.val *= mantissa64; + entry->info.double_val.val *= sign; + + } + + } + + break; + + case CONSTANT_NAME_AND_TYPE: + + result = read_u16(&entry->info.name_type.name_index, G_BIN_FORMAT(format)->content, + pos, G_BIN_FORMAT(format)->length, SRE_BIG); + result &= read_u16(&entry->info.name_type.descriptor_index, G_BIN_FORMAT(format)->content, + pos, G_BIN_FORMAT(format)->length, SRE_BIG); + + break; + + case CONSTANT_UTF8: + + result = read_u16(&length, G_BIN_FORMAT(format)->content, + pos, G_BIN_FORMAT(format)->length, SRE_BIG); + + if (result) + { + entry->info.utf8.bytes = (char *)calloc(length + 1, sizeof(char)); + memcpy(entry->info.utf8.bytes, &G_BIN_FORMAT(format)->content[*pos], length); + *pos += length; + } + + break; + + default: + result = false; + break; + + } +#endif + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* index = indice de l'élément dont la valeur est à recupérer. * +* expected = type de l'élément à trouver à l'indice donné. * +* * +* Description : Fournit une entrée donnée du réservoir de constantes. * +* * +* Retour : Entrée du réservoir de constantes ou NULL en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const constant_pool_entry *get_java_pool_entry(const GJavaFormat *format, uint16_t index, ConstantPoolTag expected) +{ + const constant_pool_entry *result; /* Entrée à retourner */ + constant_pool_entry *entry; /* Entrée du réservoir visée */ + + result = NULL; + + if (/*index < 0 && FIXME */index <= format->header.pool_len); + { + entry = &format->header.pool[index - 1]; + + if (entry->tag == expected) + result = entry; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* index = indice de l'élément de la table à recupérer. * +* expected = type de l'élément à trouver à l'indice donné. * +* * +* Description : Construit une version humaine de référence. * +* * +* Retour : Référence construite ou NULL en cas de problème. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *build_reference_from_java_pool(const GJavaFormat *format, uint16_t index, JavaRefType expected) +{ + char *result; /* Chaîne humaine à retourner */ + const constant_pool_entry *entry; /* Entrée du réservoir visée 1 */ + const constant_pool_entry *subentry; /* Entrée du réservoir visée 2 */ + const char *tmp; /* Copie de chaîne intouchable */ + + result = NULL; + + switch (expected) + { + case JRT_FIELD: + entry = get_java_pool_entry(format, index, CONSTANT_FIELD_REF); + break; + case JRT_METHOD: + entry = get_java_pool_entry(format, index, CONSTANT_METHOD_REF); + break; + case JRT_INTERFACE_METHOD: + entry = get_java_pool_entry(format, index, CONSTANT_INTERFACE_METHOD_REF); + break; + default: + entry = NULL; + break; + } + + if (entry == NULL) + goto brfjp_error; + + /* Lieu parent où trouver la référence */ + + subentry = get_java_pool_entry(format, entry->info.ref.class_index, CONSTANT_CLASS); + + if (subentry == NULL) + goto brfjp_error; + + if (!get_java_pool_ut8_string(format, subentry->info.class.name_index, &tmp)) + goto brfjp_error; + + result = strdup(tmp); + + /* Champ proprement dit */ + + subentry = get_java_pool_entry(format, entry->info.ref.name_and_type_index, CONSTANT_NAME_AND_TYPE); + + if (subentry == NULL) + goto brfjp_error; + + if (!get_java_pool_ut8_string(format, subentry->info.name_type.name_index, &tmp)) + goto brfjp_error; + + result = stradd(result, "."); + result = stradd(result, tmp); + + /* Petites retouches finales */ + + result = strrpl(result, "/", "."); + result = strrpl(result, "<", "<"); + result = strrpl(result, ">", ">"); + + return result; + + brfjp_error: + + if (result != NULL) + free(result); + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* index = indice de l'élément dont la valeur est à recupérer. * +* str = adresse où placer la chaîne de caractères trouvée. * +* * +* Description : Recherche une chaîne de caractères dans le réservoir. * +* * +* Retour : true si l'opération s'est bien déroulée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool get_java_pool_ut8_string(const GJavaFormat *format, uint16_t index, const char **str) +{ + bool result; /* Bilan à renvoyer */ + const constant_pool_entry *entry; /* Entrée du réservoir visée */ + + entry = get_java_pool_entry(format, index, CONSTANT_UTF8); + + result = (entry != NULL); + + if (result) + (*str) = entry->info.utf8.bytes; + + return result; + +} diff --git a/plugins/java/pool.h b/plugins/java/pool.h new file mode 100644 index 0000000..7f1a1db --- /dev/null +++ b/plugins/java/pool.h @@ -0,0 +1,56 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pool.h - prototypes pour la lecture du réservoir de constantes + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _FORMAT_JAVA_POOL_H +#define _FORMAT_JAVA_POOL_H + + +#include "java.h" + + + +/* Types de référence Java */ +typedef enum _JavaRefType +{ + JRT_FIELD, /* Champ */ + JRT_METHOD, /* Méthode */ + JRT_INTERFACE_METHOD /* Méthode d'interface */ + +} JavaRefType; + + +/* Charge le réservoir de constantes d'un binaire Java. xs*/ +bool load_java_pool(GJavaFormat *, off_t *); + +/* Décharge le réservoir de constantes d'un binaire Java. */ +void unload_java_pool(GJavaFormat *); + +/* Construit une version humaine de référence. */ +char *build_reference_from_java_pool(const GJavaFormat *, uint16_t, JavaRefType); + +/* Recherche une chaîne de caractères dans le réservoir. */ +bool get_java_pool_ut8_string(const GJavaFormat *, uint16_t, const char **); + + + +#endif /* _FORMAT_JAVA_POOL_H */ diff --git a/plugins/jvm/Makefile.am b/plugins/jvm/Makefile.am new file mode 100644 index 0000000..fc4ee0b --- /dev/null +++ b/plugins/jvm/Makefile.am @@ -0,0 +1,35 @@ + +noinst_LTLIBRARIES = libarchjvm.la + +libarchjvm_la_SOURCES = \ + instruction.h instruction.c \ + op_add.c \ + op_const.c \ + op_convert.c \ + op_dup.c \ + op_getput.c \ + op_invoke.c \ + op_load.c \ + op_monitor.c \ + op_nop.c \ + op_pop.c \ + op_store.c \ + op_ret.c \ + opcodes.h \ + operand.h operand.c \ + processor.h processor.c + +libarchjvm_la_CFLAGS = $(AM_CFLAGS) + + +devdir = $(includedir)/chrysalide/$(subdir:src/%=%) + +dev_HEADERS = $(libarchjvm_la_SOURCES:%c=) + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + + +SUBDIRS = diff --git a/plugins/jvm/instruction.c b/plugins/jvm/instruction.c new file mode 100644 index 0000000..c7a9bfb --- /dev/null +++ b/plugins/jvm/instruction.c @@ -0,0 +1,299 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * instruction.c - gestion des instructions JVM + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "instruction.h" + + +#include "../instruction-int.h" + + + +/* Définition générique d'une instruction d'architecture JVM (instance) */ +struct _GJvmInstruction +{ + GArchInstruction parent; /* A laisser en premier */ + + JvmOpcodes type; /* Position dans la liste */ + +}; + +/* Définition générique d'une instruction d'architecture JVM (classe) */ +struct _GJvmInstructionClass +{ + GArchInstructionClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des instructions pour JVM. */ +static void g_jvm_instruction_class_init(GJvmInstructionClass *); + +/* Initialise une instance d'opérande d'architecture JVM. */ +static void g_jvm_instruction_init(GJvmInstruction *); + + + +/* --------------------- AIDE A LA MISE EN PLACE D'INSTRUCTIONS --------------------- */ + + +/* Répertoire de toutes les instructions JVM */ +typedef struct _jvm_instruction +{ + bool care_of_data; /* Devinette = repas ? */ + bool can_wide; /* Instruction étendue ? */ + bin_t opcode; /* Opcode de l'instruction */ + + const char *keyword; /* Mot clef de la commande */ + +} jvm_instruction; + + +static jvm_instruction _instructions[JOP_COUNT] = { + + [JOP_NOP] = { false, false, 0x00, "nop" }, + [JOP_ACONST_NULL] = { false, false, 0x01, "aconst_null" }, + [JOP_ICONST_M1] = { true, false, 0x02, "iconst_m1" }, + [JOP_ICONST_0] = { true, false, 0x03, "iconst_0" }, + [JOP_ICONST_1] = { true, false, 0x04, "iconst_1" }, + [JOP_ICONST_2] = { true, false, 0x05, "iconst_2" }, + [JOP_ICONST_3] = { true, false, 0x06, "iconst_3" }, + [JOP_ICONST_4] = { true, false, 0x07, "iconst_4" }, + [JOP_ICONST_5] = { true, false, 0x08, "iconst_5" }, + + + + [JOP_POP] = { false, false, 0x57, "pop" }, + [JOP_POP2] = { false, false, 0x58, "pop2" }, + [JOP_DUP] = { false, false, 0x59, "dup" }, + [JOP_DUP_X1] = { false, false, 0x5a, "dup_x1" }, + [JOP_DUP_X2] = { false, false, 0x5b, "dup_x2" }, + [JOP_DUP2] = { false, false, 0x5c, "dup2" }, + [JOP_DUP2_X1] = { false, false, 0x5d, "dup2_x1" }, + [JOP_DUP2_X2] = { false, false, 0x5e, "dup2_x2" }, + + + [JOP_IADD] = { false, false, 0x60, "iadd" }, + + + [JOP_I2L] = { false, false, 0x85, "i2l" }, + [JOP_I2F] = { false, false, 0x86, "i2f" }, + [JOP_I2D] = { false, false, 0x87, "i2d" }, + [JOP_L2I] = { false, false, 0x88, "l2i" }, + [JOP_L2F] = { false, false, 0x89, "l2f" }, + [JOP_L2D] = { false, false, 0x8a, "l2d" }, + [JOP_F2I] = { false, false, 0x8b, "f2i" }, + [JOP_F2L] = { false, false, 0x8c, "f2l" }, + [JOP_F2D] = { false, false, 0x8d, "f2d" }, + [JOP_D2I] = { false, false, 0x8e, "d2i" }, + [JOP_D2L] = { false, false, 0x8f, "d2l" }, + [JOP_D2F] = { false, false, 0x90, "d2f" }, + [JOP_I2B] = { false, false, 0x91, "i2b" }, + [JOP_I2C] = { false, false, 0x92, "i2c" }, + [JOP_I2S] = { false, false, 0x93, "i2s" }, + + + [JOP_ILOAD_0] = { true, false, 0x1a, "iload_0" }, + [JOP_ILOAD_1] = { true, false, 0x1b, "iload_1" }, + [JOP_ILOAD_2] = { true, false, 0x1c, "iload_2" }, + [JOP_ILOAD_3] = { true, false, 0x1d, "iload_3" }, + + + + [JOP_ALOAD_0] = { true, false, 0x2a, "aload_0" }, + [JOP_ALOAD_1] = { true, false, 0x2b, "aload_1" }, + [JOP_ALOAD_2] = { true, false, 0x2c, "aload_2" }, + [JOP_ALOAD_3] = { true, false, 0x2d, "aload_3" }, + + [JOP_ISTORE_0] = { true, false, 0x3b, "istore_0" }, + [JOP_ISTORE_1] = { true, false, 0x3c, "istore_1" }, + [JOP_ISTORE_2] = { true, false, 0x3d, "istore_2" }, + [JOP_ISTORE_3] = { true, false, 0x3e, "istore_3" }, + + [JOP_IRETURN] = { false, false, 0xac, "ireturn" }, + [JOP_LRETURN] = { false, false, 0xad, "lreturn" }, + [JOP_FRETURN] = { false, false, 0xae, "freturn" }, + [JOP_DRETURN] = { false, false, 0xaf, "dreturn" }, + [JOP_ARETURN] = { false, false, 0xb0, "areturn" }, + [JOP_RETURN] = { false, false, 0xb1, "return" }, + [JOP_GETSTATIC] = { false, false, 0xb2, "getstatic" }, + + [JOP_INVOKE_VIRTUAL] = { false, false, 0xb6, "invokevirtual" }, + [JOP_INVOKE_SPECIAL] = { false, false, 0xb7, "invokespecial" }, + [JOP_INVOKE_STATIC] = { false, false, 0xb8, "invokestatic" }, + + + [JOP_MONITOR_ENTER] = { false, false, 0xc2, "monitorenter" }, + [JOP_MONITOR_EXIT] = { false, false, 0xc3, "monitorexit" } + + + +}; + + +/* Traduit une instruction en version humainement lisible. */ +static const char *jvm_get_instruction_text(const GJvmInstruction *, const GExeFormat *); + + + + + + +/* Indique le type défini pour une instruction d'architecture JVM. */ +G_DEFINE_TYPE(GJvmInstruction, g_jvm_instruction, G_TYPE_ARCH_INSTRUCTION); + + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des instructions pour JVM. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_jvm_instruction_class_init(GJvmInstructionClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instance à initialiser. * +* * +* Description : Initialise une instance d'instruction d'architecture JVM. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_jvm_instruction_init(GJvmInstruction *instr) +{ + GArchInstruction *parent; /* Instance parente */ + + parent = G_ARCH_INSTRUCTION(instr); + + //parent->get_text = (get_instruction_text_fc)jvm_get_instruction_text; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type d'instruction à représenter. * +* * +* Description : Crée une instruction pour l'architecture JVM. * +* * +* Retour : Architecture mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *g_jvm_instruction_new(JvmOpcodes type) +{ + GArchInstruction *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_JVM_INSTRUCTION, NULL); + + G_JVM_INSTRUCTION(result)->type = type; + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* AIDE A LA MISE EN PLACE D'INSTRUCTIONS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. * +* len = taille totale des données à analyser. * +* wide = étendue de la future instruction. [OUT] * +* care = la lecture de l'instr. veut-elle les opcodes ? [OUT] * +* * +* Description : Recherche l'identifiant de la prochaine instruction. * +* * +* Retour : Identifiant de la prochaine instruction à tenter de charger. * +* * +* Remarques : - * +* * +******************************************************************************/ + +JvmOpcodes jvm_guess_next_instruction(const bin_t *data, off_t pos, off_t len, bool *wide, bool *care) +{ + JvmOpcodes result; /* Identifiant à retourner */ + bin_t opcode; /* Opcode à trouver */ + + *wide = (data[pos] == 0xc4); + + if (*wide && (pos + 1) == len) return JOP_COUNT; + + opcode = data[pos + (*wide ? 1 : 0)]; + + for (result = 0; result < JOP_COUNT; result++) + { + if (*wide && !_instructions[result].can_wide) continue; + + if (_instructions[result].opcode == opcode) + { + *care = _instructions[result].care_of_data; + break; + } + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction à traiter. * +* format = format du binaire manipulé. * +* * +* Description : Traduit une instruction en version humainement lisible. * +* * +* Retour : Chaîne de caractères à libérer de la mémoire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const char *jvm_get_instruction_text(const GJvmInstruction *instr, const GExeFormat *format) +{ + return _instructions[instr->type].keyword; + +} diff --git a/plugins/jvm/instruction.h b/plugins/jvm/instruction.h new file mode 100644 index 0000000..8ec9c48 --- /dev/null +++ b/plugins/jvm/instruction.h @@ -0,0 +1,151 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * instruction.h - prototypes pour la gestion des instructions JVM + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _ARCH_JVM_INSTRUCTION_H +#define _ARCH_JVM_INSTRUCTION_H + + +#include "../instruction.h" + + + + + +/* Enumération de tous les opcodes */ +typedef enum _JvmOpcodes +{ + JOP_NOP, /* nop (0x00) */ + JOP_ACONST_NULL, /* aconst_null (0x01) */ + JOP_ICONST_M1, /* iconst_m1 (0x02) */ + JOP_ICONST_0, /* iconst_0 (0x03) */ + JOP_ICONST_1, /* iconst_1 (0x04) */ + JOP_ICONST_2, /* iconst_2 (0x05) */ + JOP_ICONST_3, /* iconst_3 (0x06) */ + JOP_ICONST_4, /* iconst_4 (0x07) */ + JOP_ICONST_5, /* iconst_5 (0x08) */ + + + JOP_POP, /* pop (0x57) */ + JOP_POP2, /* pop2 (0x58) */ + JOP_DUP, /* dup (0x59) */ + JOP_DUP_X1, /* dup_x1 (0x5a) */ + JOP_DUP_X2, /* dup_x2 (0x5b) */ + JOP_DUP2, /* dup2 (0x5c) */ + JOP_DUP2_X1, /* dup2_x1 (0x5d) */ + JOP_DUP2_X2, /* dup2_x2 (0x5e) */ + + + JOP_IADD, /* iadd (0x60) */ + + + JOP_I2L, /* i2l (0x85) */ + JOP_I2F, /* i2f (0x86) */ + JOP_I2D, /* i2d (0x87) */ + JOP_L2I, /* l2i (0x88) */ + JOP_L2F, /* l2f (0x89) */ + JOP_L2D, /* l2d (0x8a) */ + JOP_F2I, /* f2i (0x8b) */ + JOP_F2L, /* f2l (0x8c) */ + JOP_F2D, /* f2d (0x8d) */ + JOP_D2I, /* d2i (0x8e) */ + JOP_D2L, /* d2l (0x8f) */ + JOP_D2F, /* d2f (0x90) */ + JOP_I2B, /* i2b (0x91) */ + JOP_I2C, /* i2c (0x92) */ + JOP_I2S, /* i2s (0x93) */ + + + + + JOP_ILOAD_0, /* iload_0 (0x1a) */ + JOP_ILOAD_1, /* iload_1 (0x1b) */ + JOP_ILOAD_2, /* iload_2 (0x1c) */ + JOP_ILOAD_3, /* iload_3 (0x1d) */ + + + + + JOP_ALOAD_0, /* aload_0 (0x2a) */ + JOP_ALOAD_1, /* aload_1 (0x2b) */ + JOP_ALOAD_2, /* aload_2 (0x2c) */ + JOP_ALOAD_3, /* aload_3 (0x2d) */ + + + JOP_ISTORE_0, /* istore_0 (0x3b) */ + JOP_ISTORE_1, /* istore_1 (0x3c) */ + JOP_ISTORE_2, /* istore_2 (0x3d) */ + JOP_ISTORE_3, /* istore_3 (0x3e) */ + + + JOP_IRETURN, /* ireturn (0xac) */ + JOP_LRETURN, /* lreturn (0xad) */ + JOP_FRETURN, /* freturn (0xae) */ + JOP_DRETURN, /* dreturn (0xaf) */ + JOP_ARETURN, /* areturn (0xb0) */ + JOP_RETURN, /* return (0xb1) */ + JOP_GETSTATIC, /* getstatic (0xb2) */ + + JOP_INVOKE_VIRTUAL, /* invokevirtual (0xb6) */ + JOP_INVOKE_SPECIAL, /* invokespecial (0xb7) */ + JOP_INVOKE_STATIC, /* invokestatic (0xb8) */ + + JOP_MONITOR_ENTER, /* monitorenter (0xc2) */ + JOP_MONITOR_EXIT, /* monitorexit (0xc3) */ + + JOP_COUNT + +} JvmOpcodes; + + +#define G_TYPE_JVM_INSTRUCTION g_jvm_instruction_get_type() +#define G_JVM_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_JVM_INSTRUCTION, GJvmInstruction)) +#define G_IS_JVM_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_JVM_INSTRUCTION)) +#define G_JVM_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_JVM_INSTRUCTION, GJvmInstructionClass)) +#define G_IS_JVM_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_JVM_INSTRUCTION)) +#define G_JVM_INSTRUCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_JVM_INSTRUCTION, GJvmInstructionClass)) + + +/* Définition générique d'une instruction d'architecture JVM (instance) */ +typedef struct _GJvmInstruction GJvmInstruction; + +/* Définition générique d'une instruction d'architecture JVM (classe) */ +typedef struct _GJvmInstructionClass GJvmInstructionClass; + + +/* Indique le type défini pour une instruction d'architecture JVM. */ +GType g_jvm_instruction_get_type(void); + +/* Crée une instruction pour l'architecture JVM. */ +GArchInstruction *g_jvm_instruction_new(JvmOpcodes); + + + +/* --------------------- AIDE A LA MISE EN PLACE D'INSTRUCTIONS --------------------- */ + + +/* Recherche l'identifiant de la prochaine instruction. */ +JvmOpcodes jvm_guess_next_instruction(const bin_t *, off_t, off_t, bool *, bool *); + + + +#endif /* _ARCH_JVM_INSTRUCTION_H */ diff --git a/plugins/jvm/op_add.c b/plugins/jvm/op_add.c new file mode 100644 index 0000000..fbcc682 --- /dev/null +++ b/plugins/jvm/op_add.c @@ -0,0 +1,55 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * op_add.c - décodage des additions + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "opcodes.h" + + +#include "instruction.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'iadd'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_iadd(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_IADD); + + return result; + +} diff --git a/plugins/jvm/op_const.c b/plugins/jvm/op_const.c new file mode 100644 index 0000000..fc7075c --- /dev/null +++ b/plugins/jvm/op_const.c @@ -0,0 +1,87 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * op_const.c - décodage des empilements de valeurs prédéfinies + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "opcodes.h" + + +#include "instruction.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'aconst_null'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_aconst_null(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_ACONST_NULL); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'iconst_n'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_iconst_n(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + JvmOpcodes opcode; /* Instruction effective */ + + opcode = JOP_ICONST_M1 + (data[*pos] - 0x02); + + (*pos)++; + + result = g_jvm_instruction_new(opcode); + + return result; + +} diff --git a/plugins/jvm/op_convert.c b/plugins/jvm/op_convert.c new file mode 100644 index 0000000..43d9d20 --- /dev/null +++ b/plugins/jvm/op_convert.c @@ -0,0 +1,433 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * op_convert.c - décodage des conversions entre types de base + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "opcodes.h" + + +#include "instruction.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'd2f'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_d2f(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_D2F); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'd2i'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_d2i(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_D2I); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'd2l'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_d2l(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_D2L); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'f2d'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_f2d(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_F2D); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'f2i'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_f2i(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_F2I); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'f2l'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_f2l(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_F2L); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'i2b'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_i2b(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_I2B); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'i2c'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_i2c(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_I2C); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'i2d'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_i2d(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_I2D); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'i2f'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_i2f(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_I2F); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'i2l'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_i2l(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_I2L); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'i2s'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_i2s(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_I2S); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'l2d'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_l2d(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_L2D); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'l2i'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_l2i(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_L2I); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'l2f'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_l2f(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_L2F); + + return result; + +} diff --git a/plugins/jvm/op_dup.c b/plugins/jvm/op_dup.c new file mode 100644 index 0000000..a42acd8 --- /dev/null +++ b/plugins/jvm/op_dup.c @@ -0,0 +1,190 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * op_dup.c - décodage des duplications d'étages de la pile + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "opcodes.h" + + +#include "instruction.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'dup'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_dup(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_DUP); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'dup_x1'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_dup_x1(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_DUP_X1); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'dup_x2'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_dup_x2(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_DUP_X2); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'dup2'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_dup2(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_DUP2); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'dup2_x1'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_dup2_x1(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_DUP2_X1); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'dup2_x2'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_dup2_x2(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_DUP2_X2); + + return result; + +} diff --git a/plugins/jvm/op_getput.c b/plugins/jvm/op_getput.c new file mode 100644 index 0000000..c4d2b26 --- /dev/null +++ b/plugins/jvm/op_getput.c @@ -0,0 +1,62 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * op_getput.c - décodage des fonctions (get|put)* + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "opcodes.h" + + +#include "instruction.h" +#include "operand.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'getstatic'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_getstatic(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_GETSTATIC); + + if (!jvm_read_one_operand(result, data, pos, len, JOT_FIELD_REF)) + { + /*free(result); FIXME */ + return NULL; + } + + return result; + +} diff --git a/plugins/jvm/op_invoke.c b/plugins/jvm/op_invoke.c new file mode 100644 index 0000000..118f3a5 --- /dev/null +++ b/plugins/jvm/op_invoke.c @@ -0,0 +1,128 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * op_invoke.c - décodage des fonctions (get|put)* + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "opcodes.h" + + +#include "instruction.h" +#include "operand.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'invokespecial'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_invokespecial(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_INVOKE_SPECIAL); + + if (!jvm_read_one_operand(result, data, pos, len, JOT_METHOD_REF)) + { + /*free(result); FIXME */ + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'invokestatic'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_invokestatic(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_INVOKE_STATIC); + + if (!jvm_read_one_operand(result, data, pos, len, JOT_METHOD_REF)) + { + /*free(result); FIXME */ + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'invokevirtual'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_invokevirtual(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_INVOKE_VIRTUAL); + + if (!jvm_read_one_operand(result, data, pos, len, JOT_METHOD_REF)) + { + /*free(result); FIXME */ + return NULL; + } + + return result; + +} diff --git a/plugins/jvm/op_load.c b/plugins/jvm/op_load.c new file mode 100644 index 0000000..faea478 --- /dev/null +++ b/plugins/jvm/op_load.c @@ -0,0 +1,92 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * op_load.c - décodage des instructions de chargement + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "opcodes.h" + + +#include "instruction.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'aload_n'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_aload_n(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + JvmOpcodes opcode; /* Instruction effective */ + + opcode = JOP_ALOAD_0 + (data[*pos] - 0x2a); + + (*pos)++; + + result = g_jvm_instruction_new(opcode); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'iload_n'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_iload_n(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + JvmOpcodes opcode; /* Instruction effective */ + + opcode = JOP_ILOAD_0 + (data[*pos] - 0x1a); + + (*pos)++; + + result = g_jvm_instruction_new(opcode); + + return result; + +} diff --git a/plugins/jvm/op_monitor.c b/plugins/jvm/op_monitor.c new file mode 100644 index 0000000..3e0b61a --- /dev/null +++ b/plugins/jvm/op_monitor.c @@ -0,0 +1,82 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * op_monitor.c - décodage des outils pour réaliser des sémaphores sur les objets + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "opcodes.h" + + +#include "instruction.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'monitorenter'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_monitorenter(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_MONITOR_ENTER); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'monitorexit'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_monitorexit(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_MONITOR_EXIT); + + return result; + +} diff --git a/plugins/jvm/op_nop.c b/plugins/jvm/op_nop.c new file mode 100644 index 0000000..ff2f58b --- /dev/null +++ b/plugins/jvm/op_nop.c @@ -0,0 +1,55 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * op_nop.c - décodage des absences d'opération + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "opcodes.h" + + +#include "instruction.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'nop'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_nop(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_NOP); + + return result; + +} diff --git a/plugins/jvm/op_pop.c b/plugins/jvm/op_pop.c new file mode 100644 index 0000000..a9f98f1 --- /dev/null +++ b/plugins/jvm/op_pop.c @@ -0,0 +1,82 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * op_pop.c - décodage des dépilements de pile dans le vide + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "opcodes.h" + + +#include "instruction.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'pop'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_pop(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_POP); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'pop2'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_pop2(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_POP); + + return result; + +} diff --git a/plugins/jvm/op_ret.c b/plugins/jvm/op_ret.c new file mode 100644 index 0000000..6ab6df3 --- /dev/null +++ b/plugins/jvm/op_ret.c @@ -0,0 +1,184 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * op_ret.c - décodage des ordres de retour + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "opcodes.h" + + +#include "instruction.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'areturn'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_areturn(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_ARETURN); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'dreturn'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_dreturn(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_DRETURN); + + return result; + +} +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'freturn'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_freturn(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_FRETURN); + + return result; + +} +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'ireturn'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_ireturn(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_IRETURN); + + return result; + +} +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'lreturn'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_lreturn(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_LRETURN); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'return'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_return(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_jvm_instruction_new(JOP_RETURN); + + return result; + +} diff --git a/plugins/jvm/op_store.c b/plugins/jvm/op_store.c new file mode 100644 index 0000000..1804049 --- /dev/null +++ b/plugins/jvm/op_store.c @@ -0,0 +1,60 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * op_store.c - décodage des instructions d'enregistrement + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "opcodes.h" + + +#include "instruction.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'istore_n'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *jvm_read_instr_istore_n(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + JvmOpcodes opcode; /* Instruction effective */ + + opcode = JOP_ISTORE_0 + (data[*pos] - 0x3b); + + (*pos)++; + + result = g_jvm_instruction_new(opcode); + + return result; + +} diff --git a/plugins/jvm/opcodes.h b/plugins/jvm/opcodes.h new file mode 100644 index 0000000..7251fed --- /dev/null +++ b/plugins/jvm/opcodes.h @@ -0,0 +1,160 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * opcodes.h - prototypes pour la liste de tous les opcodes de l'architecture JVM + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _ARCH_JVM_OPCODES_H +#define _ARCH_JVM_OPCODES_H + + +#include "processor.h" + + + +/* Décode une instruction de type 'aconst_null'. */ +GArchInstruction *jvm_read_instr_aconst_null(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'aload_n'. */ +GArchInstruction *jvm_read_instr_aload_n(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'areturn'. */ +GArchInstruction *jvm_read_instr_areturn(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'd2f'. */ +GArchInstruction *jvm_read_instr_d2f(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'd2i'. */ +GArchInstruction *jvm_read_instr_d2i(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'd2l'. */ +GArchInstruction *jvm_read_instr_d2l(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'dreturn'. */ +GArchInstruction *jvm_read_instr_dreturn(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'dup'. */ +GArchInstruction *jvm_read_instr_dup(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'dup_x1'. */ +GArchInstruction *jvm_read_instr_dup_x1(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'dup_x2'. */ +GArchInstruction *jvm_read_instr_dup_x2(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'dup2'. */ +GArchInstruction *jvm_read_instr_dup2(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'dup2_x1'. */ +GArchInstruction *jvm_read_instr_dup2_x1(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'dup2_x2'. */ +GArchInstruction *jvm_read_instr_dup2_x2(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'f2d'. */ +GArchInstruction *jvm_read_instr_f2d(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'f2i'. */ +GArchInstruction *jvm_read_instr_f2i(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'f2l'. */ +GArchInstruction *jvm_read_instr_f2l(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'freturn'. */ +GArchInstruction *jvm_read_instr_freturn(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'getstatic'. */ +GArchInstruction *jvm_read_instr_getstatic(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'i2b'. */ +GArchInstruction *jvm_read_instr_i2b(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'i2c'. */ +GArchInstruction *jvm_read_instr_i2c(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'i2d'. */ +GArchInstruction *jvm_read_instr_i2d(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'i2f'. */ +GArchInstruction *jvm_read_instr_i2f(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'i2l'. */ +GArchInstruction *jvm_read_instr_i2l(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'i2s'. */ +GArchInstruction *jvm_read_instr_i2s(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'iadd'. */ +GArchInstruction *jvm_read_instr_iadd(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'iconst_n'. */ +GArchInstruction *jvm_read_instr_iconst_n(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'iload_n'. */ +GArchInstruction *jvm_read_instr_iload_n(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'invokespecial'. */ +GArchInstruction *jvm_read_instr_invokespecial(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'invokestatic'. */ +GArchInstruction *jvm_read_instr_invokestatic(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'invokevirtual'. */ +GArchInstruction *jvm_read_instr_invokevirtual(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'istore_n'. */ +GArchInstruction *jvm_read_instr_istore_n(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'ireturn'. */ +GArchInstruction *jvm_read_instr_ireturn(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'lreturn'. */ +GArchInstruction *jvm_read_instr_lreturn(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'l2d'. */ +GArchInstruction *jvm_read_instr_l2d(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'l2i'. */ +GArchInstruction *jvm_read_instr_l2i(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'l2f'. */ +GArchInstruction *jvm_read_instr_l2f(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'monitorenter'. */ +GArchInstruction *jvm_read_instr_monitorenter(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'monitorexit'. */ +GArchInstruction *jvm_read_instr_monitorexit(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'nop'. */ +GArchInstruction *jvm_read_instr_nop(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'pop'. */ +GArchInstruction *jvm_read_instr_pop(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'pop2'. */ +GArchInstruction *jvm_read_instr_pop2(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + +/* Décode une instruction de type 'return'. */ +GArchInstruction *jvm_read_instr_return(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); + + + +#endif /* _ARCH_JVM_OPCODES_H */ diff --git a/plugins/jvm/operand.c b/plugins/jvm/operand.c new file mode 100644 index 0000000..4168bcf --- /dev/null +++ b/plugins/jvm/operand.c @@ -0,0 +1,325 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * operand.c - gestion des operandes de l'architecture JVM + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "operand.h" + + +#include "../operand-int.h" +#include "../../common/endianness.h" +#include "../../format/java/pool.h" + + +#include "../../format/exe_format.h" /* FIXME : remme */ + + +/* ---------------------- COQUILLE VIDE POUR LES OPERANDES JVM ---------------------- */ + + +/* Définition d'un opérande de la JVM (instance) */ +struct _GJvmOperand +{ + GArchOperand parent; /* Instance parente */ + +}; + + +/* Définition d'un opérande de la JVM (classe) */ +struct _GJvmOperandClass +{ + GArchOperandClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des opérandes JVM de base. */ +static void g_jvm_operand_class_init(GJvmOperandClass *); + +/* Initialise une instance d'opérande de base pour la JVM. */ +static void g_jvm_operand_init(GJvmOperand *); + + + +/* --------------------- OPERANDES RENVOYANT VERS UNE REFERENCE --------------------- */ + + +/* Définition d'un opérande de référence de la JVM (instance) */ +struct _GJvmRefOperand +{ + GJvmOperand parent; /* Instance parente */ + + JvmOperandType type; /* Type de référence attendue */ + uint16_t index; /* Indice dans la table Java */ + +}; + + +/* Définition d'un opérande de référence de la JVM (classe) */ +struct _GJvmRefOperandClass +{ + GJvmOperandClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des opérandes de référence JVM. */ +static void g_jvm_ref_operand_class_init(GJvmRefOperandClass *); + +/* Initialise une instance d'opérande de référence pour la JVM. */ +static void g_jvm_ref_operand_init(GJvmRefOperand *); + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/* COQUILLE VIDE POUR LES OPERANDES JVM */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini par la GLib pour un opérande de JVM. */ +G_DEFINE_TYPE(GJvmOperand, g_jvm_operand, G_TYPE_ARCH_OPERAND); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des opérandes JVM de base. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_jvm_operand_class_init(GJvmOperandClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance à initialiser. * +* * +* Description : Initialise une instance d'opérande de base pour la JVM. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_jvm_operand_init(GJvmOperand *operand) +{ + +} + + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/* OPERANDES RENVOYANT VERS UNE REFERENCE */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini par la GLib pour un opérande de référence de JVM. */ +G_DEFINE_TYPE(GJvmRefOperand, g_jvm_ref_operand, G_TYPE_JVM_OPERAND); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des opérandes de référence JVM. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_jvm_ref_operand_class_init(GJvmRefOperandClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : proc = instance à initialiser. * +* * +* Description : Initialise une instance d'opérande de référence pour la JVM. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_jvm_ref_operand_init(GJvmRefOperand *operand) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* type = type de l'opérande. * +* * +* Description : Crée un opérande de référence pour la JVM. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_jvm_ref_operand_new(const bin_t *data, off_t *pos, off_t len, JvmOperandType type) +{ + GJvmRefOperand *result; /* Structure à retourner */ + uint16_t index; /* Indice dans la table Java */ + + if (!read_u16(&index, data, pos, len, SRE_BIG)) + result = NULL; + + else + { + result = g_object_new(G_TYPE_JVM_REF_OPERAND, NULL); + + /* FIXME : faire attention au type */ + + result->type = type; + result->index = index; + + } + + return G_ARCH_OPERAND(result); + +} + + +#if 0 +/****************************************************************************** +* * +* Paramètres : operand = opérande à traiter. * +* format = format du binaire manipulé. * +* * +* Description : Traduit un opérande en version humainement lisible. * +* * +* Retour : Chaîne de caractères à libérer de la mémoire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_jvm_ref_operand_get_text(const GJvmRefOperand *operand, const exe_format *format) +{ + char *result; /* Chaîne à retourner */ + + switch (operand->type) + { + case JOT_FIELD_REF: + result = NULL;//build_reference_from_java_pool((const java_format *)format, operand->index, JRT_FIELD); + break; + case JOT_METHOD_REF: + result = NULL;//build_reference_from_java_pool((const java_format *)format, operand->index, JRT_METHOD); + break; + default: + result = NULL; + break; + } + + if (result == NULL) + result = strdup("<bad_reference>"); + + return result; + +} +#endif + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/* AIDE A LA CREATION D'OPERANDES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : instr = instruction dont la définition est à compléter. [OUT]* +* data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* type = type de l'opérande. * +* ... = éventuelle(s) information(s) complémentaire(s). * +* * +* Description : Procède à la lecture d'un opérande donné. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool jvm_read_one_operand(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, JvmOperandType type, ...) +{ + va_list ap; /* Liste des compléments */ + GArchOperand *op; /* Opérande unique décodé */ + + va_start(ap, type); + + switch (type) + { + case JOT_FIELD_REF: + case JOT_METHOD_REF: + op = g_jvm_ref_operand_new(data, pos, len, type); + break; + + default: + op = NULL; + break; + } + + va_end(ap); + + if (op == NULL) return false; + + g_arch_instruction_attach_extra_operand(instr, op); + + return true; + +} diff --git a/plugins/jvm/operand.h b/plugins/jvm/operand.h new file mode 100644 index 0000000..8f4288d --- /dev/null +++ b/plugins/jvm/operand.h @@ -0,0 +1,109 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * operand.h - prototypes pour la gestion des operandes de l'architecture JVM + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _ARCH_JVM_OPERAND_H +#define _ARCH_JVM_OPERAND_H + + +#include "../instruction.h" + + + +/* Types d'opérandes supportés */ +typedef enum _JvmOperandType JvmOperandType; + + + +/* ---------------------- COQUILLE VIDE POUR LES OPERANDES JVM ---------------------- */ + + +#define G_TYPE_JVM_OPERAND g_jvm_operand_get_type() +#define G_JVM_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_JVM_OPERAND, GJvmOperand)) +#define G_IS_JVM_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_JVM_OPERAND)) +#define G_JVM_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_JVM_OPERAND, GJvmOperandClass)) +#define G_IS_JVM_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_JVM_OPERAND)) +#define G_JVM_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_JVM_OPERAND, GJvmOperandClass)) + + +/* Définition d'un opérande de la JVM (instance) */ +typedef struct _GJvmOperand GJvmOperand; + +/* Définition d'un opérande de la JVM (classe) */ +typedef struct _GJvmOperandClass GJvmOperandClass; + + +/* Indique le type défini par la GLib pour un opérande de JVM. */ +GType g_jvm_operand_get_type(void); + + + + + + + +/* --------------------- OPERANDES RENVOYANT VERS UNE REFERENCE --------------------- */ + + +#define G_TYPE_JVM_REF_OPERAND g_jvm_ref_operand_get_type() +#define G_JVM_REF_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_jvm_ref_operand_get_type(), GJvmRefOperand)) +#define G_IS_JVM_REF_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_jvm_ref_operand_get_type())) +#define G_JVM_REF_OPERAND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_jvm_ref_operand_get_type(), GJvmRefOperandIface)) + + +/* Définition d'un opérande de référence de la JVM (instance) */ +typedef struct _GJvmRefOperand GJvmRefOperand; + +/* Définition d'un opérande de référence de la JVM (classe) */ +typedef struct _GJvmRefOperandClass GJvmRefOperandClass; + + +/* Indique le type défini par la GLib pour un opérande de référence de JVM. */ +GType g_jvm_ref_operand_get_type(void); + +/* Crée un opérande de référence pour la JVM. */ +GArchOperand *g_jvm_ref_operand_new(const bin_t *, off_t *, off_t, JvmOperandType); + + + + + +/* ------------------------- AIDE A LA CREATION D'OPERANDES ------------------------- */ + + +/* Types d'opérandes supportés */ +enum _JvmOperandType +{ + JOT_FIELD_REF, /* Référence vers un champ */ + JOT_METHOD_REF, /* Référence vers une méthode */ + + JOT_COUNT + +}; + + +/* Procède à la lecture d'un opérande donné. */ +bool jvm_read_one_operand(GArchInstruction *, const bin_t *, off_t *, off_t, JvmOperandType, ...); + + + +#endif /* _ARCH_JVM_OPERAND_H */ diff --git a/plugins/jvm/processor.c b/plugins/jvm/processor.c new file mode 100644 index 0000000..f25dabc --- /dev/null +++ b/plugins/jvm/processor.c @@ -0,0 +1,400 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * processor.c - manipulation du processeur de la JVM + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#include "processor.h" + + +#include "instruction.h" +#include "opcodes.h" +#include "../processor-int.h" + + + +/* Définition du processeur de la JVM (instance) */ +struct _GJvmProcessor +{ + GArchProcessor parent; /* Instance parente */ + +}; + + +/* Définition du processeur de la JVM (classe) */ +struct _GJvmProcessorClass +{ + GArchProcessorClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des processeurs de JVM. */ +static void g_jvm_processor_class_init(GJvmProcessorClass *); + +/* Initialise une instance de processeur de JVM. */ +static void g_jvm_processor_init(GJvmProcessor *); + +/* Supprime toutes les références externes. */ +static void g_jvm_processor_dispose(GJvmProcessor *); + +/* Procède à la libération totale de la mémoire. */ +static void g_jvm_processor_finalize(GJvmProcessor *); + +/* Décode une instruction dans un flux de données. */ +static GArchInstruction *g_jvm_processor_decode_instruction(const GJvmProcessor *, const bin_t *, off_t *, off_t, vmpa_t); + + +/* Indique le type défini par la GLib pour le processeur JVM. */ +G_DEFINE_TYPE(GJvmProcessor, g_jvm_processor, G_TYPE_ARCH_PROCESSOR); + + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des processeurs de JVM. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_jvm_processor_class_init(GJvmProcessorClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GArchProcessorClass *proc; /* Encore une autre vision... */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_jvm_processor_dispose; + object->finalize = (GObjectFinalizeFunc)g_jvm_processor_finalize; + + proc = G_ARCH_PROCESSOR_CLASS(klass); + + proc->decode = (decode_instruction_fc)g_jvm_processor_decode_instruction; + +} + + +/****************************************************************************** +* * +* Paramètres : proc = instance à initialiser. * +* * +* Description : Initialise une instance de processeur de JVM. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_jvm_processor_init(GJvmProcessor *proc) +{ + GArchProcessor *parent; /* Instance parente */ + + parent = G_ARCH_PROCESSOR(proc); + + parent->endianness = SRE_BIG; + parent->memsize = MDS_32_BITS; + +} + + +/****************************************************************************** +* * +* Paramètres : proc = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_jvm_processor_dispose(GJvmProcessor *proc) +{ + G_OBJECT_CLASS(g_jvm_processor_parent_class)->dispose(G_OBJECT(proc)); + +} + + +/****************************************************************************** +* * +* Paramètres : bookmark = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_jvm_processor_finalize(GJvmProcessor *proc) +{ + G_OBJECT_CLASS(g_jvm_processor_parent_class)->finalize(G_OBJECT(proc)); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée le support de l'architecture JVM. * +* * +* Retour : Architecture mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchProcessor *g_jvm_processor_new(void) +{ + GArchProcessor *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_JVM_PROCESSOR, NULL); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : proc = architecture visée par la procédure. * +* data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* * +* Description : Décode une instruction dans un flux de données. * +* * +* Retour : Instruction mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GArchInstruction *g_jvm_processor_decode_instruction(const GJvmProcessor *proc, const bin_t *data, off_t *pos, off_t len, vmpa_t addr) +{ + GArchInstruction *result; /* Instruction à renvoyer */ + bool wide; /* Utilisation d'étendues */ + bool care; /* Traitement des opcodes */ + JvmOpcodes id; /* Identifiant d'instruction */ + + id = jvm_guess_next_instruction(data, *pos, len, &wide, &care); + + if (id != JOP_COUNT && !care) + { + if (wide) (*pos)++; + (*pos)++; + } + + switch (id) + { + case JOP_NOP: + result = jvm_read_instr_nop(data, pos, len, addr, proc); + break; + + case JOP_ACONST_NULL: + result = jvm_read_instr_aconst_null(data, pos, len, addr, proc); + break; + + case JOP_ICONST_M1: + case JOP_ICONST_0: + case JOP_ICONST_1: + case JOP_ICONST_2: + case JOP_ICONST_3: + case JOP_ICONST_4: + case JOP_ICONST_5: + result = jvm_read_instr_iconst_n(data, pos, len, addr, proc); + break; + + case JOP_POP: + result = jvm_read_instr_pop(data, pos, len, addr, proc); + break; + + case JOP_POP2: + result = jvm_read_instr_pop2(data, pos, len, addr, proc); + break; + + case JOP_DUP: + result = jvm_read_instr_dup(data, pos, len, addr, proc); + break; + + case JOP_DUP_X1: + result = jvm_read_instr_dup_x1(data, pos, len, addr, proc); + break; + + case JOP_DUP_X2: + result = jvm_read_instr_dup_x2(data, pos, len, addr, proc); + break; + + case JOP_DUP2: + result = jvm_read_instr_dup2(data, pos, len, addr, proc); + break; + + case JOP_DUP2_X1: + result = jvm_read_instr_dup2_x1(data, pos, len, addr, proc); + break; + + case JOP_DUP2_X2: + result = jvm_read_instr_dup2_x2(data, pos, len, addr, proc); + break; + + case JOP_IADD: + result = jvm_read_instr_iadd(data, pos, len, addr, proc); + break; + + case JOP_I2L: + result = jvm_read_instr_i2l(data, pos, len, addr, proc); + break; + + case JOP_I2F: + result = jvm_read_instr_i2f(data, pos, len, addr, proc); + break; + + case JOP_I2D: + result = jvm_read_instr_i2d(data, pos, len, addr, proc); + break; + + case JOP_L2I: + result = jvm_read_instr_l2i(data, pos, len, addr, proc); + break; + + case JOP_L2F: + result = jvm_read_instr_l2f(data, pos, len, addr, proc); + break; + + case JOP_L2D: + result = jvm_read_instr_l2d(data, pos, len, addr, proc); + break; + + case JOP_F2I: + result = jvm_read_instr_f2i(data, pos, len, addr, proc); + break; + + case JOP_F2L: + result = jvm_read_instr_f2l(data, pos, len, addr, proc); + break; + + case JOP_F2D: + result = jvm_read_instr_f2d(data, pos, len, addr, proc); + break; + + case JOP_D2I: + result = jvm_read_instr_d2i(data, pos, len, addr, proc); + break; + + case JOP_D2L: + result = jvm_read_instr_d2l(data, pos, len, addr, proc); + break; + + case JOP_D2F: + result = jvm_read_instr_d2f(data, pos, len, addr, proc); + break; + + case JOP_I2B: + result = jvm_read_instr_i2b(data, pos, len, addr, proc); + break; + + case JOP_I2C: + result = jvm_read_instr_i2c(data, pos, len, addr, proc); + break; + + case JOP_I2S: + result = jvm_read_instr_i2s(data, pos, len, addr, proc); + break; + + case JOP_ILOAD_0: + case JOP_ILOAD_1: + case JOP_ILOAD_2: + case JOP_ILOAD_3: + result = jvm_read_instr_iload_n(data, pos, len, addr, proc); + break; + + case JOP_ALOAD_0: + case JOP_ALOAD_1: + case JOP_ALOAD_2: + case JOP_ALOAD_3: + result = jvm_read_instr_aload_n(data, pos, len, addr, proc); + break; + + case JOP_ISTORE_0: + case JOP_ISTORE_1: + case JOP_ISTORE_2: + case JOP_ISTORE_3: + result = jvm_read_instr_istore_n(data, pos, len, addr, proc); + break; + + case JOP_IRETURN: + result = jvm_read_instr_ireturn(data, pos, len, addr, proc); + break; + + case JOP_LRETURN: + result = jvm_read_instr_lreturn(data, pos, len, addr, proc); + break; + + case JOP_FRETURN: + result = jvm_read_instr_freturn(data, pos, len, addr, proc); + break; + + case JOP_DRETURN: + result = jvm_read_instr_dreturn(data, pos, len, addr, proc); + break; + + case JOP_ARETURN: + result = jvm_read_instr_areturn(data, pos, len, addr, proc); + break; + + case JOP_RETURN: + result = jvm_read_instr_return(data, pos, len, addr, proc); + break; + + case JOP_GETSTATIC: + result = jvm_read_instr_getstatic(data, pos, len, addr, proc); + break; + + case JOP_INVOKE_VIRTUAL: + result = jvm_read_instr_invokevirtual(data, pos, len, addr, proc); + break; + + case JOP_INVOKE_SPECIAL: + result = jvm_read_instr_invokespecial(data, pos, len, addr, proc); + break; + + case JOP_INVOKE_STATIC: + result = jvm_read_instr_invokestatic(data, pos, len, addr, proc); + break; + + default: + result = NULL; + break; + + } + + return result; + +} diff --git a/plugins/jvm/processor.h b/plugins/jvm/processor.h new file mode 100644 index 0000000..7123d0c --- /dev/null +++ b/plugins/jvm/processor.h @@ -0,0 +1,55 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * processor.h - prototypes pour la manipulation du processeur de la JVM + * + * Copyright (C) 2009-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see . + */ + + +#ifndef _ARCH_JVM_PROCESSOR_H +#define _ARCH_JVM_PROCESSOR_H + + +#include "../processor.h" + + + +#define G_TYPE_JVM_PROCESSOR g_jvm_processor_get_type() +#define G_JVM_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_JVM_PROCESSOR, GJvmProcessor)) +#define G_IS_JVM_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_JVM_PROCESSOR)) +#define G_JVM_PROCESSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_JVM_PROCESSOR, GJvmProcessorClass)) +#define G_IS_JVM_PROCESSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_JVM_PROCESSOR)) +#define G_JVM_PROCESSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_JVM_PROCESSOR, GJvmProcessorClass)) + + +/* Définition du processeur de la JVM (instance) */ +typedef struct _GJvmProcessor GJvmProcessor; + +/* Définition du processeur de la JVM (classe) */ +typedef struct _GJvmProcessorClass GJvmProcessorClass; + + +/* Indique le type défini par la GLib pour le processeur JVM. */ +GType g_jvm_processor_get_type(void); + +/* Crée le support de l'architecture JVM. */ +GArchProcessor *g_jvm_processor_new(void); + + + +#endif /* _ARCH_JVM_PROCESSOR_H */ diff --git a/plugins/pychrysalide/debug/Makefile.am b/plugins/pychrysalide/debug/Makefile.am index a5d7da3..3586321 100644 --- a/plugins/pychrysalide/debug/Makefile.am +++ b/plugins/pychrysalide/debug/Makefile.am @@ -5,8 +5,7 @@ libpychrysadebug_la_SOURCES = \ debugger.h debugger.c \ module.h module.c -libpychrysadebug_la_LIBADD = \ - gdbrsp/libpychrysadebuggdbrsp.la +libpychrysadebug_la_LIBADD = libpychrysadebug_la_LDFLAGS = @@ -21,4 +20,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJE AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = gdbrsp +SUBDIRS = diff --git a/plugins/pychrysalide/debug/gdbrsp/Makefile.am b/plugins/pychrysalide/debug/gdbrsp/Makefile.am deleted file mode 100644 index 8ece12b..0000000 --- a/plugins/pychrysalide/debug/gdbrsp/Makefile.am +++ /dev/null @@ -1,19 +0,0 @@ - -noinst_LTLIBRARIES = libpychrysadebuggdbrsp.la - -libpychrysadebuggdbrsp_la_SOURCES = \ - gdb.h gdb.c \ - module.h module.c - -libpychrysadebuggdbrsp_la_LDFLAGS = - - -devdir = $(includedir)/chrysalide-$(subdir) - -dev_HEADERS = $(libpychrysadebuggdbrsp_la_SOURCES:%c=) - - -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ - -I$(top_srcdir)/src - -AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/pychrysalide/debug/gdbrsp/gdb.c b/plugins/pychrysalide/debug/gdbrsp/gdb.c deleted file mode 100644 index 77b72b0..0000000 --- a/plugins/pychrysalide/debug/gdbrsp/gdb.c +++ /dev/null @@ -1,173 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gdb.c - équivalent Python du fichier "debug/gdbrsp/gdb.c" - * - * Copyright (C) 2016 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "gdb.h" - - -#include - - -#include - - -#include - - -#include "../debugger.h" -#include "../../access.h" -#include "../../helpers.h" -#include "../../analysis/binary.h" - - - -/* Crée un nouvel objet Python de type 'GdbDebugger'. */ -static PyObject *py_gdb_debugger_new(PyTypeObject *, PyObject *, PyObject *); - - - -/****************************************************************************** -* * -* Paramètres : type = type de l'objet à instancier. * -* args = arguments fournis à l'appel. * -* kwds = arguments de type key=val fournis. * -* * -* Description : Crée un nouvel objet Python de type 'GdbDebugger'. * -* * -* Retour : Instance Python mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_gdb_debugger_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *result; /* Instance à retourner */ - PyObject *binary_obj; /* Objet pour le binaire lié */ - const char *server; /* Nom du serveur à contacter */ - unsigned short port; /* Port de connexion */ - int ret; /* Bilan de lecture des args. */ - GLoadedBinary *binary; /* Binaire chargé en mémoire */ - GBinaryDebugger *debugger; /* Création GLib à transmettre */ - - ret = PyArg_ParseTuple(args, "OsH", &binary_obj, &server, &port); - if (!ret) return NULL; - - ret = PyObject_IsInstance(binary_obj, (PyObject *)get_python_loaded_binary_type()); - if (!ret) - { - PyErr_SetString(PyExc_TypeError, _("The first argument must be an instance of LoadedBinary.")); - return NULL; - } - - binary = G_LOADED_BINARY(pygobject_get(binary_obj)); - - debugger = g_gdb_debugger_new(binary, server, port); - - result = pygobject_new(G_OBJECT(debugger)); - - g_object_unref(debugger); - - return (PyObject *)result; - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Fournit un accès à une définition de type à diffuser. * -* * -* Retour : Définition d'objet pour Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyTypeObject *get_python_gdb_debugger_type(void) -{ - static PyMethodDef py_gdb_debugger_methods[] = { - { NULL } - }; - - static PyGetSetDef py_gdb_debugger_getseters[] = { - { NULL } - }; - - static PyTypeObject py_gdb_debugger_type = { - - PyVarObject_HEAD_INIT(NULL, 0) - - .tp_name = "pychrysalide.debug.gdbrsp.GdbDebugger", - .tp_basicsize = sizeof(PyGObject), - - .tp_flags = Py_TPFLAGS_DEFAULT, - - .tp_doc = "PyChrysalide GDB debugger", - - .tp_methods = py_gdb_debugger_methods, - .tp_getset = py_gdb_debugger_getseters, - .tp_new = py_gdb_debugger_new - - }; - - return &py_gdb_debugger_type; - -} - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Prend en charge l'objet 'pychrysalide....gdbrsp.GdbDebugger'.* -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool ensure_python_gdb_debugger_is_registered(void) -{ - PyTypeObject *type; /* Type Python 'GdbDebugger' */ - PyObject *module; /* Module à recompléter */ - PyObject *dict; /* Dictionnaire du module */ - - type = get_python_gdb_debugger_type(); - - if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) - { - module = get_access_to_python_module("pychrysalide.debug.gdbrsp"); - - dict = PyModule_GetDict(module); - - if (!register_class_for_pygobject(dict, G_TYPE_GDB_DEBUGGER, type, get_python_binary_debugger_type())) - return false; - - } - - return true; - -} diff --git a/plugins/pychrysalide/debug/gdbrsp/gdb.h b/plugins/pychrysalide/debug/gdbrsp/gdb.h deleted file mode 100644 index 057a38d..0000000 --- a/plugins/pychrysalide/debug/gdbrsp/gdb.h +++ /dev/null @@ -1,42 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gdb.h - prototypes pour l'équivalent Python du fichier "debug/gdbrsp/gdb.h" - * - * Copyright (C) 2016 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#ifndef _PLUGINS_PYCHRYSALIDE_DEBUG_GDBRSP_DEBUGGER_H -#define _PLUGINS_PYCHRYSALIDE_DEBUG_GDBRSP_DEBUGGER_H - - -#include -#include - - - -/* Fournit un accès à une définition de type à diffuser. */ -PyTypeObject *get_python_gdb_debugger_type(void); - -/* Prend en charge l'objet 'pychrysalide.debug.gdbrsp.GdbDebugger'. */ -bool ensure_python_gdb_debugger_is_registered(void); - - - -#endif /* _PLUGINS_PYCHRYSALIDE_DEBUG_GDBRSP_DEBUGGER_H */ diff --git a/plugins/pychrysalide/debug/gdbrsp/module.c b/plugins/pychrysalide/debug/gdbrsp/module.c deleted file mode 100644 index c077aa7..0000000 --- a/plugins/pychrysalide/debug/gdbrsp/module.c +++ /dev/null @@ -1,94 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * module.c - intégration du répertoire gdbrsp en tant que module - * - * Copyright (C) 2012 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "module.h" - - -#include "gdb.h" -#include "../../helpers.h" - - - -/****************************************************************************** -* * -* Paramètres : super = module dont la définition est à compléter. * -* * -* Description : Ajoute le module 'debug.gdbresp' à un module Python. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool add_debug_gdbresp_module(PyObject *super) -{ - bool result; /* Bilan à retourner */ - PyObject *module; /* Sous-module mis en place */ - - static PyModuleDef py_chrysalide_debug_gdbresp_module = { - - .m_base = PyModuleDef_HEAD_INIT, - - .m_name = "pychrysalide.debug.gdbrsp", - .m_doc = "Python module for Chrysalide.debug.gdbrsp", - - .m_size = -1, - - }; - - module = build_python_module(super, &py_chrysalide_debug_gdbresp_module); - - result = (module != NULL); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Intègre les objets du module 'debug.gdbresp'. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool populate_debug_gdbresp_module(void) -{ - bool result; /* Bilan à retourner */ - - result = true; - - if (result) result = ensure_python_gdb_debugger_is_registered(); - - assert(result); - - return result; - -} diff --git a/plugins/pychrysalide/debug/gdbrsp/module.h b/plugins/pychrysalide/debug/gdbrsp/module.h deleted file mode 100644 index 0ed3719..0000000 --- a/plugins/pychrysalide/debug/gdbrsp/module.h +++ /dev/null @@ -1,42 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * module.h - prototypes pour l'intégration du répertoire gdbrsp en tant que module - * - * Copyright (C) 2012-2016 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#ifndef _PLUGINS_PYCHRYSALIDE_DEBUG_GDBRSP_MODULE_H -#define _PLUGINS_PYCHRYSALIDE_DEBUG_GDBRSP_MODULE_H - - -#include -#include - - - -/* Ajoute le module 'debug.gdbresp' à un module Python. */ -bool add_debug_gdbresp_module(PyObject *); - -/* Intègre les objets du module 'debug.gdbresp'. */ -bool populate_debug_gdbresp_module(void); - - - -#endif /* _PLUGINS_PYCHRYSALIDE_DEBUG_GDBRSP_MODULE_H */ diff --git a/plugins/pychrysalide/debug/module.c b/plugins/pychrysalide/debug/module.c index a2df8bf..1ce4fe8 100644 --- a/plugins/pychrysalide/debug/module.c +++ b/plugins/pychrysalide/debug/module.c @@ -26,7 +26,6 @@ #include "debugger.h" -#include "gdbrsp/module.h" #include "../helpers.h" @@ -63,8 +62,6 @@ bool add_debug_module(PyObject *super) result = (module != NULL); - if (result) result = add_debug_gdbresp_module(module); - if (!result) Py_XDECREF(module); @@ -93,8 +90,6 @@ bool populate_debug_module(void) if (result) result = ensure_python_binary_debugger_is_registered(); - if (result) result = populate_debug_gdbresp_module(); - assert(result); return result; diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am index 4c15349..ce5db57 100644 --- a/src/arch/Makefile.am +++ b/src/arch/Makefile.am @@ -29,13 +29,6 @@ libarch_la_SOURCES = \ undefined.h undefined.c \ vmpa.h vmpa.c -# libarch_la_LIBADD = \ -# arm/libarcharm.la \ -# dalvik/libarchdalvik.la \ -# jvm/libarchjvm.la \ -# mips/libarchmips.la \ -# x86/libarchx86.la - libarch_la_LIBADD = \ operands/libarchoperands.la @@ -52,5 +45,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -#SUBDIRS = arm dalvik jvm mips x86 SUBDIRS = operands diff --git a/src/arch/jvm/Makefile.am b/src/arch/jvm/Makefile.am deleted file mode 100644 index fc4ee0b..0000000 --- a/src/arch/jvm/Makefile.am +++ /dev/null @@ -1,35 +0,0 @@ - -noinst_LTLIBRARIES = libarchjvm.la - -libarchjvm_la_SOURCES = \ - instruction.h instruction.c \ - op_add.c \ - op_const.c \ - op_convert.c \ - op_dup.c \ - op_getput.c \ - op_invoke.c \ - op_load.c \ - op_monitor.c \ - op_nop.c \ - op_pop.c \ - op_store.c \ - op_ret.c \ - opcodes.h \ - operand.h operand.c \ - processor.h processor.c - -libarchjvm_la_CFLAGS = $(AM_CFLAGS) - - -devdir = $(includedir)/chrysalide/$(subdir:src/%=%) - -dev_HEADERS = $(libarchjvm_la_SOURCES:%c=) - - -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) - -AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) - - -SUBDIRS = diff --git a/src/arch/jvm/instruction.c b/src/arch/jvm/instruction.c deleted file mode 100644 index c7a9bfb..0000000 --- a/src/arch/jvm/instruction.c +++ /dev/null @@ -1,299 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * instruction.c - gestion des instructions JVM - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "instruction.h" - - -#include "../instruction-int.h" - - - -/* Définition générique d'une instruction d'architecture JVM (instance) */ -struct _GJvmInstruction -{ - GArchInstruction parent; /* A laisser en premier */ - - JvmOpcodes type; /* Position dans la liste */ - -}; - -/* Définition générique d'une instruction d'architecture JVM (classe) */ -struct _GJvmInstructionClass -{ - GArchInstructionClass parent; /* A laisser en premier */ - -}; - - -/* Initialise la classe des instructions pour JVM. */ -static void g_jvm_instruction_class_init(GJvmInstructionClass *); - -/* Initialise une instance d'opérande d'architecture JVM. */ -static void g_jvm_instruction_init(GJvmInstruction *); - - - -/* --------------------- AIDE A LA MISE EN PLACE D'INSTRUCTIONS --------------------- */ - - -/* Répertoire de toutes les instructions JVM */ -typedef struct _jvm_instruction -{ - bool care_of_data; /* Devinette = repas ? */ - bool can_wide; /* Instruction étendue ? */ - bin_t opcode; /* Opcode de l'instruction */ - - const char *keyword; /* Mot clef de la commande */ - -} jvm_instruction; - - -static jvm_instruction _instructions[JOP_COUNT] = { - - [JOP_NOP] = { false, false, 0x00, "nop" }, - [JOP_ACONST_NULL] = { false, false, 0x01, "aconst_null" }, - [JOP_ICONST_M1] = { true, false, 0x02, "iconst_m1" }, - [JOP_ICONST_0] = { true, false, 0x03, "iconst_0" }, - [JOP_ICONST_1] = { true, false, 0x04, "iconst_1" }, - [JOP_ICONST_2] = { true, false, 0x05, "iconst_2" }, - [JOP_ICONST_3] = { true, false, 0x06, "iconst_3" }, - [JOP_ICONST_4] = { true, false, 0x07, "iconst_4" }, - [JOP_ICONST_5] = { true, false, 0x08, "iconst_5" }, - - - - [JOP_POP] = { false, false, 0x57, "pop" }, - [JOP_POP2] = { false, false, 0x58, "pop2" }, - [JOP_DUP] = { false, false, 0x59, "dup" }, - [JOP_DUP_X1] = { false, false, 0x5a, "dup_x1" }, - [JOP_DUP_X2] = { false, false, 0x5b, "dup_x2" }, - [JOP_DUP2] = { false, false, 0x5c, "dup2" }, - [JOP_DUP2_X1] = { false, false, 0x5d, "dup2_x1" }, - [JOP_DUP2_X2] = { false, false, 0x5e, "dup2_x2" }, - - - [JOP_IADD] = { false, false, 0x60, "iadd" }, - - - [JOP_I2L] = { false, false, 0x85, "i2l" }, - [JOP_I2F] = { false, false, 0x86, "i2f" }, - [JOP_I2D] = { false, false, 0x87, "i2d" }, - [JOP_L2I] = { false, false, 0x88, "l2i" }, - [JOP_L2F] = { false, false, 0x89, "l2f" }, - [JOP_L2D] = { false, false, 0x8a, "l2d" }, - [JOP_F2I] = { false, false, 0x8b, "f2i" }, - [JOP_F2L] = { false, false, 0x8c, "f2l" }, - [JOP_F2D] = { false, false, 0x8d, "f2d" }, - [JOP_D2I] = { false, false, 0x8e, "d2i" }, - [JOP_D2L] = { false, false, 0x8f, "d2l" }, - [JOP_D2F] = { false, false, 0x90, "d2f" }, - [JOP_I2B] = { false, false, 0x91, "i2b" }, - [JOP_I2C] = { false, false, 0x92, "i2c" }, - [JOP_I2S] = { false, false, 0x93, "i2s" }, - - - [JOP_ILOAD_0] = { true, false, 0x1a, "iload_0" }, - [JOP_ILOAD_1] = { true, false, 0x1b, "iload_1" }, - [JOP_ILOAD_2] = { true, false, 0x1c, "iload_2" }, - [JOP_ILOAD_3] = { true, false, 0x1d, "iload_3" }, - - - - [JOP_ALOAD_0] = { true, false, 0x2a, "aload_0" }, - [JOP_ALOAD_1] = { true, false, 0x2b, "aload_1" }, - [JOP_ALOAD_2] = { true, false, 0x2c, "aload_2" }, - [JOP_ALOAD_3] = { true, false, 0x2d, "aload_3" }, - - [JOP_ISTORE_0] = { true, false, 0x3b, "istore_0" }, - [JOP_ISTORE_1] = { true, false, 0x3c, "istore_1" }, - [JOP_ISTORE_2] = { true, false, 0x3d, "istore_2" }, - [JOP_ISTORE_3] = { true, false, 0x3e, "istore_3" }, - - [JOP_IRETURN] = { false, false, 0xac, "ireturn" }, - [JOP_LRETURN] = { false, false, 0xad, "lreturn" }, - [JOP_FRETURN] = { false, false, 0xae, "freturn" }, - [JOP_DRETURN] = { false, false, 0xaf, "dreturn" }, - [JOP_ARETURN] = { false, false, 0xb0, "areturn" }, - [JOP_RETURN] = { false, false, 0xb1, "return" }, - [JOP_GETSTATIC] = { false, false, 0xb2, "getstatic" }, - - [JOP_INVOKE_VIRTUAL] = { false, false, 0xb6, "invokevirtual" }, - [JOP_INVOKE_SPECIAL] = { false, false, 0xb7, "invokespecial" }, - [JOP_INVOKE_STATIC] = { false, false, 0xb8, "invokestatic" }, - - - [JOP_MONITOR_ENTER] = { false, false, 0xc2, "monitorenter" }, - [JOP_MONITOR_EXIT] = { false, false, 0xc3, "monitorexit" } - - - -}; - - -/* Traduit une instruction en version humainement lisible. */ -static const char *jvm_get_instruction_text(const GJvmInstruction *, const GExeFormat *); - - - - - - -/* Indique le type défini pour une instruction d'architecture JVM. */ -G_DEFINE_TYPE(GJvmInstruction, g_jvm_instruction, G_TYPE_ARCH_INSTRUCTION); - - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des instructions pour JVM. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_jvm_instruction_class_init(GJvmInstructionClass *klass) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instance à initialiser. * -* * -* Description : Initialise une instance d'instruction d'architecture JVM. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_jvm_instruction_init(GJvmInstruction *instr) -{ - GArchInstruction *parent; /* Instance parente */ - - parent = G_ARCH_INSTRUCTION(instr); - - //parent->get_text = (get_instruction_text_fc)jvm_get_instruction_text; - -} - - -/****************************************************************************** -* * -* Paramètres : type = type d'instruction à représenter. * -* * -* Description : Crée une instruction pour l'architecture JVM. * -* * -* Retour : Architecture mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *g_jvm_instruction_new(JvmOpcodes type) -{ - GArchInstruction *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_JVM_INSTRUCTION, NULL); - - G_JVM_INSTRUCTION(result)->type = type; - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* AIDE A LA MISE EN PLACE D'INSTRUCTIONS */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. * -* len = taille totale des données à analyser. * -* wide = étendue de la future instruction. [OUT] * -* care = la lecture de l'instr. veut-elle les opcodes ? [OUT] * -* * -* Description : Recherche l'identifiant de la prochaine instruction. * -* * -* Retour : Identifiant de la prochaine instruction à tenter de charger. * -* * -* Remarques : - * -* * -******************************************************************************/ - -JvmOpcodes jvm_guess_next_instruction(const bin_t *data, off_t pos, off_t len, bool *wide, bool *care) -{ - JvmOpcodes result; /* Identifiant à retourner */ - bin_t opcode; /* Opcode à trouver */ - - *wide = (data[pos] == 0xc4); - - if (*wide && (pos + 1) == len) return JOP_COUNT; - - opcode = data[pos + (*wide ? 1 : 0)]; - - for (result = 0; result < JOP_COUNT; result++) - { - if (*wide && !_instructions[result].can_wide) continue; - - if (_instructions[result].opcode == opcode) - { - *care = _instructions[result].care_of_data; - break; - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instruction à traiter. * -* format = format du binaire manipulé. * -* * -* Description : Traduit une instruction en version humainement lisible. * -* * -* Retour : Chaîne de caractères à libérer de la mémoire. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static const char *jvm_get_instruction_text(const GJvmInstruction *instr, const GExeFormat *format) -{ - return _instructions[instr->type].keyword; - -} diff --git a/src/arch/jvm/instruction.h b/src/arch/jvm/instruction.h deleted file mode 100644 index 8ec9c48..0000000 --- a/src/arch/jvm/instruction.h +++ /dev/null @@ -1,151 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * instruction.h - prototypes pour la gestion des instructions JVM - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _ARCH_JVM_INSTRUCTION_H -#define _ARCH_JVM_INSTRUCTION_H - - -#include "../instruction.h" - - - - - -/* Enumération de tous les opcodes */ -typedef enum _JvmOpcodes -{ - JOP_NOP, /* nop (0x00) */ - JOP_ACONST_NULL, /* aconst_null (0x01) */ - JOP_ICONST_M1, /* iconst_m1 (0x02) */ - JOP_ICONST_0, /* iconst_0 (0x03) */ - JOP_ICONST_1, /* iconst_1 (0x04) */ - JOP_ICONST_2, /* iconst_2 (0x05) */ - JOP_ICONST_3, /* iconst_3 (0x06) */ - JOP_ICONST_4, /* iconst_4 (0x07) */ - JOP_ICONST_5, /* iconst_5 (0x08) */ - - - JOP_POP, /* pop (0x57) */ - JOP_POP2, /* pop2 (0x58) */ - JOP_DUP, /* dup (0x59) */ - JOP_DUP_X1, /* dup_x1 (0x5a) */ - JOP_DUP_X2, /* dup_x2 (0x5b) */ - JOP_DUP2, /* dup2 (0x5c) */ - JOP_DUP2_X1, /* dup2_x1 (0x5d) */ - JOP_DUP2_X2, /* dup2_x2 (0x5e) */ - - - JOP_IADD, /* iadd (0x60) */ - - - JOP_I2L, /* i2l (0x85) */ - JOP_I2F, /* i2f (0x86) */ - JOP_I2D, /* i2d (0x87) */ - JOP_L2I, /* l2i (0x88) */ - JOP_L2F, /* l2f (0x89) */ - JOP_L2D, /* l2d (0x8a) */ - JOP_F2I, /* f2i (0x8b) */ - JOP_F2L, /* f2l (0x8c) */ - JOP_F2D, /* f2d (0x8d) */ - JOP_D2I, /* d2i (0x8e) */ - JOP_D2L, /* d2l (0x8f) */ - JOP_D2F, /* d2f (0x90) */ - JOP_I2B, /* i2b (0x91) */ - JOP_I2C, /* i2c (0x92) */ - JOP_I2S, /* i2s (0x93) */ - - - - - JOP_ILOAD_0, /* iload_0 (0x1a) */ - JOP_ILOAD_1, /* iload_1 (0x1b) */ - JOP_ILOAD_2, /* iload_2 (0x1c) */ - JOP_ILOAD_3, /* iload_3 (0x1d) */ - - - - - JOP_ALOAD_0, /* aload_0 (0x2a) */ - JOP_ALOAD_1, /* aload_1 (0x2b) */ - JOP_ALOAD_2, /* aload_2 (0x2c) */ - JOP_ALOAD_3, /* aload_3 (0x2d) */ - - - JOP_ISTORE_0, /* istore_0 (0x3b) */ - JOP_ISTORE_1, /* istore_1 (0x3c) */ - JOP_ISTORE_2, /* istore_2 (0x3d) */ - JOP_ISTORE_3, /* istore_3 (0x3e) */ - - - JOP_IRETURN, /* ireturn (0xac) */ - JOP_LRETURN, /* lreturn (0xad) */ - JOP_FRETURN, /* freturn (0xae) */ - JOP_DRETURN, /* dreturn (0xaf) */ - JOP_ARETURN, /* areturn (0xb0) */ - JOP_RETURN, /* return (0xb1) */ - JOP_GETSTATIC, /* getstatic (0xb2) */ - - JOP_INVOKE_VIRTUAL, /* invokevirtual (0xb6) */ - JOP_INVOKE_SPECIAL, /* invokespecial (0xb7) */ - JOP_INVOKE_STATIC, /* invokestatic (0xb8) */ - - JOP_MONITOR_ENTER, /* monitorenter (0xc2) */ - JOP_MONITOR_EXIT, /* monitorexit (0xc3) */ - - JOP_COUNT - -} JvmOpcodes; - - -#define G_TYPE_JVM_INSTRUCTION g_jvm_instruction_get_type() -#define G_JVM_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_JVM_INSTRUCTION, GJvmInstruction)) -#define G_IS_JVM_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_JVM_INSTRUCTION)) -#define G_JVM_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_JVM_INSTRUCTION, GJvmInstructionClass)) -#define G_IS_JVM_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_JVM_INSTRUCTION)) -#define G_JVM_INSTRUCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_JVM_INSTRUCTION, GJvmInstructionClass)) - - -/* Définition générique d'une instruction d'architecture JVM (instance) */ -typedef struct _GJvmInstruction GJvmInstruction; - -/* Définition générique d'une instruction d'architecture JVM (classe) */ -typedef struct _GJvmInstructionClass GJvmInstructionClass; - - -/* Indique le type défini pour une instruction d'architecture JVM. */ -GType g_jvm_instruction_get_type(void); - -/* Crée une instruction pour l'architecture JVM. */ -GArchInstruction *g_jvm_instruction_new(JvmOpcodes); - - - -/* --------------------- AIDE A LA MISE EN PLACE D'INSTRUCTIONS --------------------- */ - - -/* Recherche l'identifiant de la prochaine instruction. */ -JvmOpcodes jvm_guess_next_instruction(const bin_t *, off_t, off_t, bool *, bool *); - - - -#endif /* _ARCH_JVM_INSTRUCTION_H */ diff --git a/src/arch/jvm/op_add.c b/src/arch/jvm/op_add.c deleted file mode 100644 index fbcc682..0000000 --- a/src/arch/jvm/op_add.c +++ /dev/null @@ -1,55 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * op_add.c - décodage des additions - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "opcodes.h" - - -#include "instruction.h" - - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'iadd'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_iadd(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_IADD); - - return result; - -} diff --git a/src/arch/jvm/op_const.c b/src/arch/jvm/op_const.c deleted file mode 100644 index fc7075c..0000000 --- a/src/arch/jvm/op_const.c +++ /dev/null @@ -1,87 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * op_const.c - décodage des empilements de valeurs prédéfinies - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "opcodes.h" - - -#include "instruction.h" - - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'aconst_null'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_aconst_null(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_ACONST_NULL); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'iconst_n'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_iconst_n(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - JvmOpcodes opcode; /* Instruction effective */ - - opcode = JOP_ICONST_M1 + (data[*pos] - 0x02); - - (*pos)++; - - result = g_jvm_instruction_new(opcode); - - return result; - -} diff --git a/src/arch/jvm/op_convert.c b/src/arch/jvm/op_convert.c deleted file mode 100644 index 43d9d20..0000000 --- a/src/arch/jvm/op_convert.c +++ /dev/null @@ -1,433 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * op_convert.c - décodage des conversions entre types de base - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "opcodes.h" - - -#include "instruction.h" - - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'd2f'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_d2f(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_D2F); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'd2i'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_d2i(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_D2I); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'd2l'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_d2l(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_D2L); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'f2d'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_f2d(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_F2D); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'f2i'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_f2i(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_F2I); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'f2l'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_f2l(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_F2L); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'i2b'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_i2b(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_I2B); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'i2c'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_i2c(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_I2C); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'i2d'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_i2d(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_I2D); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'i2f'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_i2f(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_I2F); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'i2l'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_i2l(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_I2L); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'i2s'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_i2s(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_I2S); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'l2d'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_l2d(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_L2D); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'l2i'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_l2i(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_L2I); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'l2f'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_l2f(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_L2F); - - return result; - -} diff --git a/src/arch/jvm/op_dup.c b/src/arch/jvm/op_dup.c deleted file mode 100644 index a42acd8..0000000 --- a/src/arch/jvm/op_dup.c +++ /dev/null @@ -1,190 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * op_dup.c - décodage des duplications d'étages de la pile - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "opcodes.h" - - -#include "instruction.h" - - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'dup'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_dup(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_DUP); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'dup_x1'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_dup_x1(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_DUP_X1); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'dup_x2'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_dup_x2(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_DUP_X2); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'dup2'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_dup2(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_DUP2); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'dup2_x1'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_dup2_x1(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_DUP2_X1); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'dup2_x2'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_dup2_x2(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_DUP2_X2); - - return result; - -} diff --git a/src/arch/jvm/op_getput.c b/src/arch/jvm/op_getput.c deleted file mode 100644 index c4d2b26..0000000 --- a/src/arch/jvm/op_getput.c +++ /dev/null @@ -1,62 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * op_getput.c - décodage des fonctions (get|put)* - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "opcodes.h" - - -#include "instruction.h" -#include "operand.h" - - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'getstatic'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_getstatic(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_GETSTATIC); - - if (!jvm_read_one_operand(result, data, pos, len, JOT_FIELD_REF)) - { - /*free(result); FIXME */ - return NULL; - } - - return result; - -} diff --git a/src/arch/jvm/op_invoke.c b/src/arch/jvm/op_invoke.c deleted file mode 100644 index 118f3a5..0000000 --- a/src/arch/jvm/op_invoke.c +++ /dev/null @@ -1,128 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * op_invoke.c - décodage des fonctions (get|put)* - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "opcodes.h" - - -#include "instruction.h" -#include "operand.h" - - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'invokespecial'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_invokespecial(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_INVOKE_SPECIAL); - - if (!jvm_read_one_operand(result, data, pos, len, JOT_METHOD_REF)) - { - /*free(result); FIXME */ - return NULL; - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'invokestatic'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_invokestatic(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_INVOKE_STATIC); - - if (!jvm_read_one_operand(result, data, pos, len, JOT_METHOD_REF)) - { - /*free(result); FIXME */ - return NULL; - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'invokevirtual'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_invokevirtual(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_INVOKE_VIRTUAL); - - if (!jvm_read_one_operand(result, data, pos, len, JOT_METHOD_REF)) - { - /*free(result); FIXME */ - return NULL; - } - - return result; - -} diff --git a/src/arch/jvm/op_load.c b/src/arch/jvm/op_load.c deleted file mode 100644 index faea478..0000000 --- a/src/arch/jvm/op_load.c +++ /dev/null @@ -1,92 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * op_load.c - décodage des instructions de chargement - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "opcodes.h" - - -#include "instruction.h" - - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'aload_n'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_aload_n(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - JvmOpcodes opcode; /* Instruction effective */ - - opcode = JOP_ALOAD_0 + (data[*pos] - 0x2a); - - (*pos)++; - - result = g_jvm_instruction_new(opcode); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'iload_n'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_iload_n(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - JvmOpcodes opcode; /* Instruction effective */ - - opcode = JOP_ILOAD_0 + (data[*pos] - 0x1a); - - (*pos)++; - - result = g_jvm_instruction_new(opcode); - - return result; - -} diff --git a/src/arch/jvm/op_monitor.c b/src/arch/jvm/op_monitor.c deleted file mode 100644 index 3e0b61a..0000000 --- a/src/arch/jvm/op_monitor.c +++ /dev/null @@ -1,82 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * op_monitor.c - décodage des outils pour réaliser des sémaphores sur les objets - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "opcodes.h" - - -#include "instruction.h" - - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'monitorenter'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_monitorenter(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_MONITOR_ENTER); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'monitorexit'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_monitorexit(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_MONITOR_EXIT); - - return result; - -} diff --git a/src/arch/jvm/op_nop.c b/src/arch/jvm/op_nop.c deleted file mode 100644 index ff2f58b..0000000 --- a/src/arch/jvm/op_nop.c +++ /dev/null @@ -1,55 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * op_nop.c - décodage des absences d'opération - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "opcodes.h" - - -#include "instruction.h" - - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'nop'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_nop(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_NOP); - - return result; - -} diff --git a/src/arch/jvm/op_pop.c b/src/arch/jvm/op_pop.c deleted file mode 100644 index a9f98f1..0000000 --- a/src/arch/jvm/op_pop.c +++ /dev/null @@ -1,82 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * op_pop.c - décodage des dépilements de pile dans le vide - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "opcodes.h" - - -#include "instruction.h" - - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'pop'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_pop(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_POP); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'pop2'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_pop2(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_POP); - - return result; - -} diff --git a/src/arch/jvm/op_ret.c b/src/arch/jvm/op_ret.c deleted file mode 100644 index 6ab6df3..0000000 --- a/src/arch/jvm/op_ret.c +++ /dev/null @@ -1,184 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * op_ret.c - décodage des ordres de retour - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "opcodes.h" - - -#include "instruction.h" - - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'areturn'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_areturn(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_ARETURN); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'dreturn'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_dreturn(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_DRETURN); - - return result; - -} -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'freturn'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_freturn(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_FRETURN); - - return result; - -} -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'ireturn'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_ireturn(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_IRETURN); - - return result; - -} -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'lreturn'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_lreturn(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_LRETURN); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'return'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_return(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - - result = g_jvm_instruction_new(JOP_RETURN); - - return result; - -} diff --git a/src/arch/jvm/op_store.c b/src/arch/jvm/op_store.c deleted file mode 100644 index 1804049..0000000 --- a/src/arch/jvm/op_store.c +++ /dev/null @@ -1,60 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * op_store.c - décodage des instructions d'enregistrement - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "opcodes.h" - - -#include "instruction.h" - - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* proc = architecture ciblée par le désassemblage. * -* * -* Description : Décode une instruction de type 'istore_n'. * -* * -* Retour : Instruction mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *jvm_read_instr_istore_n(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GJvmProcessor *proc) -{ - GArchInstruction *result; /* Instruction à retourner */ - JvmOpcodes opcode; /* Instruction effective */ - - opcode = JOP_ISTORE_0 + (data[*pos] - 0x3b); - - (*pos)++; - - result = g_jvm_instruction_new(opcode); - - return result; - -} diff --git a/src/arch/jvm/opcodes.h b/src/arch/jvm/opcodes.h deleted file mode 100644 index 7251fed..0000000 --- a/src/arch/jvm/opcodes.h +++ /dev/null @@ -1,160 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * opcodes.h - prototypes pour la liste de tous les opcodes de l'architecture JVM - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _ARCH_JVM_OPCODES_H -#define _ARCH_JVM_OPCODES_H - - -#include "processor.h" - - - -/* Décode une instruction de type 'aconst_null'. */ -GArchInstruction *jvm_read_instr_aconst_null(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'aload_n'. */ -GArchInstruction *jvm_read_instr_aload_n(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'areturn'. */ -GArchInstruction *jvm_read_instr_areturn(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'd2f'. */ -GArchInstruction *jvm_read_instr_d2f(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'd2i'. */ -GArchInstruction *jvm_read_instr_d2i(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'd2l'. */ -GArchInstruction *jvm_read_instr_d2l(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'dreturn'. */ -GArchInstruction *jvm_read_instr_dreturn(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'dup'. */ -GArchInstruction *jvm_read_instr_dup(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'dup_x1'. */ -GArchInstruction *jvm_read_instr_dup_x1(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'dup_x2'. */ -GArchInstruction *jvm_read_instr_dup_x2(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'dup2'. */ -GArchInstruction *jvm_read_instr_dup2(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'dup2_x1'. */ -GArchInstruction *jvm_read_instr_dup2_x1(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'dup2_x2'. */ -GArchInstruction *jvm_read_instr_dup2_x2(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'f2d'. */ -GArchInstruction *jvm_read_instr_f2d(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'f2i'. */ -GArchInstruction *jvm_read_instr_f2i(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'f2l'. */ -GArchInstruction *jvm_read_instr_f2l(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'freturn'. */ -GArchInstruction *jvm_read_instr_freturn(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'getstatic'. */ -GArchInstruction *jvm_read_instr_getstatic(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'i2b'. */ -GArchInstruction *jvm_read_instr_i2b(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'i2c'. */ -GArchInstruction *jvm_read_instr_i2c(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'i2d'. */ -GArchInstruction *jvm_read_instr_i2d(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'i2f'. */ -GArchInstruction *jvm_read_instr_i2f(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'i2l'. */ -GArchInstruction *jvm_read_instr_i2l(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'i2s'. */ -GArchInstruction *jvm_read_instr_i2s(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'iadd'. */ -GArchInstruction *jvm_read_instr_iadd(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'iconst_n'. */ -GArchInstruction *jvm_read_instr_iconst_n(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'iload_n'. */ -GArchInstruction *jvm_read_instr_iload_n(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'invokespecial'. */ -GArchInstruction *jvm_read_instr_invokespecial(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'invokestatic'. */ -GArchInstruction *jvm_read_instr_invokestatic(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'invokevirtual'. */ -GArchInstruction *jvm_read_instr_invokevirtual(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'istore_n'. */ -GArchInstruction *jvm_read_instr_istore_n(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'ireturn'. */ -GArchInstruction *jvm_read_instr_ireturn(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'lreturn'. */ -GArchInstruction *jvm_read_instr_lreturn(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'l2d'. */ -GArchInstruction *jvm_read_instr_l2d(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'l2i'. */ -GArchInstruction *jvm_read_instr_l2i(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'l2f'. */ -GArchInstruction *jvm_read_instr_l2f(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'monitorenter'. */ -GArchInstruction *jvm_read_instr_monitorenter(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'monitorexit'. */ -GArchInstruction *jvm_read_instr_monitorexit(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'nop'. */ -GArchInstruction *jvm_read_instr_nop(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'pop'. */ -GArchInstruction *jvm_read_instr_pop(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'pop2'. */ -GArchInstruction *jvm_read_instr_pop2(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - -/* Décode une instruction de type 'return'. */ -GArchInstruction *jvm_read_instr_return(const bin_t *, off_t *, off_t, vmpa_t, const GJvmProcessor *); - - - -#endif /* _ARCH_JVM_OPCODES_H */ diff --git a/src/arch/jvm/operand.c b/src/arch/jvm/operand.c deleted file mode 100644 index 4168bcf..0000000 --- a/src/arch/jvm/operand.c +++ /dev/null @@ -1,325 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * operand.c - gestion des operandes de l'architecture JVM - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "operand.h" - - -#include "../operand-int.h" -#include "../../common/endianness.h" -#include "../../format/java/pool.h" - - -#include "../../format/exe_format.h" /* FIXME : remme */ - - -/* ---------------------- COQUILLE VIDE POUR LES OPERANDES JVM ---------------------- */ - - -/* Définition d'un opérande de la JVM (instance) */ -struct _GJvmOperand -{ - GArchOperand parent; /* Instance parente */ - -}; - - -/* Définition d'un opérande de la JVM (classe) */ -struct _GJvmOperandClass -{ - GArchOperandClass parent; /* Classe parente */ - -}; - - -/* Initialise la classe des opérandes JVM de base. */ -static void g_jvm_operand_class_init(GJvmOperandClass *); - -/* Initialise une instance d'opérande de base pour la JVM. */ -static void g_jvm_operand_init(GJvmOperand *); - - - -/* --------------------- OPERANDES RENVOYANT VERS UNE REFERENCE --------------------- */ - - -/* Définition d'un opérande de référence de la JVM (instance) */ -struct _GJvmRefOperand -{ - GJvmOperand parent; /* Instance parente */ - - JvmOperandType type; /* Type de référence attendue */ - uint16_t index; /* Indice dans la table Java */ - -}; - - -/* Définition d'un opérande de référence de la JVM (classe) */ -struct _GJvmRefOperandClass -{ - GJvmOperandClass parent; /* Classe parente */ - -}; - - -/* Initialise la classe des opérandes de référence JVM. */ -static void g_jvm_ref_operand_class_init(GJvmRefOperandClass *); - -/* Initialise une instance d'opérande de référence pour la JVM. */ -static void g_jvm_ref_operand_init(GJvmRefOperand *); - - - - - - - -/* ---------------------------------------------------------------------------------- */ -/* COQUILLE VIDE POUR LES OPERANDES JVM */ -/* ---------------------------------------------------------------------------------- */ - - -/* Indique le type défini par la GLib pour un opérande de JVM. */ -G_DEFINE_TYPE(GJvmOperand, g_jvm_operand, G_TYPE_ARCH_OPERAND); - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des opérandes JVM de base. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_jvm_operand_class_init(GJvmOperandClass *klass) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : operand = instance à initialiser. * -* * -* Description : Initialise une instance d'opérande de base pour la JVM. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_jvm_operand_init(GJvmOperand *operand) -{ - -} - - - - - - - - -/* ---------------------------------------------------------------------------------- */ -/* OPERANDES RENVOYANT VERS UNE REFERENCE */ -/* ---------------------------------------------------------------------------------- */ - - -/* Indique le type défini par la GLib pour un opérande de référence de JVM. */ -G_DEFINE_TYPE(GJvmRefOperand, g_jvm_ref_operand, G_TYPE_JVM_OPERAND); - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des opérandes de référence JVM. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_jvm_ref_operand_class_init(GJvmRefOperandClass *klass) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : proc = instance à initialiser. * -* * -* Description : Initialise une instance d'opérande de référence pour la JVM. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_jvm_ref_operand_init(GJvmRefOperand *operand) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* type = type de l'opérande. * -* * -* Description : Crée un opérande de référence pour la JVM. * -* * -* Retour : Opérande mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_jvm_ref_operand_new(const bin_t *data, off_t *pos, off_t len, JvmOperandType type) -{ - GJvmRefOperand *result; /* Structure à retourner */ - uint16_t index; /* Indice dans la table Java */ - - if (!read_u16(&index, data, pos, len, SRE_BIG)) - result = NULL; - - else - { - result = g_object_new(G_TYPE_JVM_REF_OPERAND, NULL); - - /* FIXME : faire attention au type */ - - result->type = type; - result->index = index; - - } - - return G_ARCH_OPERAND(result); - -} - - -#if 0 -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* format = format du binaire manipulé. * -* * -* Description : Traduit un opérande en version humainement lisible. * -* * -* Retour : Chaîne de caractères à libérer de la mémoire. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static char *g_jvm_ref_operand_get_text(const GJvmRefOperand *operand, const exe_format *format) -{ - char *result; /* Chaîne à retourner */ - - switch (operand->type) - { - case JOT_FIELD_REF: - result = NULL;//build_reference_from_java_pool((const java_format *)format, operand->index, JRT_FIELD); - break; - case JOT_METHOD_REF: - result = NULL;//build_reference_from_java_pool((const java_format *)format, operand->index, JRT_METHOD); - break; - default: - result = NULL; - break; - } - - if (result == NULL) - result = strdup("<bad_reference>"); - - return result; - -} -#endif - - - - - - - -/* ---------------------------------------------------------------------------------- */ -/* AIDE A LA CREATION D'OPERANDES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : instr = instruction dont la définition est à compléter. [OUT]* -* data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* type = type de l'opérande. * -* ... = éventuelle(s) information(s) complémentaire(s). * -* * -* Description : Procède à la lecture d'un opérande donné. * -* * -* Retour : Bilan de l'opération : true en cas de succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool jvm_read_one_operand(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, JvmOperandType type, ...) -{ - va_list ap; /* Liste des compléments */ - GArchOperand *op; /* Opérande unique décodé */ - - va_start(ap, type); - - switch (type) - { - case JOT_FIELD_REF: - case JOT_METHOD_REF: - op = g_jvm_ref_operand_new(data, pos, len, type); - break; - - default: - op = NULL; - break; - } - - va_end(ap); - - if (op == NULL) return false; - - g_arch_instruction_attach_extra_operand(instr, op); - - return true; - -} diff --git a/src/arch/jvm/operand.h b/src/arch/jvm/operand.h deleted file mode 100644 index 8f4288d..0000000 --- a/src/arch/jvm/operand.h +++ /dev/null @@ -1,109 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * operand.h - prototypes pour la gestion des operandes de l'architecture JVM - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _ARCH_JVM_OPERAND_H -#define _ARCH_JVM_OPERAND_H - - -#include "../instruction.h" - - - -/* Types d'opérandes supportés */ -typedef enum _JvmOperandType JvmOperandType; - - - -/* ---------------------- COQUILLE VIDE POUR LES OPERANDES JVM ---------------------- */ - - -#define G_TYPE_JVM_OPERAND g_jvm_operand_get_type() -#define G_JVM_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_JVM_OPERAND, GJvmOperand)) -#define G_IS_JVM_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_JVM_OPERAND)) -#define G_JVM_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_JVM_OPERAND, GJvmOperandClass)) -#define G_IS_JVM_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_JVM_OPERAND)) -#define G_JVM_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_JVM_OPERAND, GJvmOperandClass)) - - -/* Définition d'un opérande de la JVM (instance) */ -typedef struct _GJvmOperand GJvmOperand; - -/* Définition d'un opérande de la JVM (classe) */ -typedef struct _GJvmOperandClass GJvmOperandClass; - - -/* Indique le type défini par la GLib pour un opérande de JVM. */ -GType g_jvm_operand_get_type(void); - - - - - - - -/* --------------------- OPERANDES RENVOYANT VERS UNE REFERENCE --------------------- */ - - -#define G_TYPE_JVM_REF_OPERAND g_jvm_ref_operand_get_type() -#define G_JVM_REF_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_jvm_ref_operand_get_type(), GJvmRefOperand)) -#define G_IS_JVM_REF_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_jvm_ref_operand_get_type())) -#define G_JVM_REF_OPERAND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_jvm_ref_operand_get_type(), GJvmRefOperandIface)) - - -/* Définition d'un opérande de référence de la JVM (instance) */ -typedef struct _GJvmRefOperand GJvmRefOperand; - -/* Définition d'un opérande de référence de la JVM (classe) */ -typedef struct _GJvmRefOperandClass GJvmRefOperandClass; - - -/* Indique le type défini par la GLib pour un opérande de référence de JVM. */ -GType g_jvm_ref_operand_get_type(void); - -/* Crée un opérande de référence pour la JVM. */ -GArchOperand *g_jvm_ref_operand_new(const bin_t *, off_t *, off_t, JvmOperandType); - - - - - -/* ------------------------- AIDE A LA CREATION D'OPERANDES ------------------------- */ - - -/* Types d'opérandes supportés */ -enum _JvmOperandType -{ - JOT_FIELD_REF, /* Référence vers un champ */ - JOT_METHOD_REF, /* Référence vers une méthode */ - - JOT_COUNT - -}; - - -/* Procède à la lecture d'un opérande donné. */ -bool jvm_read_one_operand(GArchInstruction *, const bin_t *, off_t *, off_t, JvmOperandType, ...); - - - -#endif /* _ARCH_JVM_OPERAND_H */ diff --git a/src/arch/jvm/processor.c b/src/arch/jvm/processor.c deleted file mode 100644 index f25dabc..0000000 --- a/src/arch/jvm/processor.c +++ /dev/null @@ -1,400 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * processor.c - manipulation du processeur de la JVM - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "processor.h" - - -#include "instruction.h" -#include "opcodes.h" -#include "../processor-int.h" - - - -/* Définition du processeur de la JVM (instance) */ -struct _GJvmProcessor -{ - GArchProcessor parent; /* Instance parente */ - -}; - - -/* Définition du processeur de la JVM (classe) */ -struct _GJvmProcessorClass -{ - GArchProcessorClass parent; /* Classe parente */ - -}; - - -/* Initialise la classe des processeurs de JVM. */ -static void g_jvm_processor_class_init(GJvmProcessorClass *); - -/* Initialise une instance de processeur de JVM. */ -static void g_jvm_processor_init(GJvmProcessor *); - -/* Supprime toutes les références externes. */ -static void g_jvm_processor_dispose(GJvmProcessor *); - -/* Procède à la libération totale de la mémoire. */ -static void g_jvm_processor_finalize(GJvmProcessor *); - -/* Décode une instruction dans un flux de données. */ -static GArchInstruction *g_jvm_processor_decode_instruction(const GJvmProcessor *, const bin_t *, off_t *, off_t, vmpa_t); - - -/* Indique le type défini par la GLib pour le processeur JVM. */ -G_DEFINE_TYPE(GJvmProcessor, g_jvm_processor, G_TYPE_ARCH_PROCESSOR); - - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des processeurs de JVM. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_jvm_processor_class_init(GJvmProcessorClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - GArchProcessorClass *proc; /* Encore une autre vision... */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_jvm_processor_dispose; - object->finalize = (GObjectFinalizeFunc)g_jvm_processor_finalize; - - proc = G_ARCH_PROCESSOR_CLASS(klass); - - proc->decode = (decode_instruction_fc)g_jvm_processor_decode_instruction; - -} - - -/****************************************************************************** -* * -* Paramètres : proc = instance à initialiser. * -* * -* Description : Initialise une instance de processeur de JVM. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_jvm_processor_init(GJvmProcessor *proc) -{ - GArchProcessor *parent; /* Instance parente */ - - parent = G_ARCH_PROCESSOR(proc); - - parent->endianness = SRE_BIG; - parent->memsize = MDS_32_BITS; - -} - - -/****************************************************************************** -* * -* Paramètres : proc = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_jvm_processor_dispose(GJvmProcessor *proc) -{ - G_OBJECT_CLASS(g_jvm_processor_parent_class)->dispose(G_OBJECT(proc)); - -} - - -/****************************************************************************** -* * -* Paramètres : bookmark = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_jvm_processor_finalize(GJvmProcessor *proc) -{ - G_OBJECT_CLASS(g_jvm_processor_parent_class)->finalize(G_OBJECT(proc)); - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Crée le support de l'architecture JVM. * -* * -* Retour : Architecture mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchProcessor *g_jvm_processor_new(void) -{ - GArchProcessor *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_JVM_PROCESSOR, NULL); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : proc = architecture visée par la procédure. * -* data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* addr = adresse virtuelle de l'instruction. * -* * -* Description : Décode une instruction dans un flux de données. * -* * -* Retour : Instruction mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GArchInstruction *g_jvm_processor_decode_instruction(const GJvmProcessor *proc, const bin_t *data, off_t *pos, off_t len, vmpa_t addr) -{ - GArchInstruction *result; /* Instruction à renvoyer */ - bool wide; /* Utilisation d'étendues */ - bool care; /* Traitement des opcodes */ - JvmOpcodes id; /* Identifiant d'instruction */ - - id = jvm_guess_next_instruction(data, *pos, len, &wide, &care); - - if (id != JOP_COUNT && !care) - { - if (wide) (*pos)++; - (*pos)++; - } - - switch (id) - { - case JOP_NOP: - result = jvm_read_instr_nop(data, pos, len, addr, proc); - break; - - case JOP_ACONST_NULL: - result = jvm_read_instr_aconst_null(data, pos, len, addr, proc); - break; - - case JOP_ICONST_M1: - case JOP_ICONST_0: - case JOP_ICONST_1: - case JOP_ICONST_2: - case JOP_ICONST_3: - case JOP_ICONST_4: - case JOP_ICONST_5: - result = jvm_read_instr_iconst_n(data, pos, len, addr, proc); - break; - - case JOP_POP: - result = jvm_read_instr_pop(data, pos, len, addr, proc); - break; - - case JOP_POP2: - result = jvm_read_instr_pop2(data, pos, len, addr, proc); - break; - - case JOP_DUP: - result = jvm_read_instr_dup(data, pos, len, addr, proc); - break; - - case JOP_DUP_X1: - result = jvm_read_instr_dup_x1(data, pos, len, addr, proc); - break; - - case JOP_DUP_X2: - result = jvm_read_instr_dup_x2(data, pos, len, addr, proc); - break; - - case JOP_DUP2: - result = jvm_read_instr_dup2(data, pos, len, addr, proc); - break; - - case JOP_DUP2_X1: - result = jvm_read_instr_dup2_x1(data, pos, len, addr, proc); - break; - - case JOP_DUP2_X2: - result = jvm_read_instr_dup2_x2(data, pos, len, addr, proc); - break; - - case JOP_IADD: - result = jvm_read_instr_iadd(data, pos, len, addr, proc); - break; - - case JOP_I2L: - result = jvm_read_instr_i2l(data, pos, len, addr, proc); - break; - - case JOP_I2F: - result = jvm_read_instr_i2f(data, pos, len, addr, proc); - break; - - case JOP_I2D: - result = jvm_read_instr_i2d(data, pos, len, addr, proc); - break; - - case JOP_L2I: - result = jvm_read_instr_l2i(data, pos, len, addr, proc); - break; - - case JOP_L2F: - result = jvm_read_instr_l2f(data, pos, len, addr, proc); - break; - - case JOP_L2D: - result = jvm_read_instr_l2d(data, pos, len, addr, proc); - break; - - case JOP_F2I: - result = jvm_read_instr_f2i(data, pos, len, addr, proc); - break; - - case JOP_F2L: - result = jvm_read_instr_f2l(data, pos, len, addr, proc); - break; - - case JOP_F2D: - result = jvm_read_instr_f2d(data, pos, len, addr, proc); - break; - - case JOP_D2I: - result = jvm_read_instr_d2i(data, pos, len, addr, proc); - break; - - case JOP_D2L: - result = jvm_read_instr_d2l(data, pos, len, addr, proc); - break; - - case JOP_D2F: - result = jvm_read_instr_d2f(data, pos, len, addr, proc); - break; - - case JOP_I2B: - result = jvm_read_instr_i2b(data, pos, len, addr, proc); - break; - - case JOP_I2C: - result = jvm_read_instr_i2c(data, pos, len, addr, proc); - break; - - case JOP_I2S: - result = jvm_read_instr_i2s(data, pos, len, addr, proc); - break; - - case JOP_ILOAD_0: - case JOP_ILOAD_1: - case JOP_ILOAD_2: - case JOP_ILOAD_3: - result = jvm_read_instr_iload_n(data, pos, len, addr, proc); - break; - - case JOP_ALOAD_0: - case JOP_ALOAD_1: - case JOP_ALOAD_2: - case JOP_ALOAD_3: - result = jvm_read_instr_aload_n(data, pos, len, addr, proc); - break; - - case JOP_ISTORE_0: - case JOP_ISTORE_1: - case JOP_ISTORE_2: - case JOP_ISTORE_3: - result = jvm_read_instr_istore_n(data, pos, len, addr, proc); - break; - - case JOP_IRETURN: - result = jvm_read_instr_ireturn(data, pos, len, addr, proc); - break; - - case JOP_LRETURN: - result = jvm_read_instr_lreturn(data, pos, len, addr, proc); - break; - - case JOP_FRETURN: - result = jvm_read_instr_freturn(data, pos, len, addr, proc); - break; - - case JOP_DRETURN: - result = jvm_read_instr_dreturn(data, pos, len, addr, proc); - break; - - case JOP_ARETURN: - result = jvm_read_instr_areturn(data, pos, len, addr, proc); - break; - - case JOP_RETURN: - result = jvm_read_instr_return(data, pos, len, addr, proc); - break; - - case JOP_GETSTATIC: - result = jvm_read_instr_getstatic(data, pos, len, addr, proc); - break; - - case JOP_INVOKE_VIRTUAL: - result = jvm_read_instr_invokevirtual(data, pos, len, addr, proc); - break; - - case JOP_INVOKE_SPECIAL: - result = jvm_read_instr_invokespecial(data, pos, len, addr, proc); - break; - - case JOP_INVOKE_STATIC: - result = jvm_read_instr_invokestatic(data, pos, len, addr, proc); - break; - - default: - result = NULL; - break; - - } - - return result; - -} diff --git a/src/arch/jvm/processor.h b/src/arch/jvm/processor.h deleted file mode 100644 index 7123d0c..0000000 --- a/src/arch/jvm/processor.h +++ /dev/null @@ -1,55 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * processor.h - prototypes pour la manipulation du processeur de la JVM - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _ARCH_JVM_PROCESSOR_H -#define _ARCH_JVM_PROCESSOR_H - - -#include "../processor.h" - - - -#define G_TYPE_JVM_PROCESSOR g_jvm_processor_get_type() -#define G_JVM_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_JVM_PROCESSOR, GJvmProcessor)) -#define G_IS_JVM_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_JVM_PROCESSOR)) -#define G_JVM_PROCESSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_JVM_PROCESSOR, GJvmProcessorClass)) -#define G_IS_JVM_PROCESSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_JVM_PROCESSOR)) -#define G_JVM_PROCESSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_JVM_PROCESSOR, GJvmProcessorClass)) - - -/* Définition du processeur de la JVM (instance) */ -typedef struct _GJvmProcessor GJvmProcessor; - -/* Définition du processeur de la JVM (classe) */ -typedef struct _GJvmProcessorClass GJvmProcessorClass; - - -/* Indique le type défini par la GLib pour le processeur JVM. */ -GType g_jvm_processor_get_type(void); - -/* Crée le support de l'architecture JVM. */ -GArchProcessor *g_jvm_processor_new(void); - - - -#endif /* _ARCH_JVM_PROCESSOR_H */ diff --git a/src/debug/Makefile.am b/src/debug/Makefile.am index bafceda..41de8b3 100644 --- a/src/debug/Makefile.am +++ b/src/debug/Makefile.am @@ -12,8 +12,7 @@ libdebug_la_SOURCES = \ stream-int.h \ stream.h stream.c -libdebug_la_LIBADD = \ - gdbrsp/libdebuggdbrsp.la +libdebug_la_LIBADD = libdebug_la_CFLAGS = $(AM_CFLAGS) @@ -27,4 +26,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = gdbrsp +SUBDIRS = diff --git a/src/debug/gdbrsp/Makefile.am b/src/debug/gdbrsp/Makefile.am deleted file mode 100644 index 5ee8df6..0000000 --- a/src/debug/gdbrsp/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ - -noinst_LTLIBRARIES = libdebuggdbrsp.la - -libdebuggdbrsp_la_SOURCES = \ - aops.h \ - gdb-int.h \ - gdb.h gdb.c \ - helpers.h helpers.c \ - helpers_arm.h helpers_arm.c \ - helpers_arm64.h helpers_arm64.c \ - packet.h packet.c \ - stream-int.h \ - stream.h stream.c \ - support.h support.c \ - target.h target.c \ - tcp.h tcp.c \ - utils.h utils.c - -libdebuggdbrsp_la_CFLAGS = $(AM_CFLAGS) - - -devdir = $(includedir)/chrysalide/$(subdir:src/%=%) - -dev_HEADERS = $(libdebuggdbrsp_la_SOURCES:%c=) - - -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) - -AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/src/debug/gdbrsp/aops.h b/src/debug/gdbrsp/aops.h deleted file mode 100644 index 1599615..0000000 --- a/src/debug/gdbrsp/aops.h +++ /dev/null @@ -1,57 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * aops.h - prototypes pour les compléments utiles à GDB pour l'architecture ARM - * - * Copyright (C) 2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _DEBUG_GDBRSP_AOPS_H -#define _DEBUG_GDBRSP_AOPS_H - - -#include "gdb.h" - - - -/* Détermine le point d'exécution courant. */ -typedef bool (* get_pc_fc) (GGdbDebugger *, virt_t *); - -/* Remonte la pile d'appels jusqu'au point courant. */ -typedef bool (* compute_call_stack_fc) (const GGdbDebugger *, virt_t **, size_t *); - -/* Complète la commande manipulant des points d'arrêt. */ -typedef const char * (* get_bp_kind_fc) (const GGdbDebugger *, virt_t); - -/* Construit une instruction provoquant un arrêt d'exécution. */ -typedef const uint8_t * (* get_bp_data_fc) (const GGdbDebugger *, virt_t, size_t *); - - -/* Procédures spécifiques pour une architecture */ -typedef struct _gdb_arch_ops -{ - get_pc_fc get_pc; /* Obtention du point d'exéc. */ - compute_call_stack_fc compute_cstack; /* Calcule la pile d'appels */ - get_bp_kind_fc get_bp_kind; /* Fournit le type d'un point */ - get_bp_data_fc get_bp_data; /* Code d'un point d'arrêt */ - -} gdb_arch_ops; - - - -#endif /* _DEBUG_GDBRSP_AOPS_H */ diff --git a/src/debug/gdbrsp/gdb-int.h b/src/debug/gdbrsp/gdb-int.h deleted file mode 100644 index 11b4753..0000000 --- a/src/debug/gdbrsp/gdb-int.h +++ /dev/null @@ -1,116 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gdb.h - prototypes pour le débogage à l'aide de gdb. - * - * Copyright (C) 2009-2012 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _DEBUG_GDBRSP_GDB_INT_H -#define _DEBUG_GDBRSP_GDB_INT_H - - -#include "aops.h" -#include "gdb.h" -#include "stream.h" -#include "support.h" -#include "target.h" -#include "../break-int.h" -#include "../debugger-int.h" - - - - - - - - - - -/* Définition d'un point d'arrêt appliqué */ -typedef struct _gdb_breakpoint -{ - raw_breakpoint raw; /* A laisser en premier */ - - bool is_z; /* Usage de commande dédiée ? */ - - union - { - const char *kind; /* Précision de taille */ - - struct - { - uint8_t memory[16]; /* Données d'origine remplacées*/ - size_t len; /* Quantité de ces données */ - }; - - }; - -} gdb_breakpoint; - - - - - - - - - - - - - - -/* Débogueur utilisant un serveur GDB (instance) */ -struct _GGdbDebugger -{ - GBinaryDebugger parent; /* A laisser en premier */ - - SourceEndian endian; /* Boutisme du format */ - MemoryDataSize msize; /* Taille des adresses */ - - const gdb_arch_ops *ops; /* Opérations spécifiques */ - - GGdbStream *stream; /* Flux de communication */ - GGdbSupport *support; /* Configuration à adopter */ - GGdbTarget *target; /* Architecture ciblée par GDB */ - -}; - - -/* Débogueur utilisant un serveur GDB (classe) */ -struct _GGdbDebuggerClass -{ - GBinaryDebuggerClass parent; /* A laisser en premier */ - -}; - - - -/* ------------------------ ACCUEIL D'EVENEMENTS ASYNCHRONES ------------------------ */ - - -/* Réagit à la réception d'un signal par le programme étudié. */ -void g_gdb_debugger_receive_signal_reply(GGdbDebugger *, int); - -/* Réagit à la sortie d'exécution d'un programme étudié. */ -void g_gdb_debugger_receive_exit_reply(GGdbDebugger *, int, pid_t); - - - -#endif /* _DEBUG_GDBRSP_GDB_INT_H */ diff --git a/src/debug/gdbrsp/gdb.c b/src/debug/gdbrsp/gdb.c deleted file mode 100644 index 1d0ffe5..0000000 --- a/src/debug/gdbrsp/gdb.c +++ /dev/null @@ -1,1524 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gdb.c - débogage à l'aide de gdb. - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "gdb.h" - - - -#include -#include -#include -#include -#include - - -#include "gdb-int.h" -#include "helpers.h" -#include "helpers_arm.h" -#include "helpers_arm64.h" -#include "tcp.h" -#include "utils.h" -#include "../../common/cpp.h" -#include "../../format/format.h" - - - - - - - - -/* Initialise la classe du débogueur utilisant gdb. */ -static void g_gdb_debugger_class_init(GGdbDebuggerClass *); - -/* Procède à l'initialisation du débogueur utilisant gdb. */ -static void g_gdb_debugger_init(GGdbDebugger *); - -/* Supprime toutes les références externes. */ -static void g_gdb_debugger_dispose(GGdbDebugger *); - -/* Procède à la libération totale de la mémoire. */ -static void g_gdb_debugger_finalize(GGdbDebugger *); - - -/* Met en marche le débogueur utilisant un serveur GDB. */ -static bool g_gdb_debugger_run(GGdbDebugger *); - -/* Remet en marche le débogueur utilisant un serveur GDB. */ -//static bool g_gdb_debugger_resume(GGdbDebugger *); - -/* Tue le débogueur utilisant un serveur GDB. */ -static bool g_gdb_debugger_kill(GGdbDebugger *); - - - - - - -/* --------------------------- ENTREES / SORTIES BASIQUES --------------------------- */ - - -/* Lit une valeur quelconque à une adresse arbitraire. */ -static bool g_gdb_debugger_read_memory(GGdbDebugger *, virt_t, size_t, ...); - -/* Ecrit une valeur quelconque à une adresse arbitraire. */ -static bool g_gdb_debugger_write_memory(GGdbDebugger *, virt_t, size_t, ...); - -/* Liste l'ensemble des registres appartenant à un groupe. */ -static char **g_gdb_debugger_get_register_names(const GGdbDebugger *, const char *, size_t *); - -/* Indique la taille associée à un registre donné. */ -static unsigned int g_gdb_debugger_get_register_size(const GGdbDebugger *, const char *); - -/* Effectue la lecture d'un registre donné. */ -static bool g_gdb_debugger_read_register(GGdbDebugger *, const char *, size_t, ...); - -/* Effectue l'écriture d'un registre donné. */ -static bool g_gdb_debugger_write_register(GGdbDebugger *, const char *, size_t, ...); - - - -/* ------------------------- MANIPULATION DE L'ETAT COURANT ------------------------- */ - - -/* Détermine le point d'exécution courant. */ -static bool g_gdb_debugger_get_current_pc(GGdbDebugger *, virt_t *); - -/* Remonte la pile d'appels jusqu'au point courant. */ -static bool g_gdb_debugger_compute_call_stack(GGdbDebugger *, virt_t **, size_t *); - - - -/* --------------------------- GESTION DES POINTS D'ARRET --------------------------- */ - - -/* Ajoute un point d'arrêt basique en mémoire. */ -static gdb_breakpoint *g_gdb_debugger_enable_memory_breakpoint(GGdbDebugger *, virt_t); - -/* Retire un point d'arrêt basique en mémoire. */ -static bool g_gdb_debugger_disable_memory_breakpoint(GGdbDebugger *, gdb_breakpoint *); - - - -/* -------------------------- CONTROLE DU FLOT D'EXECUTION -------------------------- */ - - -/* Redémarre le processus de débogage lié à un serveur GDB. */ -static bool g_gdb_debugger_restart(GGdbDebugger *); - -/* Remet en marche le débogueur utilisant un serveur GDB. */ -static bool g_gdb_debugger_resume(GGdbDebugger *); - - - - - - - - - - - - -/* Détermine l'identifiant du thread principal courant. */ -static char *g_gdb_debugger_get_active_thread(GGdbDebugger *); - - - - - - -/* ------------------------ ACCUEIL D'EVENEMENTS ASYNCHRONES ------------------------ */ - - - - - - - - -/* Indique le type défini par la GLib pour le débogueur gdb. */ -G_DEFINE_TYPE(GGdbDebugger, g_gdb_debugger, G_TYPE_BINARY_DEBUGGER); - - -/****************************************************************************** -* * -* Paramètres : klass = classe de débogueur à initialiser. * -* * -* Description : Initialise la classe du débogueur utilisant gdb. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_debugger_class_init(GGdbDebuggerClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - GBinaryDebuggerClass *parent; /* Version en classe parente */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_gdb_debugger_dispose; - object->finalize = (GObjectFinalizeFunc)g_gdb_debugger_finalize; - - parent = G_BINARY_DEBUGGER_CLASS(klass); - - parent->read_mem = (read_mem_any_fc)g_gdb_debugger_read_memory; - parent->write_mem = (write_mem_any_fc)g_gdb_debugger_write_memory; - parent->get_reg_names = (get_reg_names_fc)g_gdb_debugger_get_register_names; - parent->get_reg_size = (get_reg_size_fc)g_gdb_debugger_get_register_size; - parent->read_reg = (read_write_reg_any_fc)g_gdb_debugger_read_register; - parent->write_reg = (read_write_reg_any_fc)g_gdb_debugger_write_register; - - parent->get_current_pc = (get_current_pc_fc)g_gdb_debugger_get_current_pc; - parent->get_call_stack = (get_call_stack_fc)g_gdb_debugger_compute_call_stack; - - parent->enable_bp = (enable_mem_bp_fc)g_gdb_debugger_enable_memory_breakpoint; - parent->disable_bp = (disable_mem_bp_fc)g_gdb_debugger_disable_memory_breakpoint; - - parent->restart = (restart_debugger_fc)g_gdb_debugger_restart; - parent->resume = (resume_debugger_fc)g_gdb_debugger_resume; - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = instance de débogueur à préparer. * -* * -* Description : Procède à l'initialisation du débogueur utilisant gdb. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_debugger_init(GGdbDebugger *debugger) -{ - GBinaryDebugger *parent; /* Instance parente */ - - parent = G_BINARY_DEBUGGER(debugger); - - parent->run = (basic_debugger_fc)g_gdb_debugger_run; - //parent->resume = (resume_debugger_fc)g_gdb_debugger_resume; - parent->kill = (basic_debugger_fc)g_gdb_debugger_kill; - - //parent->get_reg_values = (get_register_values_fc)get_register_values_using_gdb_debugger; - - //debugger->cond = g_cond_new(); - //debugger->mutex = g_mutex_new(); - - - // FIXME - //debugger->compute_cstack = compute_call_stack_for_arm64; - //debugger->fill_mem_bp = fill_memory_breakpoint_cmd_for_arm64; - - - - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_debugger_dispose(GGdbDebugger *debugger) -{ - if (debugger->stream != NULL) - g_object_unref(G_OBJECT(debugger->stream)); - - if (debugger->support != NULL) - g_object_unref(G_OBJECT(debugger->support)); - - if (debugger->target != NULL) - g_object_unref(G_OBJECT(debugger->target)); - - G_OBJECT_CLASS(g_gdb_debugger_parent_class)->dispose(G_OBJECT(debugger)); - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_debugger_finalize(GGdbDebugger *debugger) -{ - G_OBJECT_CLASS(g_gdb_debugger_parent_class)->finalize(G_OBJECT(debugger)); - -} - - -/****************************************************************************** -* * -* Paramètres : binary = binaire représenter à déboguer. * -* server = nom ou adresse du serveur à contacter. * -* port = port de connexion. * -* * -* Description : Crée un débogueur utilisant un serveur GDB distant. * -* * -* Retour : Instance de débogueur mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GBinaryDebugger *g_gdb_debugger_new(GLoadedBinary *binary, const char *server, unsigned short port) -{ - GGdbDebugger *result; /* Débogueur à retourner */ - GExeFormat *format; /* Format du binaire chargé */ - const char *arch; /* Architecture d'exécution */ - GArchProcessor *proc; /* Processeur lié au binaire */ - char service[sizeof(XSTR(UINT16_MAX)) + 1]; /* Conversion requise */ - - result = g_object_new(G_TYPE_GDB_DEBUGGER, NULL); - - G_BINARY_DEBUGGER(result)->binary = binary; - g_object_ref(G_OBJECT(binary)); - - /* Propriétés de la cible */ - - format = g_loaded_binary_get_format(binary); - - result->endian = g_binary_format_get_endianness(G_BIN_FORMAT(format)); - - arch = g_exe_format_get_target_machine(format); - - if (strcmp(arch, "armv7") == 0) - result->ops = get_arm_operations(); - else - result->ops = NULL; - - g_object_unref(G_OBJECT(format)); - - if (result->ops == NULL) - goto ggdn_error; - - proc = g_loaded_binary_get_processor(binary); - - result->msize = g_arch_processor_get_memory_size(proc); - - g_object_unref(G_OBJECT(proc)); - - /* Mise en place des modules auxialiaires */ - - snprintf(service, sizeof(service), "%hu", port); - - result->stream = g_gdb_tcp_client_new(server, service, result); - if (result->stream == NULL) goto ggdn_error; - - result->support = g_gdb_support_new(result->stream); - - result->target = g_gdb_target_new(result->stream); - if (result->target == NULL) goto ggdn_error; - - return G_BINARY_DEBUGGER(result); - - ggdn_error: - - g_object_unref(G_OBJECT(result)); - - return NULL; - -} - - - - - - - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à lancer. * -* * -* Description : Met en marche le débogueur utilisant un serveur GDB. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_debugger_run(GGdbDebugger *debugger) -{ - - - - GGdbPacket *packet; - - bool test; - - const char *data; - size_t len; - - - int sig; - vmpa_t addr; - pid_t thread; - - - debugger->stream = g_gdb_tcp_client_new("127.0.0.1", "6666", NULL); - if (debugger->stream == NULL) return false; - - - printf("Connection done !\n"); - - - - packet = g_gdb_stream_get_free_packet(debugger->stream); - - g_gdb_packet_start_new_command(packet); - g_gdb_packet_append(packet, "?"); - - - test = g_gdb_stream_send_packet(debugger->stream, packet); - - - - printf(" >> Paquet '%s' bien envoyé ? %s\n", "?", test ? "oui" : "non"); - - - - g_gdb_stream_mark_packet_as_free(debugger->stream, packet); - - packet = g_gdb_stream_recv_packet(debugger->stream); - - g_gdb_packet_get_data(packet, &data, &len, NULL); - - printf(" << Réception de '%s'\n", data); - - - - - - get_stop_reply_sig_info(packet, &sig, &addr, &thread, SRE_LITTLE); - - g_signal_emit_by_name(debugger, "halted", sig, addr, thread); - - - - return true; - -} - - - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à relancer. * -* * -* Description : Tue le débogueur utilisant un serveur GDB. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_debugger_kill(GGdbDebugger *debugger) -{ - - -#if 0 - int ret; /* Bilan de l'appel système */ - - ret = kill(debugger->child, SIGKILL); - if (ret != 0) perror("kill"); - - debugger->child = 0; - - g_mutex_lock(debugger->mutex); - debugger->run_again = TRUE; - g_cond_signal(debugger->cond); - g_mutex_unlock(debugger->mutex); -#endif - return true; - -} - - - - - - - - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à consulter. * -* * -* Description : Détermine l'identifiant du thread principal courant. * -* * -* Retour : Identifiant du thread actif principal ou NULL en cas d'échec.* -* * -* Remarques : - * -* * -******************************************************************************/ - -static char *g_gdb_debugger_get_active_thread(GGdbDebugger *debugger) -{ - char *result; /* Identifiant à renvoyer */ - GGdbPacket *packet; /* Paquet de communication */ - bool status; /* Bilan d'une communication */ - const char *data; /* Données reçues à analyser */ - const char *start; /* Début d'identification */ - const char *end; /* Fin d'identification */ - - result = NULL; - - /* Envoi de la requête */ - - packet = g_gdb_stream_get_free_packet(debugger->stream); - - g_gdb_packet_start_new_command(packet); - g_gdb_packet_append(packet, "?"); - - status = g_gdb_stream_send_packet(debugger->stream, packet); - - if (!status) - goto ggdgat_exit; - - /* Réception de la réponse */ - - packet = g_gdb_stream_recv_packet(debugger->stream); - - g_gdb_packet_get_data(packet, &data, NULL, NULL); - - start = strstr(data, "thread:"); - if (start == NULL) goto ggdgat_exit; - - start += sizeof("thread:") - 1 /* '\0' */; - - end = strstr(start, ";"); - if (end == NULL) goto ggdgat_exit; - - result = strndup(start, end - start); - - ggdgat_exit: - - g_gdb_stream_mark_packet_as_free(debugger->stream, packet); - - return result; - -} - - - - - - - - - - - - - - - - - - - - -/* ---------------------------------------------------------------------------------- */ -/* ENTREES / SORTIES BASIQUES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à consulter. * -* addr = emplacement en mémoire à venir consulter. * -* size = taille des données mises en jeu. * -* ... = emplacement de la valeur lue à conserver. [OUT] * -* * -* Description : Lit une valeur quelconque à une adresse arbitraire. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_debugger_read_memory(GGdbDebugger *debugger, virt_t addr, size_t size, ...) -{ - bool result; /* Bilan d'opération à renvoyer*/ - char cmd[1 + VMPA_MAX_LEN + 3]; /* Commande à émettre */ - GGdbPacket *packet; /* Paquet de communication */ - const char *data; /* Données reçues à analyser */ - size_t len; /* Quantité de données reçues */ - va_list ap; /* Liste variable d'arguments */ - uint8_t *val8; /* Valeur sur 8 bits */ - uint16_t *val16; /* Valeur sur 16 bits */ - uint16_t conv16; /* Valeur adaptée sur 16 bits */ - uint32_t *val32; /* Valeur sur 32 bits */ - uint32_t conv32; /* Valeur adaptée sur 32 bits */ - uint64_t *val64; /* Valeur sur 64 bits */ - uint64_t conv64; /* Valeur adaptée sur 64 bits */ - - /* Envoi de la requête */ - - cmd[0] = 'm'; - - result = translate_virt_to_hex(debugger, addr, &cmd[1]); - - switch (size) - { - case 8: - strcat(cmd, ",1"); - break; - - case 16: - strcat(cmd, ",2"); - break; - - case 32: - strcat(cmd, ",4"); - break; - - case 64: - strcat(cmd, ",8"); - break; - - default: - assert(false); - result = false; - goto ggdrm_exit; - break; - - } - - packet = g_gdb_stream_get_free_packet(debugger->stream); - - g_gdb_packet_start_new_command(packet); - g_gdb_packet_append(packet, cmd); - - result = g_gdb_stream_send_packet(debugger->stream, packet); - - g_gdb_stream_mark_packet_as_free(debugger->stream, packet); - - if (!result) - goto ggdrm_exit; - - /* Réception de la réponse */ - - packet = g_gdb_stream_recv_packet(debugger->stream); - - g_gdb_packet_get_data(packet, &data, &len, NULL); - - if (is_error_code(data, len)) - { - result = false; - goto ggdrm_error; - } - - va_start(ap, size); - - switch (size) - { - case 8: - val8 = va_arg(ap, uint8_t *); - result = hex_to_u8(data, val8); - break; - - case 16: - val16 = va_arg(ap, uint16_t *); - result = hex_to_u16(data, &conv16); - *val16 = from_u16(&conv16, debugger->endian); - break; - - case 32: - val32 = va_arg(ap, uint32_t *); - result = hex_to_u32(data, &conv32); - *val32 = from_u32(&conv32, debugger->endian); - break; - - case 64: - val64 = va_arg(ap, uint64_t *); - result = hex_to_u64(data, &conv64); - *val64 = from_u64(&conv64, debugger->endian); - break; - - default: - assert(false); - result = false; - break; - - } - - va_end(ap); - - ggdrm_error: - - g_gdb_stream_mark_packet_as_free(debugger->stream, packet); - - ggdrm_exit: - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à manipuler. * -* addr = emplacement en mémoire à venir consulter. * -* size = taille des données mises en jeu. * -* ... = emplacement de la valeur lue à conserver. [OUT] * -* * -* Description : Lit une valeur quelconque à une adresse arbitraire. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_debugger_write_memory(GGdbDebugger *debugger, virt_t addr, size_t size, ...) -{ - bool result; /* Bilan d'opération à renvoyer*/ - char cmd[1 + 3 * VMPA_MAX_LEN + 3]; /* Commande à émettre */ - va_list ap; /* Liste variable d'arguments */ - const uint8_t *val8; /* Valeur sur 8 bits */ - const uint16_t *val16; /* Valeur sur 16 bits */ - uint16_t conv16; /* Valeur adaptée sur 16 bits */ - const uint32_t *val32; /* Valeur sur 32 bits */ - uint32_t conv32; /* Valeur adaptée sur 32 bits */ - const uint64_t *val64; /* Valeur sur 64 bits */ - uint64_t conv64; /* Valeur adaptée sur 64 bits */ - char hexval[17]; /* Valeur sous forme hexa */ - GGdbPacket *packet; /* Paquet de communication */ - const char *data; /* Données reçues à analyser */ - size_t len; /* Quantité de données reçues */ - - /* Envoi de la requête */ - - cmd[0] = 'M'; - - result = translate_virt_to_hex(debugger, addr, &cmd[1]); - - va_start(ap, size); - - switch (size) - { - case 8: - val8 = va_arg(ap, uint8_t *); - result = u8_to_hex(val8, hexval); - - strcat(cmd, ",1:"); - strcat(cmd, hexval); - break; - - case 16: - val16 = va_arg(ap, uint16_t *); - conv16 = to_u16(val16, debugger->endian); - result = u16_to_hex(&conv16, hexval); - - strcat(cmd, ",2:"); - strcat(cmd, hexval); - break; - - case 32: - val32 = va_arg(ap, uint32_t *); - conv32 = to_u32(val32, debugger->endian); - result = u32_to_hex(&conv32, hexval); - - strcat(cmd, ",4:"); - strcat(cmd, hexval); - break; - - case 64: - val64 = va_arg(ap, uint64_t *); - conv64 = to_u64(val64, debugger->endian); - result = u16_to_hex(&conv64, hexval); - - strcat(cmd, ",8:"); - strcat(cmd, hexval); - break; - - default: - assert(false); - result = false; - break; - - } - - if (!result) - goto ggdwm_exit; - - packet = g_gdb_stream_get_free_packet(debugger->stream); - - g_gdb_packet_start_new_command(packet); - g_gdb_packet_append(packet, cmd); - - result = g_gdb_stream_send_packet(debugger->stream, packet); - - g_gdb_stream_mark_packet_as_free(debugger->stream, packet); - - if (!result) - goto ggdwm_exit; - - /* Réception de la réponse */ - - packet = g_gdb_stream_recv_packet(debugger->stream); - - g_gdb_packet_get_data(packet, &data, &len, NULL); - - if (len == 3 && data[0] == 'E') - { - result = false; - goto ggdrm_error; - } - - ggdrm_error: - - g_gdb_stream_mark_packet_as_free(debugger->stream, packet); - - ggdwm_exit: - - va_end(ap); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à consulter. * -* group = éventuel groupe de registres ciblé ou NULL. * -* count = nombre d'éléments dans la liste de noms. [OUT] * -* * -* Description : Liste l'ensemble des registres appartenant à un groupe. * -* * -* Retour : Liste de noms à libérer de la mémoire après utilisation. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static char **g_gdb_debugger_get_register_names(const GGdbDebugger *debugger, const char *group, size_t *count) -{ - return g_gdb_target_get_register_names(debugger->target, group, count); - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à consulter. * -* name = désignation du registre visé. * -* * -* Description : Indique la taille associée à un registre donné. * -* * -* Retour : Taille en bits, ou 0 si le registre n'a pas été trouvé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static unsigned int g_gdb_debugger_get_register_size(const GGdbDebugger *debugger, const char *name) -{ - return g_gdb_target_get_register_size(debugger->target, name); - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à consulter. * -* reg = désignation humaine du register à consulter. * -* size = taille des données mises en jeu. * -* ... = emplacement de la valeur lue à conserver. [OUT] * -* * -* Description : Effectue la lecture d'un registre donné. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_debugger_read_register(GGdbDebugger *debugger, const char *reg, size_t size, ...) -{ - bool result; /* Bilan d'opération à renvoyer*/ - va_list ap; /* Liste variable d'arguments */ - uint8_t *val8; /* Valeur sur 8 bits */ - uint16_t *val16; /* Valeur sur 16 bits */ - uint32_t *val32; /* Valeur sur 32 bits */ - uint64_t *val64; /* Valeur sur 64 bits */ - - va_start(ap, size); - - switch (size) - { - case 8: - val8 = va_arg(ap, uint8_t *); - result = g_gdb_target_read_register(debugger->target, debugger->stream, debugger->endian, - reg, 8, val8); - break; - - case 16: - val16 = va_arg(ap, uint16_t *); - result = g_gdb_target_read_register(debugger->target, debugger->stream, debugger->endian, - reg, 16, val16); - break; - - case 32: - val32 = va_arg(ap, uint32_t *); - result = g_gdb_target_read_register(debugger->target, debugger->stream, debugger->endian, - reg, 32, val32); - break; - - case 64: - val64 = va_arg(ap, uint64_t *); - result = g_gdb_target_read_register(debugger->target, debugger->stream, debugger->endian, - reg, 64, val64); - break; - - default: - assert(false); - result = false; - break; - - } - - va_end(ap); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à manipuler. * -* reg = désignation humaine du register à consulter. * -* size = taille des données mises en jeu. * -* ... = emplacement de la valeur à écrire. * -* * -* Description : Effectue l'écriture d'un registre donné. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_debugger_write_register(GGdbDebugger *debugger, const char *reg, size_t size, ...) -{ - bool result; /* Bilan d'opération à renvoyer*/ - va_list ap; /* Liste variable d'arguments */ - const uint8_t *val8; /* Valeur sur 8 bits */ - const uint16_t *val16; /* Valeur sur 16 bits */ - const uint32_t *val32; /* Valeur sur 32 bits */ - const uint64_t *val64; /* Valeur sur 64 bits */ - - va_start(ap, size); - - switch (size) - { - case 8: - val8 = va_arg(ap, const uint8_t *); - result = g_gdb_target_write_register(debugger->target, debugger->stream, debugger->endian, - reg, 8, val8); - break; - - case 16: - val16 = va_arg(ap, const uint16_t *); - result = g_gdb_target_write_register(debugger->target, debugger->stream, debugger->endian, - reg, 16, val16); - break; - - case 32: - val32 = va_arg(ap, const uint32_t *); - result = g_gdb_target_write_register(debugger->target, debugger->stream, debugger->endian, - reg, 32, val32); - break; - - case 64: - val64 = va_arg(ap, const uint64_t *); - result = g_gdb_target_write_register(debugger->target, debugger->stream, debugger->endian, - reg, 64, val64); - break; - - default: - assert(false); - result = false; - break; - - } - - va_end(ap); - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* MANIPULATION DE L'ETAT COURANT */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à consulter. * -* pc = adresse de l'instruction courante. [OUT] * -* * -* Description : Détermine le point d'exécution courant. * -* * -* Retour : Bilan de la récupération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_debugger_get_current_pc(GGdbDebugger *debugger, virt_t *pc) -{ - bool result; /* Bilan à retourner */ - - result = debugger->ops->get_pc(debugger, pc); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à consulter. * -* callstack = pile d'appels reconstituée. [OUT] * -* size = taille de cette pile. [OUT] * -* * -* Description : Remonte la pile d'appels jusqu'au point courant. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_debugger_compute_call_stack(GGdbDebugger *debugger, virt_t **callstack, size_t *size) -{ - bool result; /* Bilan global à retourner */ - - if (debugger->ops->compute_cstack != NULL) - result = debugger->ops->compute_cstack(debugger, callstack, size); - - else - result = false; - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* GESTION DES POINTS D'ARRET */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à manipuler ici. * -* addr = emplacement du point mémoire à traiter. * -* * -* Description : Ajoute un point d'arrêt basique en mémoire. * -* * -* Retour : Structure de suivi mise en place pour l'occasion, voire NULL.* -* * -* Remarques : - * -* * -******************************************************************************/ - -static gdb_breakpoint *g_gdb_debugger_enable_memory_breakpoint(GGdbDebugger *debugger, virt_t addr) -{ - gdb_breakpoint *result; /* Nouveau suivi à retourner */ - char cmd[3 + VMPA_MAX_LEN + 3]; /* Commande à émettre */ - bool status; /* Bilan d'une opération */ - const char *kind; /* Taille spécifique du point */ - GGdbPacket *packet; /* Paquet de communication */ - const char *data; /* Données reçues à analyser */ - size_t len; /* Quantité de données reçues */ - GBinaryDebugger *dbg; /* Autre version du débogueur */ - const uint8_t *bp; /* Données du point d'arrêt */ - size_t bp_len; /* Quantité de ces données */ - uint8_t memory[16]; /* Sauvegarde de la mémoire */ - - result = NULL; - - /* Si l'utilisation de la commande dédiée est possible */ - if (1) //////// TODO - { - /* Envoi de la requête */ - - strcpy(cmd, "Z0,"); - - status = translate_virt_to_hex(debugger, addr, &cmd[3]); - - if (!status) - goto ggdemb_exit; - - kind = debugger->ops->get_bp_kind(debugger, addr); - - if (kind == NULL) - goto ggdemb_exit; - - strcat(cmd, kind); - - packet = g_gdb_stream_get_free_packet(debugger->stream); - - g_gdb_packet_start_new_command(packet); - g_gdb_packet_append(packet, cmd); - - status = g_gdb_stream_send_packet(debugger->stream, packet); - - g_gdb_stream_mark_packet_as_free(debugger->stream, packet); - - if (!status) - goto ggdemb_exit; - - /* Réception de la réponse */ - - packet = g_gdb_stream_recv_packet(debugger->stream); - - g_gdb_packet_get_data(packet, &data, &len, NULL); - - if (is_error_code(data, len)) - { - g_gdb_stream_mark_packet_as_free(debugger->stream, packet); - goto ggdemb_fallback; - } - - if (strcmp(data, "OK") != 0) - { - g_gdb_stream_mark_packet_as_free(debugger->stream, packet); - goto ggdemb_fallback; - } - - g_gdb_stream_mark_packet_as_free(debugger->stream, packet); - - /* Constitution d'un dossier de suivi */ - - result = (gdb_breakpoint *)malloc(sizeof(gdb_breakpoint)); - - result->is_z = true; - - result->kind = kind; - - } - - else - { - - ggdemb_fallback: - - dbg = G_BINARY_DEBUGGER(debugger); - - /* Détermination du point d'arrêt */ - - bp = debugger->ops->get_bp_data(debugger, addr, &bp_len); - - assert(bp_len <= 16); - - /* Sauvegarde de la mémoire courante */ - - status = g_binary_debugger_read_memory_data(dbg, addr, memory, bp_len); - - if (!status) goto ggdemb_exit; - - /* Application du point d'arrêt */ - - status = g_binary_debugger_write_memory_data(dbg, addr, bp, bp_len); - - if (!status) goto ggdemb_exit; - - /* Constitution d'un dossier de suivi */ - - result = (gdb_breakpoint *)malloc(sizeof(gdb_breakpoint)); - - result->is_z = false; - - memcpy(result->memory, memory, bp_len); - result->len = bp_len; - - } - - init_raw_breakpoint((raw_breakpoint *)result, addr); - - ggdemb_exit: - - return result; -} - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à manipuler ici. * -* bp = point d'arrêt à traiter. * -* * -* Description : Retire un point d'arrêt basique de la mémoire ciblée. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_debugger_disable_memory_breakpoint(GGdbDebugger *debugger, gdb_breakpoint *bp) -{ - bool result; /* Bilan à retourner */ - char cmd[3 + VMPA_MAX_LEN + 3]; /* Commande à émettre */ - bool status; /* Bilan d'une opération */ - GGdbPacket *packet; /* Paquet de communication */ - const char *data; /* Données reçues à analyser */ - size_t len; /* Quantité de données reçues */ - GBinaryDebugger *dbg; /* Autre version du débogueur */ - - result = false; - - /* Si l'utilisation de la commande dédiée est requise */ - if (bp->is_z) - { - /* Envoi de la requête */ - - strcpy(cmd, "z0,"); - - status = translate_virt_to_hex(debugger, bp->raw.addr, &cmd[3]); - - if (!status) - goto ggddmb_exit; - - strcat(cmd, bp->kind); - - packet = g_gdb_stream_get_free_packet(debugger->stream); - - g_gdb_packet_start_new_command(packet); - g_gdb_packet_append(packet, cmd); - - status = g_gdb_stream_send_packet(debugger->stream, packet); - - g_gdb_stream_mark_packet_as_free(debugger->stream, packet); - - if (!status) - goto ggddmb_exit; - - /* Réception de la réponse */ - - packet = g_gdb_stream_recv_packet(debugger->stream); - - g_gdb_packet_get_data(packet, &data, &len, NULL); - - if (is_error_code(data, len)) - { - g_gdb_stream_mark_packet_as_free(debugger->stream, packet); - goto ggddmb_exit; - } - - if (strcmp(data, "OK") != 0) - { - g_gdb_stream_mark_packet_as_free(debugger->stream, packet); - goto ggddmb_exit; - } - - g_gdb_stream_mark_packet_as_free(debugger->stream, packet); - - result = true; - - } - - else - { - dbg = G_BINARY_DEBUGGER(debugger); - - result = g_binary_debugger_write_memory_data(dbg, bp->raw.addr, bp->memory, bp->len); - - } - - ggddmb_exit: - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* CONTROLE DU FLOT D'EXECUTION */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à redémarrer. * -* * -* Description : Redémarre le processus de débogage lié à un serveur GDB. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_debugger_restart(GGdbDebugger *debugger) -{ - bool result; /* Bilan à retourner */ - GGdbPacket *packet; /* Paquet de communication */ - return true; - /* Envoi de la requête */ - - packet = g_gdb_stream_get_free_packet(debugger->stream); - - g_gdb_packet_start_new_command(packet); - g_gdb_packet_append(packet, "R00"); - - result = g_gdb_stream_send_packet(debugger->stream, packet); - - g_gdb_stream_mark_packet_as_free(debugger->stream, packet); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à relancer. * -* * -* Description : Remet en marche le débogueur utilisant un serveur GDB. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_debugger_resume(GGdbDebugger *debugger) -{ - bool result; /* Bilan à retourner */ - //char *id; /* Identifiant de thread */ - GGdbPacket *packet; /* Paquet de communication */ - //const char *data; /* Données reçues à analyser */ - - static bool _twice = false; - - - if (!_twice && 0) - { - - packet = g_gdb_stream_get_free_packet(debugger->stream); - - g_gdb_packet_start_new_command(packet); - g_gdb_packet_append(packet, "$QPassSignals:e;10;14;17;1a;1b;1c;21;24;25;2c;4c;"); - - result = g_gdb_stream_send_packet(debugger->stream, packet); - - g_gdb_stream_mark_packet_as_free(debugger->stream, packet); - - if (!result) - goto ggdhmb_exit; - - } - - - - - - - /* Envoi de la requête */ - - /* - id = g_gdb_debugger_get_active_thread(debugger); - if (id == NULL) return false; - - printf("ID : %s\n", id); - */ - - /* - id = g_gdb_support_get_id(debugger->support); - if (id == NULL) return false; - - printf("ID : %s\n", id); - */ - - packet = g_gdb_stream_get_free_packet(debugger->stream); - - g_gdb_packet_start_new_command(packet); - g_gdb_packet_append(packet, "vCont;c:-1"); - //g_gdb_packet_append(packet, "vCont;c:p256f.-1"); - - - /* - if (_twice) - { - g_gdb_packet_start_new_command(packet); - g_gdb_packet_append(packet, "vCont;c:p"); - g_gdb_packet_append(packet, id); - g_gdb_packet_append(packet, "."); - g_gdb_packet_append(packet, id); - } - else - { - _twice = true; - g_gdb_packet_start_new_command(packet); - g_gdb_packet_append(packet, "vCont;c:p"); - g_gdb_packet_append(packet, id); - g_gdb_packet_append(packet, ".-1"); - } - */ - - - - - - result = g_gdb_stream_send_packet(debugger->stream, packet); - - g_gdb_stream_mark_packet_as_free(debugger->stream, packet); - - if (!result) - goto ggdhmb_exit; - - /* Réception de la réponse */ - /* - packet = g_gdb_stream_recv_packet(debugger->stream); - - g_gdb_packet_get_data(packet, &data, NULL, NULL); - - printf("Ack cont...\n"); - - //result = (strcmp(data, "OK") == 0); - - g_gdb_stream_mark_packet_as_free(debugger->stream, packet); - */ - ggdhmb_exit: - - _twice = true; - - return result; - -} - - - - - - - - - - - - - - -/* ---------------------------------------------------------------------------------- */ -/* ACCUEIL D'EVENEMENTS ASYNCHRONES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : debugger = instance liée à un débogueur GDB à manipuler. * -* signum = indentifiant du signal concerné. * -* * -* Description : Réagit à la réception d'un signal par le programme étudié. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_gdb_debugger_receive_signal_reply(GGdbDebugger *debugger, int signum) -{ - virt_t pc; /* Position courante du CPU */ - bool status; /* Bilan d'une opération */ - GBinaryDebugger *base; /* Version basique du débogueur*/ - - base = G_BINARY_DEBUGGER(debugger); - - status = g_binary_debugger_get_current_pc(base, &pc); - - if (!status) - pc = VMPA_NO_VIRTUAL; - - on_binary_debugger_stopped(base, pc); - - g_signal_emit_by_name(debugger, "signaled", signum); - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = instance liée à un débogueur GDB à manipuler. * -* status = indication d'état à la sortie. * -* pid = éventuel identifiant de processus concerné ou -1. * -* * -* Description : Réagit à la sortie d'exécution d'un programme étudié. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_gdb_debugger_receive_exit_reply(GGdbDebugger *debugger, int status, pid_t pid) -{ - GBinaryDebugger *base; /* Version basique du débogueur*/ - - base = G_BINARY_DEBUGGER(debugger); - - on_binary_debugger_finished(base, pid); - - g_signal_emit_by_name(debugger, "exited", status, pid); - -} diff --git a/src/debug/gdbrsp/gdb.h b/src/debug/gdbrsp/gdb.h deleted file mode 100644 index a338f98..0000000 --- a/src/debug/gdbrsp/gdb.h +++ /dev/null @@ -1,61 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gdb.h - prototypes pour le débogage à l'aide de gdb. - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _DEBUG_GDBRSP_GDB_H -#define _DEBUG_GDBRSP_GDB_H - - -#include - - -#include "../debugger.h" - - - -#define G_TYPE_GDB_DEBUGGER (g_gdb_debugger_get_type()) -#define G_GDB_DEBUGGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_GDB_DEBUGGER, GGdbDebugger)) -#define G_IS_GDB_DEBUGGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_GDB_DEBUGGER)) -#define G_GDB_DEBUGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_DEBUGGER, GGdbDebuggerClass)) -#define G_IS_GDB_DEBUGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_DEBUGGER)) -#define G_GDB_DEBUGGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_DEBUGGER, GGdbDebuggerClass)) - - -/* Débogueur utilisant un serveur GDB (instance) */ -typedef struct _GGdbDebugger GGdbDebugger; - -/* Débogueur utilisant un serveur GDB (classe) */ -typedef struct _GGdbDebuggerClass GGdbDebuggerClass; - - -/* Indique le type défini par la GLib pour le débogueur gdb. */ -GType g_gdb_debugger_get_type(void); - -/* Crée un débogueur utilisant un serveur GDB distant. */ -GBinaryDebugger *g_gdb_debugger_new(GLoadedBinary *, const char *, unsigned short); - - -void test_gdb(void); - - - -#endif /* _DEBUG_GDBRSP_GDB_H */ diff --git a/src/debug/gdbrsp/helpers.c b/src/debug/gdbrsp/helpers.c deleted file mode 100644 index 1bdf6f7..0000000 --- a/src/debug/gdbrsp/helpers.c +++ /dev/null @@ -1,224 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * helpers.c - assistanat dans la manipulation des paquets GDB - * - * Copyright (C) 2010-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "helpers.h" - - -#include -#include - - -#include "gdb-int.h" -#include "utils.h" - - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à consulter. * -* addr = emplacement en mémoire à venir consulter. * -* out = zone d'impression en hexadécimal. [OUT] * -* * -* Description : Traduit une adresse en chaîne hexadécimale pour GDB. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool translate_virt_to_hex(const GGdbDebugger *debugger, virt_t addr, char *out) -{ - bool result; /* Bilan d'opération à renvoyer*/ - uint8_t conv8; /* Valeur adaptée sur 8 bits */ - uint16_t conv16; /* Valeur adaptée sur 16 bits */ - uint32_t conv32; /* Valeur adaptée sur 32 bits */ - uint64_t conv64; /* Valeur adaptée sur 64 bits */ - char hexval[17]; /* Valeur sous forme hexa */ - bool got_msn; /* Obtention d'un quartet ? */ - size_t i; /* Boucle de parcours */ - - /* Conversion */ - - switch (debugger->msize) - { - case MDS_8_BITS: - conv8 = addr; - result = u8_to_hex(&conv8, hexval); - break; - - case MDS_16_BITS: - conv16 = addr; - conv16 = to_u16(&conv16, SRE_BIG); - result = u16_to_hex(&conv16, hexval); - break; - - case MDS_32_BITS: - conv32 = addr; - conv32 = to_u32(&conv32, SRE_BIG); - result = u32_to_hex(&conv32, hexval); - break; - - case MDS_64_BITS: - conv64 = addr; - conv64 = to_u64(&conv64, SRE_BIG); - result = u64_to_hex(&conv64, hexval); - break; - - default: - result = false; - break; - - } - - /* On saute les zéros préliminaires... */ - - if (result) - { - got_msn = false; - - for (i = 0; i < 17; i++) - { - if (!got_msn) - { - if (hexval[i] == '0') - continue; - else - got_msn = true; - } - - *out = hexval[i]; - out++; - - } - - *out = '\0'; - - } - - return result; - -} - - - - - - - - -/* -------------------------- PAQUETS DES REPONSES D'ARRET -------------------------- */ - - - - - - -/****************************************************************************** -* * -* Paramètres : packet = paquet de deonnées à interpréter. * -* sig = identifiant du signal source. [OUT] * -* addr = adresse de l'instruction courante. [OUT] * -* thread = identifiant du thread concerné. [OUT] * -* endian = boutisme de la plateforme ciblée. * -* * -* Description : Récupère les informations liées à un arrêt suite à signal. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : Les données sont la forme : * -* T0505:00000000;04:a08de6bf;08:505878b7;thread:50dc; * -* * -******************************************************************************/ - -bool get_stop_reply_sig_info(const GGdbPacket *packet, int *sig, vmpa_t *addr, pid_t *thread, SourceEndian endian) -{ - const char *data; /* Données brutes du paquet */ - size_t length; /* Quantité de ces données */ - uint8_t index; /* Indice de 8 bits quelconque */ - size_t pos; /* Tête de lecture courante */ - regex_t preg; /* Expression régulière */ - int ret; /* Bilan d'un appel */ - regmatch_t pmatch[3]; /* Zones remarquées */ - size_t key_len; /* Taille de l'indicatif */ - - *addr = 0ull; - - g_gdb_packet_get_data(packet, &data, &length, NULL); - - pos = 1; - - /* Lecture du numéro du signal */ - - if (!strtou8(&index, data, &pos, length, SRE_LITTLE)) - return false; - - *sig = index; - - /* Reste des informations */ - - ret = regcomp(&preg, "([^:]+):([^;]+);", REG_EXTENDED | REG_ICASE); - if (ret != 0) return false; - - for (ret = regexec(&preg, &data[pos], 3, pmatch, 0); - ret != REG_NOMATCH; - ret = regexec(&preg, &data[pos], 3, pmatch, 0)) - { - key_len = pmatch[1].rm_eo - pmatch[1].rm_so; - - /* Indication sur le thread */ - if (key_len == strlen("thread") - && strncmp(&data[pos + pmatch[1].rm_so], "thread", key_len) == 0) - { - - /* TODO printf("Thread found !\n"); */ - - } - - /* Valeur de registre ? */ - else if (key_len == 2) - { - if (!strtou8(&index, data, (size_t []) { pos + pmatch[1].rm_so }, length, SRE_LITTLE)) - return false; - - if (index != 8 /* FIXME */) - goto next_field; - - if (!strtou32(addr, data, (size_t []) { pos + pmatch[2].rm_so }, length, SRE_LITTLE/* FIXME */)) - return false; - - } - - next_field: - pos += pmatch[0].rm_eo; - - } - - regfree(&preg); - - return (*addr != 0ull); - -} - - - diff --git a/src/debug/gdbrsp/helpers.h b/src/debug/gdbrsp/helpers.h deleted file mode 100644 index 0492ea3..0000000 --- a/src/debug/gdbrsp/helpers.h +++ /dev/null @@ -1,62 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * helpers.h - prototypes pour un assistanat dans la manipulation des paquets GDB - * - * Copyright (C) 2010-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _DEBUG_GDBRSP_HELPERS_H -#define _DEBUG_GDBRSP_HELPERS_H - - -#include "gdb.h" -#include "packet.h" - - - -/* Traduit une adresse en chaîne hexadécimale pour GDB. */ -bool translate_virt_to_hex(const GGdbDebugger *, virt_t, char *); - - - - - - -/* -------------------------- PAQUETS DES REPONSES D'ARRET -------------------------- */ - - -/* Récupère les informations liées à un arrêt suite à signal. */ -bool get_stop_reply_sig_info(const GGdbPacket *, int *, vmpa_t *, pid_t *, SourceEndian); - - - -/* ---------------------------------------------------------------------------------- */ -/* PAQUETS DES REPONSES D'ARRET */ -/* ---------------------------------------------------------------------------------- */ - - - - - - - - - - -#endif /* _DEBUG_GDBRSP_HELPERS_H */ diff --git a/src/debug/gdbrsp/helpers_arm.c b/src/debug/gdbrsp/helpers_arm.c deleted file mode 100644 index 4b486d4..0000000 --- a/src/debug/gdbrsp/helpers_arm.c +++ /dev/null @@ -1,252 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * helpers_arm.c - compléments utiles à GDB pour l'architecture ARM - * - * Copyright (C) 2016 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "helpers_arm.h" - - -#include -#include - - -#include "gdb-int.h" - - - -/* Détermine le point d'exécution courant. */ -static bool get_arm_pc(GGdbDebugger *, virt_t *); - -/* Remonte la pile d'appels jusqu'au point courant. */ -static bool compute_call_stack_for_arm(const GGdbDebugger *, virt_t **, size_t *); - -/* Complète la commande manipulant des points d'arrêt. */ -static const char *get_breakpoint_kind_for_arm(const GGdbDebugger *, virt_t); - -/* Construit une instruction provoquant un arrêt d'exécution. */ -static const uint8_t *get_arm_breakpoint_data(const GGdbDebugger *, virt_t, size_t *); - - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Fournit les fonctions adaptées aux opérations pour ARM. * -* * -* Retour : Opérations spécifiques adaptées à ARM. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const gdb_arch_ops *get_arm_operations(void) -{ - static const gdb_arch_ops arm_ops = { - - .get_pc = get_arm_pc, - .compute_cstack = compute_call_stack_for_arm, - .get_bp_kind = get_breakpoint_kind_for_arm, - .get_bp_data = get_arm_breakpoint_data - - }; - - return &arm_ops; - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à consulter. * -* pc = adresse de l'instruction courante. [OUT] * -* * -* Description : Détermine le point d'exécution courant. * -* * -* Retour : Bilan de la récupération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool get_arm_pc(GGdbDebugger *debugger, virt_t *pc) -{ - bool result; /* Bilan à retourner */ - uint32_t value; - - result = g_binary_debugger_read_register_u32(G_BINARY_DEBUGGER(debugger), "pc", &value); - - if (result) - *pc = value; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à consulter. * -* callstack = pile d'appels reconstituée. [OUT] * -* size = taille de cette pile. [OUT] * -* * -* Description : Remonte la pile d'appels jusqu'au point courant. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool compute_call_stack_for_arm(const GGdbDebugger *debugger, virt_t **callstack, size_t *size) -{ - bool result; /* Bilan global à retourner */ - GBinaryDebugger *base; /* Version basique d'instance */ - uint32_t lr; /* Retour de fonction */ - uint32_t fp; /* Pointeur de cadre à suivre */ - - base = G_BINARY_DEBUGGER(debugger); - - result = g_binary_debugger_read_register_u32(base, "lr", &lr); - - if (result && lr != 0) - { - *callstack = (virt_t *)realloc(*callstack, ++(*size) * sizeof(virt_t)); - - (*callstack)[*size - 1] = lr; - - } - - result &= g_binary_debugger_read_register_u32(base, "r11", &fp); - - while (result && fp != 0) - { - /** - * fp[-0] : pc sauvegardé - * fp[-1] : lr sauvegardé - * fp[-2] : sp précédent - * fp[-3] : fp précédent - */ - - result = g_binary_debugger_read_memory_u32(base, fp - 2 * sizeof(uint32_t), &lr); - if (!result) break; - - if (lr != 0) - { - *callstack = (virt_t *)realloc(*callstack, ++(*size) * sizeof(virt_t)); - - (*callstack)[*size - 1] = lr; - - } - - result = g_binary_debugger_read_memory_u32(base, fp - 4 * sizeof(uint32_t), &fp); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à manipuler ici. * -* virt = emplacement du point mémoire à traiter. * -* * -* Description : Complète la commande manipulant des points d'arrêt. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static const char *get_breakpoint_kind_for_arm(const GGdbDebugger *debugger, virt_t virt) -{ - const char *result; /* Indication à retourner */ - GArchProcessor *proc; /* Processeur lié au binaire */ - vmpa2t addr; /* Format d'adresse complet */ - GArchInstruction *instr; /* Instruction ciblée */ - const char *encoding; /* Encodage de l'instruction */ - - proc = g_loaded_binary_get_processor(G_BINARY_DEBUGGER(debugger)->binary); - - init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); - instr = g_arch_processor_find_instr_by_address(proc, &addr); - - if (instr == NULL) - result = NULL; - - else - { - encoding = g_arch_instruction_get_encoding(instr); - - if (strcmp(encoding, "Thumb/16") == 0) - result = ",2"; - - if (strcmp(encoding, "Thumb/32") == 0) - result = ",3"; - - if (strcmp(encoding, "ARM") == 0) - result = ",4"; - - else - result = NULL; - - g_object_unref(G_OBJECT(instr)); - - } - - g_object_unref(G_OBJECT(proc)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à manipuler ici. * -* addr = emplacement du point mémoire à traiter. * -* len = quantité de mémoire à remplacer. [OUT] * -* * -* Description : Construit une instruction provoquant un arrêt d'exécution. * -* * -* Retour : Définition du point d'arrêt à placer à l'adresse donnée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static const uint8_t *get_arm_breakpoint_data(const GGdbDebugger *debugger, virt_t addr, size_t *len) -{ - const uint8_t *result; /* Données à placer en mémoire */ - - /* Version point d'arrêt */ - static const uint32_t bkpt_code[] = { 0xe1200070 }; - - *len = sizeof(bkpt_code);; - - result = (const uint8_t *)bkpt_code; - - return result; - -} diff --git a/src/debug/gdbrsp/helpers_arm.h b/src/debug/gdbrsp/helpers_arm.h deleted file mode 100644 index ec82b27..0000000 --- a/src/debug/gdbrsp/helpers_arm.h +++ /dev/null @@ -1,37 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * helpers_arm.h - prototypes pour les compléments utiles à GDB pour l'architecture ARM - * - * Copyright (C) 2016 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _DEBUG_GDBRSP_HELPERS_ARM_H -#define _DEBUG_GDBRSP_HELPERS_ARM_H - - -#include "aops.h" - - - -/* Fournit les fonctions adaptées aux opérations pour ARM. */ -const gdb_arch_ops *get_arm_operations(void); - - - -#endif /* _DEBUG_GDBRSP_HELPERS_ARM_H */ diff --git a/src/debug/gdbrsp/helpers_arm64.c b/src/debug/gdbrsp/helpers_arm64.c deleted file mode 100644 index 810c8b3..0000000 --- a/src/debug/gdbrsp/helpers_arm64.c +++ /dev/null @@ -1,97 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * helpers_arm64.c - compléments utiles à GDB pour l'architecture AArch64 - * - * Copyright (C) 2016 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "helpers_arm64.h" - - -#include - - -#include "gdb-int.h" - - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à consulter. * -* callstack = pile d'appels reconstituée. [OUT] * -* size = taille de cette pile. [OUT] * -* * -* Description : Remonte la pile d'appels jusqu'au point courant. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool compute_call_stack_for_arm64(GGdbDebugger *debugger, virt_t **callstack, size_t *size) -{ - bool result; /* Bilan global à retourner */ - GBinaryDebugger *base; /* Version basique d'instance */ - uint64_t fp; /* Pointeur de cadre à suivre */ - uint64_t previous; /* Appel de fonction précédent */ - - base = G_BINARY_DEBUGGER(debugger); - - result = g_binary_debugger_read_register_u64(base, "x29", &fp); - - while (result && fp != 0) - { - result = g_binary_debugger_read_memory_u64(base, fp + sizeof(uint64_t), &previous); - if (!result) break; - - *callstack = (virt_t *)realloc(*callstack, ++(*size) * sizeof(virt_t)); - - (*callstack)[*size - 1] = previous; - - result = g_binary_debugger_read_memory_u64(base, fp, &fp); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : debugger = débogueur à manipuler ici. * -* addr = emplacement du point mémoire à traiter. * -* cmd = commande en cours de constitution. [OUT] * -* * -* Description : Complète la commande manipulant des points d'arrêt. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool fill_memory_breakpoint_cmd_for_arm64(GGdbDebugger *debugger, virt_t addr, char *cmd) -{ - strcat(cmd, ",4"); - - return true; - -} diff --git a/src/debug/gdbrsp/helpers_arm64.h b/src/debug/gdbrsp/helpers_arm64.h deleted file mode 100644 index 5e89deb..0000000 --- a/src/debug/gdbrsp/helpers_arm64.h +++ /dev/null @@ -1,40 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * helpers_arm64.h - prototypes pour les compléments utiles à GDB pour l'architecture AArch64 - * - * Copyright (C) 2016 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _DEBUG_GDBRSP_HELPERS_ARM64_H -#define _DEBUG_GDBRSP_HELPERS_ARM64_H - - -#include "gdb.h" - - - -/* Remonte la pile d'appels jusqu'au point courant. */ -bool compute_call_stack_for_arm64(GGdbDebugger *, virt_t **, size_t *); - -/* Complète la commande manipulant des points d'arrêt. */ -bool fill_memory_breakpoint_cmd_for_arm64(GGdbDebugger *, virt_t, char *); - - - -#endif /* _DEBUG_GDBRSP_HELPERS_ARM64_H */ diff --git a/src/debug/gdbrsp/packet.c b/src/debug/gdbrsp/packet.c deleted file mode 100644 index 806c6b0..0000000 --- a/src/debug/gdbrsp/packet.c +++ /dev/null @@ -1,389 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * packet.c - manipulation des paquets de données GDB. - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "packet.h" - - -#include -#include - - -#include "../../common/dllist.h" - - - -/* Répresentation d'un paquet GDB (instance) */ -struct _GGdbPacket -{ - GObject parent; /* A laisser en premier */ - - DL_LIST_ITEM(link); /* Lien vers les autres */ - - char *buffer; /* Données à traiter */ - size_t len; /* Quantité de ces données */ - size_t allocated; /* Taille du tampon */ - - uint8_t checksum; /* Empreinte de contrôle */ - -}; - - -/* Répresentation d'un paquet GDB (classe) */ -struct _GGdbPacketClass -{ - GObjectClass parent; /* A laisser en premier */ - -}; - - -/* Initialise la classe des représentations des paquets GDB. */ -static void g_gdb_packet_class_init(GGdbPacketClass *); - -/* Initialise une instance de représentation de paquet GDB. */ -static void g_gdb_packet_init(GGdbPacket *); - - - -/* Indique le type défini pour une répresentation de paquet GDB. */ -G_DEFINE_TYPE(GGdbPacket, g_gdb_packet, G_TYPE_OBJECT); - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des représentations des paquets GDB. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_packet_class_init(GGdbPacketClass *klass) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : packet = instance à initialiser. * -* * -* Description : Initialise une instance de représentation de paquet GDB. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_packet_init(GGdbPacket *packet) -{ - DL_LIST_ITEM_INIT(&packet->link); - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Crée une représentation de paquet GDB. * -* * -* Retour : Adresse de la structure mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GGdbPacket *g_gdb_packet_new(void) -{ - GGdbPacket *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_GDB_PACKET, NULL); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : packet = paquet à préparer pour une émission. * -* * -* Description : Prépare un paquet pour un envoi prochain. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_gdb_packet_start_new_command(GGdbPacket *packet) -{ - if (packet->allocated == 0) - { - packet->allocated = 1; - packet->buffer = (char *)calloc(packet->allocated, sizeof(char)); - } - - packet->buffer[0] = '\0'; - packet->len = 0; - -} - - -/****************************************************************************** -* * -* Paramètres : packet = paquet à préparer pour une émission. * -* string = chaîne à inclure dans le paquet. * -* * -* Description : Complète un paquet pour un envoi prochain. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_gdb_packet_append(GGdbPacket *packet, const char *string) -{ - size_t len; /* Taille de la chaîne donnée */ - - len = strlen(string); - - /* Si la place n'est pas assez grande */ - if ((packet->len + len + 1) > packet->allocated) - { - packet->buffer = (char *)realloc(packet->buffer, (packet->len + len + 1) * sizeof(char)); - packet->allocated = packet->len + len + 1; - } - - - memcpy(packet->buffer + packet->len, string, len + 1); - //strcat(packet->buffer, string); - - packet->len += len; - -} - - -/****************************************************************************** -* * -* Paramètres : packet = paquet à analyser. * -* * -* Description : Détermine l'empreinte des données d'un paquet GDB. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_gdb_packet_compute_checksum(GGdbPacket *packet) -{ - int sum; /* Valeur cumulée des données */ - size_t i; /* Boucle de parcours */ - - sum = 0; - - for (i = 0; i < packet->len; i++) - sum += packet->buffer[i]; - - packet->checksum = sum % 256; - -} - - -/****************************************************************************** -* * -* Paramètres : packet = paquet à analyser. * -* checksum = contrôle d'intégrité à retrouver. * -* * -* Description : Contrôle l'intégrité des données d'un paquet GDB. * -* * -* Retour : Bilan de la vérification. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_gdb_packet_verify_checksum(GGdbPacket *packet, uint8_t checksum) -{ - g_gdb_packet_compute_checksum(packet); - - return checksum == packet->checksum; - -} - - -/****************************************************************************** -* * -* Paramètres : packet = paquet à décoder et/ou décompresser. * -* * -* Description : Décode et/ou décompresse un paquet GDB. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_gdb_packet_decode(GGdbPacket *packet) -{ - bool result; /* Bilan à retourner */ - char *buffer; /* Données transcrites */ - size_t allocated; /* Quantité de données gérées */ - size_t i; /* Boucle de parcours */ - size_t k; /* Point d'insertion */ - size_t repeat; /* Nombre de répétitions */ - - result = true; - - allocated = packet->len + 1; - buffer = (char *)calloc(allocated, sizeof(char)); - - for (i = 0, k = 0; i < packet->len && result; i++) - switch (packet->buffer[i]) - { - case '#': - case '$': - result = false; - break; - - case '*': - - if (++i == packet->len || k == 0) - { - result = false; - break; - } - - repeat = packet->buffer[i] - ' ' + 3; - - allocated += repeat; - buffer = (char *)realloc(buffer, allocated * sizeof(char)); - - memset(&buffer[k], buffer[k - 1], repeat); - k += repeat; - - break; - - case '}': - - if (++i == packet->len) - { - result = false; - break; - } - - buffer[k++] = packet->buffer[i] ^ 0x20; - - break; - - default: - buffer[k++] = packet->buffer[i]; - break; - - } - - if (packet->buffer != NULL) - free(packet->buffer); - - buffer[k] = '\0'; - - packet->buffer = buffer; - packet->len = k; - packet->allocated = allocated; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : packet = paquet à analyser. * -* data = données contenues dans le paquet. [OUT] * -* len = quantité de ces données ou NULL. [OUT] * -* checksum = contrôle d'intégrité des données ou NULL. [OUT] * -* * -* Description : Fournit le contenu du paquet. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_gdb_packet_get_data(const GGdbPacket *packet, const char **data, size_t *len, uint8_t *checksum) -{ - *data = packet->buffer; - - if (len != NULL) - *len = packet->len; - - if (checksum != NULL) - *checksum = packet->checksum; - -} - - -/****************************************************************************** -* * -* 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_gdb_packet_push(GGdbPacket **list, GGdbPacket *item) -{ - dl_list_push(item, list, GGdbPacket, 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 : - * -* * -******************************************************************************/ - -GGdbPacket *g_gdb_packet_pop(GGdbPacket **list) -{ - return dl_list_pop(list, GGdbPacket, link); - -} diff --git a/src/debug/gdbrsp/packet.h b/src/debug/gdbrsp/packet.h deleted file mode 100644 index 7f362bd..0000000 --- a/src/debug/gdbrsp/packet.h +++ /dev/null @@ -1,82 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * packet.h - prototypes pour la manipulation des paquets de données GDB. - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _DEBUG_GDBRSP_PACKET_H -#define _DEBUG_GDBRSP_PACKET_H - - -#include -#include -#include - - - -#define G_TYPE_GDB_PACKET g_gdb_packet_get_type() -#define G_GDB_PACKET(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_gdb_packet_get_type(), GGdbPacket)) -#define G_IS_GDB_PACKET(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_gdb_packet_get_type())) -#define G_GDB_PACKET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_PACKET, GGdbPacketClass)) -#define G_IS_GDB_PACKET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_PACKET)) -#define G_GDB_PACKET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_PACKET, GGdbPacketClass)) - - -/* Répresentation d'un paquet GDB (instance) */ -typedef struct _GGdbPacket GGdbPacket; - -/* Répresentation d'un paquet GDB (classe) */ -typedef struct _GGdbPacketClass GGdbPacketClass; - - - -/* Indique le type défini pour une répresentation de paquet GDB. */ -GType g_gdb_packet_get_type(void); - -/* Crée une représentation de paquet GDB. */ -GGdbPacket *g_gdb_packet_new(void); - -/* Prépare un paquet pour un envoi prochain. */ -void g_gdb_packet_start_new_command(GGdbPacket *); - -/* Complète un paquet pour un envoi prochain. */ -void g_gdb_packet_append(GGdbPacket *, const char *); - -/* Détermine l'empreinte des données d'un paquet GDB. */ -void g_gdb_packet_compute_checksum(GGdbPacket *); - -/* Contrôle l'intégrité des données d'un paquet GDB. */ -bool g_gdb_packet_verify_checksum(GGdbPacket *, uint8_t); - -/* Décode et/ou décompresse un paquet GDB. */ -bool g_gdb_packet_decode(GGdbPacket *); - -/* Fournit le contenu du paquet. */ -void g_gdb_packet_get_data(const GGdbPacket *, const char **, size_t *, uint8_t *); - -/* Ajoute un paquet à une liste de paquets. */ -void g_gdb_packet_push(GGdbPacket **, GGdbPacket *); - -/* Retire et fournit le premier élément d'une liste de paquets. */ -GGdbPacket *g_gdb_packet_pop(GGdbPacket **); - - - -#endif /* _DEBUG_GDBRSP_PACKET_H */ diff --git a/src/debug/gdbrsp/stream-int.h b/src/debug/gdbrsp/stream-int.h deleted file mode 100644 index ab26dc2..0000000 --- a/src/debug/gdbrsp/stream-int.h +++ /dev/null @@ -1,89 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * stream-int.h - prototypes internes pour la gestion des connexions aux serveurs GDB. - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _DEBUG_GDBRSP_STREAM_INT_H -#define _DEBUG_GDBRSP_STREAM_INT_H - - -#include "gdb.h" -#include "stream.h" - - - -/* Envoie des données à un serveur GDB. */ -typedef bool (* send_gdb_data_fc) (GGdbStream *, const char *, size_t); - -/* Réceptionne un octet de donnée d'un serveur GDB. */ -typedef bool (* recv_gdb_byte_fc) (GGdbStream *, char *); - - -/* Flux de communication avec un serveur GDB (instance) */ -struct _GGdbStream -{ - GObject parent; /* A laisser en premier */ - - int fd; /* Flux ouvert en L./E. */ - - GGdbDebugger *owner; /* Propriétaire du flux */ - - send_gdb_data_fc send_data; /* Envoi d'un paquet GDB */ - recv_gdb_byte_fc recv_byte; /* Réception d'un paquet GDB */ - - GThread *listening; /* Thread pour les réceptions */ - - GGdbPacket *free_packets; /* Liste des disponibles */ - GMutex free_mutex; /* Accès à la liste */ - - GGdbPacket *recv_packets; /* Liste des paquets reçus */ - GCond recv_cond; /* Attente de disponibilité */ - GMutex recv_mutex; /* Accès à la liste */ - - GGdbPacket *status_packets; /* Liste des paquets d'état */ - GCond status_cond; /* Attente de disponibilité */ - GMutex status_mutex; /* Accès à la liste */ - - - - - bool skip_ack; - - bool want_status; - - -}; - - -/* Flux de communication avec un serveur GDB (classe) */ -struct _GGdbStreamClass -{ - GObjectClass parent; /* A laisser en premier */ - -}; - - -/* Lance l'écoute d'un flux de communication avec GDB. */ -bool g_gdb_stream_listen(GGdbStream *); - - - -#endif /* _DEBUG_GDBRSP_STREAM_INT_H */ diff --git a/src/debug/gdbrsp/stream.c b/src/debug/gdbrsp/stream.c deleted file mode 100644 index f86f630..0000000 --- a/src/debug/gdbrsp/stream.c +++ /dev/null @@ -1,696 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * stream.c - gestion des connexions aux serveurs GDB. - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "stream.h" - - -#include -#include -#include -#include -#include -#include - - -#include "gdb-int.h" -#include "stream-int.h" -#include "utils.h" -#include "../../common/dllist.h" -#include "../../core/logs.h" - - - -/* Initialise la classe des flux de communication avec GDB. */ -static void g_gdb_stream_class_init(GGdbStreamClass *); - -/* Initialise une instance de flux de communication avec GDB. */ -static void g_gdb_stream_init(GGdbStream *); - -/* Supprime toutes les références externes. */ -static void g_gdb_stream_dispose(GGdbStream *); - -/* Procède à la libération totale de la mémoire. */ -static void g_gdb_stream_finalize(GGdbStream *); - -/* Envoie un acquittement pour la dernière réception. */ -static bool gdb_stream_ack(GGdbStream *); - -/* Ecoute une connexion à un serveur GDB. */ -static void *gdb_stream_thread(GGdbStream *); - -/* Reste en alerte quant au changement de statut de l'exécution. */ -static void *gdb_stream_status_thread(GGdbStream *); - -/* Réceptionne un paquet d'un serveur GDB. */ -static bool g_gdb_stream_read_packet(GGdbStream *, GGdbPacket *); - - - -/* Indique le type défini pour un flux de communication avec un serveur GDB. */ -G_DEFINE_TYPE(GGdbStream, g_gdb_stream, G_TYPE_OBJECT); - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des flux de communication avec GDB. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_stream_class_init(GGdbStreamClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_gdb_stream_dispose; - object->finalize = (GObjectFinalizeFunc)g_gdb_stream_finalize; - -} - - -/****************************************************************************** -* * -* Paramètres : stream = instance à initialiser. * -* * -* Description : Initialise une instance de flux de communication avec GDB. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_stream_init(GGdbStream *stream) -{ - g_mutex_init(&stream->free_mutex); - - g_cond_init(&stream->recv_cond); - g_mutex_init(&stream->recv_mutex); - - g_cond_init(&stream->status_cond); - g_mutex_init(&stream->status_mutex); - - stream->skip_ack = false; - - stream->want_status = false; - -} - - -/****************************************************************************** -* * -* Paramètres : stream = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_stream_dispose(GGdbStream *stream) -{ - g_object_unref(G_OBJECT(stream->owner)); - - - /* TODO... */ - - - G_OBJECT_CLASS(g_gdb_stream_parent_class)->dispose(G_OBJECT(stream)); - -} - - -/****************************************************************************** -* * -* Paramètres : stream = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_stream_finalize(GGdbStream *stream) -{ - - /* TODO */ - - - G_OBJECT_CLASS(g_gdb_stream_parent_class)->finalize(G_OBJECT(stream)); - -} - - -/****************************************************************************** -* * -* Paramètres : stream = instance à modifier. * -* * -* Description : Ne participe plus aux acquitements de paquets. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_gdb_stream_do_not_ack(GGdbStream *stream) -{ - stream->skip_ack = true; - -} - - - -/****************************************************************************** -* * -* Paramètres : stream = instance à réellement lancer. * -* * -* Description : Lance l'écoute d'un flux de communication avec GDB. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_gdb_stream_listen(GGdbStream *stream) -{ - bool result; /* Bilan final à retourner */ - - result = true; - - if (!g_thread_new("chrysalide_gdb_stream", (GThreadFunc)gdb_stream_thread, stream)) - result = false; - - if (!g_thread_new("chrysalide_gdb_status", (GThreadFunc)gdb_stream_status_thread, stream)) - result = false; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : stream = encadrement associée à l'opération. * -* * -* Description : Envoie un acquittement pour la dernière réception. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool gdb_stream_ack(GGdbStream *stream) -{ - /// - //return true; - - bool result; /* Bilan à retourner */ - GGdbPacket *packet; /* Paquet à envoyer */ - - packet = g_gdb_stream_get_free_packet(stream); - - g_gdb_packet_start_new_command(packet); - g_gdb_packet_append(packet, "+"); - - result = g_gdb_stream_send_packet(stream, packet); - - g_gdb_stream_mark_packet_as_free(stream, packet); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : stream = encadrement associée à l'opération. * -* * -* Description : Ecoute une connexion à un serveur GDB. * -* * -* Retour : ??? * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void *gdb_stream_thread(GGdbStream *stream) -{ - fd_set rfds; /* Liste des flux à surveiller */ - int ret; /* Bilan d'un appel */ - GGdbPacket *packet; /* Nouveau paquet reçu */ - - - const char *data; /* Données reçues à analyser */ - size_t len; /* Quantité de ces données */ - - - - while (1) - { - FD_ZERO(&rfds); - FD_SET(stream->fd, &rfds); - - ret = select(stream->fd + 1, &rfds, NULL, NULL, NULL); - - switch (ret) - { - case -1: - perror("select()"); - break; - - case 0: - break; - - default: - - packet = g_gdb_stream_get_free_packet(stream); - - g_gdb_packet_start_new_command(packet); - - if (g_gdb_stream_read_packet(stream, packet)) - { - /* Acquittement ? */ - if (!stream->skip_ack) - { - if (!gdb_stream_ack(stream)) goto bad_recv; - } - - - /* On conserve le résultat ? */ - - - g_gdb_packet_get_data(packet, &data, &len, NULL); - - - //printf("---------------------------\n"); - //printf(">> want status ? %d\n", stream->want_status); - //printf(">> got '%s'\n", data); - - - if (len >= 1) - { - if (stream->want_status) - stream->want_status = false; - - else if (index("STWX", data[0]) != NULL) - { - g_mutex_lock(&stream->status_mutex); - g_gdb_packet_push(&stream->status_packets, packet); - g_mutex_unlock(&stream->status_mutex); - - g_cond_signal(&stream->status_cond); - - break; - } - - // else message inconnu -> log_message() ! - - } - - - - - g_mutex_lock(&stream->recv_mutex); - g_gdb_packet_push(&stream->recv_packets, packet); - g_mutex_unlock(&stream->recv_mutex); - - g_cond_signal(&stream->recv_cond); - - } - - else - g_gdb_stream_mark_packet_as_free(stream, packet); - - break; - - bad_recv: - - printf("bad things happend...\n"); - - g_gdb_stream_mark_packet_as_free(stream, packet); - - break; - - } - - } - - - printf("Oh noes....\n"); - - - return NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : stream = encadrement associée à l'opération. * -* * -* Description : Reste en alerte quant au changement de statut de l'exécution.* -* * -* Retour : ??? * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void *gdb_stream_status_thread(GGdbStream *stream) -{ - GGdbPacket *packet; /* Nouveau paquet reçu */ - const char *data; /* Données reçues à analyser */ - size_t len; /* Quantité de ces données */ - bool malformed; /* Echec d'interprétation */ - uint8_t byte; /* Valeur quelconque sur 8 bits*/ - bool ret; /* Bilan d'un appel */ - - while (1) - { - /* Réception d'un nouveau paquet de statut */ - - g_mutex_lock(&stream->status_mutex); - - if (dl_list_empty(stream->status_packets)) - g_cond_wait(&stream->status_cond, &stream->status_mutex); - - packet = g_gdb_packet_pop(&stream->status_packets); - - g_mutex_unlock(&stream->status_mutex); - - /* Traitement du paquet reçu */ - - g_gdb_packet_get_data(packet, &data, &len, NULL); - - malformed = false; - - switch (data[0]) - { - case 'S': - - ret = read_fixed_byte(data + 1, len - 1, &byte); - - if (!ret) - { - malformed = true; - goto gsst_processed; - } - - g_gdb_debugger_receive_signal_reply(stream->owner, byte); - break; - - case 'T': - assert(false); // TODO - break; - - case 'W': - - ret = read_fixed_byte(data + 1, len - 1, &byte); - - if (!ret) - { - malformed = true; - goto gsst_processed; - } - - - // TODO : ";process:pid" - - - printf("Program exited (status=%hhu)\n", byte); - - - g_gdb_debugger_receive_exit_reply(stream->owner, byte, -1); - - - // log_message en cas de mauvais format... - - - break; - - - default: - assert(false); - break; - - } - - gsst_processed: - - if (malformed && true/* TODO : config->show_... */) - log_variadic_message(LMT_WARNING, "Malformed GDB status reply: '%s'", data); - - g_gdb_stream_mark_packet_as_free(stream, packet); - - } - - return NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : stream = flux de communication avec GDB à consulter. * -* * -* Description : Fournit un paquet prêt à emploi. * -* * -* Retour : Paquet prêt à emploi. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GGdbPacket *g_gdb_stream_get_free_packet(GGdbStream *stream) -{ - GGdbPacket *result; /* Paquet à retourner */ - - g_mutex_lock(&stream->free_mutex); - - if (dl_list_empty(stream->free_packets)) - result = g_gdb_packet_new(); - - else - result = g_gdb_packet_pop(&stream->free_packets); - - g_mutex_unlock(&stream->free_mutex); - - // ??? - //g_gdb_packet_start_new_command(result); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : stream = flux de communication avec GDB à mettre à jour. * -* packet = paquet à considérer comme disponible. * -* * -* Description : Place un paquet en attente d'une future utilisation. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_gdb_stream_mark_packet_as_free(GGdbStream *stream, GGdbPacket *packet) -{ - //// Utile ? - g_gdb_packet_start_new_command(packet); - - - g_mutex_lock(&stream->free_mutex); - - g_gdb_packet_push(&stream->free_packets, packet); - - g_mutex_unlock(&stream->free_mutex); - -} - - -/****************************************************************************** -* * -* Paramètres : stream = flux ouvert en lecture à utiliser. * -* packet = données à recevoir. * -* * -* Description : Réceptionne un paquet d'un serveur GDB. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_stream_read_packet(GGdbStream *stream, GGdbPacket *packet) -{ - bool result; /* Bilan à renvoyer */ - char tmp[3]; /* Tampon de réception */ - uint8_t checksum; /* Contrôle d'intégrité */ - - do - { - result = stream->recv_byte(stream, tmp); - if (tmp[0] != '+') break; - } - while (0); - - if (tmp[0] != '$') return false; - - tmp[1] = '\0'; - - while ((result = stream->recv_byte(stream, tmp))) - { - //printf(" .. '%c'\n", tmp[0]); - - if (tmp[0] == '#') break; - else g_gdb_packet_append(packet, tmp); - } - - if (result) - { - result = stream->recv_byte(stream, &tmp[0]); - result &= stream->recv_byte(stream, &tmp[1]); - - tmp[2] = 0; - checksum = strtol(tmp, NULL, 16); - - } - - if (result) - result = g_gdb_packet_verify_checksum(packet, checksum); - - if (result) - result = g_gdb_packet_decode(packet); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : stream = flux ouvert en écriture à mettre à jour. * -* packet = données à transmettre. * -* * -* Description : Envoie un paquet à un serveur GDB. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ -#include -bool g_gdb_stream_send_packet(GGdbStream *stream, GGdbPacket *packet) -{ - bool result; /* Bilan à renvoyer */ - const char *data; /* Données à envoyer */ - size_t len; /* Quantité de ces données */ - uint8_t checksum; /* Contrôle d'intégrité */ - char tmp[3]; /* Impression du checksum */ - - g_gdb_packet_get_data(packet, &data, &len, NULL); - -#if 1 - /* Ack ? */ - if (len == 1 && data[0] == '+') - result = stream->send_data(stream, "+", 1); - - else -#endif - { - - result = stream->send_data(stream, "$", 1); - //result = stream->send_data(stream, "+$", 2); - - g_gdb_packet_compute_checksum(packet); - g_gdb_packet_get_data(packet, &data, &len, &checksum); - - - if (len == 1 && data[0] == '?') - stream->want_status = true; - - /* - if (memcmp(data, "vCont;c", strlen("vCont;c")) == 0) - stream->want_status = true; - */ - - - - result &= stream->send_data(stream, data, len); - - result = stream->send_data(stream, "#", 1); - - snprintf(tmp, 3, "%02hhx", checksum); - result &= stream->send_data(stream, tmp, 2); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : stream = flux de communication avec GDB à consulter. * -* * -* Description : Fournit un paquet reçu d'un serveur GDB. * -* * -* Retour : Paquet GDB. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GGdbPacket *g_gdb_stream_recv_packet(GGdbStream *stream) -{ - GGdbPacket *result; /* Paquet à retourner */ - - g_mutex_lock(&stream->recv_mutex); - - if (dl_list_empty(stream->recv_packets)) - g_cond_wait(&stream->recv_cond, &stream->recv_mutex); - - result = g_gdb_packet_pop(&stream->recv_packets); - - g_mutex_unlock(&stream->recv_mutex); - - return result; - -} diff --git a/src/debug/gdbrsp/stream.h b/src/debug/gdbrsp/stream.h deleted file mode 100644 index a64485a..0000000 --- a/src/debug/gdbrsp/stream.h +++ /dev/null @@ -1,68 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * stream.h - prototypes pour la gestion des connexions aux serveurs GDB. - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _DEBUG_GDBRSP_STREAM_H -#define _DEBUG_GDBRSP_STREAM_H - - -#include "packet.h" - - - -#define G_TYPE_GDB_STREAM g_gdb_stream_get_type() -#define G_GDB_STREAM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_gdb_stream_get_type(), GGdbStream)) -#define G_IS_GDB_STREAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_gdb_stream_get_type())) -#define G_GDB_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_STREAM, GGdbStreamClass)) -#define G_IS_GDB_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_STREAM)) -#define G_GDB_STREAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_STREAM, GGdbStreamClass)) - - -/* Flux de communication avec un serveur GDB (instance) */ -typedef struct _GGdbStream GGdbStream; - -/* Flux de communication avec un serveur GDB (classe) */ -typedef struct _GGdbStreamClass GGdbStreamClass; - - - -/* Indique le type défini pour un flux de communication avec un serveur GDB. */ -GType g_gdb_stream_get_type(void); - -/* Ne participe plus aux acquitements de paquets. */ -void g_gdb_stream_do_not_ack(GGdbStream *); - -/* Fournit un paquet prêt à emploi. */ -GGdbPacket *g_gdb_stream_get_free_packet(GGdbStream *); - -/* Place un paquet en attente d'une future utilisation. */ -void g_gdb_stream_mark_packet_as_free(GGdbStream *, GGdbPacket *); - -/* Envoie un paquet à un serveur GDB. */ -bool g_gdb_stream_send_packet(GGdbStream *, GGdbPacket *); - -/* Fournit un paquet reçu d'un serveur GDB. */ -GGdbPacket *g_gdb_stream_recv_packet(GGdbStream *); - - - -#endif /* _DEBUG_GDBRSP_STREAM_H */ diff --git a/src/debug/gdbrsp/support.c b/src/debug/gdbrsp/support.c deleted file mode 100644 index 3d27c06..0000000 --- a/src/debug/gdbrsp/support.c +++ /dev/null @@ -1,598 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * support.c - conformité dans l'interfaçage client/serveur - * - * Copyright (C) 2016 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "support.h" - - -#include -#include - - - -/* Indications quant à l'interfaçage client/serveur GDB (instance) */ -struct _GGdbSupport -{ - GObject parent; /* A laisser en premier */ - - unsigned long packet_size; /* Taille maximale d'un paquet */ - - bool os_data; - - - bool extended_mode; /* Mode étendu présent & actif */ - - - char *id; - -}; - -/* Indications quant à l'interfaçage client/serveur GDB (classe) */ -struct _GGdbSupportClass -{ - GObjectClass parent; /* A laisser en premier */ - -}; - - -/* Initialise la classe des détails d'interfaçage GDB. */ -static void g_gdb_support_class_init(GGdbSupportClass *); - -/* Procède à l'initialisation des détails d'interfaçage GDB. */ -static void g_gdb_support_init(GGdbSupport *); - -/* Supprime toutes les références externes. */ -static void g_gdb_support_dispose(GGdbSupport *); - -/* Procède à la libération totale de la mémoire. */ -static void g_gdb_support_finalize(GGdbSupport *); - -/* Lit une valeur booléenne à partir des détails du serveur. */ -static bool g_gdb_support_read_bool(GGdbSupport *, const char *, const char *, bool *); - -/* Lit une valeur longue à partir des détails du serveur. */ -static bool g_gdb_support_read_ulong(GGdbSupport *, const char *, const char *, unsigned long *); - - - -/* Indique le type défini par la GLib pour les détails d'interfaçage GDB. */ -G_DEFINE_TYPE(GGdbSupport, g_gdb_support, G_TYPE_OBJECT); - - -/****************************************************************************** -* * -* Paramètres : klass = classe de débogueur à initialiser. * -* * -* Description : Initialise la classe des détails d'interfaçage GDB. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_support_class_init(GGdbSupportClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_gdb_support_dispose; - object->finalize = (GObjectFinalizeFunc)g_gdb_support_finalize; - -} - - -/****************************************************************************** -* * -* Paramètres : support = instance de débogueur à préparer. * -* * -* Description : Procède à l'initialisation des détails d'interfaçage GDB. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_support_init(GGdbSupport *support) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : support = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_support_dispose(GGdbSupport *support) -{ - G_OBJECT_CLASS(g_gdb_support_parent_class)->dispose(G_OBJECT(support)); - -} - - -/****************************************************************************** -* * -* Paramètres : support = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_support_finalize(GGdbSupport *support) -{ - G_OBJECT_CLASS(g_gdb_support_parent_class)->finalize(G_OBJECT(support)); - -} - - - - - - - - - - - - - - -#include - -static char *build_id(GGdbStream *stream) -{ - char *result; /* Identifiant à renvoyer */ - GGdbPacket *packet; /* Paquet de communication */ - bool status; /* Bilan d'une communication */ - const char *data; /* Données reçues à analyser */ - const char *start; /* Début d'identification */ - const char *end; /* Fin d'identification */ - - result = NULL; - - /* Envoi de la requête */ - - packet = g_gdb_stream_get_free_packet(stream); - - g_gdb_packet_start_new_command(packet); - g_gdb_packet_append(packet, "?"); - - status = g_gdb_stream_send_packet(stream, packet); - - if (!status) - goto ggdgat_exit; - - /* Réception de la réponse */ - - packet = g_gdb_stream_recv_packet(stream); - - g_gdb_packet_get_data(packet, &data, NULL, NULL); - - start = strstr(data, "thread:"); - if (start == NULL) goto ggdgat_exit; - - start += sizeof("thread:") - 1 /* '\0' */; - - end = strstr(start, ";"); - if (end == NULL) goto ggdgat_exit; - - result = strndup(start, end - start); - - ggdgat_exit: - - g_gdb_stream_mark_packet_as_free(stream, packet); - - return result; - -} - - - - - - - -/****************************************************************************** -* * -* Paramètres : stream = flux de communication ouvert avec le débogueur. * -* * -* Description : Crée une définition des détails d'interfaçage GDB. * -* * -* Retour : Instance de détails mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GGdbSupport *g_gdb_support_new(GGdbStream *stream) -{ - GGdbSupport *result; /* Débogueur à retourner */ - GGdbPacket *packet; /* Paquet de communication GDB */ - - - //goto end; - - //goto skip; - - packet = g_gdb_stream_get_free_packet(stream); - - g_gdb_packet_start_new_command(packet); - //g_gdb_packet_append(packet, "qSupported:multiprocess+;xmlRegisters"); - g_gdb_packet_append(packet, "qSupported"); - - g_gdb_packet_append(packet, "qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+"); - - - bool test; - - const char *data; /* Données reçues à analyser */ - size_t len; - - test = g_gdb_stream_send_packet(stream, packet); - - - - printf(" >> Paquet '%s' bien envoyé ? %s\n", "qSupported", test ? "oui" : "non"); - - - - g_gdb_stream_mark_packet_as_free(stream, packet); - - packet = g_gdb_stream_recv_packet(stream); - - g_gdb_packet_get_data(packet, &data, &len, NULL); - - printf(" << Réception de '%s'\n", data); - - - - - result = g_object_new(G_TYPE_GDB_SUPPORT, NULL); - - - - /* Découpage des éléments de réponse */ - - char *answer; /* Réponse modifiable */ - char *save; /* Sauvegarde de position */ - char *token; /* Elément de réponse cerné */ - - answer = strdup(data); - - for (token = strtok_r(answer, ";", &save); - token != NULL; - token = strtok_r(NULL, ";", &save)) - { - - - printf("TOKEN :: %s\n", token); - - if (g_gdb_support_read_ulong(result, token, "PacketSize", &result->packet_size)) - continue; - - if (g_gdb_support_read_bool(result, token, "qXfer:osdata:read", &result->os_data)) - { - printf(" -->> %d\n", result->os_data); - continue; - } - - - - - } - - free(answer); - - - - /** - * Première chose : plus d'acquitement ! - * - * Dans les faits, c'est impossible à gérer en asynchrone. Par exemple : - * - * C> vCont;c - * C> g Txx... extended_mode = (strcmp(data, "OK") == 0); - - g_gdb_stream_mark_packet_as_free(stream, packet); - - - - - result->id = build_id(stream); - - - -#if 0 - //end: - -#define CMD "?" - - - packet = g_gdb_stream_get_free_packet(stream); - - g_gdb_packet_start_new_command(packet); - //g_gdb_packet_append(packet, "qSupported:multiprocess+;xmlRegisters"); - g_gdb_packet_append(packet, CMD); - - - test = g_gdb_stream_send_packet(stream, packet); - - - - printf(" >> Paquet '%s' bien envoyé ? %s\n", CMD, test ? "oui" : "non"); - - - - g_gdb_stream_mark_packet_as_free(stream, packet); - - packet = g_gdb_stream_recv_packet(stream); - - g_gdb_packet_get_data(packet, &data, &len, NULL); - - printf(" << [pkt = %p ] Réception de '%s' (len=%d)\n", packet, data, (int)len); - - -#endif - - - - // qfThreadInfo - - -#undef CMD - - //#define CMD "qXfer:threads:read::0,1fff" - //#define CMD "qXfer:btrace:read:all:0,1fff" - //#define CMD "g" - //#define CMD "m400000,8" -#define CMD "qsThreadInfo" - - packet = g_gdb_stream_get_free_packet(stream); - - g_gdb_packet_start_new_command(packet); - //g_gdb_packet_append(packet, "qSupported:multiprocess+;xmlRegisters"); - g_gdb_packet_append(packet, CMD); - - - test = g_gdb_stream_send_packet(stream, packet); - - - - printf(" >> Paquet '%s' bien envoyé ? %s\n", CMD, test ? "oui" : "non"); - - - - g_gdb_stream_mark_packet_as_free(stream, packet); - - packet = g_gdb_stream_recv_packet(stream); - - g_gdb_packet_get_data(packet, &data, &len, NULL); - - printf(" << [pkt = %p ] Réception de '%s' (len=%d)\n", packet, data, (int)len); - - - - - - - - - - - - return result; - - ggsn_error: - - - - return NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : support = ensemble de détails à préciser. * -* raw = données brutes à parcourir. * -* name = désignation de la valeur recherchée. * -* value = emplacement de la valeur à inscrire. * -* * -* Description : Lit une valeur booléenne à partir des détails du serveur. * -* * -* Retour : true en cas d'affectation, false dans tous les autres cas. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_support_read_bool(GGdbSupport *support, const char *raw, const char *name, bool *value) -{ - bool result; /* Bilan à retourner */ - size_t rlen; /* Taille de l'ensemble */ - size_t nlen; /* Taille du nom */ - - rlen = strlen(raw); - nlen = strlen(name); - - if ((nlen + 1) != rlen) - return false; - - if (strncmp(raw, name, nlen) != 0) - return false; - - switch (raw[nlen]) - { - case '+': - *value = true; - result = true; - break; - - case '-': - case '?': - *value = false; - result = true; - break; - - default: - result = false; - break; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : support = ensemble de détails à préciser. * -* raw = données brutes à parcourir. * -* name = désignation de la valeur recherchée. * -* value = emplacement de la valeur à inscrire. * -* * -* Description : Lit une valeur longue à partir des détails du serveur. * -* * -* Retour : true en cas d'affectation, false dans tous les autres cas. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_support_read_ulong(GGdbSupport *support, const char *raw, const char *name, unsigned long *value) -{ - size_t rlen; /* Taille de l'ensemble */ - size_t nlen; /* Taille du nom */ - unsigned long v; /* Valeur récupérée à assigner */ - - rlen = strlen(raw); - nlen = strlen(name); - - if (strncmp(raw, name, nlen) != 0) - return false; - - if (raw[nlen] != '=') - return false; - - v = strtoul(raw + nlen + 1, NULL, 16); - - if (v == ULONG_MAX/* && errno == ERANGE*/) - return false; - - *value = v; - - return true; - -} - - - - - - -char *g_gdb_support_get_id(const GGdbSupport *support) -{ - return support->id; - -} - - - - - diff --git a/src/debug/gdbrsp/support.h b/src/debug/gdbrsp/support.h deleted file mode 100644 index 2f6259c..0000000 --- a/src/debug/gdbrsp/support.h +++ /dev/null @@ -1,73 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * support.h - prototypes pour la conformité dans l'interfaçage client/serveur - * - * Copyright (C) 2016 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _DEBUG_GDBRSP_SUPPORT_H -#define _DEBUG_GDBRSP_SUPPORT_H - - -#include -#include - - -#include "stream.h" - - - -#define G_TYPE_GDB_SUPPORT (g_gdb_support_get_type()) -#define G_GDB_SUPPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_GDB_SUPPORT, GGdbSupport)) -#define G_IS_GDB_SUPPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_GDB_SUPPORT)) -#define G_GDB_SUPPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_SUPPORT, GGdbSupportClass)) -#define G_IS_GDB_SUPPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_SUPPORT)) -#define G_GDB_SUPPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_SUPPORT, GGdbSupportClass)) - - -/* Indications quant à l'interfaçage client/serveur GDB (instance) */ -typedef struct _GGdbSupport GGdbSupport; - -/* Indications quant à l'interfaçage client/serveur GDB (classe) */ -typedef struct _GGdbSupportClass GGdbSupportClass; - - -/* Indique le type défini par la GLib pour les détails d'interfaçage GDB. */ -GType g_gdb_support_get_type(void); - -/* Crée une définition des détails d'interfaçage GDB. */ -GGdbSupport *g_gdb_support_new(GGdbStream *); - - - - - - - -char *g_gdb_support_get_id(const GGdbSupport *support); - - - - - - - - - -#endif /* _DEBUG_GDBRSP_SUPPORT_H */ diff --git a/src/debug/gdbrsp/target.c b/src/debug/gdbrsp/target.c deleted file mode 100644 index cf28a49..0000000 --- a/src/debug/gdbrsp/target.c +++ /dev/null @@ -1,950 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * target.c - gestion des éléments propres à l'architecture reconnue par GDB - * - * Copyright (C) 2016 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "target.h" - - -#include -#include -#include -#include -#include - - -#include "utils.h" -#include "../../common/cpp.h" -#include "../../common/extstr.h" -#include "../../common/xml.h" - - - -/* Définitions de registres */ - -typedef struct _arch_register_t -{ - char *name; /* Nom de registre */ - unsigned int size; /* Taille en bits */ - -} arch_register_t; - -typedef struct _target_cpu_t -{ - char *label; /* Désignation de l'ensemble */ - - arch_register_t *regs; /* Définition des registres */ - unsigned int count; /* Quantité de ces définitions */ - -} target_cpu_t; - - -/* Indications quant à l'interfaçage client/serveur GDB (instance) */ -struct _GGdbTarget -{ - GObject parent; /* A laisser en premier */ - - target_cpu_t **defs; /* Liste de définitions */ - size_t count; /* Taille de cette même liste */ - - bool read_single_register; /* Lecture spécifique permise ?*/ - bool write_single_register; /* Ecriture spécifique valide ?*/ - -}; - -/* Indications quant à l'interfaçage client/serveur GDB (classe) */ -struct _GGdbTargetClass -{ - GObjectClass parent; /* A laisser en premier */ - -}; - - -/* Initialise la classe des détails d'interfaçage GDB. */ -static void g_gdb_target_class_init(GGdbTargetClass *); - -/* Procède à l'initialisation des détails d'interfaçage GDB. */ -static void g_gdb_target_init(GGdbTarget *); - -/* Supprime toutes les références externes. */ -static void g_gdb_target_dispose(GGdbTarget *); - -/* Procède à la libération totale de la mémoire. */ -static void g_gdb_target_finalize(GGdbTarget *); - -/* Charge la définition d'un groupe de registres. */ -static bool g_gdb_target_load_register_definition(GGdbTarget *, GGdbStream *, const char *); - -/* Recherche l'indice correspondant à un registre donné. */ -static bool g_gdb_target_find_register_index(const GGdbTarget *, const char *, unsigned int *); - -/* Recherche la position correspondant à un registre donné. */ -static bool g_gdb_target_find_register_offset(const GGdbTarget *, unsigned int, size_t *); - - - -/* Indique le type défini par la GLib pour les détails d'interfaçage GDB. */ -G_DEFINE_TYPE(GGdbTarget, g_gdb_target, G_TYPE_OBJECT); - - -/****************************************************************************** -* * -* Paramètres : klass = classe de débogueur à initialiser. * -* * -* Description : Initialise la classe des détails d'interfaçage GDB. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_target_class_init(GGdbTargetClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_gdb_target_dispose; - object->finalize = (GObjectFinalizeFunc)g_gdb_target_finalize; - -} - - -/****************************************************************************** -* * -* Paramètres : target = instance de débogueur à préparer. * -* * -* Description : Procède à l'initialisation des détails d'interfaçage GDB. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_target_init(GGdbTarget *target) -{ - target->defs = NULL; - target->count = 0; - - target->read_single_register = true; - target->write_single_register = true; - -} - - -/****************************************************************************** -* * -* Paramètres : target = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_target_dispose(GGdbTarget *target) -{ - G_OBJECT_CLASS(g_gdb_target_parent_class)->dispose(G_OBJECT(target)); - -} - - -/****************************************************************************** -* * -* Paramètres : target = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_target_finalize(GGdbTarget *target) -{ - G_OBJECT_CLASS(g_gdb_target_parent_class)->finalize(G_OBJECT(target)); - -} - - -/****************************************************************************** -* * -* Paramètres : stream = flux de communication ouvert avec le débogueur. * -* * -* Description : Crée une définition des détails d'interfaçage GDB. * -* * -* Retour : Instance de détails mise en place ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GGdbTarget *g_gdb_target_new(GGdbStream *stream) -{ - GGdbTarget *result; /* Débogueur à retourner */ - GGdbPacket *packet; /* Paquet de communication GDB */ - bool status; /* Bilan d'une communication */ - - const char *data; /* Données reçues du serveur */ - size_t len; /* Quantité de ces données */ - char *xmldata; /* Données modifiables */ - xmlDocPtr xdoc; /* Document XML récupéré */ - xmlXPathContextPtr context; /* Contexte d'analyse associé */ - xmlXPathObjectPtr xobject; /* Cible d'une recherche */ - unsigned int i; /* Boucle de parcours */ - char *access; /* Chemin d'accès à un élément */ - char *xmlref; /* Référence de définitions */ - - - - - result = NULL; - - - //goto end; - - //goto skip; - - - packet = g_gdb_stream_get_free_packet(stream); - - g_gdb_packet_start_new_command(packet); - //g_gdb_packet_append(packet, "qTargeted:multiprocess+;xmlRegisters"); - g_gdb_packet_append(packet, "qXfer:features:read:target.xml:0,3fff"); - - //g_gdb_packet_append(packet, "qTargeted:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContTargeted+;QThreadEvents+;no-resumed+"); - - - - status = g_gdb_stream_send_packet(stream, packet); - if (!status) goto ggtn_failed; - - - - - g_gdb_stream_mark_packet_as_free(stream, packet); - - packet = g_gdb_stream_recv_packet(stream); - - g_gdb_packet_get_data(packet, &data, &len, NULL); - - printf(" << Réception de '%s'\n", data); - - /* Marqueur de fin placé au début ?! */ - if (data[0] != 'l') - goto ggtn_failed; - - xmldata = strdup(data + 1); - - /** - * On cherche à éviter la déconvenue suivante avec la libxml2 : - * - * noname.xml:12: namespace error : Namespace prefix xi on include is not defined - * - */ - - xmldata = strrpl(xmldata, "xi:include", "include"); - - if (!load_xml_from_memory(xmldata, len - 1, &xdoc, &context)) - goto ggtn_failed; - - - result = g_object_new(G_TYPE_GDB_TARGET, NULL); - - - xobject = get_node_xpath_object(context, "/target/include"); - - for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobject); i++) - { - asprintf(&access, "/target/include[position()=%u]", i + 1); - - xmlref = get_node_prop_value(context, access, "href"); - - free(access); - - if (xmlref != NULL) - { - printf("REF>> %s\n", xmlref); - /*static bool */g_gdb_target_load_register_definition(result, stream, xmlref); - - free(xmlref); - - } - - } - - if(xobject != NULL) - xmlXPathFreeObject(xobject); - - close_xml_file(xdoc, context); - - free(xmldata); - - - - - - - - - - - //result = g_object_new(G_TYPE_GDB_TARGET, NULL); - - - ggtn_failed: - - g_gdb_stream_mark_packet_as_free(stream, packet); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : target = ensemble d'informations liées à l'architecture. * -* stream = flux de communication ouvert avec le débogueur. * -* name = désignation des définitions de registres à charger. * -* * -* Description : Charge la définition d'un groupe de registres. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_target_load_register_definition(GGdbTarget *target, GGdbStream *stream, const char *name) -{ - bool result; /* Bilan à retourner */ - GGdbPacket *packet; /* Paquet de communication GDB */ - bool status; /* Bilan d'une communication */ - const char *data; /* Données reçues du serveur */ - size_t len; /* Quantité de ces données */ - xmlDocPtr xdoc; /* Document XML récupéré */ - xmlXPathContextPtr context; /* Contexte d'analyse associé */ - xmlXPathObjectPtr xobject; /* Cible d'une recherche */ - target_cpu_t *def; /* Nouvelle définition à lire */ - unsigned int i; /* Boucle de parcours */ - char *access; /* Chemin d'accès à un élément */ - char *type; /* Espèce de définition */ - - result = false; - - /* Envoi de la requête */ - - packet = g_gdb_stream_get_free_packet(stream); - - g_gdb_packet_start_new_command(packet); - - g_gdb_packet_append(packet, "qXfer:features:read:"); - g_gdb_packet_append(packet, name); - g_gdb_packet_append(packet, ":0,3fff"); - - status = g_gdb_stream_send_packet(stream, packet); - if (!status) goto ggtlrd_failed; - - g_gdb_stream_mark_packet_as_free(stream, packet); - - /* Réception de la réponse */ - - packet = g_gdb_stream_recv_packet(stream); - - g_gdb_packet_get_data(packet, &data, &len, NULL); - - //printf(">>>> '%s'\n", data); - - /* Marqueur de fin placé au début ?! */ - if (data[0] != 'l') - goto ggtlrd_failed; - - if (!load_xml_from_memory(data + 1, len - 1, &xdoc, &context)) - goto ggtlrd_failed; - - /* Chargement des définitions */ - - xobject = get_node_xpath_object(context, "/feature/*"); - - def = (target_cpu_t *)calloc(1, sizeof(target_cpu_t)); - - def->count = XPATH_OBJ_NODES_COUNT(xobject); - def->regs = (arch_register_t *)calloc(def->count, sizeof(arch_register_t)); - - for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobject); i++) - { - asprintf(&access, "/feature/*[position()=%u]", i + 1); - - type = get_node_name(context, access); - - if (strcmp(type, "reg") == 0) - { - def->regs[i].name = get_node_prop_value(context, access, "name"); - def->regs[i].size = atoi(get_node_prop_value(context, access, "bitsize")); - - //printf("load reg '%s' (%u)\n", def->regs[i].name, def->regs[i].size); - - } - - free(type); - - free(access); - - } - - if(xobject != NULL) - xmlXPathFreeObject(xobject); - - close_xml_file(xdoc, context); - - /* Intégration finale */ - - target->defs = (target_cpu_t **)realloc(target->defs, ++target->count * sizeof(target_cpu_t *)); - - target->defs[target->count - 1] = def; - - ggtlrd_failed: - - g_gdb_stream_mark_packet_as_free(stream, packet); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : target = ensemble d'informations liées à l'architecture. * -* group = éventuel groupe de registres ciblé ou NULL. * -* count = nombre d'éléments dans la liste de noms. [OUT] * -* * -* Description : Liste l'ensemble des registres appartenant à un groupe. * -* * -* Retour : Liste de noms à libérer de la mémoire après utilisation. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char **g_gdb_target_get_register_names(const GGdbTarget *target, const char *group, size_t *count) -{ - char **result; /* Désignations à retourner */ - unsigned int i; /* Boucle de parcours #1 */ - const target_cpu_t *rgrp; /* Groupe de registres */ - unsigned int j; /* Boucle de parcours #2 */ - - result = NULL; - - for (i = 0; i < target->count && result == NULL; i++) - { - rgrp = target->defs[i]; - - if (group != NULL) - { - if (strcmp(rgrp->label, group) != 0) - continue; - } - - *count = rgrp->count; - - result = (char **)calloc(*count, sizeof(char *)); - - for (j = 0; j < *count; j++) - result[j] = strdup(rgrp->regs[j].name); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : target = ensemble d'informations liées à l'architecture. * -* name = désignation du registre visé. * -* * -* Description : Indique la taille associée à un registre donné. * -* * -* Retour : Taille en bits, ou 0 si le registre n'a pas été trouvé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -unsigned int g_gdb_target_get_register_size(const GGdbTarget *target, const char *name) -{ - unsigned int result; /* Taille en bits à retourner */ - unsigned int i; /* Boucle de parcours #1 */ - const target_cpu_t *rgrp; /* Groupe de registres */ - unsigned int j; /* Boucle de parcours #2 */ - - result = 0; - - for (i = 0; i < target->count && result == 0; i++) - { - rgrp = target->defs[i]; - - for (j = 0; j < rgrp->count; j++) - if (strcmp(rgrp->regs[j].name, name) == 0) - result = rgrp->regs[j].size; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : target = ensemble d'informations liées à l'architecture. * -* reg = désignation humaine du register à consulter. * -* index = indice correspondant au registre pour GDB. [OUT] * -* * -* Description : Recherche l'indice correspondant à un registre donné. * -* * -* Retour : Bilan de l'opération : trouvaille ou échec ? * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_target_find_register_index(const GGdbTarget *target, const char *reg, unsigned int *index) -{ - bool result; /* Bilan à retourner */ - unsigned int i; /* Boucle de parcours #1 */ - unsigned int j; /* Boucle de parcours #2 */ - - result = false; - - *index = 0; - - for (i = 0; i < target->count && !result; i++) - for (j = 0; j < target->defs[i]->count && !result; j++) - { - if (strcmp(target->defs[i]->regs[j].name, reg) == 0) - result = true; - else - (*index)++; - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : target = ensemble d'informations liées à l'architecture. * -* index = indice correspondant au registre pour GDB. * -* offset = position de valeur du registre dans du texte. [OUT] * -* * -* Description : Recherche la position correspondant à un registre donné. * -* * -* Retour : Bilan de l'opération : trouvaille ou échec ? * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_target_find_register_offset(const GGdbTarget *target, unsigned int index, size_t *offset) -{ - unsigned int i; /* Boucle de parcours #1 */ - unsigned int j; /* Boucle de parcours #2 */ - - *offset = 0; - - for (i = 0; i < target->count && index > 0; i++) - for (j = 0; j < target->defs[i]->count && index > 0; j++) - { - assert(target->defs[i]->regs[j].size % 4 == 0); - - *offset += target->defs[i]->regs[j].size / 4; - - index--; - - } - - return (index == 0); - -} - - -/****************************************************************************** -* * -* Paramètres : target = ensemble d'informations liées à l'architecture. * -* stream = flux de communication ouvert avec le débogueur. * -* endian = boutisme de la cible. * -* reg = désignation humaine du register à consulter. * -* size = taille des données mises en jeu. * -* ... = emplacement de la valeur lue à conserver. [OUT] * -* * -* Description : Effectue la lecture d'un registre donné. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_gdb_target_read_register(GGdbTarget *target, GGdbStream *stream, SourceEndian endian, const char *reg, size_t size, ...) -{ - bool result; /* Bilan à retourner */ - unsigned int index; /* Indice du registre ciblé */ - GGdbPacket *packet; /* Paquet de communication */ - char cmd[sizeof(XSTR(UINT_MAX)) + 1]; /* Elément de requête */ - const char *data; /* Données reçues à analyser */ - size_t len; /* Quantité de ces données */ - const char *raw; /* Début de zone à relire */ - size_t offset; /* Position dans la masse */ - va_list ap; /* Liste variable d'arguments */ - uint8_t *val8; /* Valeur sur 8 bits */ - uint16_t *val16; /* Valeur sur 16 bits */ - uint16_t conv16; /* Valeur adaptée sur 16 bits */ - uint32_t *val32; /* Valeur sur 32 bits */ - uint32_t conv32; /* Valeur adaptée sur 32 bits */ - uint64_t *val64; /* Valeur sur 64 bits */ - uint64_t conv64; /* Valeur adaptée sur 64 bits */ - - result = g_gdb_target_find_register_index(target, reg, &index); - if (!result) goto ggtrr_error; - - /** - * Essai avec la méthode précise. - */ - - if (!target->read_single_register) - goto read_all_register_fallback; - - packet = g_gdb_stream_get_free_packet(stream); - - g_gdb_packet_start_new_command(packet); - g_gdb_packet_append(packet, "p"); - - snprintf(cmd, sizeof(cmd), "%x", index); - g_gdb_packet_append(packet, cmd); - - result = g_gdb_stream_send_packet(stream, packet); - - g_gdb_stream_mark_packet_as_free(stream, packet); - - if (!result) - goto ggtrr_error; - - /* Réception de la réponse */ - - packet = g_gdb_stream_recv_packet(stream); - - g_gdb_packet_get_data(packet, &data, &len, NULL); - - if (len != 0 && !is_error_code(data, len)) - raw = data; - - else - { - target->read_single_register = false; - - g_gdb_stream_mark_packet_as_free(stream, packet); - - read_all_register_fallback: - - /** - * Utilisation de la méthode de masse au besoin... - */ - - packet = g_gdb_stream_get_free_packet(stream); - - g_gdb_packet_start_new_command(packet); - g_gdb_packet_append(packet, "g"); - - result = g_gdb_stream_send_packet(stream, packet); - - g_gdb_stream_mark_packet_as_free(stream, packet); - - if (!result) - goto ggtrr_error; - - /* Réception de la réponse */ - - packet = g_gdb_stream_recv_packet(stream); - - g_gdb_packet_get_data(packet, &data, &len, NULL); - - result = g_gdb_target_find_register_offset(target, index, &offset); - - if (!result || offset > len) - goto ggtrr_exit; - - raw = data + offset; - len -= offset; - - } - - /* Lecture finale de la valeur recherchée */ - - va_start(ap, size); - - switch (size) - { - case 8: - val8 = va_arg(ap, uint8_t *); - result = hex_to_u8(raw, val8); - break; - - case 16: - val16 = va_arg(ap, uint16_t *); - result = hex_to_u16(raw, &conv16); - *val16 = from_u16(&conv16, endian); - break; - - case 32: - val32 = va_arg(ap, uint32_t *); - result = hex_to_u32(raw, &conv32); - *val32 = from_u32(&conv32, endian); - break; - - case 64: - val64 = va_arg(ap, uint64_t *); - result = hex_to_u64(raw, &conv64); - *val64 = from_u64(&conv64, endian); - break; - - default: - assert(false); - result = false; - break; - - } - - va_end(ap); - - ggtrr_exit: - - g_gdb_stream_mark_packet_as_free(stream, packet); - - ggtrr_error: - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : target = ensemble d'informations liées à l'architecture. * -* stream = flux de communication ouvert avec le débogueur. * -* endian = boutisme de la cible. * -* reg = désignation humaine du register à consulter. * -* size = taille des données mises en jeu. * -* ... = emplacement de la valeur à écrire. * -* * -* Description : Effectue l'écriture d'un registre donné. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_gdb_target_write_register(GGdbTarget *target, GGdbStream *stream, SourceEndian endian, const char *reg, size_t size, ...) -{ - bool result; /* Bilan d'opération à renvoyer*/ - va_list ap; /* Liste variable d'arguments */ - const uint8_t *val8; /* Valeur sur 8 bits */ - const uint16_t *val16; /* Valeur sur 16 bits */ - uint16_t conv16; /* Valeur adaptée sur 16 bits */ - const uint32_t *val32; /* Valeur sur 32 bits */ - uint32_t conv32; /* Valeur adaptée sur 32 bits */ - const uint64_t *val64; /* Valeur sur 64 bits */ - uint64_t conv64; /* Valeur adaptée sur 64 bits */ - char hexval[17]; /* Valeur sous forme hexa */ - unsigned int index; /* Indice du registre ciblé */ - GGdbPacket *packet; /* Paquet de communication */ - char cmd[sizeof(XSTR(UINT_MAX)) + 1]; /* Elément de requête */ - const char *data; /* Données reçues à analyser */ - size_t len; /* Quantité de ces données */ - char *new; /* Nouvelles valeurs générales */ - size_t offset; /* Position dans la masse */ - - /* Tronc commun : récupération de la valeur */ - - va_start(ap, size); - - switch (size) - { - case 8: - val8 = va_arg(ap, uint8_t *); - result = u8_to_hex(val8, hexval); - break; - - case 16: - val16 = va_arg(ap, uint16_t *); - conv16 = to_u16(val16, endian); - result = u16_to_hex(&conv16, hexval); - break; - - case 32: - val32 = va_arg(ap, uint32_t *); - conv32 = to_u32(val32, endian); - result = u32_to_hex(&conv32, hexval); - break; - - case 64: - val64 = va_arg(ap, uint64_t *); - conv64 = to_u64(val64, endian); - result = u16_to_hex(&conv64, hexval); - break; - - default: - assert(false); - result = false; - break; - - } - - va_end(ap); - - if (!result) - goto ggtwr_error; - - /* Préparation de la suite */ - - result = g_gdb_target_find_register_index(target, reg, &index); - if (!result) goto ggtwr_error; - - /** - * Essai avec la méthode précise. - */ - - if (!target->write_single_register) - goto write_all_register_fallback; - - packet = g_gdb_stream_get_free_packet(stream); - - g_gdb_packet_start_new_command(packet); - g_gdb_packet_append(packet, "P"); - - snprintf(cmd, sizeof(cmd), "%x", index); - g_gdb_packet_append(packet, cmd); - - g_gdb_packet_append(packet, "="); - - g_gdb_packet_append(packet, hexval); - - result = g_gdb_stream_send_packet(stream, packet); - - g_gdb_stream_mark_packet_as_free(stream, packet); - - if (!result) - goto ggtwr_error; - - /* Réception de la réponse */ - - packet = g_gdb_stream_recv_packet(stream); - - g_gdb_packet_get_data(packet, &data, &len, NULL); - - if (is_error_code(data, len) || strcmp(data, "OK") != 0) - { - target->write_single_register = false; - - g_gdb_stream_mark_packet_as_free(stream, packet); - - write_all_register_fallback: - - /** - * Utilisation de la méthode de masse au besoin... - */ - - /* Lecture de l'ensemble des registres */ - - packet = g_gdb_stream_get_free_packet(stream); - - g_gdb_packet_start_new_command(packet); - g_gdb_packet_append(packet, "g"); - - result = g_gdb_stream_send_packet(stream, packet); - - g_gdb_stream_mark_packet_as_free(stream, packet); - - if (!result) - goto ggtwr_error; - - /* Réception de la réponse et mise à jour */ - - packet = g_gdb_stream_recv_packet(stream); - - g_gdb_packet_get_data(packet, &data, &len, NULL); - - result = g_gdb_target_find_register_offset(target, index, &offset); - - if (!result || offset > len) - goto ggtwr_exit; - - new = (char *)malloc(len); - - memcpy(new, data, len); - memcpy(new + offset, hexval, strlen(hexval)); - - g_gdb_stream_mark_packet_as_free(stream, packet); - - /* Ecrasement de tous les registres */ - - packet = g_gdb_stream_get_free_packet(stream); - - g_gdb_packet_start_new_command(packet); - g_gdb_packet_append(packet, "G"); - - g_gdb_packet_append(packet, new); - free(new); - - result = g_gdb_stream_send_packet(stream, packet); - - g_gdb_stream_mark_packet_as_free(stream, packet); - - if (!result) - goto ggtwr_error; - - /* Réception de la réponse */ - - packet = g_gdb_stream_recv_packet(stream); - - g_gdb_packet_get_data(packet, &data, &len, NULL); - - result = (!is_error_code(data, len) && strcmp(data, "OK") == 0); - - } - - ggtwr_exit: - - g_gdb_stream_mark_packet_as_free(stream, packet); - - ggtwr_error: - - return result; - -} diff --git a/src/debug/gdbrsp/target.h b/src/debug/gdbrsp/target.h deleted file mode 100644 index bbdbec1..0000000 --- a/src/debug/gdbrsp/target.h +++ /dev/null @@ -1,72 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * target.h - prototypes pour la gestion des éléments propres à l'architecture reconnue par GDB - * - * Copyright (C) 2016 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _DEBUG_GDBRSP_TARGET_H -#define _DEBUG_GDBRSP_TARGET_H - - -#include -#include - - -#include "stream.h" -#include "../../common/endianness.h" - - - -#define G_TYPE_GDB_TARGET (g_gdb_target_get_type()) -#define G_GDB_TARGET(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_GDB_TARGET, GGdbTarget)) -#define G_IS_GDB_TARGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_GDB_TARGET)) -#define G_GDB_TARGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_TARGET, GGdbTargetClass)) -#define G_IS_GDB_TARGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_TARGET)) -#define G_GDB_TARGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_TARGET, GGdbTargetClass)) - - -/* Indications quant à l'interfaçage client/serveur GDB (instance) */ -typedef struct _GGdbTarget GGdbTarget; - -/* Indications quant à l'interfaçage client/serveur GDB (classe) */ -typedef struct _GGdbTargetClass GGdbTargetClass; - - -/* Indique le type défini par la GLib pour les détails d'interfaçage GDB. */ -GType g_gdb_target_get_type(void); - -/* Crée une définition des détails d'interfaçage GDB. */ -GGdbTarget *g_gdb_target_new(GGdbStream *); - -/* Liste l'ensemble des registres appartenant à un groupe. */ -char **g_gdb_target_get_register_names(const GGdbTarget *, const char *, size_t *); - -/* Indique la taille associée à un registre donné. */ -unsigned int g_gdb_target_get_register_size(const GGdbTarget *, const char *); - -/* Effectue la lecture d'un registre donné. */ -bool g_gdb_target_read_register(GGdbTarget *, GGdbStream *, SourceEndian, const char *, size_t, ...); - -/* Effectue l'écriture d'un registre donné. */ -bool g_gdb_target_write_register(GGdbTarget *, GGdbStream *, SourceEndian, const char *, size_t, ...); - - - -#endif /* _DEBUG_GDBRSP_TARGET_H */ diff --git a/src/debug/gdbrsp/tcp.c b/src/debug/gdbrsp/tcp.c deleted file mode 100644 index 8458dc6..0000000 --- a/src/debug/gdbrsp/tcp.c +++ /dev/null @@ -1,280 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * tcp.c - gestion des connexions TCP aux serveurs GDB. - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "tcp.h" - - -#include -#include -#include -#include -#include -#include - - -#include "stream-int.h" - - -#include "../../common/net.h" - - -/* Flux de communication TCP avec un serveur GDB (instance) */ -struct _GGdbTcpClient -{ - GGdbStream parent; /* A laisser en premier */ - -}; - - -/* Flux de communication TCP avec un serveur GDB (classe) */ -struct _GGdbTcpClientClass -{ - GGdbStreamClass parent; /* A laisser en premier */ - -}; - - -/* Initialise la classe des flux de communication TCP avec GDB. */ -static void g_gdb_tcp_client_class_init(GGdbTcpClientClass *); - -/* Initialise une instance de flux de communication avec GDB. */ -static void g_gdb_tcp_client_init(GGdbTcpClient *); - -/* Ouvre une connexion TCP à un serveur GDB. */ -//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); - -/* Réceptionne un octet de donnée d'un serveur GDB. */ -static bool g_gdb_tcp_client_recv_byte(GGdbTcpClient *, char *); - - - -/* Indique le type défini pour un flux de communication TCP avec un serveur GDB. */ -G_DEFINE_TYPE(GGdbTcpClient, g_gdb_tcp_client, G_TYPE_GDB_STREAM); - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des flux de communication TCP avec GDB. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_tcp_client_class_init(GGdbTcpClientClass *klass) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : client = instance à initialiser. * -* * -* Description : Initialise une instance de flux de communication avec GDB. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_gdb_tcp_client_init(GGdbTcpClient *client) -{ - GGdbStream *stream; /* Version parente */ - - stream = G_GDB_STREAM(client); - - stream->send_data = (send_gdb_data_fc)g_gdb_tcp_client_send_data; - stream->recv_byte = (recv_gdb_byte_fc)g_gdb_tcp_client_recv_byte; - -} - - -/****************************************************************************** -* * -* Paramètres : server = nom ou adresse du serveur à contacter. * -* port = port de connexion. * -* * -* Description : Ouvre une connexion TCP à un serveur GDB. * -* * -* Retour : Flux ouvert en lecture/écriture ou -1 en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ -#if 0 -static int connect_via_tcp(const char *server, const char *port) -{ - 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 */ - struct sockaddr_in addr; /* Infos de connexion distante */ - - 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; - - ret = getpeername(result, (struct sockaddr *)&addr, (socklen_t []){ sizeof(struct sockaddr_in) }); - if (ret == -1) - { - perror("getpeername"); - close(result); - return -1; - } - - printf("Connecté à %s:%hd\n", server, ntohs(addr.sin_port)); - - return result; - -} -#endif - -/****************************************************************************** -* * -* Paramètres : server = nom ou adresse du serveur à contacter. * -* port = port de connexion. * -* owner = débogueur tributaire du canal de communication. * -* * -* Description : Crée une nouvelle connexion TCP à un serveur GDB. * -* * -* Retour : Adresse de la structure mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GGdbStream *g_gdb_tcp_client_new(const char *server, const char *port, GGdbDebugger *owner) -{ - GGdbTcpClient *result; /* Structure à retourner */ - int sock; /* Flux ouvert à construire */ - - sock = connect_via_tcp(server, port, NULL); - if (sock == -1) return NULL; - - result = g_object_new(G_TYPE_GDB_TCP_CLIENT, NULL); - - G_GDB_STREAM(result)->fd = sock; - - G_GDB_STREAM(result)->owner = owner; - g_object_ref(G_OBJECT(owner)); - - if (!g_gdb_stream_listen(G_GDB_STREAM(result))) - goto ggtcn_error; - - return G_GDB_STREAM(result); - - ggtcn_error: - - return NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : client = flux ouvert en écriture à utiliser. * -* data = données à envoyer. * -* len = quantité de ces données. * -* * -* Description : Envoie des données à un serveur GDB. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_tcp_client_send_data(GGdbTcpClient *client, const char *data, size_t len) -{ - ssize_t sent; /* Quantité de données envoyée */ - - sent = send(G_GDB_STREAM(client)->fd, data, len, 0); - - //printf(" sent '%s'\n", data); - //printf(" sent ? %d vs %d\n", (int)sent, (int)len); - - return (sent == len); - -} - - -/****************************************************************************** -* * -* Paramètres : client = flux ouvert en lecture à utiliser. * -* data = donnée à recevoir. * -* * -* Description : Réceptionne un octet de donnée d'un serveur GDB. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_gdb_tcp_client_recv_byte(GGdbTcpClient *client, char *data) -{ - ssize_t got; /* Quantité de données reçue */ - - got = recv(G_GDB_STREAM(client)->fd, data, 1, 0); - - //printf(" got ? %d vs %d -> %c (0x%02hhx\n", (int)got, (int)1, *data, *data); - - return (got == 1); - -} diff --git a/src/debug/gdbrsp/tcp.h b/src/debug/gdbrsp/tcp.h deleted file mode 100644 index 3472fd2..0000000 --- a/src/debug/gdbrsp/tcp.h +++ /dev/null @@ -1,57 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * tcp.h - prototypes pour la gestion des connexions TCP aux serveurs GDB. - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _DEBUG_GDBRSP_TCP_H -#define _DEBUG_GDBRSP_TCP_H - - -#include "gdb.h" -#include "stream.h" - - - -#define G_TYPE_GDB_TCP_CLIENT g_gdb_tcp_client_get_type() -#define G_GDB_TCP_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_gdb_tcp_client_get_type(), GGdbTcpClient)) -#define G_IS_GDB_TCP_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_gdb_tcp_client_get_type())) -#define G_GDB_TCP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GDB_TCP_CLIENT, GGdbTcpClientClass)) -#define G_IS_GDB_TCP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GDB_TCP_CLIENT)) -#define G_GDB_TCP_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GDB_TCP_CLIENT, GGdbTcpClientClass)) - - -/* Flux de communication TCP avec un serveur GDB (instance) */ -typedef struct _GGdbTcpClient GGdbTcpClient; - -/* Flux de communication TCP avec un serveur GDB (classe) */ -typedef struct _GGdbTcpClientClass GGdbTcpClientClass; - - - -/* Indique le type défini pour un flux de communication TCP avec un serveur GDB. */ -GType g_gdb_tcp_client_get_type(void); - -/* Crée une nouvelle connexion TCP à un serveur GDB. */ -GGdbStream *g_gdb_tcp_client_new(const char *, const char *, GGdbDebugger *); - - - -#endif /* _DEBUG_GDBRSP_TCP_H */ diff --git a/src/debug/gdbrsp/utils.c b/src/debug/gdbrsp/utils.c deleted file mode 100644 index 1088e51..0000000 --- a/src/debug/gdbrsp/utils.c +++ /dev/null @@ -1,354 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * utils.h - fonctions qui simplifient la vie dans les interactions avec un serveur GDB - * - * Copyright (C) 2016 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "utils.h" - - -#include -#include -#include -#include -#include -#include - - - -/****************************************************************************** -* * -* Paramètres : data = données à inspecter. * -* len = quantité de ces données. * -* * -* Description : Indique si les données correspondent à un code d'erreur. * -* * -* Retour : Bilan de l'analyse. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool is_error_code(const char *data, size_t len) -{ - bool result; /* Bilan à retourner */ - - result = (len == 3); - - if (result) - result = (data[0] == 'E' && isdigit(data[1]) && isdigit(data[2])); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : data = données à analyser. * -* size = taille de ces données. * -* byte = statut de sortie d'un programme. [OUT] * -* * -* Description : Relit une valeur sur 8 bits et deux lettres. * -* * -* Retour : Bilan de la lecture. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool read_fixed_byte(const char *data, size_t len, uint8_t *byte) -{ - bool result; /* Bilan à retourner */ - const char *iter; /* Boucle de parcours #1 */ - size_t i; /* Boucle de parcours #2 */ - uint8_t nibble; /* Valeur affichée */ - - result = true; - - len = MIN(2, len); - - for (i = 0, iter = data; i < len; i++, iter++) - { - switch (*iter) - { - case '0' ... '9': - nibble = *iter - '0'; - break; - - case 'a' ... 'f': - nibble = *iter - 'a' + 10; - break; - - case 'A' ... 'F': - nibble = *iter - 'A' + 10; - break; - - default: - result = false; - break; - - } - - if (!result) - break; - - if (i == 0) - *byte = (nibble << 4); - else - *byte |= nibble; - - } - - if (result) - result = (i == 2); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : hex = tampon d'origine assez grand. * -* size = taille de la valeur à considérer pour les travaux. * -* value = valeur sur XX bits à transcrire. [OUT] * -* * -* Description : Traduit en valeur sur XX bits une forme textuelle. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool hex_to_any_u(const char *hex, size_t size, ...) -{ - bool result; /* Bilan à retourner */ - va_list ap; /* Gestion de l'inconnue */ - uint8_t *value8; /* Valeur sur 8 bits */ - uint16_t *value16; /* Valeur sur 16 bits */ - uint32_t *value32; /* Valeur sur 32 bits */ - uint64_t *value64; /* Valeur sur 64 bits */ - uint8_t *iter; /* Boucle de parcours #1 */ - size_t i; /* Boucle de parcours #2 */ - char nibble; /* Valeur à afficher */ - - result = false; - - /* Récupération de la destination */ - - va_start(ap, size); - - switch (size) - { - case 1: - value8 = va_arg(ap, uint8_t *); - iter = value8; - break; - - case 2: - value16 = va_arg(ap, uint16_t *); - iter = (uint8_t *)value16; - break; - - case 4: - value32 = va_arg(ap, uint32_t *); - iter = (uint8_t *)value32; - break; - - case 8: - value64 = va_arg(ap, uint64_t *); - iter = (uint8_t *)value64; - break; - - default: - goto done; - break; - - } - - /* Lecture de la valeur */ - - for (i = 0; i < size; i++, iter++) - { - *iter = 0; - - nibble = hex[i * 2]; - - switch (nibble) - { - case '0' ... '9': - *iter = (nibble - '0') << 4; - break; - - case 'a' ... 'f': - *iter = (nibble - 'a' + 0xa) << 4; - break; - - case 'A' ... 'F': - *iter = (nibble - 'A' + 0xa) << 4; - break; - - default: - goto done; - break; - - } - - nibble = hex[i * 2 + 1]; - - switch (nibble) - { - case '0' ... '9': - *iter |= (nibble - '0'); - break; - - case 'a' ... 'f': - *iter |= (nibble - 'a' + 0xa); - break; - - case 'A' ... 'F': - *iter |= (nibble - 'A' + 0xa); - break; - - default: - goto done; - break; - - } - - } - - result = (i == size); - - done: - - va_end(ap); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : size = taille de la valeur à considérer pour les travaux. * -* hex = tampon de destination assez grand. * -* value = valeur sur XX bits à transcrire. [OUT] * -* * -* Description : Traduit une valeur sur XX bits en forme textuelle. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool any_u_to_hex(size_t size, char hex[17], ...) -{ - bool result; /* Bilan à retourner */ - va_list ap; /* Gestion de l'inconnue */ - uint8_t *value8; /* Valeur sur 8 bits */ - uint16_t *value16; /* Valeur sur 16 bits */ - uint32_t *value32; /* Valeur sur 32 bits */ - uint64_t *value64; /* Valeur sur 64 bits */ - size_t i; /* Boucle de parcours #1 */ - const uint8_t *iter; /* Boucle de parcours #2 */ - uint8_t nibble; /* Valeur à retenir */ - - result = true; - - /* Récupération de la destination */ - - va_start(ap, hex); - - switch (size) - { - case 1: - value8 = va_arg(ap, uint8_t *); - iter = (const uint8_t *)value8; - break; - - case 2: - value16 = va_arg(ap, uint16_t *); - iter = (const uint8_t *)value16; - break; - - case 4: - value32 = va_arg(ap, uint32_t *); - iter = (const uint8_t *)value32; - break; - - case 8: - value64 = va_arg(ap, uint64_t *); - iter = (const uint8_t *)value64; - break; - - default: - result = false; - goto done; - break; - - } - - /* Lecture de la valeur */ - - for (i = 0; i < size; i++, iter++) - { - nibble = (*iter & 0xf0) >> 4; - - switch (nibble) - { - case 0x0 ... 0x9: - hex[i * 2] = '0' + nibble; - break; - - case 0xa ... 0xf: - hex[i * 2] = 'A' + nibble - 0xa; - break; - - } - - nibble = (*iter & 0x0f); - - switch (nibble) - { - case 0x0 ... 0x9: - hex[i * 2 + 1] = '0' + nibble; - break; - - case 0xa ... 0xf: - hex[i * 2 + 1] = 'A' + nibble - 0xa; - break; - - } - - } - - hex[size * 2] = '\0'; - - done: - - va_end(ap); - - return result; - -} diff --git a/src/debug/gdbrsp/utils.h b/src/debug/gdbrsp/utils.h deleted file mode 100644 index 833fe69..0000000 --- a/src/debug/gdbrsp/utils.h +++ /dev/null @@ -1,58 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * utils.h - prototypes pour les fonctions qui simplifient la vie dans les interactions avec un serveur GDB - * - * Copyright (C) 2016 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _DEBUG_GDBRSP_UTILS_H -#define _DEBUG_GDBRSP_UTILS_H - - -#include -#include -#include - - - -/* Indique si les données correspondent à un code d'erreur. */ -bool is_error_code(const char *, size_t); - -/* Relit une valeur sur 8 bits et deux lettres. */ -bool read_fixed_byte(const char *, size_t, uint8_t *); - -/* Traduit en valeur sur XX bits une forme textuelle. */ -bool hex_to_any_u(const char *, size_t, ...); - -#define hex_to_u8(h, v) hex_to_any_u(h, 1, v) -#define hex_to_u16(h, v) hex_to_any_u(h, 2, v) -#define hex_to_u32(h, v) hex_to_any_u(h, 4, v) -#define hex_to_u64(h, v) hex_to_any_u(h, 8, v) - -/* Traduit une valeur sur XX bits en forme textuelle. */ -bool any_u_to_hex(size_t, char [17], ...); - -#define u8_to_hex(v, h) any_u_to_hex(1, h, v) -#define u16_to_hex(v, h) any_u_to_hex(2, h, v) -#define u32_to_hex(v, h) any_u_to_hex(4, h, v) -#define u64_to_hex(v, h) any_u_to_hex(8, h, v) - - - -#endif /* _DEBUG_GDBRSP_UTILS_H */ diff --git a/src/format/Makefile.am b/src/format/Makefile.am index 9cabaee..1ab4825 100644 --- a/src/format/Makefile.am +++ b/src/format/Makefile.am @@ -31,4 +31,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -# SUBDIRS = java +SUBDIRS = diff --git a/src/format/java/Makefile.am b/src/format/java/Makefile.am deleted file mode 100644 index 0e40bfa..0000000 --- a/src/format/java/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ - -noinst_LTLIBRARIES = libformatjava.la - -libformatjava_la_SOURCES = \ - java-int.h java-int.c \ - java.h java.c \ - java_def.h \ - pool.h pool.c - - -# libformatjava_la_SOURCES = \ -# attribute.h attribute.c \ -# e_java.h e_java.c \ -# field.h field.c \ -# java-int.h \ -# method.h method.c \ -# pool.h pool.c - -libformatjava_la_LDFLAGS = - - -devdir = $(includedir)/chrysalide/$(subdir:src/%=%) - -dev_HEADERS = $(libformatjava_la_SOURCES:%c=) - - -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) - -AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/src/format/java/attribute.c b/src/format/java/attribute.c deleted file mode 100644 index 3e04ea9..0000000 --- a/src/format/java/attribute.c +++ /dev/null @@ -1,717 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * attribute.c - manipulation des attributs Java - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "attribute.h" - - -#include -#include - - -#include "java-int.h" -#include "pool.h" -#include "../../common/endianness.h" -#include "../../panel/log.h" - - - -#define _(str) str - - - -/* Charge les propriétés d'un attribut quelconque. */ -bool load_java_attribute(java_format *, java_attribute *, off_t *); - -/* Décharge les propriétés d'un attribut quelconque. */ -void unload_java_attribute(java_format *, java_attribute *); - -/* Charge les propriétés d'un attribut de valeur constante. */ -bool load_java_const_value_attribute(java_format *, const_value_attrib *, off_t *); - -/* Charge les propriétés d'un attribut de code. */ -bool load_java_code_attribute(java_format *, code_attrib *, off_t *); - -/* Décharge les propriétés d'un attribut de code. */ -void unload_java_code_attribute(java_format *, code_attrib *); - -/*Charge les propriétés d'un attribut d'exceptions lançables. */ -bool load_java_exceptions_attribute(java_format *, exceptions_attrib *, off_t *); - -/* Décharge les propriétés d'un attribut d'exceptions lançables. */ -void unload_java_exceptions_attribute(java_format *, exceptions_attrib *); - -/* Charge les propriétés d'un attribut de classes internes. */ -bool load_java_inner_classes_attribute(java_format *, inner_classes_attrib *, off_t *); - -/* Décharge les propriétés d'un attribut de classes internes. */ -void unload_java_inner_classes_attribute(java_format *, inner_classes_attrib *); - -/* Charge les propriétés d'un attribut de fichier source. */ -bool load_java_source_file_attribute(java_format *, source_file_attrib *, off_t *); - -/* Charge les propriétés d'un attribut de correspondance. */ -bool load_java_line_number_attribute(java_format *, line_number_attrib *, off_t *); - -/* Décharge les propriétés d'un attribut de correspondance. */ -void unload_java_line_number_attribute(java_format *, line_number_attrib *); - -/* Charge les propriétés d'un attribut de variables locales. */ -bool load_java_local_variables_attribute(java_format *, local_variables_attrib *, off_t *); - -/* Décharge les propriétés d'un attribut de variables locales. */ -void unload_java_local_variables_attribute(java_format *, local_variables_attrib *); - - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* pos = point de lecture à faire évoluer. [OUT] * -* attributes = tableau des attributs chargés. [OUT] * -* count = nombre d'éléments à charger. [OUT] * -* * -* Description : Charge les attribus d'un élément d'un binaire Java. * -* * -* Retour : true si l'opération s'est bien déroulée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_java_attributes(java_format *format, off_t *pos, java_attribute **attributes, uint16_t *count) -{ - bool result; /* Bilan à remonter */ - uint16_t i; /* Boucle de parcours */ - - result = read_u16(count, EXE_FORMAT(format)->content, pos, - EXE_FORMAT(format)->length, SRE_BIG); - - if (!result) return false; - - if (*count > 0) - { - *attributes = (java_attribute *)calloc(*count, sizeof(java_attribute)); - - for (i = 0; i < *count && result; i++) - result = load_java_attribute(format, &(*attributes)[i], pos); - - if (!result) - unload_java_attributes(format, *attributes, *count); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à libérer. * -* attributes = tableau des attributs à décharger. * -* count = nombre d'éléments à décharger. * -* * -* Description : Décharge les attribus d'un élément d'un binaire Java. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void unload_java_attributes(java_format *format, java_attribute *attributes, uint16_t count) -{ - uint16_t i; /* Boucle de parcours */ - - for (i = 0; i < count; i++) - unload_java_attribute(format, &attributes[i]); - - free(attributes); - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* attrib = élément à spécifier. [OUT] * -* pos = point de lecture à faire évoluer. [OUT] * -* * -* Description : Charge les propriétés d'un attribut quelconque. * -* * -* Retour : true si l'opération s'est bien déroulée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_java_attribute(java_format *format, java_attribute *attrib, off_t *pos) -{ - bool result; /* Bilan à retourner */ - uint16_t index; /* Indice du nom assimilé */ - const char *name; /* Version humainement lisible */ - uint32_t attrib_length; /* Taille de la charge utile */ - off_t saved_pos; /* Conservation de la position */ - - result = read_u16(&index, EXE_FORMAT(format)->content, pos, - EXE_FORMAT(format)->length, SRE_BIG); - - result &= get_java_pool_ut8_string(format, index, &name); - - if (result) - { - result = read_u32(&attrib_length, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - saved_pos = *pos; - - if (result && strcmp("ConstantValue", name) == 0) - { - attrib->type = JAT_CONSTANT_VALUE; - result = load_java_const_value_attribute(format, &attrib->info.const_value, pos); - } - - else if (result && strcmp("Code", name) == 0) - { - attrib->type = JAT_CODE; - result = load_java_code_attribute(format, &attrib->info.code, pos); - } - - else if (result && strcmp("Exceptions", name) == 0) - { - attrib->type = JAT_EXCEPTIONS; - result = load_java_exceptions_attribute(format, &attrib->info.exceptions, pos); - } - - else if (result && strcmp("InnerClasses", name) == 0) - { - attrib->type = JAT_INNER_CLASSES; - result = load_java_inner_classes_attribute(format, &attrib->info.inner_classes, pos); - } - - else if (result && strcmp("Synthetic", name) == 0) - attrib->type = JAT_SYNTHETIC; - - else if (result && strcmp("SourceFile", name) == 0) - { - attrib->type = JAT_LINE_NUMBER; - result = load_java_source_file_attribute(format, &attrib->info.source_file, pos); - } - - else if (result && strcmp("LineNumberTable", name) == 0) - { - attrib->type = JAT_SOURCE_FILE; - result = load_java_line_number_attribute(format, &attrib->info.line_number, pos); - } - - else if (result && strcmp("LocalVariableTable", name) == 0) - { - attrib->type = JAT_LOCAL_VARIABLES; - result = load_java_local_variables_attribute(format, &attrib->info.local_vars, pos); - } - - else if (result && strcmp("Deprecated", name) == 0) - attrib->type = JAT_DEPRECATED; - - else if (result) - { - result = false; - log_variadic_message(LMT_BAD_BINARY, _("Attribute name not supported: '%s'"), name); - } - - if (result && attrib_length != (*pos - saved_pos)) - log_variadic_message(LMT_BAD_BINARY, _("Size indication of the attribute '%s' not verified: %d vs %d"), - name, attrib_length, *pos - saved_pos); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* attrib = élément à libérer. * -* * -* Description : Décharge les propriétés d'un attribut quelconque. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void unload_java_attribute(java_format *format, java_attribute *attrib) -{ - switch (attrib->type) - { - case JAT_NONE: - break; - - case JAT_CONSTANT_VALUE: - break; - - case JAT_CODE: - unload_java_code_attribute(format, &attrib->info.code); - break; - - case JAT_EXCEPTIONS: - unload_java_exceptions_attribute(format, &attrib->info.exceptions); - break; - - case JAT_INNER_CLASSES: - unload_java_inner_classes_attribute(format, &attrib->info.inner_classes); - break; - - case JAT_SYNTHETIC: - break; - - case JAT_SOURCE_FILE: - break; - - case JAT_LINE_NUMBER: - unload_java_line_number_attribute(format, &attrib->info.line_number); - break; - - case JAT_LOCAL_VARIABLES: - unload_java_local_variables_attribute(format, &attrib->info.local_vars); - break; - - case JAT_DEPRECATED: - break; - - } - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* attrib = élément à spécifier. [OUT] * -* pos = point de lecture à faire évoluer. [OUT] * -* * -* Description : Charge les propriétés d'un attribut de valeur constante. * -* * -* Retour : true si l'opération s'est bien déroulée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_java_const_value_attribute(java_format *format, const_value_attrib *attrib, off_t *pos) -{ - bool result; /* Bilan à retourner */ - - result = read_u16(&attrib->const_value_index, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* attrib = élément à spécifier. [OUT] * -* pos = point de lecture à faire évoluer. [OUT] * -* * -* Description : Charge les propriétés d'un attribut de code. * -* * -* Retour : true si l'opération s'est bien déroulée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_java_code_attribute(java_format *format, code_attrib *attrib, off_t *pos) -{ - bool result; /* Bilan à retourner */ - uint16_t i; /* Boucle de parcours */ - - result = read_u16(&attrib->max_stack, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - result &= read_u16(&attrib->max_locals, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - result &= read_u32(&attrib->code_length, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - result &= ((*pos + attrib->code_length) <= EXE_FORMAT(format)->length); - - if (result) - { - attrib->content = *pos; - *pos += attrib->code_length; - } - - result &= read_u16(&attrib->exceptions_count, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - if (result && attrib->exceptions_count > 0) - { - attrib->exceptions = (code_exception *)calloc(attrib->exceptions_count, sizeof(code_exception)); - - for (i = 0; i < attrib->exceptions_count && result; i++) - { - result &= read_u16(&attrib->exceptions[i].start_pc, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - result &= read_u16(&attrib->exceptions[i].end_pc, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - result &= read_u16(&attrib->exceptions[i].handler_pc, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - result &= read_u16(&attrib->exceptions[i].catch_type, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - } - - } - - result &= load_java_attributes(format, pos, &attrib->attributes, &attrib->attributes_count); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* attrib = élément à libérer de la mémoire. * -* * -* Description : Décharge les propriétés d'un attribut de code. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void unload_java_code_attribute(java_format *format, code_attrib *attrib) -{ - if (attrib->exceptions != NULL) - free(attrib->exceptions); - - if (attrib->attributes != NULL) - unload_java_attributes(format, attrib->attributes, attrib->attributes_count); - -} - - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* attrib = élément à spécifier. [OUT] * -* pos = point de lecture à faire évoluer. [OUT] * -* * -* Description : Charge les propriétés d'un attribut d'exceptions lançables. * -* * -* Retour : true si l'opération s'est bien déroulée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_java_exceptions_attribute(java_format *format, exceptions_attrib *attrib, off_t *pos) -{ - bool result; /* Bilan à retourner */ - uint16_t i; /* Boucle de parcours */ - - result = read_u16(&attrib->throw_count, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - if (result && attrib->throw_count > 0) - { - attrib->throw = (uint16_t *)calloc(attrib->throw_count, sizeof(uint16_t)); - - for (i = 0; i < attrib->throw_count && result; i++) - result &= read_u16(&attrib->throw[i], EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* attrib = élément à libérer de la mémoire. * -* * -* Description : Décharge les propriétés d'un attribut d'exceptions lançables.* -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void unload_java_exceptions_attribute(java_format *format, exceptions_attrib *attrib) -{ - if (attrib->throw != NULL) - free(attrib->throw); - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* attrib = élément à spécifier. [OUT] * -* pos = point de lecture à faire évoluer. [OUT] * -* * -* Description : Charge les propriétés d'un attribut de classes internes. * -* * -* Retour : true si l'opération s'est bien déroulée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_java_inner_classes_attribute(java_format *format, inner_classes_attrib *attrib, off_t *pos) -{ - bool result; /* Bilan à retourner */ - uint16_t i; /* Boucle de parcours */ - - result = read_u16(&attrib->classes_count, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - if (result && attrib->classes_count > 0) - { - attrib->classes = (inner_class *)calloc(attrib->classes_count, sizeof(inner_class)); - - for (i = 0; i < attrib->classes_count && result; i++) - { - result &= read_u16(&attrib->classes[i].inner_class_info_index, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - result &= read_u16(&attrib->classes[i].outer_class_info_index, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - result &= read_u16(&attrib->classes[i].inner_name_index, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - result &= read_u16((uint16_t *)&attrib->classes[i].access, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* attrib = élément à libérer de la mémoire. * -* * -* Description : Décharge les propriétés d'un attribut de classes internes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void unload_java_inner_classes_attribute(java_format *format, inner_classes_attrib *attrib) -{ - if (attrib->classes != NULL) - free(attrib->classes); - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* attrib = élément à spécifier. [OUT] * -* pos = point de lecture à faire évoluer. [OUT] * -* * -* Description : Charge les propriétés d'un attribut de fichier source. * -* * -* Retour : true si l'opération s'est bien déroulée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_java_source_file_attribute(java_format *format, source_file_attrib *attrib, off_t *pos) -{ - bool result; /* Bilan à retourner */ - - result = read_u16(&attrib->source_file_index, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* attrib = élément à spécifier. [OUT] * -* pos = point de lecture à faire évoluer. [OUT] * -* * -* Description : Charge les propriétés d'un attribut de correspondance. * -* * -* Retour : true si l'opération s'est bien déroulée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_java_line_number_attribute(java_format *format, line_number_attrib *attrib, off_t *pos) -{ - bool result; /* Bilan à retourner */ - uint16_t i; /* Boucle de parcours */ - - result = read_u16(&attrib->lines_count, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - if (result && attrib->lines_count > 0) - { - attrib->lines = (pc_and_line *)calloc(attrib->lines_count, sizeof(pc_and_line)); - - for (i = 0; i < attrib->lines_count && result; i++) - { - result &= read_u16(&attrib->lines[i].start_pc, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - result &= read_u16(&attrib->lines[i].number, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* attrib = élément à libérer de la mémoire. * -* * -* Description : Décharge les propriétés d'un attribut de correspondance. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void unload_java_line_number_attribute(java_format *format, line_number_attrib *attrib) -{ - if (attrib->lines != NULL) - free(attrib->lines); - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* attrib = élément à spécifier. [OUT] * -* pos = point de lecture à faire évoluer. [OUT] * -* * -* Description : Charge les propriétés d'un attribut de variables locales. * -* * -* Retour : true si l'opération s'est bien déroulée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_java_local_variables_attribute(java_format *format, local_variables_attrib *attrib, off_t *pos) -{ - bool result; /* Bilan à retourner */ - uint16_t i; /* Boucle de parcours */ - - result = read_u16(&attrib->vars_count, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - if (result && attrib->vars_count > 0) - { - attrib->vars = (local_variable *)calloc(attrib->vars_count, sizeof(local_variable)); - - for (i = 0; i < attrib->vars_count && result; i++) - { - result &= read_u16(&attrib->vars[i].start_pc, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - result &= read_u16(&attrib->vars[i].length, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - result &= read_u16(&attrib->vars[i].name_index, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - result &= read_u16(&attrib->vars[i].descriptor_index, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - result &= read_u16(&attrib->vars[i].index, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* attrib = élément à libérer de la mémoire. * -* * -* Description : Décharge les propriétés d'un attribut de variables locales. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void unload_java_local_variables_attribute(java_format *format, local_variables_attrib *attrib) -{ - if (attrib->vars != NULL) - free(attrib->vars); - -} diff --git a/src/format/java/attribute.h b/src/format/java/attribute.h deleted file mode 100644 index 155aa7e..0000000 --- a/src/format/java/attribute.h +++ /dev/null @@ -1,40 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * attribute.h - prototypes pour la manipulation des attributs Java - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _FORMAT_JAVA_ATTRIBUTE_H -#define _FORMAT_JAVA_ATTRIBUTE_H - - -#include "e_java.h" - - - -/* Charge les attribus d'un élément d'un binaire Java. */ -bool load_java_attributes(java_format *, off_t *, java_attribute **, uint16_t *); - -/* Décharge les attribus d'un élément d'un binaire Java. */ -void unload_java_attributes(java_format *, java_attribute *, uint16_t); - - - -#endif /* _FORMAT_JAVA_ATTRIBUTE_H */ diff --git a/src/format/java/e_java.c b/src/format/java/e_java.c deleted file mode 100644 index 7d05fa9..0000000 --- a/src/format/java/e_java.c +++ /dev/null @@ -1,284 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * e_java.c - support du format Java - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "e_java.h" - - -#include -#include - - -#include "attribute.h" -#include "field.h" -#include "java-int.h" -#include "method.h" -#include "pool.h" -#include "../../common/endianness.h" - - - - -/* Indique le type d'architecture visée par le format. */ -FormatTargetMachine get_java_target_machine(const java_format *); - - - -/* Fournit les références aux zones de code à analyser. */ -bin_part **get_java_default_code_parts(const java_format *, size_t *); - - -/* Fournit le prototype de toutes les routines détectées. */ -GBinRoutine **get_all_java_routines(const java_format *, size_t *); - - - - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à parcourir. * -* length = taille du contenu en question. * -* * -* Description : Indique si le format peut être pris en charge ici. * -* * -* Retour : true si la réponse est positive, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool java_is_matching(const uint8_t *content, off_t length) -{ - bool result; /* Bilan à faire connaître */ - - result = false; - - if (length >= 4) - result = (strncmp((const char *)content, "\xca\xfe\xba\xbe", 4) == 0); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à parcourir. * -* length = taille du contenu en question. * -* * -* Description : Prend en charge une nouvelle classe Java. * -* * -* Retour : Adresse de la structure mise en place ou NULL en cas d'échec.* -* * -* Remarques : - * -* * -******************************************************************************/ - -exe_format *load_java(const uint8_t *content, off_t length) -{ - java_format *result; /* Adresse à retourner */ - off_t pos; /* Point d'analyse */ - uint32_t magic; /* Identifiant Java */ - uint16_t i; /* Boucle de parcours */ - - result = (java_format *)calloc(1, sizeof(java_format)); - - EXE_FORMAT(result)->content = content; - EXE_FORMAT(result)->length = length; - - EXE_FORMAT(result)->get_target_machine = (get_target_machine_fc)get_java_target_machine; - EXE_FORMAT(result)->get_def_parts = (get_def_parts_fc)get_java_default_code_parts; - EXE_FORMAT(result)->get_all_routines = (get_all_routines_fc)get_all_java_routines; - - pos = 0; - - if (!read_u32(&magic, content, &pos, length, SRE_BIG)) - goto ldj_error; - - if (!read_u16(&result->minor_version, content, &pos, length, SRE_BIG)) - goto ldj_error; - - if (!read_u16(&result->major_version, content, &pos, length, SRE_BIG)) - goto ldj_error; - - if (!load_java_pool(result, &pos)) - goto ldj_error; - - if (!read_u16((uint16_t *)&result->access, content, &pos, length, SRE_BIG)) - goto ldj_error; - - if (!read_u16(&result->this_class, content, &pos, length, SRE_BIG)) - goto ldj_error; - - if (!read_u16(&result->super_class, content, &pos, length, SRE_BIG)) - goto ldj_error; - - if (!read_u16(&result->interfaces_count, content, &pos, length, SRE_BIG)) - goto ldj_error; - - for (i = 0; i < result->interfaces_count; i++) - if (!read_u16(&result->interfaces[i], content, &pos, length, SRE_BIG)) - goto ldj_error; - - if (!load_java_fields(result, &pos)) - goto ldj_error; - - if (!load_java_methods(result, &pos)) - goto ldj_error; - - if (!load_java_attributes(result, &pos, &result->attributes, &result->attributes_count)) - goto ldj_error; - - return EXE_FORMAT(result); - - ldj_error: - - unload_java(result); - - return NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à supprimer. * -* * -* Description : Efface la prise en charge une nouvelle classe Java. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void unload_java(java_format *format) -{ - if (format->pool_len > 0) - unload_java_pool(format); - - if (format->interfaces_count > 0) - free(format->interfaces); - - if (format->fields_count > 0) - unload_java_fields(format); - - if (format->methods_count > 0) - unload_java_methods(format); - - if (format->attributes_count > 0) - unload_java_attributes(format, format->attributes, format->attributes_count); - - free(format); - -} - - - - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* * -* Description : Indique le type d'architecture visée par le format. * -* * -* Retour : Identifiant de l'architecture ciblée par le format. * -* * -* Remarques : - * -* * -******************************************************************************/ - -FormatTargetMachine get_java_target_machine(const java_format *format) -{ - return FTM_JVM; - -} - - - - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* count = quantité de zones listées. [OUT] * -* * -* Description : Fournit les références aux zones de code à analyser. * -* * -* Retour : Zones de code à analyser. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bin_part **get_java_default_code_parts(const java_format *format, size_t *count) -{ - bin_part **result; /* Tableau à retourner */ - uint16_t i; /* Boucle de parcours */ - off_t offset; /* Position physique */ - off_t size; /* Taille de la partie */ - bin_part *part; /* Partie à intégrer à la liste*/ - - result = NULL; - *count = 0; - - for (i = 0; i < format->methods_count; i++) - if (find_java_method_code_part(&format->methods[i], &offset, &size)) - { - part = create_bin_part(); - - set_bin_part_values(part, offset, size, offset); - - result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *)); - result[*count - 1] = part; - - } - - return result; - -} - - - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* count = taille du tableau créé. [OUT] * -* * -* Description : Fournit le prototype de toutes les routines détectées. * -* * -* Retour : Tableau créé ou NULL si aucun symbole de routine trouvé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GBinRoutine **get_all_java_routines(const java_format *format, size_t *count) -{ - *count = 0; - - return NULL; - -} diff --git a/src/format/java/e_java.h b/src/format/java/e_java.h deleted file mode 100644 index 65befbd..0000000 --- a/src/format/java/e_java.h +++ /dev/null @@ -1,49 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * e_java.h - prototypes pour le support du format Java - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _FORMAT_JAVA_E_JAVA_H -#define _FORMAT_JAVA_E_JAVA_H - - -#include "../exe_format.h" - - -/* Description des attributs Java */ -typedef struct _java_attribute java_attribute; - -/* Description du format Java */ -typedef struct _java_format java_format; - - -/* Indique si le format peut être pris en charge ici. */ -bool java_is_matching(const uint8_t *, off_t); - -/* Prend en charge une nouvelle classe Java. */ -exe_format *load_java(const uint8_t *, off_t); - -/* Efface la prise en charge une nouvelle classe Java. */ -void unload_java(java_format *); - - - -#endif /* _FORMAT_JAVA_E_JAVA_H */ diff --git a/src/format/java/field.c b/src/format/java/field.c deleted file mode 100644 index e7df342..0000000 --- a/src/format/java/field.c +++ /dev/null @@ -1,158 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * field.c - gestion des champs Java - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "field.h" - - -#include - - -#include "attribute.h" -#include "java-int.h" -#include "../../common/endianness.h" - - - -/* Charge les propriétés d'un champ de classe. */ -bool load_java_field(java_format *, java_field *, off_t *); - -/* Décharge les propriétés d'un champ de classe. */ -void unload_java_field(java_format *, java_field *); - - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* pos = point de lecture à faire évoluer. [OUT] * -* * -* Description : Charge les champs d'un binaire Java. * -* * -* Retour : true si l'opération s'est bien déroulée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_java_fields(java_format *format, off_t *pos) -{ - bool result; /* Bilan à remonter */ - uint16_t i; /* Boucle de parcours */ - - result = read_u16(&format->fields_count, EXE_FORMAT(format)->content, pos, - EXE_FORMAT(format)->length, SRE_BIG); - - if (!result) return false; - - if (format->fields_count > 0) - { - format->fields = (java_field *)calloc(format->fields_count, sizeof(java_field)); - - for (i = 0; i < format->fields_count && result; i++) - result = load_java_field(format, &format->fields[i], pos); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à vider. * -* * -* Description : Décharge les champs d'un binaire Java. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void unload_java_fields(java_format *format) -{ - uint16_t i; /* Boucle de parcours */ - - for (i = 0; i < format->fields_count; i++) - unload_java_field(format, &format->fields[i]); - - free(format->fields); - - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* field = élément à spécifier. [OUT] * -* pos = point de lecture à faire évoluer. [OUT] * -* * -* Description : Charge les propriétés d'un champ de classe. * -* * -* Retour : true si l'opération s'est bien déroulée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_java_field(java_format *format, java_field *field, off_t *pos) -{ - bool result; /* Bilan à retourner */ - - result = read_u16((uint16_t *)&field->access, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - result &= read_u16(&field->name_index, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - result &= read_u16(&field->descriptor_index, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - result &= load_java_attributes(format, pos, - &field->attributes, &field->attributes_count); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* field = élément à libérer. * -* * -* Description : Décharge les propriétés d'un champ de classe. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void unload_java_field(java_format *format, java_field *field) -{ - if (field->attributes_count > 0) - unload_java_attributes(format, field->attributes, field->attributes_count); - -} diff --git a/src/format/java/field.h b/src/format/java/field.h deleted file mode 100644 index 686c13f..0000000 --- a/src/format/java/field.h +++ /dev/null @@ -1,40 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * field.h - prototypes pour la gestion des champs Java - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _FORMAT_JAVA_FIELD_H -#define _FORMAT_JAVA_FIELD_H - - -#include "e_java.h" - - - -/* Charge les champs d'un binaire Java. */ -bool load_java_fields(java_format *, off_t *); - -/* Décharge les champs d'un binaire Java. */ -void unload_java_fields(java_format *); - - - -#endif /* _FORMAT_JAVA_FIELD_H */ diff --git a/src/format/java/java-int.c b/src/format/java/java-int.c deleted file mode 100644 index c1c8aa5..0000000 --- a/src/format/java/java-int.c +++ /dev/null @@ -1,92 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * java-int.c - structures internes du format Java - * - * Copyright (C) 2010-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "java-int.h" - - -#include "pool.h" -#include "../../common/endianness.h" - - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* pos = position de début de lecture. [OUT] * -* header = structure lue à retourner. [OUT] * -* * -* Description : Procède à la lecture d'une en-tête de programme Java. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool read_java_header(const GJavaFormat *format, off_t *pos, java_header *header) -{ - bool result; /* Bilan à retourner */ - const bin_t *content; /* Contenu binaire à lire */ - off_t length; /* Taille totale du contenu */ - uint32_t magic; /* Identifiant Java */ - size_t i; /* Boucle de parcours */ - - result = true; - - content = NULL; //G_BIN_FORMAT(format)->content; - length = 0; //G_BIN_FORMAT(format)->length; - - result &= read_u32(&magic, content, pos, length, SRE_BIG); - printf("magic :: 0x%08x\n", magic); - result &= read_u16(&header->minor_version, content, pos, length, SRE_BIG); - result &= read_u16(&header->major_version, content, pos, length, SRE_BIG); - - printf("avant :: %d\n", result); - - result &= load_java_pool(format, pos); - - printf("après :: %d\n", result); - - result &= read_u16((uint16_t *)&header->access, content, pos, length, SRE_BIG); - result &= read_u16(&header->this_class, content, pos, length, SRE_BIG); - result &= read_u16(&header->super_class, content, pos, length, SRE_BIG); - result &= read_u16(&header->interfaces_count, content, pos, length, SRE_BIG); - -/* for (i = 0; i < header->interfaces_count; i++) */ -/* result &= read_u16(&header->interfaces[i], content, pos, length, SRE_BIG)) */ -/* goto ldj_error; */ - -/* result &= load_java_fields(result, pos); */ - -/* result &= load_java_methods(result, pos); */ - -/* result &= load_java_attributes(result, pos, &header->attributes, &header->attributes_count); */ - - return result; - -} - - - - - diff --git a/src/format/java/java-int.h b/src/format/java/java-int.h deleted file mode 100644 index 1636d1e..0000000 --- a/src/format/java/java-int.h +++ /dev/null @@ -1,66 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * java-int.h - prototypes pour les structures internes du format Java - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _FORMAT_JAVA_JAVA_INT_H -#define _FORMAT_JAVA_JAVA_INT_H - - -#include "java.h" -#include "java_def.h" -#include "../executable-int.h" - - - - - -/* Format d'exécutable Java (instance) */ -struct _GJavaFormat -{ - GExeFormat parent; /* A laisser en premier */ - - java_header header; /* En-tête du programme */ - -}; - -/* Format d'exécutable Java (classe) */ -struct _GJavaFormatClass -{ - GExeFormatClass parent; /* A laisser en premier */ - -}; - - - - - -/* Procède à la lecture d'une en-tête de programme Java. */ -bool read_java_header(const GJavaFormat *, off_t *, java_header *); - - - - - - - - -#endif /* _FORMAT_JAVA_JAVA_INT_H */ diff --git a/src/format/java/java.c b/src/format/java/java.c deleted file mode 100644 index dcd8299..0000000 --- a/src/format/java/java.c +++ /dev/null @@ -1,508 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * java.c - support du format Java - * - * Copyright (C) 2010-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "java.h" - - -#include - - -#include "java-int.h" - - - - - - - - - - - -/* Initialise la classe des formats d'exécutables Java. */ -static void g_java_format_class_init(GJavaFormatClass *); - -/* Initialise une instance de format d'exécutable Java. */ -static void g_java_format_init(GJavaFormat *); - -/* Supprime toutes les références externes. */ -static void g_java_format_dispose(GJavaFormat *); - -/* Procède à la libération totale de la mémoire. */ -static void g_java_format_finalize(GJavaFormat *); - -/* Indique le type d'architecture visée par le format. */ -static const char *g_java_format_get_target_machine(const GJavaFormat *); - - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à parcourir. * -* * -* Description : Indique si le format peut être pris en charge ici. * -* * -* Retour : true si la réponse est positive, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool java_is_matching(GBinContent *content) -{ - bool result; /* Bilan à faire connaître */ - vmpa2t addr; /* Tête de lecture initiale */ - char magic[4]; /* Idenfiant standard */ - - init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); - - result = g_binary_content_read_raw(content, &addr, 4, (bin_t *)magic); - - result &= (memcmp(magic, "\xca\xfe\xba\xbe", 4) == 0); - - return result; - -} - - -/* Indique le type défini pour un format d'exécutable Java. */ -G_DEFINE_TYPE(GJavaFormat, g_java_format, G_TYPE_EXE_FORMAT); - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des formats d'exécutables Java. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_java_format_class_init(GJavaFormatClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - GExeFormatClass *exe; /* Version en exécutable */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_java_format_dispose; - object->finalize = (GObjectFinalizeFunc)g_java_format_finalize; - - exe = G_EXE_FORMAT_CLASS(klass); - - exe->get_machine = (get_target_machine_fc)g_java_format_get_target_machine; - //exe->refine_portions = (refine_portions_fc)g_java_format_refine_portions; - - exe->translate_phys = (translate_phys_fc)g_exe_format_without_virt_translate_offset_into_vmpa; - exe->translate_virt = (translate_virt_fc)g_exe_format_without_virt_translate_address_into_vmpa; - -} - - -/****************************************************************************** -* * -* Paramètres : format = instance à initialiser. * -* * -* Description : Initialise une instance de format d'exécutable Java. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_java_format_init(GJavaFormat *format) -{ - -} - - -/****************************************************************************** -* * -* Paramètres : format = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_java_format_dispose(GJavaFormat *format) -{ - G_OBJECT_CLASS(g_java_format_parent_class)->dispose(G_OBJECT(format)); - -} - - -/****************************************************************************** -* * -* Paramètres : format = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_java_format_finalize(GJavaFormat *format) -{ - G_OBJECT_CLASS(g_java_format_parent_class)->finalize(G_OBJECT(format)); - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à parcourir. * -* length = taille du contenu en question. * -* * -* Description : Prend en charge un nouveau format Java. * -* * -* Retour : Adresse de la structure mise en place ou NULL en cas d'échec.* -* * -* Remarques : - * -* * -******************************************************************************/ - -GBinFormat *g_java_format_new(const bin_t *content, off_t length) -{ - GJavaFormat *result; /* Structure à retourner */ - off_t offset; /* Tête de lecture */ - - result = g_object_new(G_TYPE_JAVA_FORMAT, NULL); - - //g_binary_format_set_content(G_BIN_FORMAT(result), content, length); - - - offset = 0; - - if (!read_java_header(result, &offset, &result->header)) - { - /* TODO */ - return NULL; - } - - - return G_BIN_FORMAT(result); - -} - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* * -* Description : Indique le type d'architecture visée par le format. * -* * -* Retour : Identifiant de l'architecture ciblée par le format. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static const char *g_java_format_get_target_machine(const GJavaFormat *format) -{ - return "jvm"; - -} - - - - - - - - - - - - -#if 0 - -#include -#include - - -#include "attribute.h" -#include "field.h" -#include "java-int.h" -#include "method.h" -#include "pool.h" -#include "../../common/endianness.h" - - - - -/* Indique le type d'architecture visée par le format. */ -FormatTargetMachine get_java_target_machine(const java_format *); - - - -/* Fournit les références aux zones de code à analyser. */ -bin_part **get_java_default_code_parts(const java_format *, size_t *); - - -/* Fournit le prototype de toutes les routines détectées. */ -GBinRoutine **get_all_java_routines(const java_format *, size_t *); - - - - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à parcourir. * -* length = taille du contenu en question. * -* * -* Description : Indique si le format peut être pris en charge ici. * -* * -* Retour : true si la réponse est positive, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool java_is_matching(const uint8_t *content, off_t length) -{ - bool result; /* Bilan à faire connaître */ - - result = false; - - if (length >= 4) - result = (strncmp((const char *)content, "\xca\xfe\xba\xbe", 4) == 0); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à parcourir. * -* length = taille du contenu en question. * -* * -* Description : Prend en charge une nouvelle classe Java. * -* * -* Retour : Adresse de la structure mise en place ou NULL en cas d'échec.* -* * -* Remarques : - * -* * -******************************************************************************/ - -exe_format *load_java(const uint8_t *content, off_t length) -{ - java_format *result; /* Adresse à retourner */ - off_t pos; /* Point d'analyse */ - uint32_t magic; /* Identifiant Java */ - uint16_t i; /* Boucle de parcours */ - - result = (java_format *)calloc(1, sizeof(java_format)); - - EXE_FORMAT(result)->content = content; - EXE_FORMAT(result)->length = length; - - EXE_FORMAT(result)->get_target_machine = (get_target_machine_fc)get_java_target_machine; - EXE_FORMAT(result)->get_def_parts = (get_def_parts_fc)get_java_default_code_parts; - EXE_FORMAT(result)->get_all_routines = (get_all_routines_fc)get_all_java_routines; - - pos = 0; - - if (!read_u32(&magic, content, &pos, length, SRE_BIG)) - goto ldj_error; - - if (!read_u16(&result->minor_version, content, &pos, length, SRE_BIG)) - goto ldj_error; - - if (!read_u16(&result->major_version, content, &pos, length, SRE_BIG)) - goto ldj_error; - - if (!load_java_pool(result, &pos)) - goto ldj_error; - - if (!read_u16((uint16_t *)&result->access, content, &pos, length, SRE_BIG)) - goto ldj_error; - - if (!read_u16(&result->this_class, content, &pos, length, SRE_BIG)) - goto ldj_error; - - if (!read_u16(&result->super_class, content, &pos, length, SRE_BIG)) - goto ldj_error; - - if (!read_u16(&result->interfaces_count, content, &pos, length, SRE_BIG)) - goto ldj_error; - - for (i = 0; i < result->interfaces_count; i++) - if (!read_u16(&result->interfaces[i], content, &pos, length, SRE_BIG)) - goto ldj_error; - - if (!load_java_fields(result, &pos)) - goto ldj_error; - - if (!load_java_methods(result, &pos)) - goto ldj_error; - - if (!load_java_attributes(result, &pos, &result->attributes, &result->attributes_count)) - goto ldj_error; - - return EXE_FORMAT(result); - - ldj_error: - - unload_java(result); - - return NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à supprimer. * -* * -* Description : Efface la prise en charge une nouvelle classe Java. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void unload_java(java_format *format) -{ - if (format->pool_len > 0) - unload_java_pool(format); - - if (format->interfaces_count > 0) - free(format->interfaces); - - if (format->fields_count > 0) - unload_java_fields(format); - - if (format->methods_count > 0) - unload_java_methods(format); - - if (format->attributes_count > 0) - unload_java_attributes(format, format->attributes, format->attributes_count); - - free(format); - -} - - - - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* * -* Description : Indique le type d'architecture visée par le format. * -* * -* Retour : Identifiant de l'architecture ciblée par le format. * -* * -* Remarques : - * -* * -******************************************************************************/ - -FormatTargetMachine get_java_target_machine(const java_format *format) -{ - return FTM_JVM; - -} - - - - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* count = quantité de zones listées. [OUT] * -* * -* Description : Fournit les références aux zones de code à analyser. * -* * -* Retour : Zones de code à analyser. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bin_part **get_java_default_code_parts(const java_format *format, size_t *count) -{ - bin_part **result; /* Tableau à retourner */ - uint16_t i; /* Boucle de parcours */ - off_t offset; /* Position physique */ - off_t size; /* Taille de la partie */ - bin_part *part; /* Partie à intégrer à la liste*/ - - result = NULL; - *count = 0; - - for (i = 0; i < format->methods_count; i++) - if (find_java_method_code_part(&format->methods[i], &offset, &size)) - { - part = create_bin_part(); - - set_bin_part_values(part, offset, size, offset); - - result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *)); - result[*count - 1] = part; - - } - - return result; - -} - - - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* count = taille du tableau créé. [OUT] * -* * -* Description : Fournit le prototype de toutes les routines détectées. * -* * -* Retour : Tableau créé ou NULL si aucun symbole de routine trouvé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GBinRoutine **get_all_java_routines(const java_format *format, size_t *count) -{ - *count = 0; - - return NULL; - -} - -#endif diff --git a/src/format/java/java.h b/src/format/java/java.h deleted file mode 100644 index ad70e43..0000000 --- a/src/format/java/java.h +++ /dev/null @@ -1,63 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * java.h - prototypes pour le support du format Java - * - * Copyright (C) 2010-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _FORMAT_JAVA_JAVA_H -#define _FORMAT_JAVA_JAVA_H - - -#include -#include -#include - - -#include "../../core/formats.h" - - - -#define G_TYPE_JAVA_FORMAT g_java_format_get_type() -#define G_JAVA_FORMAT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_JAVA_FORMAT, GJavaFormat)) -#define G_IS_JAVA_FORMAT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_JAVA_FORMAT)) -#define G_JAVA_FORMAT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_JAVA_FORMAT, GJavaFormatClass)) -#define G_IS_JAVA_FORMAT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_JAVA_FORMAT)) -#define G_JAVA_FORMAT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_JAVA_FORMAT, GJavaFormatClass)) - - -/* Format d'exécutable Java (instance) */ -typedef struct _GJavaFormat GJavaFormat; - -/* Format d'exécutable Java (classe) */ -typedef struct _GJavaFormatClass GJavaFormatClass; - - -/* Indique si le format peut être pris en charge ici. */ -bool java_is_matching(GBinContent *); - -/* Indique le type défini pour un format d'exécutable Java. */ -GType g_java_format_get_type(void); - -/* Prend en charge un nouveau format Java. */ -GBinFormat *g_java_format_new(const bin_t *, off_t); - - - -#endif /* _FORMAT_JAVA_JAVA_H */ diff --git a/src/format/java/java_def.h b/src/format/java/java_def.h deleted file mode 100644 index 2b1da67..0000000 --- a/src/format/java/java_def.h +++ /dev/null @@ -1,418 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * java_def.h - liste des structures et constantes utilisées par le format Java - * - * Copyright (C) 2010-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _FORMAT_JAVA_JAVA_DEF_H -#define _FORMAT_JAVA_JAVA_DEF_H - - -#include - - - -/* Description des attributs Java */ -typedef struct _java_attribute java_attribute; - - - -/* ----------------------- ELEMENTS DU RESERVOIR A CONSTANTES ----------------------- */ - - -/* Types de données dans le réservoir (§4.4) */ -typedef enum _ConstantPoolTag -{ - CONSTANT_EMPTY = 0, /* Non initialisé ou sur 2 */ - - CONSTANT_CLASS = 7, /* Classe ou interface */ - CONSTANT_FIELD_REF = 9, /* Champ ou méthode */ - CONSTANT_METHOD_REF = 10, /* Champ ou méthode */ - CONSTANT_INTERFACE_METHOD_REF = 11, /* Champ ou méthode */ - CONSTANT_STRING = 8, /* Chaîne constante */ - CONSTANT_INTEGER = 3, /* Valeur entière */ - CONSTANT_FLOAT = 4, /* Valeur flottante */ - CONSTANT_LONG = 5, /* Valeur longue */ - CONSTANT_DOUBLE = 6, /* Valeur double */ - CONSTANT_NAME_AND_TYPE = 12, /* Prototype complet */ - CONSTANT_UTF8 = 1 /* Chaîne codée en UTF8 */ - -} ConstantPoolTag; - - -/* Représentation d'une classe ou d'une interface */ -typedef struct _class_info -{ - uint16_t name_index; /* Indice pour le nom */ - -} class_info; - -/* Représentation d'un champ ou d'une méthode */ -typedef struct _ref_info -{ - uint16_t class_index; /* Indice de la classe */ - uint16_t name_and_type_index; /* Prototype associé */ - -} ref_info; - -/* Représentation d'une chaîne constante */ -typedef struct _string_info -{ - uint16_t string_index; /* Indice de la valeur UTF8 */ - -} string_info; - -/* Représentation d'une valeur 'int' */ -typedef struct _integer_info -{ - uint32_t val; /* Valeur au format 'int' */ - -} integer_info; - -/* Représentation d'une valeur 'float' */ -typedef struct _float_info -{ - float val; /* Valeur au format 'float' */ - -} float_info; - -/* Représentation d'une valeur 'long' */ -typedef struct _long_info -{ - long val; /* Valeur au format 'long' */ - -} long_info; - -/* Représentation d'une valeur 'double' */ -typedef struct _double_info -{ - double val; /* Valeur au format 'double' */ - -} double_info; - -/* Représentation brève d'un champ ou d'une méthode */ -typedef struct _name_and_type_info -{ - uint16_t name_index; /* Indice du nom correspondant */ - uint16_t descriptor_index; /* Prototype associé */ - -} name_and_type_info; - -/* Représentation d'une chaîne codée en UTF8 */ -typedef struct _utf8_info -{ - char *bytes; /* Valeur de la chaîne */ - -} utf8_info; - - -/* Entrée du réservoir */ -typedef struct _constant_pool_entry -{ - ConstantPoolTag tag; /* Type d'entrée présente */ - - union - { - class_info class; - ref_info ref; - string_info string; - integer_info int_val; - float_info float_val; - long_info long_val; - double_info double_val; - name_and_type_info name_type; - utf8_info utf8; - - } info; /* Infos portées par l'entrée */ - -} constant_pool_entry; - - - -/* ------------------------ ATTRIBUTS POUR DES ELEMENTS JAVA ------------------------ */ - - -/* Types des attributs reconnus */ -typedef enum _JavaAttributeType -{ - JAT_NONE = 0, /* Attribu non chargé */ - - JAT_CONSTANT_VALUE, /* Valeur constante */ - JAT_CODE, /* Code exécutable */ - JAT_EXCEPTIONS, /* Exceptions remontables */ - JAT_INNER_CLASSES, /* Classes internes */ - JAT_SYNTHETIC, /* Membre non présent */ - JAT_SOURCE_FILE, /* Fichier source du code */ - JAT_LINE_NUMBER, /* Correspondances de débogage */ - JAT_LOCAL_VARIABLES, /* Variable(s) locale(s) */ - JAT_DEPRECATED /* Elément vieillot à oublier */ - -} JavaAttributeType; - -/* Représentation d'un attribut à valeur constante (§4.7.2) */ -typedef struct _const_value_attrib -{ - uint16_t const_value_index; /* Indice dans le réservoir */ - -} const_value_attrib; - -/* Représentation d'un attribut de code (§4.7.3) */ - -typedef struct _code_exception -{ - uint16_t start_pc; /* Début de la zone couverte */ - uint16_t end_pc; /* Fin de la zone couverte */ - uint16_t handler_pc; /* Début du gestionnaire */ - uint16_t catch_type; /* Indice du type d'exception */ - -} code_exception; - -typedef struct _code_attrib -{ - uint16_t max_stack; /* Taille maximale de la pile */ - uint16_t max_locals; /* Nombre de variables (!) */ - uint32_t code_length; /* Taille du code référencé */ - - off_t content; /* Début du code exécutable */ - - code_exception *exceptions; /* Exceptions gérées */ - uint16_t exceptions_count; /* Nombre de ces exceptions */ - - java_attribute *attributes; /* Attributs liés au code */ - uint16_t attributes_count; /* Nombre de ces attributs */ - -} code_attrib; - -/* Représentation d'un attribut fixant les exceptions remontables (§4.7.4) */ - -typedef struct _exceptions_attrib -{ - uint16_t *throw; /* Exceptions remontées */ - uint16_t throw_count; /* Nombre de ces exceptions */ - -} exceptions_attrib; - -/* Représentation d'un attribut présentant les classes internes (§4.7.5) */ - -typedef enum _InnerClassAccessFlags -{ - ICA_PUBLIC = 0x0001, /* Elément public */ - ICA_PRIVATE = 0x0002, /* Elément privé */ - ICA_PROTECTED = 0x0004, /* Elément sous protection */ - ICA_STATIC = 0x0008, /* Elément statique */ - ICA_FINAL = 0x0010, /* Elément défini un seule fois*/ - ICA_INTERFACE = 0x0200, /* Déclaration d'interface */ - ICA_ABSTRACT = 0x0400 /* Déclaré comme abstrait */ - -} InnerClassAccessFlags; - -typedef struct _inner_class -{ - uint16_t inner_class_info_index; /* Propriétés de la classe */ - uint16_t outer_class_info_index; /* Propriétés de la parente */ - uint16_t inner_name_index; /* Nom de la classe */ - InnerClassAccessFlags access; /* Droits d'accès */ - -} inner_class; - -typedef struct _inner_classes_attrib -{ - inner_class *classes; /* Classes internes */ - uint16_t classes_count; /* Nombre de ces classe */ - -} inner_classes_attrib; - -/* Représentation d'un fichier source (§4.7.7) */ -typedef struct _source_file_attrib -{ - uint16_t source_file_index; /* Indice dans le réservoir */ - -} source_file_attrib; - -/* Représentation des correspondances entre lignes et code (§4.7.8) */ - -typedef struct _pc_and_line -{ - uint16_t start_pc; /* Début de la zone visée */ - uint16_t number; /* Numéro de ligne du code */ - -} pc_and_line; - -typedef struct _line_number_attrib -{ - pc_and_line *lines; /* Correspondances code/source */ - uint16_t lines_count; /* Nombre de correspondances */ - -} line_number_attrib; - -/* Représentation des variables locales (§4.7.9) */ - -typedef struct _local_variable -{ - uint16_t start_pc; /* Position dans le code */ - uint16_t length; /* Taille de la variable */ - uint16_t name_index; /* Indice nominal de réservoir */ - uint16_t descriptor_index; /* Type de la variable */ - uint16_t index; /* Place dans la liste complète*/ - -} local_variable; - -typedef struct _local_variables_attrib -{ - local_variable *vars; /* Variables locales */ - uint16_t vars_count; /* Nombre de ces variables */ - -} local_variables_attrib; - -/* Description des attributs Java */ -struct _java_attribute -{ - JavaAttributeType type; /* Type d'attribut représenté */ - - union - { - const_value_attrib const_value; - code_attrib code; - exceptions_attrib exceptions; - inner_classes_attrib inner_classes; - source_file_attrib source_file; - line_number_attrib line_number; - local_variables_attrib local_vars; - - } info; /* Infos portées par l'attribut*/ - -}; - - - -/* ---------------------------- CHAMPS POUR CLASSES JAVA ---------------------------- */ - - -/* Types d'accès aux champs (§4.5) */ -typedef enum _FieldAccessFlags -{ - FAC_PUBLIC = 0x0001, /* Elément public */ - FAC_PRIVATE = 0x0002, /* Elément privé */ - FAC_PROTECTED = 0x0004, /* Elément sous protection */ - FAC_STATIC = 0x0008, /* Elément statique */ - FAC_FINAL = 0x0010, /* Elément défini un seule fois*/ - FAC_VOLATILE = 0x0040, /* Elément sans cache */ - FAC_TRANSIENT = 0x0080 /* Elément ni lu ni écrit... */ - -} FieldAccessFlags; - -/* Description d'un champ Java */ -typedef struct _java_field -{ - FieldAccessFlags access; /* Droits d'accès */ - - uint16_t name_index; /* Nom dans le réservoir */ - uint16_t descriptor_index; /* Prototype au même endroit */ - - java_attribute *attributes; /* Attributs liés au champ */ - uint16_t attributes_count; /* Nombre de ces attributs */ - -} java_field; - - - -/* --------------------------- METHODES POUR CLASSES JAVA --------------------------- */ - - -/* Types d'accès aux champs (§4.6) */ -typedef enum _MethodAccessFlags -{ - MAC_PUBLIC = 0x0001, /* Elément public */ - MAC_PRIVATE = 0x0002, /* Elément privé */ - MAC_PROTECTED = 0x0004, /* Elément sous protection */ - MAC_STATIC = 0x0008, /* Elément statique */ - MAC_FINAL = 0x0010, /* Elément défini un seule fois*/ - MAC_SYNCHRONIZED = 0x0020, /* Elément avec mutex natif */ - MAC_NATIVE = 0x0100, /* Elément conçu sans Java */ - MAC_ABSTRACT = 0x0400, /* Elément sans implantation */ - MAC_STRICT = 0x0800 /* Elément déclaré stricte FP */ - -} MethodAccessFlags; - -/* Description d'une méthode Java */ -typedef struct _java_method -{ - MethodAccessFlags access; /* Droits d'accès */ - - uint16_t name_index; /* Nom dans le réservoir */ - uint16_t descriptor_index; /* Prototype au même endroit */ - - java_attribute *attributes; /* Attributs liés à la méthode */ - uint16_t attributes_count; /* Nombre de ces attributs */ - -} java_method; - - - -/* ---------------------------- LISTE DES DROITS D'ACCES ---------------------------- */ - - -/* Types d'accès (§4.1) */ -typedef enum _ClassAccessFlags -{ - CAC_PUBLIC = 0x0001, /* Elément public */ - CAC_FINAL = 0x0010, /* Déclaré comme final */ - CAC_SUPER = 0x0020, /* Traitement spécial */ - CAC_INTERFACE = 0x0200, /* Déclaration d'interface */ - CAC_ABSTRACT = 0x0400 /* Déclaré comme abstrait */ - -} ClassAccessFlags; - - - -/* --------------------------- DESCRIPTION DU FORMAT JAVA --------------------------- */ - - -/* En-tête de tout programe Java */ -typedef struct _java_header -{ - uint16_t minor_version; /* Numéro de révision mineur */ - uint16_t major_version; /* Numéro de révision majeur */ - - constant_pool_entry *pool; /* Réservoir de constantes */ - uint16_t pool_len; /* Quantité de ces éléments */ - - ClassAccessFlags access; /* Type de classe/interface */ - - uint16_t this_class; /* Infos sur la classe */ - uint16_t super_class; /* Infos sur la classe parente */ - - uint16_t *interfaces; /* Interfaces intégrées */ - uint16_t interfaces_count; /* Nombre de ces interfaces */ - - java_field *fields; /* Champs de la classe */ - uint16_t fields_count; /* Nombre de champs présents */ - - java_method *methods; /* Méthodes de la classe */ - uint16_t methods_count; /* Nombre de méthodes listées */ - - java_attribute *attributes; /* Attributs liés à la classe */ - uint16_t attributes_count; /* Nombre de ces attributs */ - -} java_header; - - - -#endif /* _FORMAT_JAVA_JAVA_DEF_H */ diff --git a/src/format/java/method.c b/src/format/java/method.c deleted file mode 100644 index 371ba8c..0000000 --- a/src/format/java/method.c +++ /dev/null @@ -1,187 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * method.c - gestion des méthodes Java - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "method.h" - - -#include - - -#include "attribute.h" -#include "../../common/endianness.h" - - - -/* Charge les propriétés d'une méthode de classe. */ -bool load_java_method(java_format *, java_method *, off_t *); - -/* Décharge les propriétés d'une méthode de classe. */ -void unload_java_method(java_format *, java_method *); - - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* pos = point de lecture à faire évoluer. [OUT] * -* * -* Description : Charge les méthodes d'un binaire Java. * -* * -* Retour : true si l'opération s'est bien déroulée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_java_methods(java_format *format, off_t *pos) -{ - bool result; /* Bilan à remonter */ - uint16_t i; /* Boucle de parcours */ - - result = read_u16(&format->methods_count, EXE_FORMAT(format)->content, pos, - EXE_FORMAT(format)->length, SRE_BIG); - - if (!result) return false; - - if (format->methods_count > 0) - { - format->methods = (java_method *)calloc(format->methods_count, sizeof(java_method)); - - for (i = 0; i < format->methods_count && result; i++) - result = load_java_method(format, &format->methods[i], pos); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à vider. * -* * -* Description : Décharge les méthodes d'un binaire Java. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void unload_java_methods(java_format *format) -{ - uint16_t i; /* Boucle de parcours */ - - for (i = 0; i < format->methods_count; i++) - unload_java_method(format, &format->methods[i]); - - free(format->methods); - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* method = élément à spécifier. [OUT] * -* pos = point de lecture à faire évoluer. [OUT] * -* * -* Description : Charge les propriétés d'une méthode de classe. * -* * -* Retour : true si l'opération s'est bien déroulée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_java_method(java_format *format, java_method *method, off_t *pos) -{ - bool result; /* Bilan à retourner */ - - result = read_u16((uint16_t *)&method->access, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - result &= read_u16(&method->name_index, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - result &= read_u16(&method->descriptor_index, EXE_FORMAT(format)->content, - pos, EXE_FORMAT(format)->length, SRE_BIG); - - result &= load_java_attributes(format, pos, - &method->attributes, &method->attributes_count); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* method = élément à libérer. * -* * -* Description : Décharge les propriétés d'une méthode de classe. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void unload_java_method(java_format *format, java_method *method) -{ - if (method->attributes_count > 0) - unload_java_attributes(format, method->attributes, method->attributes_count); - -} - - -/****************************************************************************** -* * -* Paramètres : method = élément à traiter. * -* offset = position physique du code de la méthode. [OUT] * -* size = taille du code de la méthode. [OUT] * -* * -* Description : Retrouve le code binaire correspondant à une méthode. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool find_java_method_code_part(const java_method *method, off_t *offset, off_t *size) -{ - uint16_t i; /* Boucle de parcours */ - - for (i = 0; i < method->attributes_count; i++) - if (method->attributes[i].type == JAT_CODE) - { - *offset = method->attributes[i].info.code.content; - *size = method->attributes[i].info.code.code_length; - break; - } - - return (i < method->attributes_count); - -} diff --git a/src/format/java/method.h b/src/format/java/method.h deleted file mode 100644 index 35b04e1..0000000 --- a/src/format/java/method.h +++ /dev/null @@ -1,44 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * method.h - prototypes pour la gestion des méthodes Java - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _FORMAT_JAVA_METHOD_H -#define _FORMAT_JAVA_METHOD_H - - -#include "e_java.h" -#include "java-int.h" - - - -/* Charge les méthodes d'un binaire Java. */ -bool load_java_methods(java_format *, off_t *); - -/* Décharge les méthodes d'un binaire Java. */ -void unload_java_methods(java_format *); - -/* Retrouve le code binaire correspondant à une méthode. */ -bool find_java_method_code_part(const java_method *method, off_t *, off_t *); - - - -#endif /* _FORMAT_JAVA_METHOD_H */ diff --git a/src/format/java/pool.c b/src/format/java/pool.c deleted file mode 100644 index 625e9cc..0000000 --- a/src/format/java/pool.c +++ /dev/null @@ -1,474 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * pool.c - lecture du réservoir de constantes - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#include "pool.h" - - -#include -#include -#include - -#include "java-int.h" -#include "../../common/endianness.h" -#include "../../common/extstr.h" - - - -/* Charge les propriétés d'une constante du réservoir. */ -bool load_java_pool_entry(GJavaFormat *, constant_pool_entry *, off_t *); - -/* Fournit une entrée donnée du réservoir de constantes. */ -const constant_pool_entry *get_java_pool_entry(const GJavaFormat *, uint16_t, ConstantPoolTag); - - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* pos = point de lecture à faire évoluer. [OUT] * -* * -* Description : Charge le réservoir de constantes d'un binaire Java. * -* * -* Retour : true si l'opération s'est bien déroulée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_java_pool(GJavaFormat *format, off_t *pos) -{ - bool result; /* Bilan à remonter */ - uint16_t count; /* Nombre d'éléments présents */ - uint16_t i; /* Boucle de parcours */ - - result = false/*read_u16(&count, G_BIN_FORMAT(format)->content, pos, - G_BIN_FORMAT(format)->length, SRE_BIG)*/; -#if 0 - printf("Alloc %hu entries (result=%d)\n", count, result); - - format->header.pool_len = count - 1; - format->header.pool = (constant_pool_entry *)calloc(count - 1, sizeof(constant_pool_entry)); - - for (i = 1; i < count && result; i++) - { - result = load_java_pool_entry(format, &format->header.pool[i - 1], pos); - - if (format->header.pool[i - 1].tag == CONSTANT_LONG - || format->header.pool[i - 1].tag == CONSTANT_DOUBLE) - { - i++; - - /* On n'est jamais trop prudent */ - if (i < count) - format->header.pool[i - 1].tag = CONSTANT_EMPTY; - - } - - } -#endif - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à vider. * -* * -* Description : Décharge le réservoir de constantes d'un binaire Java. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void unload_java_pool(GJavaFormat *format) -{ - uint16_t i; /* Boucle de parcours */ - - for (i = 0; i < format->header.pool_len; i++) - switch (format->header.pool[i].tag) - { - case CONSTANT_EMPTY: - case CONSTANT_CLASS: - case CONSTANT_FIELD_REF: - case CONSTANT_METHOD_REF: - case CONSTANT_INTERFACE_METHOD_REF: - case CONSTANT_STRING: - case CONSTANT_INTEGER: - case CONSTANT_FLOAT: - case CONSTANT_LONG: - case CONSTANT_DOUBLE: - case CONSTANT_NAME_AND_TYPE: - break; - - case CONSTANT_UTF8: - free(format->header.pool[i].info.utf8.bytes); - break; - - } - - free(format->header.pool); - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* entry = élément à spécifier. [OUT] * -* pos = point de lecture à faire évoluer. [OUT] * -* * -* Description : Charge les propriétés d'une constante du réservoir. * -* * -* Retour : true si l'opération s'est bien déroulée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_java_pool_entry(GJavaFormat *format, constant_pool_entry *entry, off_t *pos) -{ - bool result; /* Bilan à retourner */ - uint8_t tag; /* Type de l'élément */ - uint32_t low_bytes; /* Octets de poids faible */ - uint32_t high_bytes; /* Octets de poids fort */ - uint64_t bits; /* Nombre lu sur 64 bits */ - int sign; /* Signe du nombre lu */ - int exponent; /* Exposant du nombre lu */ - uint64_t mantissa32; /* Mantisse du nombre lu 32b */ - uint64_t mantissa64; /* Mantisse du nombre lu 64b */ - uint16_t length; /* Taille d'une chaîne */ - - result = false/*read_u8(&tag, G_BIN_FORMAT(format)->content, pos, - G_BIN_FORMAT(format)->length, SRE_BIG)*/; -#if 0 - entry->tag = tag; - - switch (entry->tag) - { - case CONSTANT_CLASS: - result = read_u16(&entry->info.class.name_index, G_BIN_FORMAT(format)->content, - pos, G_BIN_FORMAT(format)->length, SRE_BIG); - break; - - case CONSTANT_FIELD_REF: - case CONSTANT_METHOD_REF: - case CONSTANT_INTERFACE_METHOD_REF: - - result = read_u16(&entry->info.ref.class_index, G_BIN_FORMAT(format)->content, - pos, G_BIN_FORMAT(format)->length, SRE_BIG); - result &= read_u16(&entry->info.ref.name_and_type_index, G_BIN_FORMAT(format)->content, - pos, G_BIN_FORMAT(format)->length, SRE_BIG); - - break; - - case CONSTANT_STRING: - result = read_u16(&entry->info.string.string_index, G_BIN_FORMAT(format)->content, - pos, G_BIN_FORMAT(format)->length, SRE_BIG); - break; - - case CONSTANT_INTEGER: - result = read_u32(&entry->info.int_val.val, G_BIN_FORMAT(format)->content, - pos, G_BIN_FORMAT(format)->length, SRE_BIG); - break; - - case CONSTANT_FLOAT: - - result = read_u32(&low_bytes, G_BIN_FORMAT(format)->content, - pos, G_BIN_FORMAT(format)->length, SRE_BIG); - - if (result) - { - if (low_bytes == 0x7f800000) - entry->info.float_val.val = INFINITY; - - else if (low_bytes == 0xff800000) - entry->info.float_val.val = /* -1* */INFINITY; - - else if ((low_bytes >= 0x7f800001 && low_bytes <= 0x7fffffff) - || (low_bytes >= 0xff800001 && low_bytes <= 0xffffffff)) - entry->info.float_val.val = NAN; - - else if (low_bytes == 0x00000000 || low_bytes == 0x80000000) - entry->info.float_val.val = 0; - - else - { - sign = (low_bytes & 0x80000000) ? -1 : 1; - exponent = (low_bytes >> 23) & 0xff; - mantissa32 = (exponent == 0 ? - (low_bytes & 0x7fffff) << 1 : - (low_bytes & 0x7fffff) | 0x800000); - - entry->info.float_val.val = pow(2, (exponent - 150)); - entry->info.float_val.val *= mantissa32; - entry->info.float_val.val *= sign; - - } - - } - - break; - - case CONSTANT_LONG: - - result = read_u32(&high_bytes, G_BIN_FORMAT(format)->content, - pos, G_BIN_FORMAT(format)->length, SRE_BIG); - result &= read_u32(&low_bytes, G_BIN_FORMAT(format)->content, - pos, G_BIN_FORMAT(format)->length, SRE_BIG); - - if (result) - { - entry->info.double_val.val = (uint64_t)high_bytes << 32; - entry->info.double_val.val += low_bytes; - } - - break; - - case CONSTANT_DOUBLE: - - result = read_u32(&high_bytes, G_BIN_FORMAT(format)->content, - pos, G_BIN_FORMAT(format)->length, SRE_BIG); - result &= read_u32(&low_bytes, G_BIN_FORMAT(format)->content, - pos, G_BIN_FORMAT(format)->length, SRE_BIG); - - if (result) - { - bits = (uint64_t)high_bytes << 32 | (uint64_t)low_bytes; - - if (bits == 0x7ff0000000000000ll) - entry->info.double_val.val = INFINITY; - - else if (bits == 0xfff0000000000000ll) - entry->info.double_val.val = /* -1* */INFINITY; - - else if ((bits >= 0x7ff0000000000001ll && bits <= 0x7fffffffffffffffll) - || (bits >= 0xfff0000000000001ll && bits <= 0xffffffffffffffffll)) - entry->info.double_val.val = NAN; - - else if (bits == 0x0000000000000000ll || bits == 0x8000000000000000ll) - entry->info.double_val.val = 0; - - else - { - sign = ((bits >> 63) == 0) ? 1 : -1; - exponent = (bits >> 52) & 0x7ffl; - mantissa64 = (exponent == 0 ? - (bits & 0xfffffffffffffll) << 1 : - (bits & 0xfffffffffffffll) | 0x10000000000000ll); - - entry->info.double_val.val = pow(2, (exponent - 1075)); - entry->info.double_val.val *= mantissa64; - entry->info.double_val.val *= sign; - - } - - } - - break; - - case CONSTANT_NAME_AND_TYPE: - - result = read_u16(&entry->info.name_type.name_index, G_BIN_FORMAT(format)->content, - pos, G_BIN_FORMAT(format)->length, SRE_BIG); - result &= read_u16(&entry->info.name_type.descriptor_index, G_BIN_FORMAT(format)->content, - pos, G_BIN_FORMAT(format)->length, SRE_BIG); - - break; - - case CONSTANT_UTF8: - - result = read_u16(&length, G_BIN_FORMAT(format)->content, - pos, G_BIN_FORMAT(format)->length, SRE_BIG); - - if (result) - { - entry->info.utf8.bytes = (char *)calloc(length + 1, sizeof(char)); - memcpy(entry->info.utf8.bytes, &G_BIN_FORMAT(format)->content[*pos], length); - *pos += length; - } - - break; - - default: - result = false; - break; - - } -#endif - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* index = indice de l'élément dont la valeur est à recupérer. * -* expected = type de l'élément à trouver à l'indice donné. * -* * -* Description : Fournit une entrée donnée du réservoir de constantes. * -* * -* Retour : Entrée du réservoir de constantes ou NULL en cas d'erreur. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const constant_pool_entry *get_java_pool_entry(const GJavaFormat *format, uint16_t index, ConstantPoolTag expected) -{ - const constant_pool_entry *result; /* Entrée à retourner */ - constant_pool_entry *entry; /* Entrée du réservoir visée */ - - result = NULL; - - if (/*index < 0 && FIXME */index <= format->header.pool_len); - { - entry = &format->header.pool[index - 1]; - - if (entry->tag == expected) - result = entry; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* index = indice de l'élément de la table à recupérer. * -* expected = type de l'élément à trouver à l'indice donné. * -* * -* Description : Construit une version humaine de référence. * -* * -* Retour : Référence construite ou NULL en cas de problème. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *build_reference_from_java_pool(const GJavaFormat *format, uint16_t index, JavaRefType expected) -{ - char *result; /* Chaîne humaine à retourner */ - const constant_pool_entry *entry; /* Entrée du réservoir visée 1 */ - const constant_pool_entry *subentry; /* Entrée du réservoir visée 2 */ - const char *tmp; /* Copie de chaîne intouchable */ - - result = NULL; - - switch (expected) - { - case JRT_FIELD: - entry = get_java_pool_entry(format, index, CONSTANT_FIELD_REF); - break; - case JRT_METHOD: - entry = get_java_pool_entry(format, index, CONSTANT_METHOD_REF); - break; - case JRT_INTERFACE_METHOD: - entry = get_java_pool_entry(format, index, CONSTANT_INTERFACE_METHOD_REF); - break; - default: - entry = NULL; - break; - } - - if (entry == NULL) - goto brfjp_error; - - /* Lieu parent où trouver la référence */ - - subentry = get_java_pool_entry(format, entry->info.ref.class_index, CONSTANT_CLASS); - - if (subentry == NULL) - goto brfjp_error; - - if (!get_java_pool_ut8_string(format, subentry->info.class.name_index, &tmp)) - goto brfjp_error; - - result = strdup(tmp); - - /* Champ proprement dit */ - - subentry = get_java_pool_entry(format, entry->info.ref.name_and_type_index, CONSTANT_NAME_AND_TYPE); - - if (subentry == NULL) - goto brfjp_error; - - if (!get_java_pool_ut8_string(format, subentry->info.name_type.name_index, &tmp)) - goto brfjp_error; - - result = stradd(result, "."); - result = stradd(result, tmp); - - /* Petites retouches finales */ - - result = strrpl(result, "/", "."); - result = strrpl(result, "<", "<"); - result = strrpl(result, ">", ">"); - - return result; - - brfjp_error: - - if (result != NULL) - free(result); - - return NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* index = indice de l'élément dont la valeur est à recupérer. * -* str = adresse où placer la chaîne de caractères trouvée. * -* * -* Description : Recherche une chaîne de caractères dans le réservoir. * -* * -* Retour : true si l'opération s'est bien déroulée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool get_java_pool_ut8_string(const GJavaFormat *format, uint16_t index, const char **str) -{ - bool result; /* Bilan à renvoyer */ - const constant_pool_entry *entry; /* Entrée du réservoir visée */ - - entry = get_java_pool_entry(format, index, CONSTANT_UTF8); - - result = (entry != NULL); - - if (result) - (*str) = entry->info.utf8.bytes; - - return result; - -} diff --git a/src/format/java/pool.h b/src/format/java/pool.h deleted file mode 100644 index 7f1a1db..0000000 --- a/src/format/java/pool.h +++ /dev/null @@ -1,56 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * pool.h - prototypes pour la lecture du réservoir de constantes - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see . - */ - - -#ifndef _FORMAT_JAVA_POOL_H -#define _FORMAT_JAVA_POOL_H - - -#include "java.h" - - - -/* Types de référence Java */ -typedef enum _JavaRefType -{ - JRT_FIELD, /* Champ */ - JRT_METHOD, /* Méthode */ - JRT_INTERFACE_METHOD /* Méthode d'interface */ - -} JavaRefType; - - -/* Charge le réservoir de constantes d'un binaire Java. xs*/ -bool load_java_pool(GJavaFormat *, off_t *); - -/* Décharge le réservoir de constantes d'un binaire Java. */ -void unload_java_pool(GJavaFormat *); - -/* Construit une version humaine de référence. */ -char *build_reference_from_java_pool(const GJavaFormat *, uint16_t, JavaRefType); - -/* Recherche une chaîne de caractères dans le réservoir. */ -bool get_java_pool_ut8_string(const GJavaFormat *, uint16_t, const char **); - - - -#endif /* _FORMAT_JAVA_POOL_H */ -- cgit v0.11.2-87-g4458