From 216a3d0121fabd678e50ea6b4fa2447ae9b921f0 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 12 Apr 2009 19:15:35 +0000 Subject: Created a debugging layout and introduced a heavier use of GLib. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@58 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 108 ++++++ configure.ac | 4 + src/Makefile.am | 6 +- src/analysis/Makefile.am | 4 + src/analysis/line-int.h | 88 +++++ src/analysis/line.c | 711 ++++++++-------------------------- src/analysis/line.h | 82 ++-- src/analysis/line_code.c | 283 ++++++++++++++ src/analysis/line_code.h | 59 +++ src/analysis/line_comment.c | 237 ++++++++++++ src/analysis/line_comment.h | 58 +++ src/analysis/line_prologue.c | 168 ++++++++ src/analysis/line_prologue.h | 60 +++ src/arch/Makefile.am | 2 +- src/arch/x86/Makefile.am | 2 +- src/arch/x86/instruction.h | 2 + src/arch/x86/op_int.c | 43 +++ src/arch/x86/op_jump.c | 37 ++ src/arch/x86/opcodes.h | 6 + src/arch/x86/processor.c | 2 + src/binary.c | 336 ++++++---------- src/binary.h | 21 +- src/debug/Makefile.am | 16 + src/debug/debugger-int.h | 74 ++++ src/debug/debuggers.c | 197 ++++++++++ src/debug/debuggers.h | 91 +++++ src/debug/ptrace/Makefile.am | 15 + src/debug/ptrace/options.c | 104 +++++ src/debug/ptrace/options.h | 50 +++ src/debug/ptrace/ptrace.c | 449 ++++++++++++++++++++++ src/debug/ptrace/ptrace.h | 55 +++ src/easygtk.c | 37 ++ src/easygtk.h | 3 + src/editor.c | 723 ++++++++++++++-------------------- src/format/elf/strings.c | 25 +- src/format/exe_format.c | 30 ++ src/format/exe_format.h | 4 +- src/gtkbinview.c | 227 ----------- src/gtkbinview.h | 69 ---- src/gtkext/Makefile.am | 13 +- src/gtkext/gtkbinview.c | 227 +++++++++++ src/gtkext/gtkbinview.h | 69 ++++ src/gtkext/gtksnippet.c | 896 +++++++++++++++++++++++++++++++++++++++++++ src/gtkext/gtksnippet.h | 156 ++++++++ src/gtksnippet.c | 835 ---------------------------------------- src/gtksnippet.h | 156 -------- src/pan_symbols.c | 2 +- src/panel/Makefile.am | 5 +- src/panel/log.c | 7 + src/panel/log.h | 1 + src/panel/panels.c | 2 + src/panel/panels.h | 1 + src/panel/registers.c | 236 ++++++++++++ src/panel/registers.h | 47 +++ 54 files changed, 4595 insertions(+), 2546 deletions(-) create mode 100644 src/analysis/line-int.h create mode 100644 src/analysis/line_code.c create mode 100644 src/analysis/line_code.h create mode 100644 src/analysis/line_comment.c create mode 100644 src/analysis/line_comment.h create mode 100644 src/analysis/line_prologue.c create mode 100644 src/analysis/line_prologue.h create mode 100755 src/debug/Makefile.am create mode 100644 src/debug/debugger-int.h create mode 100644 src/debug/debuggers.c create mode 100644 src/debug/debuggers.h create mode 100644 src/debug/ptrace/Makefile.am create mode 100644 src/debug/ptrace/options.c create mode 100644 src/debug/ptrace/options.h create mode 100644 src/debug/ptrace/ptrace.c create mode 100644 src/debug/ptrace/ptrace.h delete mode 100644 src/gtkbinview.c delete mode 100644 src/gtkbinview.h create mode 100644 src/gtkext/gtkbinview.c create mode 100644 src/gtkext/gtkbinview.h create mode 100644 src/gtkext/gtksnippet.c create mode 100644 src/gtkext/gtksnippet.h delete mode 100644 src/gtksnippet.c delete mode 100644 src/gtksnippet.h create mode 100644 src/panel/registers.c create mode 100644 src/panel/registers.h diff --git a/ChangeLog b/ChangeLog index 0fa7f66..53f81ef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,111 @@ +2009-04-12 Cyrille Bagard + + * configure.ac: + Create a file for GLib marshals. Add the new Makefiles from the + 'src/debug' and 'src/debug/ptrace' directories to AC_CONFIG_FILES. + + * src/analysis/line.c: + * src/analysis/line_code.c: + * src/analysis/line_code.h: + * src/analysis/line_comment.c: + * src/analysis/line_comment.h: + * src/analysis/line.h: + * src/analysis/line-int.h: + * src/analysis/line_prologue.c: + * src/analysis/line_prologue.h: + Refine by dividing lines into several files. + + * src/analysis/Makefile.am: + Add line*[ch], line_code.[ch], line_comment.[ch] and line_prologue.[ch] + to libanalysis_a_SOURCES. + + * src/arch/Makefile.am: + Add LIBGTK_CFLAGS to INCLUDES (for born dead registers board ; need + to be removed ?). + + * src/arch/x86/instruction.h: + Support new instructions: jb (0x7f) and int3 (0xcc). + + * src/arch/x86/Makefile.am: + Add LIBGTK_CFLAGS to INCLUDES (for born dead registers board ; need + to be removed ?). + + * src/arch/x86/opcodes.h: + * src/arch/x86/op_int.c: + * src/arch/x86/op_jump.c: + * src/arch/x86/processor.c: + Support new instructions: jb (0x7f) and int3 (0xcc). + + * src/binary.c: + * src/binary.h: + Update the code ; try to use more often the openida_binary structure. + + * src/debug/debugger-int.h: + * src/debug/debuggers.c: + * src/debug/debuggers.h: + * src/debug/Makefile.am: + * src/debug/ptrace/Makefile.am: + * src/debug/ptrace/options.c: + * src/debug/ptrace/options.h: + * src/debug/ptrace/ptrace.c: + * src/debug/ptrace/ptrace.h: + New entries: allow to debug using the ptrace() function. + + * src/easygtk.c: + * src/easygtk.h: + Fix the alignment when building GtkLabel. Create a wrapper for GtkEntry. + + * src/editor.c: + Add menus for debugging. Clean the code by removing old code running debug. + + * src/format/elf/strings.c: + Try to load even if there is no section. Fix a bug when duplicating + found strings. + + * src/format/exe_format.c: + * src/format/exe_format.h: + Change the way executable formats are loaded. + + * src/gtkbinview.c: + * src/gtkbinview.h: + Moved entries: move these files to src/gtkext/. + + * src/gtkext/gtksnippet.c: + * src/gtkext/gtksnippet.h: + Clean/update the code and fix some GCC warnings. + + * src/gtkext/Makefile.am: + Add the iodamarshal.[ch] files to BUILT_SOURCES, and gtkbinview.[ch], + gtksnippet.[ch], iodamarshal.[ch] to libgtkext_a_SOURCES. Use the + 'glib-genmarshal' command to generate iodamarshal.[ch]. + + * src/gtksnippet.c: + * src/gtksnippet.h: + Moved entries: move these files to src/gtkext/. + + * src/Makefile.am: + Remove the gtkbinview.[ch] and gtksnippet.[ch] files from + openida_SOURCES ; add the debug/libdebug.a and debug/ptrace/libdebugptrace.a + ones to openida_LDADD. + + * src/panel/log.c: + * src/panel/log.h: + Add a message type for debugging sessions. + + * src/panel/Makefile.am: + Add the registers.[ch] files to libpanel_a_SOURCES. + + * src/panel/panels.c: + * src/panel/panels.h: + Add a new type for the registers panel and register it. + + * src/panel/registers.c: + * src/panel/registers.h: + New entries: display registers while debugging. + + * src/pan_symbols.c: + Update the code: including gtkbinview.h -> including gtkext/gtkbinview.h. + 2009-04-05 Cyrille Bagard * src/common/macros.h: diff --git a/configure.ac b/configure.ac index 1b7bdfa..775e50d 100644 --- a/configure.ac +++ b/configure.ac @@ -187,6 +187,8 @@ AC_SUBST(LIBXML_LIBS) AC_CONFIG_FILES([stamp-h po/Makefile.in], [echo timestamp > stamp-h]) +AC_CONFIG_COMMANDS([marshal], [echo "VOID:UINT64,UINT64" > src/gtkext/iodamarshal.list]) + AC_CONFIG_FILES([Makefile pixmaps/Makefile src/Makefile @@ -194,6 +196,8 @@ AC_CONFIG_FILES([Makefile src/arch/Makefile src/arch/x86/Makefile src/common/Makefile + src/debug/Makefile + src/debug/ptrace/Makefile src/format/Makefile src/format/dwarf/Makefile src/format/elf/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index a3e4c74..da52127 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,8 +6,6 @@ openida_SOURCES = \ dlg_sections.h dlg_sections.c \ easygtk.h easygtk.c \ editor.c \ - gtkbinview.h gtkbinview.c \ - gtksnippet.h gtksnippet.c \ pan_strings.h pan_strings.c \ pan_symbols.h pan_symbols.c \ project.h project.c \ @@ -29,6 +27,8 @@ openida_LDFLAGS = $(LIBGTK_LIBS) -L/usr/X11R6/lib -ldl -lm $(LIBXML_LIBS) `pkg-c openida_LDADD = $(LIBINTL) \ arch/libarch.a \ arch/x86/libarchx86.a \ + debug/libdebug.a \ + debug/ptrace/libdebugptrace.a \ format/libformat.a \ format/dwarf/libformatdwarf.a \ format/elf/libformatelf.a \ @@ -41,4 +41,4 @@ openida_LDADD = $(LIBINTL) \ common/libcommon.a -SUBDIRS = analysis arch common format gtkext panel +SUBDIRS = analysis arch common debug format gtkext panel diff --git a/src/analysis/Makefile.am b/src/analysis/Makefile.am index df380b5..e5f7689 100755 --- a/src/analysis/Makefile.am +++ b/src/analysis/Makefile.am @@ -3,6 +3,10 @@ lib_LIBRARIES = libanalysis.a libanalysis_a_SOURCES = \ line.h line.c \ + line-int.h \ + line_code.h line_code.c \ + line_comment.h line_comment.c \ + line_prologue.h line_prologue.c \ prototype.h prototype.c \ variable.h variable.c diff --git a/src/analysis/line-int.h b/src/analysis/line-int.h new file mode 100644 index 0000000..142230e --- /dev/null +++ b/src/analysis/line-int.h @@ -0,0 +1,88 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * line-int.h - prototypes pour l'interface des représentations des lignes de rendu + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _ANALYSIS_LINE_INT_H +#define _ANALYSIS_LINE_INT_H + + +#include "line.h" + + +#include "../common/dllist.h" + + + +/* Méthode de mise à jour du nombre d'octets maximal par instruction. */ +typedef void (* get_bin_len_fc) (GRenderingLine *, off_t *); + +/* Méthode de mise à jour d'une ligne de représentation. */ +typedef void (* refresh_markup_fc) (GRenderingLine *); + + +/* Ligne de représentation générique (instance) */ +struct _GRenderingLine +{ + GObject parent; /* A laisser en premier */ + + DL_LIST_ITEM(link); /* Maillon de liste chaînée */ + + uint64_t offset; /* Position en mémoire/physique*/ + + RenderingLineType type; /* Type de représentation */ + RenderingLineFlag flags; /* Extension d'informations */ + + PangoLayout *layout; /* Moteur de rendu du code/txt */ + + get_bin_len_fc get_bin_len; /* Nbre d'octets représentés */ + off_t max_bin_len; /* Nombre global maximal */ + + refresh_markup_fc refresh_markup; /* Reconstruit la représentat° */ + +}; + + +#define lines_list_next_iter(iter, head) dl_list_next_iter(iter, head, GRenderingLine, link) +#define lines_list_add_tail(new, head) dl_list_add_tail(new, head, GRenderingLine, link) +#define lines_list_splice_before(pos, head1, head2) dl_list_splice_before(pos, head1, head2, GRenderingLine, link) +#define lines_list_for_each(pos, head) dl_list_for_each(pos, head, GRenderingLine, link) + + +/* Ligne de représentation générique (classe) */ +struct _GRenderingLineClass +{ + GObjectClass parent; /* A laisser en premier */ + + /* Signaux */ + + void (* rendering_line_flags_changed) (GRenderingLine *); + +}; + + + +/* Taille max d'une traduction */ +#define CODE_BUFFER_LEN 128 + + + +#endif /* _ANALYSIS_LINE_INT_H */ diff --git a/src/analysis/line.c b/src/analysis/line.c index 21f0fd5..4fc0ac5 100644 --- a/src/analysis/line.c +++ b/src/analysis/line.c @@ -24,6 +24,10 @@ #include "line.h" +#include "line-int.h" + + + #include #include #include @@ -40,121 +44,49 @@ extern GtkWidget *mywid; +/* Initialise la classe des lignes de représentation. */ +static void g_rendering_line_class_init(GRenderingLineClass *); +/* Initialise une instance de ligne de représentation. */ +static void g_rendering_line_init(GRenderingLine *); -/* Méthode de mise à jour du nombre d'octets maximal par instruction. */ -typedef void (* get_bin_len_fc) (rendering_line *, off_t *); - -/* Méthode de mise à jour d'une ligne de représentation. */ -typedef void (* refresh_markup_fc) (rendering_line *); - - - -/* Ligne de représentation générique */ -struct _rendering_line -{ - DL_LIST_ITEM(link); /* Maillon de liste chaînée */ - - uint64_t offset; /* Position en mémoire/physique*/ - - RenderingLineType type; /* Type de représentation */ - RenderingLineFlag flags; /* Extension d'informations */ - - PangoLayout *layout; /* Moteur de rendu du code/txt */ - - get_bin_len_fc get_bin_len; /* Nbre d'octets représentés */ - off_t max_bin_len; /* Nombre global maximal */ - - refresh_markup_fc refresh_markup; /* Reconstruit la représentat° */ - -}; - - -#define RENDERING_LINE(l) ((rendering_line *)l) - - -#define lines_list_next_iter(iter, head) dl_list_next_iter(iter, head, rendering_line, link) -#define lines_list_add_tail(new, head) dl_list_add_tail(new, head, rendering_line, link) -#define lines_list_splice_before(pos, head1, head2) dl_list_splice_before(pos, head1, head2, rendering_line, link) -#define lines_list_for_each(pos, head) dl_list_for_each(pos, head, rendering_line, link) - - -/* Procède à l'initialisation des bases d'une représentation. */ -void init_rendering_line(rendering_line *); - - - -/* ------------------------- LIGNE EN TETE DE DESASSEMBLAGE ------------------------- */ - - -/* Ligne de représentation de prologue */ -typedef struct _prologue_line -{ - rendering_line basic; /* A laisser en premier */ - - char *comment; /* Texte à afficher */ - -} prologue_line; - - -/* Met à jour la ligne de représentation de prologue. */ -void refresh_prologue_markup(prologue_line *); - - - -/* ----------------------- COMMENTAIRES SUR UNE LIGNE ENTIERE ----------------------- */ - - -/* Ligne de commantaires entière */ -typedef struct _comment_line -{ - rendering_line basic; /* A laisser en premier */ - - char *comment; /* Texte à afficher */ - const disass_options *options; /* Options de représentation */ - -} comment_line; -/* Met à jour la ligne de représentation de commentaires. */ -void refresh_comment_markup(comment_line *); +/* Indique le type définit pour une ligne de représentation. */ +G_DEFINE_TYPE(GRenderingLine, g_rendering_line, G_TYPE_OBJECT); -/* ------------------------ LIGNE DE CODE EN LANGAGE MACHINE ------------------------ */ - +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des lignes de représentation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ -/* Ligne de représentation de prologue */ -typedef struct _code_line +static void g_rendering_line_class_init(GRenderingLineClass *klass) { - rendering_line basic; /* A laisser en premier */ - - asm_instr *instr; /* Instruction représentée */ - const disass_options *options; /* Options de représentation */ - -} code_line; - - -/* Taille max d'une traduction */ -#define CODE_BUFFER_LEN 128 - - -/* Met à jour la nombre d'octets maximale par instruction. */ -void get_code_binary_len(code_line *, off_t *); - -/* Met à jour la ligne de représentation de code. */ -void refresh_code_markup(code_line *); - - - + g_signal_new("rendering-line-flags-changed", + G_TYPE_RENDERING_LINE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GRenderingLineClass, rendering_line_flags_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0, NULL); +} /****************************************************************************** * * -* Paramètres : line = adresse de la structure commune. * +* Paramètres : line = instance à initialiser. * * * -* Description : Procède à l'initialisation des bases d'une représentation. * +* Description : Initialise une instance de ligne de représentation. * * * * Retour : - * * * @@ -162,7 +94,7 @@ void refresh_code_markup(code_line *); * * ******************************************************************************/ -void init_rendering_line(rendering_line *line) +static void g_rendering_line_init(GRenderingLine *line) { DL_LIST_ITEM_INIT(&line->link); @@ -171,8 +103,25 @@ void init_rendering_line(rendering_line *line) line->get_bin_len = NULL; line->refresh_markup = NULL; +} +/****************************************************************************** +* * +* Paramètres : line = ligne dont les informations sont à consulter. * +* * +* Description : Fournit le type d'une ligne. * +* * +* Retour : Type de la ligne fournie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +RenderingLineType get_rendering_line_type(const GRenderingLine *line) +{ + return line->type; + } @@ -189,10 +138,12 @@ void init_rendering_line(rendering_line *line) * * ******************************************************************************/ -void add_rendering_line_flag(rendering_line *line, RenderingLineFlag flag) +void g_rendering_line_add_flag(GRenderingLine *line, RenderingLineFlag flag) { line->flags |= flag; + g_signal_emit_by_name(line, "rendering-line-flags-changed"); + } @@ -209,61 +160,67 @@ void add_rendering_line_flag(rendering_line *line, RenderingLineFlag flag) * * ******************************************************************************/ -void remove_rendering_line_flag(rendering_line *line, RenderingLineFlag flag) +void g_rendering_line_remove_flag(GRenderingLine *line, RenderingLineFlag flag) { line->flags &= ~flag; + g_signal_emit_by_name(line, "rendering-line-flags-changed"); + } /****************************************************************************** * * * Paramètres : line = ligne dont les informations sont à mettre à jour. * +* flag = extension d'information à ajouter ou retirer. * * * -* Description : Fournit les informations supplémentaires d'une ligne. * +* Description : Bascule l'état d'une information sur d'une ligne. * * * -* Retour : Extensions d'informations courantes. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -RenderingLineFlag get_rendering_line_flags(const rendering_line *line) +void g_rendering_line_toggle_flag(GRenderingLine *line, RenderingLineFlag flag) { - return line->flags; - -} + line->flags = (line->flags & ~flag) | (line->flags ^ flag); + g_signal_emit_by_name(line, "rendering-line-flags-changed"); +} /****************************************************************************** * * -* Paramètres : lines = liste de lignes à compléter, ou NULL. * -* line = nouvelle ligne à intégrer à l'ensemble. * +* Paramètres : line = ligne dont les informations sont à consulter. * * * -* Description : Ajoute une ligne à un ensemble existant. * +* Description : Fournit les informations supplémentaires d'une ligne. * * * -* Retour : - * +* Retour : Extensions d'informations courantes. * * * -* Remarques : La ligne est considérée comme étant insérée au bon endroit. * +* Remarques : - * * * ******************************************************************************/ -void add_line_to_rendering_lines(rendering_line **lines, rendering_line *line) +RenderingLineFlag g_rendering_line_get_flags(const GRenderingLine *line) { - lines_list_add_tail(line, lines); + return line->flags; } /****************************************************************************** * * -* Paramètres : lines = liste de lignes à compléter, ou NULL. * -* line = nouvelle ligne à intégrer à l'ensemble. * -* first = position de la ligne en cas d'adresse partagée. * +* Paramètres : line = adresse de la structure à représenter. * +* drawable = support de rendu pour le dessin. * +* gc = contexte graphique à utiliser. * +* x0 = abscisse de la zone de rendu (marge). * +* x1 = abscisse de la zone de rendu (texte). * +* y = ordonnée de la zone de rendu. * +* h = hauteur réservée pour la ligne. * * * -* Description : Insère une ligne dans un ensemble existant. * +* Description : Procède à l'initialisation des bases d'une représentation. * * * * Retour : - * * * @@ -271,70 +228,83 @@ void add_line_to_rendering_lines(rendering_line **lines, rendering_line *line) * * ******************************************************************************/ -void insert_line_into_rendering_lines(rendering_line **lines, rendering_line *line, bool first) +void g_rendering_line_draw(GRenderingLine *line, GdkDrawable *drawable, GdkGC *gc, gint x0, gint x1, gint y, gint h) { - rendering_line *iter; /* Boucle de parcours */ + GdkPixbuf *pixbuf; /* Données utiles au dessin */ - lines_list_for_each(iter, *lines) + gdk_draw_layout(drawable, gc, x1, y, line->layout); + + if (line->flags & RLF_BREAK_POINT) + pixbuf = gtk_widget_render_icon(mywid, "gtk-yes", GTK_ICON_SIZE_MENU, NULL); + + else if (line->flags & RLF_RUNNING_BP) + pixbuf = gtk_widget_render_icon(mywid, "gtk-no", GTK_ICON_SIZE_MENU, NULL); + + else pixbuf = NULL; + + if (pixbuf != NULL) { - if (first && iter->offset >= line->offset) break; - else if (!first) - { - /* TODO */; - } + gdk_draw_pixbuf(drawable, gc, pixbuf, 0, 0, x0, y, + gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), + GDK_RGB_DITHER_NORMAL, 0, 0); + + g_object_unref(pixbuf); } - if (iter == NULL) - lines_list_add_tail(line, lines); + /* Le point d'entrée prime */ - else + if (line->flags & RLF_ENTRY_POINT) + pixbuf = gtk_widget_render_icon(mywid, "gtk-go-forward", GTK_ICON_SIZE_MENU, NULL); + + else pixbuf = NULL; + + if (pixbuf != NULL) { - if (first) - lines_list_splice_before(iter, lines, line); - else - /* TODO */; + gdk_draw_pixbuf(drawable, gc, pixbuf, 0, 0, x0, y, + gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), + GDK_RGB_DITHER_NORMAL, 0, 0); + + g_object_unref(pixbuf); + } } + +/* ---------------------------------------------------------------------------------- */ +/* TRAITEMENT DES LIGNES PAR GROUPE */ +/* ---------------------------------------------------------------------------------- */ + + /****************************************************************************** * * -* Paramètres : lines = liste de lignes à parcourir. * -* offset = position en mémoire ou physique à chercher. * +* Paramètres : lines = liste de lignes à compléter, ou NULL. * +* line = nouvelle ligne à intégrer à l'ensemble. * * * -* Description : Recherche une ligne d'après sa position en mémoire/physique. * +* Description : Ajoute une ligne à un ensemble existant. * * * -* Retour : Ligne représentant l'adresse donnée, NULL si aucune trouvée. * +* Retour : - * * * -* Remarques : - * +* Remarques : La ligne est considérée comme étant insérée au bon endroit. * * * ******************************************************************************/ -rendering_line *find_offset_in_rendering_lines(rendering_line *lines, uint64_t offset) +void g_rendering_line_add_to_lines(GRenderingLine **lines, GRenderingLine *line) { - rendering_line *result; - - lines_list_for_each(result, lines) - if (result->offset == offset) break; - - return result; + lines_list_add_tail(line, lines); } /****************************************************************************** * * -* Paramètres : line = adresse de la structure à représenter. * -* drawable = support de rendu pour le dessin. * -* gc = contexte graphique à utiliser. * -* x0 = abscisse de la zone de rendu (marge). * -* x1 = abscisse de la zone de rendu (texte). * -* y = ordonnée de la zone de rendu. * -* h = hauteur réservée pour la ligne. * +* Paramètres : lines = liste de lignes à compléter, ou NULL. * +* line = nouvelle ligne à intégrer à l'ensemble. * +* first = position de la ligne en cas d'adresse partagée. * * * -* Description : Procède à l'initialisation des bases d'une représentation. * +* Description : Insère une ligne dans un ensemble existant. * * * * Retour : - * * * @@ -342,36 +312,34 @@ rendering_line *find_offset_in_rendering_lines(rendering_line *lines, uint64_t o * * ******************************************************************************/ -void draw_rendering_line(rendering_line *line, GdkDrawable *drawable, GdkGC *gc, gint x0, gint x1, gint y, gint h) +void g_rendering_line_insert_into_lines(GRenderingLine **lines, GRenderingLine *line, bool first) { - GdkPixbuf *pixbuf; /* Données utiles au dessin */ + GRenderingLine *iter; /* Boucle de parcours */ - gdk_draw_layout(drawable, gc, x1, y, line->layout); + lines_list_for_each(iter, *lines) + { + if (first && iter->offset >= line->offset) break; + else if (!first) + { + /* TODO */; + } - if (line->flags & RLF_ENTRY_POINT) - pixbuf = gtk_widget_render_icon(mywid, "gtk-go-forward", GTK_ICON_SIZE_MENU, NULL); + } - else pixbuf = NULL; + if (iter == NULL) + lines_list_add_tail(line, lines); - if (pixbuf != NULL) + else { - gdk_draw_pixbuf(drawable, gc, pixbuf, 0, 0, x0, y, - gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), - GDK_RGB_DITHER_NORMAL, 0, 0); - - g_object_unref(pixbuf); - + if (first) + lines_list_splice_before(iter, lines, line); + else + /* TODO */; } } - -/* ---------------------------------------------------------------------------------- */ -/* TRAITEMENT DES LIGNES PAR GROUPE */ -/* ---------------------------------------------------------------------------------- */ - - /****************************************************************************** * * * Paramètres : line = liste de lignes de représentation à actualiser. * @@ -385,9 +353,9 @@ void draw_rendering_line(rendering_line *line, GdkDrawable *drawable, GdkGC *gc, * * ******************************************************************************/ -rendering_line *g_rendering_line_get_next_iter(rendering_line *lines, const rendering_line *iter) +GRenderingLine *g_rendering_line_get_next_iter(GRenderingLine *lines, const GRenderingLine *iter) { - rendering_line *result; /* Elément suivant à renvoyer */ + GRenderingLine *result; /* Elément suivant à renvoyer */ if (iter == NULL) iter = lines; @@ -410,9 +378,9 @@ rendering_line *g_rendering_line_get_next_iter(rendering_line *lines, const rend * * ******************************************************************************/ -void g_rendering_lines_update_bin_len(rendering_line *lines) +void g_rendering_line_update_bin_len(GRenderingLine *lines) { - rendering_line *iter; /* Boucle de parcours */ + GRenderingLine *iter; /* Boucle de parcours */ off_t bin_len; /* Taille d'instruction */ bin_len = 0; @@ -445,9 +413,9 @@ void g_rendering_lines_update_bin_len(rendering_line *lines) * * ******************************************************************************/ -void g_rendering_lines_get_size(rendering_line *lines, int *width, int *height, int *alone) +void g_rendering_line_get_size(GRenderingLine *lines, int *width, int *height, int *alone) { - rendering_line *iter; /* Boucle de parcours */ + GRenderingLine *iter; /* Boucle de parcours */ int w; /* Largeur de l'objet actuelle */ int h; /* Hauteur de l'objet actuelle */ @@ -470,399 +438,58 @@ void g_rendering_lines_get_size(rendering_line *lines, int *width, int *height, } - -/* ---------------------------------------------------------------------------------- */ -/* LIGNE EN TETE DE DESASSEMBLAGE */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : comment = texte à afficher au final. * -* * -* Description : Crée une des lignes de description initiales. * -* * -* Retour : Adresse de la structure mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -rendering_line *create_prologue_line(const char *comment) -{ - prologue_line *result; /* Structure à retourner */ - - result = (prologue_line *)calloc(1, sizeof(prologue_line)); - - init_rendering_line(RENDERING_LINE(result)); - - RENDERING_LINE(result)->offset = 0; - - RENDERING_LINE(result)->type = RLT_PROLOGUE; - - RENDERING_LINE(result)->refresh_markup = (refresh_markup_fc)refresh_prologue_markup; - - result->comment = strdup(comment); - - return RENDERING_LINE(result); - -} - - -/****************************************************************************** -* * -* Paramètres : line = ligne de représentation à actualiser. * -* * -* Description : Met à jour la ligne de représentation de prologue. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void refresh_prologue_markup(prologue_line *line) -{ - size_t len; /* Taille du contenu */ - char *content; /* Contenu réellement imprimé */ - - len = strlen(""); - len += strlen("; ") + strlen(line->comment); - len += strlen(""); - - content = (char *)calloc(len + 1, sizeof(char)); - - snprintf(content, len + 1, "; %s", line->comment); - - pango_layout_set_markup(RENDERING_LINE(line)->layout, content, len); - - free(content); - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* COMMENTAIRES SUR UNE LIGNE ENTIERE */ -/* ---------------------------------------------------------------------------------- */ - - /****************************************************************************** * * -* Paramètres : offset = position dans la mémoire ou le fichier. * -* type = type du commentaire. * -* comment = texte à afficher au final. * -* options = paramétrage du rendu. * +* Paramètres : lines = liste de lignes à parcourir. * +* y = ordonnée à vérifier et à mettre à jour. [OUT] * * * -* Description : Crée une ligne de commentaires entière. * +* Description : Recherche une ligne d'après sa position à l'écran. * * * -* Retour : Adresse de la structure mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -rendering_line *create_comment_line(uint64_t offset, RenderingLineType type, const char *comment, const disass_options *options) -{ - comment_line *result; /* Structure à retourner */ - - result = (comment_line *)calloc(1, sizeof(comment_line)); - - init_rendering_line(RENDERING_LINE(result)); - - RENDERING_LINE(result)->offset = offset; - - RENDERING_LINE(result)->type = type; - - RENDERING_LINE(result)->refresh_markup = (refresh_markup_fc)refresh_comment_markup; - - result->comment = strdup(comment); - result->options = options; - - return RENDERING_LINE(result); - -} - - -/****************************************************************************** -* * -* Paramètres : line = ligne de représentation à actualiser. * -* * -* Description : Met à jour la ligne de représentation de commentaires. * -* * -* Retour : - * +* Retour : Ligne représentant l'adresse donnée, NULL si aucune trouvée. * * * * Remarques : - * * * ******************************************************************************/ -void refresh_comment_markup(comment_line *line) +GRenderingLine *g_rendering_line_find_by_y(GRenderingLine *lines, gdouble *y) { - size_t len; /* Taille du contenu */ - char *content; /* Contenu réellement imprimé */ - char buffer[CODE_BUFFER_LEN]; /* Zone tampon à utiliser */ - size_t clen; /* Taille du commentaire */ - - len = strlen("") + 1; - content = (char *)calloc(len, sizeof(char)); - strcpy(content, ""); + GRenderingLine *result; /* Trouvaille à retourner */ + int h; /* Hauteur de l'objet actuel */ - /* Eventuelle adresse virtuelle */ - - if (line->options->show_address) - { - switch (ADM_32BITS /* FIXME */) - { - case ADM_32BITS: - snprintf(buffer, CODE_BUFFER_LEN, - "0x%08llx", - RENDERING_LINE(line)->offset); - break; - - case ADM_64BITS: - snprintf(buffer, CODE_BUFFER_LEN, - "0x%16llx", - RENDERING_LINE(line)->offset); - break; - - } - - len += strlen(buffer); - content = (char *)realloc(content, len * sizeof(char)); - strcat(content, buffer); - - } - - /* Eventuel code brut (sauté) */ - - if (line->options->show_code) + lines_list_for_each(result, lines) { - clen = (line->options->show_address ? strlen("\t") : 0); - clen += RENDERING_LINE(line)->max_bin_len; - - content = (char *)realloc(content, (len + clen) * sizeof(char)); + pango_layout_get_pixel_size(result->layout, NULL, &h); - if (line->options->show_address) - { - strcat(content, "\t"); - len += strlen("\t"); - } - - memset(&content[len - 1], RENDERING_LINE(line)->type == RLT_PROTOTYPE ? '-' : ' ', - RENDERING_LINE(line)->max_bin_len); - len += RENDERING_LINE(line)->max_bin_len; - - content[len] = '\0'; + if (*y < h) break; + else *y -= h; } - /* Commentaire proprement dit */ - - clen = (line->options->show_address || line->options->show_code ? strlen("\t") : 0); - clen += strlen(""); - clen += strlen("; ") + strlen(line->comment); - clen += strlen(""); - - content = (char *)realloc(content, (len + clen) * sizeof(char)); - - if (line->options->show_address || line->options->show_code) - { - strcat(content, "\t"); - len += strlen("\t"); - clen -= strlen("\t"); - } - - snprintf(&content[len - 1], clen + 1, "; %s", line->comment); - - len += clen; - - /* Finalisation */ - - len += strlen(""); - content = (char *)realloc(content, len * sizeof(char)); - strcat(content, ""); - - pango_layout_set_markup(RENDERING_LINE(line)->layout, content, len - 1); - - free(content); - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* LIGNE DE CODE EN LANGAGE MACHINE */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : instr = instruction à représenter. * -* options = paramétrage du rendu. * -* * -* Description : Crée une ligne de représentation de code binaire. * -* * -* Retour : Adresse de la structure mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -rendering_line *create_code_line(asm_instr *instr, uint64_t offset, const disass_options *options) -{ - code_line *result; /* Structure à retourner */ - - result = (code_line *)calloc(1, sizeof(code_line)); - - init_rendering_line(RENDERING_LINE(result)); - - RENDERING_LINE(result)->offset = offset; - - RENDERING_LINE(result)->type = RLT_CODE; - - RENDERING_LINE(result)->get_bin_len = (get_bin_len_fc)get_code_binary_len; - RENDERING_LINE(result)->refresh_markup = (refresh_markup_fc)refresh_code_markup; - - result->instr = instr; - result->options = options; - - return RENDERING_LINE(result); - -} - - -/****************************************************************************** -* * -* Paramètres : line = ligne de représentation à actualiser. * -* blen = longueur maximale à mettre à jour. [OUT] * -* * -* Description : Met à jour le nombre d'octets maximal par instruction. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void get_code_binary_len(code_line *line, off_t *blen) -{ - off_t len; /* Taille propre à la ligne */ - - get_asm_instr_offset_and_length(line->instr, NULL, &len); - - *blen = MAX(*blen, len); + return result; } /****************************************************************************** * * -* Paramètres : line = ligne de représentation à actualiser. * +* Paramètres : lines = liste de lignes à parcourir. * +* offset = position en mémoire ou physique à chercher. * * * -* Description : Met à jour la ligne de représentation de code. * +* Description : Recherche une ligne d'après sa position en mémoire/physique. * * * -* Retour : - * +* Retour : Ligne représentant l'adresse donnée, NULL si aucune trouvée. * * * * Remarques : - * * * ******************************************************************************/ -void refresh_code_markup(code_line *line) +GRenderingLine *g_rendering_line_find_by_offset(GRenderingLine *lines, uint64_t offset) { - size_t len; /* Taille du contenu */ - char *content; /* Contenu réellement imprimé */ - off_t bin_offset; /* Début de l'instruction */ - off_t bin_len; /* Taille d'instruction */ - char buffer[CODE_BUFFER_LEN]; /* Zone tampon à utiliser */ - const uint8_t *exe_content; /* Contenu binaire global */ - char *bin_code; /* Tampon du code binaire */ - off_t k; /* Boucle de parcours #2 */ - off_t j; /* Boucle de parcours #1 */ - - len = strlen("") + 1; - content = (char *)calloc(len, sizeof(char)); - strcpy(content, ""); - - if (line->options->show_code) - get_asm_instr_offset_and_length(line->instr, &bin_offset, &bin_len); - - /* Eventuelle adresse virtuelle */ - - if (line->options->show_address) - { - switch (ADM_32BITS /* FIXME */) - { - case ADM_32BITS: - snprintf(buffer, CODE_BUFFER_LEN, - "0x%08llx", - RENDERING_LINE(line)->offset); - break; - - case ADM_64BITS: - snprintf(buffer, CODE_BUFFER_LEN, - "0x%16llx", - RENDERING_LINE(line)->offset); - break; - - } + GRenderingLine *result; /* Trouvaille à retourner */ - len += strlen(buffer); - content = (char *)realloc(content, len * sizeof(char)); - strcat(content, buffer); - - } - - /* Eventuel code brut */ - - if (line->options->show_code) - { - exe_content = get_exe_content(line->options->format, NULL); - - bin_code = (char *)calloc(RENDERING_LINE(line)->max_bin_len + 1, sizeof(char)); - - k = 0; - - for (j = 0; j < bin_len; j++) - { - if ((j + 1) < bin_len) - k += snprintf(&bin_code[j * (2 + 1)], 4, "%02hhx ", exe_content[bin_offset + j]); - else - k += snprintf(&bin_code[j * (2 + 1)], 3, "%02hhx", exe_content[bin_offset + j]); - } - - for (; k < RENDERING_LINE(line)->max_bin_len; k++) - snprintf(&bin_code[k], 2, " "); - - if (line->options->show_address) len += strlen("\t"); - len += strlen(bin_code); - content = (char *)realloc(content, len * sizeof(char)); - if (line->options->show_address) strcat(content, "\t"); - strcat(content, bin_code); - - free(bin_code); - - } - - /* Instruction proprement dite */ - - print_hinstruction(line->options->proc, line->options->format, - line->instr, buffer, CODE_BUFFER_LEN, ASX_INTEL/*FIXME*/); - - if (line->options->show_address || line->options->show_code) len += strlen("\t"); - len += strlen(buffer); - - content = (char *)realloc(content, len * sizeof(char)); - if (line->options->show_address || line->options->show_code) strcat(content, "\t"); - strcat(content, buffer); - - /* Finalisation */ - - len += strlen(""); - content = (char *)realloc(content, len * sizeof(char)); - strcat(content, ""); - - pango_layout_set_markup(RENDERING_LINE(line)->layout, content, len - 1); + lines_list_for_each(result, lines) + if (result->offset == offset) break; - free(content); + return result; } diff --git a/src/analysis/line.h b/src/analysis/line.h index abb2757..0213cab 100644 --- a/src/analysis/line.h +++ b/src/analysis/line.h @@ -48,7 +48,8 @@ typedef enum _RenderingLineFlag { RLF_NONE = (0 << 0), /* Ligne commune */ RLF_ENTRY_POINT = (1 << 0), /* Point d'entrée du prgm. */ - RLF_BREAK_POINT = (1 << 1) /* Point d'arrêt */ + RLF_BREAK_POINT = (1 << 1), /* Point d'arrêt */ + RLF_RUNNING_BP = (1 << 2) /* Point d'arrêt activé */ } RenderingLineFlag; @@ -65,76 +66,65 @@ typedef struct _disass_options -/* Ligne de représentation générique */ -typedef struct _rendering_line rendering_line; +#define G_TYPE_RENDERING_LINE g_rendering_line_get_type() +#define G_RENDERING_LINE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_rendering_line_get_type(), GRenderingLine)) +#define G_IS_RENDERING_LINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_rendering_line_get_type())) +#define G_RENDERING_LINE_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_rendering_line_get_type(), GRenderingLineIface)) -/* Ajoute une information supplémentaire à une ligne. */ -void add_rendering_line_flag(rendering_line *, RenderingLineFlag); - -/* Retire une information supplémentaire d'une ligne. */ -void remove_rendering_line_flag(rendering_line *, RenderingLineFlag); - -/* Fournit les informations supplémentaires d'une ligne. */ -RenderingLineFlag get_rendering_line_flags(const rendering_line *); +/* Ligne de représentation générique (instance) */ +typedef struct _GRenderingLine GRenderingLine; +/* Ligne de représentation générique (classe) */ +typedef struct _GRenderingLineClass GRenderingLineClass; +/* Indique le type définit pour une ligne de représentation. */ +GType g_rendering_line_get_type(void); -/* Ajoute une ligne à un ensemble existant. */ -void add_line_to_rendering_lines(rendering_line **, rendering_line *); +/* Fournit le type d'une ligne. */ +RenderingLineType get_rendering_line_type(const GRenderingLine *); -/* Insère une ligne dans un ensemble existant. */ -void insert_line_into_rendering_lines(rendering_line **, rendering_line *, bool); +/* Ajoute une information supplémentaire à une ligne. */ +void g_rendering_line_add_flag(GRenderingLine *, RenderingLineFlag); -/* Recherche une ligne d'après sa position en mémoire/physique. */ -rendering_line *find_offset_in_rendering_lines(rendering_line *, uint64_t); +/* Retire une information supplémentaire d'une ligne. */ +void g_rendering_line_remove_flag(GRenderingLine *, RenderingLineFlag); +/* Bascule l'état d'une information sur d'une ligne. */ +void g_rendering_line_toggle_flag(GRenderingLine *, RenderingLineFlag); +/* Fournit les informations supplémentaires d'une ligne. */ +RenderingLineFlag g_rendering_line_get_flags(const GRenderingLine *); /* Procède à l'initialisation des bases d'une représentation. */ -void draw_rendering_line(rendering_line *, GdkDrawable *, GdkGC *, gint, gint, gint, gint); +void g_rendering_line_draw(GRenderingLine *, GdkDrawable *, GdkGC *, gint, gint, gint, gint); /* ------------------------ TRAITEMENT DES LIGNES PAR GROUPE ------------------------ */ +/* Ajoute une ligne à un ensemble existant. */ +void g_rendering_line_add_to_lines(GRenderingLine **, GRenderingLine *); + +/* Insère une ligne dans un ensemble existant. */ +void g_rendering_line_insert_into_lines(GRenderingLine **, GRenderingLine *, bool); + /* Fournit l'élement suivant un autre pour un parcours. */ -rendering_line *g_rendering_line_get_next_iter(rendering_line *, const rendering_line *); +GRenderingLine *g_rendering_line_get_next_iter(GRenderingLine *, const GRenderingLine *); /* Met à jour le nombre d'octets maximal par instruction. */ -void g_rendering_lines_update_bin_len(rendering_line *); +void g_rendering_line_update_bin_len(GRenderingLine *); /* Fournit les dimensions de lignes de représentation. */ -void g_rendering_lines_get_size(rendering_line *, int *, int *, int *); - - - -/* ------------------------- LIGNE EN TETE DE DESASSEMBLAGE ------------------------- */ - - -/* Crée une des lignes de description initiales. */ -rendering_line *create_prologue_line(const char *); - - - -/* ----------------------- COMMENTAIRES SUR UNE LIGNE ENTIERE ----------------------- */ - - -/* Crée une ligne de commentaires entière. */ -rendering_line *create_comment_line(uint64_t, RenderingLineType, const char *, const disass_options *); - - - -/* ------------------------ LIGNE DE CODE EN LANGAGE MACHINE ------------------------ */ - - -/* Crée une ligne de représentation de code binaire. */ -rendering_line *create_code_line(asm_instr *, uint64_t, const disass_options *); - +void g_rendering_line_get_size(GRenderingLine *, int *, int *, int *); +/* Recherche une ligne d'après sa position à l'écran. */ +GRenderingLine *g_rendering_line_find_by_y(GRenderingLine *, gdouble *); +/* Recherche une ligne d'après sa position en mémoire/physique. */ +GRenderingLine *g_rendering_line_find_by_offset(GRenderingLine *, uint64_t); diff --git a/src/analysis/line_code.c b/src/analysis/line_code.c new file mode 100644 index 0000000..2dd5a7c --- /dev/null +++ b/src/analysis/line_code.c @@ -0,0 +1,283 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * line_code.c - représentation des lignes de code binaire. + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "line_code.h" + + +#include +#include + + +#include "line-int.h" + + + +/* Ligne de représentation de code binaire (instance) */ +struct _GCodeLine +{ + GRenderingLine parent; /* Instance parente */ + + asm_instr *instr; /* Instruction représentée */ + const disass_options *options; /* Options de représentation */ + +}; + + +/* Ligne de représentation de code binaire (classe) */ +struct _GCodeLineClass +{ + GRenderingLineClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des lignes de code binaire. */ +static void g_code_line_class_init(GCodeLineClass *); + +/* Initialise la classe des lignes de code binaire. */ +static void g_code_line_init(GCodeLine *); + +/* Met à jour le nombre d'octets maximal par instruction. */ +void g_code_line_get_binary_len(GCodeLine *, off_t *); + +/* Met à jour la ligne de représentation de code. */ +void g_code_line_refresh_markup(GCodeLine *); + + + +/* Indique le type définit par la GLib pour la ligne. */ +G_DEFINE_TYPE(GCodeLine, g_code_line, G_TYPE_RENDERING_LINE); + + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des lignes de code binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_code_line_class_init(GCodeLineClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : line = instance à initialiser. * +* * +* Description : Initialise la classe des lignes de code binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_code_line_init(GCodeLine *line) +{ + GRenderingLine *parent; /* Instance parente */ + + parent = G_RENDERING_LINE(line); + + parent->offset = 0; + + parent->type = RLT_CODE; + + parent->get_bin_len = (get_bin_len_fc)g_code_line_get_binary_len; + parent->refresh_markup = (refresh_markup_fc)g_code_line_refresh_markup; + +} + + +/****************************************************************************** +* * +* Paramètres : line = ligne de représentation à actualiser. * +* blen = longueur maximale à mettre à jour. [OUT] * +* * +* Description : Met à jour le nombre d'octets maximal par instruction. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_code_line_get_binary_len(GCodeLine *line, off_t *blen) +{ + off_t len; /* Taille propre à la ligne */ + + get_asm_instr_offset_and_length(line->instr, NULL, &len); + + *blen = MAX(*blen, len); + +} + + +/****************************************************************************** +* * +* Paramètres : line = ligne de représentation à actualiser. * +* * +* Description : Met à jour la ligne de représentation de code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_code_line_refresh_markup(GCodeLine *line) +{ + size_t len; /* Taille du contenu */ + char *content; /* Contenu réellement imprimé */ + off_t bin_offset; /* Début de l'instruction */ + off_t bin_len; /* Taille d'instruction */ + char buffer[CODE_BUFFER_LEN]; /* Zone tampon à utiliser */ + const uint8_t *exe_content; /* Contenu binaire global */ + char *bin_code; /* Tampon du code binaire */ + off_t k; /* Boucle de parcours #2 */ + off_t j; /* Boucle de parcours #1 */ + + len = strlen("") + 1; + content = (char *)calloc(len, sizeof(char)); + strcpy(content, ""); + + if (line->options->show_code) + get_asm_instr_offset_and_length(line->instr, &bin_offset, &bin_len); + + /* Eventuelle adresse virtuelle */ + + if (line->options->show_address) + { + switch (ADM_32BITS /* FIXME */) + { + case ADM_32BITS: + snprintf(buffer, CODE_BUFFER_LEN, + "0x%08llx", + G_RENDERING_LINE(line)->offset); + break; + + case ADM_64BITS: + snprintf(buffer, CODE_BUFFER_LEN, + "0x%16llx", + G_RENDERING_LINE(line)->offset); + break; + + } + + len += strlen(buffer); + content = (char *)realloc(content, len * sizeof(char)); + strcat(content, buffer); + + } + + /* Eventuel code brut */ + + if (line->options->show_code) + { + exe_content = get_exe_content(line->options->format, NULL); + + bin_code = (char *)calloc(G_RENDERING_LINE(line)->max_bin_len + 1, sizeof(char)); + + k = 0; + + for (j = 0; j < bin_len; j++) + { + if ((j + 1) < bin_len) + k += snprintf(&bin_code[j * (2 + 1)], 4, "%02hhx ", exe_content[bin_offset + j]); + else + k += snprintf(&bin_code[j * (2 + 1)], 3, "%02hhx", exe_content[bin_offset + j]); + } + + for (; k < G_RENDERING_LINE(line)->max_bin_len; k++) + snprintf(&bin_code[k], 2, " "); + + if (line->options->show_address) len += strlen("\t"); + len += strlen(bin_code); + content = (char *)realloc(content, len * sizeof(char)); + if (line->options->show_address) strcat(content, "\t"); + strcat(content, bin_code); + + free(bin_code); + + } + + /* Instruction proprement dite */ + + print_hinstruction(line->options->proc, line->options->format, + line->instr, buffer, CODE_BUFFER_LEN, ASX_INTEL/*FIXME*/); + + if (line->options->show_address || line->options->show_code) len += strlen("\t"); + len += strlen(buffer); + + content = (char *)realloc(content, len * sizeof(char)); + if (line->options->show_address || line->options->show_code) strcat(content, "\t"); + strcat(content, buffer); + + /* Finalisation */ + + len += strlen(""); + content = (char *)realloc(content, len * sizeof(char)); + strcat(content, ""); + + pango_layout_set_markup(G_RENDERING_LINE(line)->layout, content, len - 1); + + free(content); + +} + + +/****************************************************************************** +* * +* Paramètres : offset = emplacement physique ou en mémoire. * +* instr = instruction à représenter. * +* options = paramétrage du rendu. * +* * +* Description : Crée une ligne de code binaire. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GRenderingLine *g_code_line_new(uint64_t offset, asm_instr *instr, const disass_options *options) +{ + GCodeLine *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_CODE_LINE, NULL); + + G_RENDERING_LINE(result)->offset = offset; + + result->instr = instr; + result->options = options; + + return G_RENDERING_LINE(result); + +} diff --git a/src/analysis/line_code.h b/src/analysis/line_code.h new file mode 100644 index 0000000..3564038 --- /dev/null +++ b/src/analysis/line_code.h @@ -0,0 +1,59 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * line_code.h - prototypes pour la représentation de code binaire + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _ANALYSIS_LINE_CODE_H +#define _ANALYSIS_LINE_CODE_H + + +#include + + +#include "line.h" +#include "../arch/processor.h" + + + +#define G_TYPE_CODE_LINE (g_code_line_get_type()) +#define G_CODE_LINE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_CODE_LINE, GCodeLine)) +#define G_IS_CODE_LINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_CODE_LINE)) +#define G_CODE_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CODE_LINE, GCodeLineClass)) +#define G_IS_CODE_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CODE_LINE)) +#define G_CODE_LINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CODE_LINE, GCodeLineClass)) + + +/* Ligne de représentation de code binaire (instance) */ +typedef struct _GCodeLine GCodeLine; + +/* Ligne de représentation de code binaire (classe) */ +typedef struct _GCodeLineClass GCodeLineClass; + + +/* Indique le type définit par la GLib pour la ligne. */ +GType g_code_line_get_type(void); + +/* Crée une ligne de code binaire. */ +GRenderingLine *g_code_line_new(uint64_t, asm_instr *, const disass_options *); + + + +#endif /* _ANALYSIS_LINE_CODE_H */ diff --git a/src/analysis/line_comment.c b/src/analysis/line_comment.c new file mode 100644 index 0000000..6df7b96 --- /dev/null +++ b/src/analysis/line_comment.c @@ -0,0 +1,237 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * line_comment.c - représentation des lignes commentaires entières + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "line_comment.h" + + +#include +#include + + +#include "line-int.h" + + + +/* Ligne de représentation de commentaires entière (instance) */ +struct _GCommentLine +{ + GRenderingLine parent; /* Instance parente */ + + char *comment; /* Texte à afficher */ + const disass_options *options; /* Options de représentation */ + +}; + + +/* Ligne de représentation de commentaires entière (classe) */ +struct _GCommentLineClass +{ + GRenderingLineClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des lignes de commentaires entière. */ +static void g_comment_line_class_init(GCommentLineClass *); + +/* Initialise la classe des lignes de commentaires entière. */ +static void g_comment_line_init(GCommentLine *); + +/* Met à jour la ligne de représentation de commentaires. */ +void g_comment_line_refresh_markup(GCommentLine *); + + + +/* Indique le type définit par la GLib pour la ligne. */ +G_DEFINE_TYPE(GCommentLine, g_comment_line, G_TYPE_RENDERING_LINE); + + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des lignes de commentaires entière. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_comment_line_class_init(GCommentLineClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : line = instance à initialiser. * +* * +* Description : Initialise la classe des lignes de commentaires entière. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_comment_line_init(GCommentLine *line) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : line = ligne de représentation à actualiser. * +* * +* Description : Met à jour la ligne de représentation de commentaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_comment_line_refresh_markup(GCommentLine *line) +{ + size_t len; /* Taille du contenu */ + char *content; /* Contenu réellement imprimé */ + char buffer[CODE_BUFFER_LEN]; /* Zone tampon à utiliser */ + size_t clen; /* Taille du commentaire */ + + len = strlen("") + 1; + content = (char *)calloc(len, sizeof(char)); + strcpy(content, ""); + + /* Eventuelle adresse virtuelle */ + + if (line->options->show_address) + { + switch (ADM_32BITS /* FIXME */) + { + case ADM_32BITS: + snprintf(buffer, CODE_BUFFER_LEN, + "0x%08llx", + G_RENDERING_LINE(line)->offset); + break; + + case ADM_64BITS: + snprintf(buffer, CODE_BUFFER_LEN, + "0x%16llx", + G_RENDERING_LINE(line)->offset); + break; + + } + + len += strlen(buffer); + content = (char *)realloc(content, len * sizeof(char)); + strcat(content, buffer); + + } + + /* Eventuel code brut (sauté) */ + + if (line->options->show_code) + { + clen = (line->options->show_address ? strlen("\t") : 0); + clen += G_RENDERING_LINE(line)->max_bin_len; + + content = (char *)realloc(content, (len + clen) * sizeof(char)); + + if (line->options->show_address) + { + strcat(content, "\t"); + len += strlen("\t"); + } + + memset(&content[len - 1], G_RENDERING_LINE(line)->type == RLT_PROTOTYPE ? '-' : ' ', + G_RENDERING_LINE(line)->max_bin_len); + len += G_RENDERING_LINE(line)->max_bin_len; + + content[len] = '\0'; + + } + + /* Commentaire proprement dit */ + + clen = (line->options->show_address || line->options->show_code ? strlen("\t") : 0); + clen += strlen(""); + clen += strlen("; ") + strlen(line->comment); + clen += strlen(""); + + content = (char *)realloc(content, (len + clen) * sizeof(char)); + + if (line->options->show_address || line->options->show_code) + { + strcat(content, "\t"); + len += strlen("\t"); + clen -= strlen("\t"); + } + + snprintf(&content[len - 1], clen + 1, "; %s", line->comment); + + len += clen; + + /* Finalisation */ + + len += strlen(""); + content = (char *)realloc(content, len * sizeof(char)); + strcat(content, ""); + + pango_layout_set_markup(G_RENDERING_LINE(line)->layout, content, len - 1); + + free(content); + +} + + +/****************************************************************************** +* * +* Paramètres : offset = emplacement physique ou en mémoire. * +* comment = texte à afficher au final. * +* options = paramétrage du rendu. * +* * +* Description : Crée une ligne de commentaires entière. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GRenderingLine *g_comment_line_new(uint64_t offset, const char *comment, const disass_options *options) +{ + GCommentLine *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_COMMENT_LINE, NULL); + + G_RENDERING_LINE(result)->offset = offset; + + result->comment = strdup(comment); + + return G_RENDERING_LINE(result); + +} diff --git a/src/analysis/line_comment.h b/src/analysis/line_comment.h new file mode 100644 index 0000000..7d103f4 --- /dev/null +++ b/src/analysis/line_comment.h @@ -0,0 +1,58 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * line_comment.h - prototypes pour la représentation des lignes commentaires entières + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _ANALYSIS_LINE_COMMENT_H +#define _ANALYSIS_LINE_COMMENT_H + + +#include + + +#include "line.h" + + + +#define G_TYPE_COMMENT_LINE (g_comment_line_get_type()) +#define G_COMMENT_LINE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_COMMENT_LINE, GCommentLine)) +#define G_IS_COMMENT_LINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_COMMENT_LINE)) +#define G_COMMENT_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_COMMENT_LINE, GCommentLineClass)) +#define G_IS_COMMENT_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_COMMENT_LINE)) +#define G_COMMENT_LINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_COMMENT_LINE, GCommentLineClass)) + + +/* Ligne de représentation de commentaires entière (instance) */ +typedef struct _GCommentLine GCommentLine; + +/* Ligne de représentation de commentaires entière (classe) */ +typedef struct _GCommentLineClass GCommentLineClass; + + +/* Indique le type définit par la GLib pour la ligne. */ +GType g_comment_line_get_type(void); + +/* Crée une ligne de commentaires entière. */ +GRenderingLine *g_comment_line_new(uint64_t, const char *, const disass_options *); + + + +#endif /* _ANALYSIS_LINE_COMMENT_H */ diff --git a/src/analysis/line_prologue.c b/src/analysis/line_prologue.c new file mode 100644 index 0000000..74b5642 --- /dev/null +++ b/src/analysis/line_prologue.c @@ -0,0 +1,168 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * line_prologue.c - représentation des lignes d'en-tête de désassemblage + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "line_prologue.h" + + +#include +#include + + +#include "line-int.h" + + + +/* Ligne de représentation de descriptions initiales (instance) */ +struct _GPrologueLine +{ + GRenderingLine parent; /* Instance parente */ + + char *comment; /* Texte à afficher */ + +}; + + +/* Ligne de représentation de descriptions initiales (classe) */ +struct _GPrologueLineClass +{ + GRenderingLineClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des lignes de descriptions initiales. */ +static void g_prologue_line_class_init(GPrologueLineClass *); + +/* Initialise la classe des lignes de descriptions initiales. */ +static void g_prologue_line_init(GPrologueLine *); + +/* Met à jour la ligne de représentation de prologue. */ +void g_prologue_line_refresh_markup(GPrologueLine *); + + + +/* Indique le type définit par la GLib pour la ligne. */ +G_DEFINE_TYPE(GPrologueLine, g_prologue_line, G_TYPE_RENDERING_LINE); + + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des lignes de descriptions initiales. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_prologue_line_class_init(GPrologueLineClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : line = instance à initialiser. * +* * +* Description : Initialise la classe des lignes de descriptions initiales. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_prologue_line_init(GPrologueLine *line) +{ + GRenderingLine *parent; /* Instance parente */ + + parent = G_RENDERING_LINE(line); + + parent->offset = 0; + + parent->type = RLT_PROLOGUE; + + parent->refresh_markup = (refresh_markup_fc)g_prologue_line_refresh_markup; + +} + + +/****************************************************************************** +* * +* Paramètres : line = ligne de représentation à actualiser. * +* * +* Description : Met à jour la ligne de représentation de prologue. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_prologue_line_refresh_markup(GPrologueLine *line) +{ + size_t len; /* Taille du contenu */ + char *content; /* Contenu réellement imprimé */ + + len = strlen(""); + len += strlen("; ") + strlen(line->comment); + len += strlen(""); + + content = (char *)calloc(len + 1, sizeof(char)); + + snprintf(content, len + 1, "; %s", line->comment); + + pango_layout_set_markup(G_RENDERING_LINE(line)->layout, content, len); + + free(content); + +} + + +/****************************************************************************** +* * +* Paramètres : comment = texte à afficher au final. * +* * +* Description : Crée une des lignes de descriptions initiales. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GRenderingLine *g_prologue_line_new(const char *comment) +{ + GPrologueLine *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_PROLOGUE_LINE, NULL); + + result->comment = strdup(comment); + + return G_RENDERING_LINE(result); + +} diff --git a/src/analysis/line_prologue.h b/src/analysis/line_prologue.h new file mode 100644 index 0000000..45ee7fc --- /dev/null +++ b/src/analysis/line_prologue.h @@ -0,0 +1,60 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * line_prologue.h - prototypes pour la représentation des lignes d'en-tête de désassemblage + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _ANALYSIS_LINE_PROLOGUE_H +#define _ANALYSIS_LINE_PROLOGUE_H + + +#include + + +#include "line.h" + + + +#define G_TYPE_PROLOGUE_LINE (g_prologue_line_get_type()) +#define G_PROLOGUE_LINE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PROLOGUE_LINE, GPrologueLine)) +#define G_IS_PROLOGUE_LINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PROLOGUE_LINE)) +#define G_PROLOGUE_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PROLOGUE_LINE, GPrologueLineClass)) +#define G_IS_PROLOGUE_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PROLOGUE_LINE)) +#define G_PROLOGUE_LINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PROLOGUE_LINE, GPrologueLineClass)) + + + +/* Ligne de représentation de descriptions initiales (instance) */ +typedef struct _GPrologueLine GPrologueLine; + +/* Ligne de représentation de descriptions initiales (classe) */ +typedef struct _GPrologueLineClass GPrologueLineClass; + + + +/* Indique le type définit par la GLib pour la ligne. */ +GType g_prologue_line_get_type(void); + +/* Crée une des lignes de descriptions initiales. */ +GRenderingLine *g_prologue_line_new(const char *); + + + +#endif /* _ANALYSIS_LINE_PROLOGUE_H */ diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am index a7134b6..2f7f072 100644 --- a/src/arch/Makefile.am +++ b/src/arch/Makefile.am @@ -12,7 +12,7 @@ libarch_a_SOURCES = \ libarch_a_CFLAGS = $(AM_CFLAGS) -INCLUDES = +INCLUDES = $(LIBGTK_CFLAGS) AM_CPPFLAGS = diff --git a/src/arch/x86/Makefile.am b/src/arch/x86/Makefile.am index a061438..e2847ab 100644 --- a/src/arch/x86/Makefile.am +++ b/src/arch/x86/Makefile.am @@ -43,7 +43,7 @@ libarchx86_a_SOURCES = \ libarchx86_a_CFLAGS = $(AM_CFLAGS) -INCLUDES = +INCLUDES = $(LIBGTK_CFLAGS) AM_CPPFLAGS = diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h index 3823a90..c54d626 100644 --- a/src/arch/x86/instruction.h +++ b/src/arch/x86/instruction.h @@ -100,6 +100,7 @@ typedef enum _X86Opcodes X86_OP_JE_8, /* je (0x74) */ X86_OP_JNE_8, /* jne (0x75) */ + X86_OP_JG_REL8, /* jg (0x7f) */ X86_OP_XOR_RM8_IMM8, /* xor (0x80 6) */ X86_OP_CMP_RM8_IMM8, /* cmp (0x80 7) */ @@ -167,6 +168,7 @@ typedef enum _X86Opcodes X86_OP_LEAVE, /* leave (0xc9) */ + X86_OP_INT_3, /* int 3 (0xcc) */ X86_OP_INT, /* int (0xcd) */ X86_OP_SHL_RM1632_CL, /* shl ([0x66] 0xd3 4) */ diff --git a/src/arch/x86/op_int.c b/src/arch/x86/op_int.c index 7c2ae1d..4fdb73a 100644 --- a/src/arch/x86/op_int.c +++ b/src/arch/x86/op_int.c @@ -63,3 +63,46 @@ asm_x86_instr *x86_read_instr_int(const uint8_t *data, off_t *pos, off_t len, ui return result; } + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* offset = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'int 3'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_int_3(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ + asm_x86_instr *result; /* Instruction à retourner */ + asm_x86_operand *op; /* Opérande unique décodé */ + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + + op = create_new_x86_operand(); + if (!fill_imm_operand_with_value(ASM_OPERAND(op), AOS_8_BITS, (int []) { 3 })) + { + free(op); + free(result); + return NULL; + } + + ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); + ASM_INSTRUCTION(result)->operands_count = 1; + + ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(op); + + return result; + +} diff --git a/src/arch/x86/op_jump.c b/src/arch/x86/op_jump.c index 44256e9..4a7fc72 100644 --- a/src/arch/x86/op_jump.c +++ b/src/arch/x86/op_jump.c @@ -112,6 +112,43 @@ asm_x86_instr *x86_read_instr_je_8(const uint8_t *data, off_t *pos, off_t len, u * offset = adresse virtuelle de l'instruction. * * proc = architecture ciblée par le désassemblage. * * * +* Description : Décode une instruction de type 'jg' (saut 8b si supérieur). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_jg_rel8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ + asm_x86_instr *result; /* Instruction à retourner */ + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + + ASM_INSTRUCTION(result)->type = AIT_JUMP; + + if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL8, offset)) + { + free(result); + 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. * +* offset = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * * Description : Décode une instruction de type 'jnb' (saut 8b si !inférieur).* * * * Retour : Instruction mise en place ou NULL. * diff --git a/src/arch/x86/opcodes.h b/src/arch/x86/opcodes.h index f7d91ac..51af021 100644 --- a/src/arch/x86/opcodes.h +++ b/src/arch/x86/opcodes.h @@ -91,6 +91,9 @@ asm_x86_instr *x86_read_instr_hlt(const uint8_t *, off_t *, off_t, uint64_t, con /* Décode une instruction de type 'inc'. */ asm_x86_instr *x86_read_instr_inc_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +/* Décode une instruction de type 'int 3'. */ +asm_x86_instr *x86_read_instr_int_3(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + /* Décode une instruction de type 'int'. */ asm_x86_instr *x86_read_instr_int(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); @@ -100,6 +103,9 @@ asm_x86_instr *x86_read_instr_jb_rel8(const uint8_t *, off_t *, off_t, uint64_t, /* Décode une instruction de type 'je' (petit saut). */ asm_x86_instr *x86_read_instr_je_8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +/* Décode une instruction de type 'jg' (saut 8b si supérieur). */ +asm_x86_instr *x86_read_instr_jg_rel8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + /* Décode une instruction de type 'jnb' (saut 8b si !inférieur). */ asm_x86_instr *x86_read_instr_jnb_rel8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c index 9bb3a23..15d26a4 100644 --- a/src/arch/x86/processor.c +++ b/src/arch/x86/processor.c @@ -301,6 +301,7 @@ void x86_register_instructions(asm_x86_processor *proc) register_opcode(proc->opcodes[X86_OP_JE_8], 0x74, "je", x86_read_instr_je_8); register_opcode(proc->opcodes[X86_OP_JNE_8], 0x75, "jne", x86_read_instr_jne_8); + register_opcode(proc->opcodes[X86_OP_JG_REL8], 0x7f, "jg", x86_read_instr_jg_rel8); register_opcode_with_ext(proc->opcodes[X86_OP_XOR_RM8_IMM8], 0x80, 6, "xor", x86_read_instr_xor_rm8_with_imm8); register_opcode_with_ext(proc->opcodes[X86_OP_CMP_RM8_IMM8], 0x80, 7, "cmp", x86_read_instr_cmp_rm8_with_imm8); @@ -368,6 +369,7 @@ void x86_register_instructions(asm_x86_processor *proc) register_opcode(proc->opcodes[X86_OP_LEAVE], 0xc9, "leave", x86_read_instr_leave); + register_opcode(proc->opcodes[X86_OP_INT_3], 0xcc, "int", x86_read_instr_int_3); register_opcode(proc->opcodes[X86_OP_INT], 0xcd, "int", x86_read_instr_int); register_opcode_1632_with_ext(proc->opcodes[X86_OP_SHL_RM1632_CL], 0xd3, 4, "shl", x86_read_instr_shl_rm1632_cl); diff --git a/src/binary.c b/src/binary.c index e43d644..85196d9 100644 --- a/src/binary.c +++ b/src/binary.c @@ -35,6 +35,9 @@ #include +#include "analysis/line_code.h" +#include "analysis/line_comment.h" +#include "analysis/line_prologue.h" #include "analysis/prototype.h" #include "arch/processor.h" @@ -43,10 +46,6 @@ #include "format/exe_format.h" -#include "format/elf/e_elf.h" -#include "format/dwarf/d_dwarf.h" -#include "format/java/e_java.h" -#include "format/pe/e_pe.h" #ifndef _ @@ -59,31 +58,35 @@ extern bool find_line_info(const uint8_t *content, off_t *size); -/* Charge en mémoire le contenu d'un fichier à partir d'XML. */ -openida_binary *load_binary_file_from_xml(xmlXPathObjectPtr); - - - - -/* Charge en mémoire le contenu d'un fichier. */ -uint8_t *map_binary_file(const char *, size_t *); - -/* Construit la description d'introduction du désassemblage. */ -rendering_line *build_binary_prologue(const char *, const uint8_t *, off_t); - - - /* Description d'un fichier binaire */ struct _openida_binary { char *filename; /* Fichier chargé en mémoire */ + off_t bin_length; /* Taille des données brutes */ + uint8_t *bin_data; /* Données binaires brutes */ + + exe_format *format; /* Format du binaire */ + asm_processor *proc; /* Architecture du binaire */ + + GRenderingLine *lines; /* Lignes de rendu en place */ + disass_options options; /* Options de désassemblage */ }; +/* Charge en mémoire le contenu d'un fichier à partir d'XML. */ +openida_binary *load_binary_file_from_xml(xmlXPathObjectPtr); + +/* Charge en mémoire le contenu d'un fichier. */ +uint8_t *map_binary_file(const char *, off_t *); +/* Construit la description d'introduction du désassemblage. */ +GRenderingLine *build_binary_prologue(const char *, const uint8_t *, off_t); + +/* Procède au désassemblage basique d'un contenu binaire. */ +void disassemble_openida_binary(openida_binary *); @@ -107,12 +110,32 @@ openida_binary *load_binary_file(const char *filename) result->filename = strdup(filename); + result->bin_data = map_binary_file(filename, &result->bin_length); + if (result->bin_data == NULL) goto lbf_error; + + result->format = load_new_exe_format(result->bin_data, result->bin_length); + if (result->format == NULL) goto lbf_error; + + + result->proc = create_x86_processor(); + + result->options.show_address = true; + result->options.show_code = true; + result->options.format = result->format; + result->options.proc = result->proc; + disassemble_openida_binary(result); return result; + lbf_error: + + unload_binary_file(result); + + return NULL; + } @@ -171,7 +194,26 @@ void unload_binary_file(openida_binary *binary) /****************************************************************************** * * -* Paramètres : binary = élément binaire à traiter. * +* Paramètres : binary = élément binaire à consulter. * +* * +* Description : Fournit le fichier correspondant à l'élément binaire. * +* * +* Retour : Nom de fichier avec chemin absolu. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *openida_binary_get_filename(const openida_binary *binary) +{ + return binary->filename; + +} + + +/****************************************************************************** +* * +* Paramètres : binary = élément binaire à consulter. * * * * Description : Fournit une description humaine d'un élément binaire. * * * @@ -190,6 +232,24 @@ const char *openida_binary_to_string(const openida_binary *binary) +/****************************************************************************** +* * +* Paramètres : binary = élément binaire à consulter. * +* * +* Description : Fournit les lignes de rendu issues du désassemblage. * +* * +* Retour : Lignes issues du désassemblage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GRenderingLine *get_openida_binary_lines(const openida_binary *binary) +{ + return binary->lines; + +} + @@ -306,7 +366,7 @@ bool write_openida_binary_to_xml(const openida_binary *binary, xmlTextWriterPtr * * ******************************************************************************/ -uint8_t *map_binary_file(const char *filename, size_t *length) +uint8_t *map_binary_file(const char *filename, off_t *length) { uint8_t *result; /* Données à retourner */ int fd; /* Fichier ouvert en lecture */ @@ -360,25 +420,25 @@ uint8_t *map_binary_file(const char *filename, size_t *length) * * ******************************************************************************/ -rendering_line *build_binary_prologue(const char *filename, const uint8_t *data, off_t length) +GRenderingLine *build_binary_prologue(const char *filename, const uint8_t *data, off_t length) { - rendering_line *result; /* Contenu à renvoyer */ + GRenderingLine *result; /* Contenu à renvoyer */ size_t len; /* Taille du texte */ char *content; /* Contenu textuel d'une ligne */ - rendering_line *line; /* Représentation à ajouter */ + GRenderingLine *line; /* Représentation à ajouter */ GChecksum *checksum; /* Calcul de l'empreinte */ const gchar *hex; /* Valeur hexadécimale du SHA */ result = NULL;/* FIXME DL_LIST_HEAD_INIT( **/ - line = create_prologue_line("Disassembly generated by OpenIDA"); - add_line_to_rendering_lines(&result, line); + line = g_prologue_line_new("Disassembly generated by OpenIDA"); + g_rendering_line_add_to_lines(&result, line); - line = create_prologue_line("OpenIDA is free software - © 2008-2009 Cyrille Bagard"); - add_line_to_rendering_lines(&result, line); + line = g_prologue_line_new("OpenIDA is free software - © 2008-2009 Cyrille Bagard"); + g_rendering_line_add_to_lines(&result, line); - line = create_prologue_line(""); - add_line_to_rendering_lines(&result, line); + line = g_prologue_line_new(""); + g_rendering_line_add_to_lines(&result, line); /* Fichier */ @@ -387,8 +447,8 @@ rendering_line *build_binary_prologue(const char *filename, const uint8_t *data, snprintf(content, len + 1, "%s%s", _("File: "), filename); - line = create_prologue_line(content); - add_line_to_rendering_lines(&result, line); + line = g_prologue_line_new(content); + g_rendering_line_add_to_lines(&result, line); free(content); @@ -406,33 +466,36 @@ rendering_line *build_binary_prologue(const char *filename, const uint8_t *data, g_checksum_free(checksum); - line = create_prologue_line(content); - add_line_to_rendering_lines(&result, line); + line = g_prologue_line_new(content); + g_rendering_line_add_to_lines(&result, line); free(content); - line = create_prologue_line(""); - add_line_to_rendering_lines(&result, line); + line = g_prologue_line_new(""); + g_rendering_line_add_to_lines(&result, line); - line = create_prologue_line(""); - add_line_to_rendering_lines(&result, line); + line = g_prologue_line_new(""); + g_rendering_line_add_to_lines(&result, line); return result; } +/****************************************************************************** +* * +* Paramètres : binary = binaire dont le contenu est à analyser. * +* * +* Description : Procède au désassemblage basique d'un contenu binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ - -void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2) +void disassemble_openida_binary(openida_binary *binary) { - off_t length; - uint8_t *bin_data; - int ret; - - exe_format *format; - dbg_format *dformat; - asm_processor *proc; asm_instr *instr; bin_routine **routines; /* Liste des routines trouvées */ @@ -442,24 +505,14 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2) size_t parts_count; - char **comments; - uint64_t *offsets; - size_t comments_count; - code_line_info **comments_list; - rendering_line *lines; - rendering_line *line; + GRenderingLine *line; - code_line_info **list; - size_t list_len; - code_line_info *item; off_t start; off_t pos; off_t len; - char buffer[64]; - uint64_t base = 0; uint64_t offset = 0; @@ -471,50 +524,18 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2) char *routine_desc; /* Prototype d'une routine */ - disass_options options; - - proc = create_x86_processor(); - - pos = 0; - len = 0x28; - - - register_exe_format(_("ELF"), elf_is_matching, load_elf); - register_exe_format(_("Java"), java_is_matching, load_java); - register_exe_format(_("Portable Executable"), pe_is_matching, load_pe); - - - bin_data = map_binary_file("/tmp/hello", &length); - printf(" ~~ bin_data ~~ :: %p (%d)\n", bin_data, length); + binary->lines = build_binary_prologue(binary->filename, binary->bin_data, binary->bin_length); - if (bin_data == NULL) return; - format = load_new_exe_format(bin_data, length); - printf(" --> ok ? %p\n", format); + routines = get_all_exe_routines(binary->format, &routines_count); - //exit(0); - - lines = build_binary_prologue("/tmp/hello", bin_data, length); - - - - - options.show_address = true; - options.show_code = true; - - options.format = format; - options.proc = proc; - - routines = get_all_exe_routines(format, &routines_count); - - - parts = get_elf_default_code_parts(format, &parts_count); + parts = get_elf_default_code_parts(binary->format, &parts_count); qsort(parts, parts_count, sizeof(bin_part *), compare_bin_parts); @@ -534,11 +555,11 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2) offset = base + pos; - instr = decode_instruction(proc, &bin_data[start], &pos, len, start, offset); + instr = decode_instruction(binary->proc, &binary->bin_data[start], &pos, len, start, offset); - line = create_code_line(instr, offset, &options); - add_line_to_rendering_lines(&lines, line); + line = g_code_line_new(offset, instr, &binary->options); + g_rendering_line_add_to_lines(&binary->lines, line); } @@ -552,8 +573,8 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2) routine_desc = routine_to_string(routines[k]); - line = create_comment_line(routine_offset, RLT_PROTOTYPE, routine_desc, &options); - insert_line_into_rendering_lines(&lines, line, true); + line = g_comment_line_new(routine_offset, routine_desc, &binary->options); + g_rendering_line_insert_into_lines(&binary->lines, line, true); free(routine_desc); @@ -566,127 +587,10 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2) - line = find_offset_in_rendering_lines(lines, get_exe_entry_point(format)); - add_rendering_line_flag(line, RLF_ENTRY_POINT); - - - gtk_snippet_set_rendering_lines(snippet, lines); - - handle_new_exe_on_symbols_panel(panel, format); - handle_new_exe_on_strings_panel(panel2, format); - - return; - - - /////format = load_elf(bin_data, length); - dformat = load_dwarf(bin_data, length, format); - - - //comments_count = get_dwarf_comments(dformat, &comments, &offsets); - - comments = NULL; - offsets = NULL; - comments_count = 0; - - get_elf_symbol_comments(format, &comments, &offsets, &comments_count); - - comments_list = (code_line_info **)calloc(comments_count, sizeof(code_line_info *)); - - for (i = 0; i < comments_count; i++) - comments_list[i] = create_code_line_info(offsets[i], NULL, strdup(comments[i])); - - - qsort(comments_list, comments_count, sizeof(code_line_info *), compare_code_line_info); - - - - parts = get_elf_default_code_parts(format, &parts_count); - - - - list = NULL; - list_len = 0; - - - gtk_snippet_set_format(snippet, format); - gtk_snippet_set_processor(snippet, proc); - - - for (i = 0; i < parts_count; i++) - { - get_bin_part_values(parts[i], &pos, &len, &base); - + line = g_rendering_line_find_by_offset(binary->lines, get_exe_entry_point(binary->format)); + g_rendering_line_add_flag(line, RLF_ENTRY_POINT); - /*find_line_info(bin_data, &len);*/ - /* - printf("Exiting...\n"); - exit(0); - */ - - offset = base; - - for (k = 0; k < comments_count; k++) - if (comments_list[k]->offset >= base) break; - - - - - item = create_code_line_info(offset, NULL, "Simple HelloWorld !"); - - list = (code_line_info **)realloc(list, ++list_len * sizeof(code_line_info *)); - list[list_len - 1] = item; - - - - start = pos; - pos = 0; - - while (pos < len) - { - offset = base + pos; - - /* Si on a un commentaire pour cette ligne... */ - if (k < comments_count && comments_list[k]->offset == offset) - { - list = (code_line_info **)realloc(list, ++list_len * sizeof(code_line_info *)); - list[list_len - 1] = comments_list[k++]; - } - - - instr = decode_instruction(proc, &bin_data[start], &pos, len, start, offset); - - - item = create_code_line_info(offset, instr, NULL); - - list = (code_line_info **)realloc(list, ++list_len * sizeof(code_line_info *)); - list[list_len - 1] = item; - - //gtk_snippet_add_line(snippet, offset, instr, NULL); - - - } - - - /**** - ret = munmap(bin_data, length); - ****/ - - /* - gtk_snippet_build_content(snippet); - */ - - } - - for (i = 0; i < list_len; i++) - { - gtk_snippet_add_line(snippet, list[i]); - /* TODO: free() */ - } - - handle_new_exe_on_symbols_panel(panel, format); - handle_new_exe_on_strings_panel(panel2, format); } - diff --git a/src/binary.h b/src/binary.h index 8a36a02..ed3522d 100644 --- a/src/binary.h +++ b/src/binary.h @@ -29,6 +29,9 @@ #include "xml.h" +#include "analysis/line.h" + + /* Description d'un fichier binaire */ typedef struct _openida_binary openida_binary; @@ -43,6 +46,12 @@ void unload_binary_file(openida_binary *); /* Fournit une description humaine d'un élément binaire. */ const char *openida_binary_to_string(const openida_binary *); +/* Fournit le fichier correspondant à l'élément binaire. */ +const char *openida_binary_get_filename(const openida_binary *); + +/* Fournit les lignes de rendu issues du désassemblage. */ +GRenderingLine *get_openida_binary_lines(const openida_binary *); + /* Lit un élément binaire depuis un fichier XML. */ @@ -54,18 +63,6 @@ bool write_openida_binary_to_xml(const openida_binary *, xmlTextWriterPtr); -#include "gtksnippet.h" - - - - - - - - - -void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2); - diff --git a/src/debug/Makefile.am b/src/debug/Makefile.am new file mode 100755 index 0000000..caea642 --- /dev/null +++ b/src/debug/Makefile.am @@ -0,0 +1,16 @@ + +lib_LIBRARIES = libdebug.a + +libdebug_a_SOURCES = \ + debuggers.h debuggers.c + +libdebug_a_CFLAGS = $(AM_CFLAGS) + + +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CPPFLAGS = + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +SUBDIRS = ptrace diff --git a/src/debug/debugger-int.h b/src/debug/debugger-int.h new file mode 100644 index 0000000..1b47a03 --- /dev/null +++ b/src/debug/debugger-int.h @@ -0,0 +1,74 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * debugger-int.h - prototypes pour l'interface des débogueurs + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _DEBUG_DEBUGGER_INT_H +#define _DEBUG_DEBUGGER_INT_H + + +#include "debuggers.h" + + +#include + + + +/* Démarre, met en pause ou tue une procédure de débogage. */ +typedef bool (* basic_debugger_fc) (GBinaryDebugger *); + +/* Reprend une procédure de débogage. */ +typedef bool (* resume_debugger_fc) (GBinaryDebugger *); + +/* Fournit la valeur des registres de l'architecture. */ +typedef register_value * (* get_register_values_fc) (GBinaryDebugger *, size_t *); + + +/* Définition des fonctionnalités d'un débogueur (instance) */ +struct _GBinaryDebugger +{ + GObject parent; /* A laisser en premier */ + + openida_binary *binary; /* Cible à traiter */ + + basic_debugger_fc run; /* Démarre le débogueur */ + basic_debugger_fc pause; /* Met en pause le débogueur */ + resume_debugger_fc resume; /* Relance le débogueur */ + basic_debugger_fc kill; /* Tue le débogueur */ + + get_register_values_fc get_reg_values; /* Obtient les valeurs de reg. */ + +}; + + +/* Définition des fonctionnalités d'un débogueur (classe) */ +struct _GBinaryDebuggerClass +{ + GObjectClass parent; /* A laisser en premier */ + + /* Signaux */ + + void (* debugger_stopped) (GBinaryDebugger *, uint64_t, uint64_t); + +}; + + +#endif /* _DEBUG_DEBUGGER_INT_H */ diff --git a/src/debug/debuggers.c b/src/debug/debuggers.c new file mode 100644 index 0000000..a9537c3 --- /dev/null +++ b/src/debug/debuggers.c @@ -0,0 +1,197 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * debugger.sc - gestion des différents débogueurs + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "debuggers.h" + +#include "debugger-int.h" +#include "ptrace/ptrace.h" +#include "../gtkext/iodamarshal.h" + + + +/* Initialise la classe de base des débogueurs. */ +static void g_binary_debugger_class_init(GBinaryDebuggerClass *); + +/* Initialise une instance de base d'un débogueur. */ +static void g_binary_debugger_init(GBinaryDebugger *); + + + +/* Indique le type définit pour une ligne de représentation. */ +G_DEFINE_TYPE(GBinaryDebugger, g_binary_debugger, G_TYPE_OBJECT); + + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe de base des débogueurs. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_debugger_class_init(GBinaryDebuggerClass *klass) +{ + g_signal_new("debugger-stopped", + G_TYPE_BINARY_DEBUGGER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GBinaryDebuggerClass, debugger_stopped), + NULL, NULL, + g_cclosure_user_marshal_VOID__UINT64_UINT64, + G_TYPE_NONE, 2, G_TYPE_UINT64, G_TYPE_UINT64); + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = instance à initialiser. * +* * +* Description : Initialise une instance de base d'un débogueur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_debugger_init(GBinaryDebugger *debugger) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : type = type de débigueur choisi pour l'opération. * +* binary = binaire devant être débogué. * +* * +* Description : Crée un nouveau débogueur. * +* * +* Retour : Composant GObject mis en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinaryDebugger *g_new_binary_debugger(DebuggerType type, openida_binary *binary) +{ + GBinaryDebugger *result; + + switch (type) + { + case DGT_PTRACE: + result = g_object_new(G_TYPE_PTRACE_DEBUGGER, NULL); + break; + default: + result = NULL; + break; + } + + if (result != NULL) + result->binary = binary; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à manipuler ici. * +* * +* Description : Démarre une procédure de débogage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_debugger_run(GBinaryDebugger *debugger) +{ + debugger->run(debugger); + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à manipuler ici. * +* * +* Description : Reprend une procédure de débogage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_debugger_resume(GBinaryDebugger *debugger) +{ + debugger->resume(debugger); + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à manipuler ici. * +* * +* Description : Tue une procédure de débogage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_debugger_kill(GBinaryDebugger *debugger) +{ + debugger->kill(debugger); + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à manipuler ici. * +* count = nombre de transmissions effetuées. * +* * +* Description : Fournit la valeur des registres de l'architecture. * +* * +* Retour : Tableau de valeurs transmises à libérer de la mémoire / NULL.* +* * +* Remarques : - * +* * +******************************************************************************/ + +register_value *g_binary_debugger_get_registers(GBinaryDebugger *debugger, size_t *count) +{ + return debugger->get_reg_values(debugger, count); + +} diff --git a/src/debug/debuggers.h b/src/debug/debuggers.h new file mode 100644 index 0000000..96e0c47 --- /dev/null +++ b/src/debug/debuggers.h @@ -0,0 +1,91 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * debuggers.h - prototypes pour la gestion des différents débogueurs + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _DEBUG_DEBUGGER_H +#define _DEBUG_DEBUGGER_H + + +#include +#include +#include + + +#include "../binary.h" + + + +/* Liste de tous les débogueurs */ +typedef enum _DebuggerType +{ + DGT_PTRACE, /* Utilisation de ptrace() */ + + DGT_COUNT + +} DebuggerType; + + +/* Transmission des valeurs des registres */ +typedef struct _register_value +{ + const char *name; /* Nom à ne pas libérer */ + uint64_t value; /* Valeur (taille maximale) */ + +} register_value; + + +#define G_TYPE_BINARY_DEBUGGER g_binary_debugger_get_type() +#define G_BINARY_DEBUGGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_binary_debugger_get_type(), GBinaryDebugger)) +#define G_IS_BINARY_DEBUGGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_binary_debugger_get_type())) +#define G_BINARY_DEBUGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BINARY_DEBUGGER, GGBinaryDebuggerClass)) +#define G_IS_BINARY_DEBUGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BINARY_DEBUGGER)) +#define G_BINARY_DEBUGGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BINARY_DEBUGGER, GGBinaryDebuggerClass)) + + +/* Définition des fonctionnalités d'un débogueur (instance) */ +typedef struct _GBinaryDebugger GBinaryDebugger; + +/* Définition des fonctionnalités d'un débogueur (classe) */ +typedef struct _GBinaryDebuggerClass GBinaryDebuggerClass; + + +/* Indique le type définit par la GLib pour le débogueur ptrace(). */ +GType g_binary_debugger_get_type(void); + +/* Crée un nouveau débogueur. */ +GBinaryDebugger *g_new_binary_debugger(DebuggerType, openida_binary *); + +/* Démarre une procédure de débogage. */ +void g_binary_debugger_run(GBinaryDebugger *); + +/* Reprend une procédure de débogage. */ +void g_binary_debugger_resume(GBinaryDebugger *); + +/* Tue une procédure de débogage. */ +void g_binary_debugger_kill(GBinaryDebugger *); + +/* Fournit la valeur des registres de l'architecture. */ +register_value *g_binary_debugger_get_registers(GBinaryDebugger *, size_t *); + + + +#endif /* _DEBUG_DEBUGGER_H */ diff --git a/src/debug/ptrace/Makefile.am b/src/debug/ptrace/Makefile.am new file mode 100644 index 0000000..0512721 --- /dev/null +++ b/src/debug/ptrace/Makefile.am @@ -0,0 +1,15 @@ + +lib_LIBRARIES = libdebugptrace.a + +libdebugptrace_a_SOURCES = \ + options.h options.c \ + ptrace.h ptrace.c + +libdebugptrace_a_CFLAGS = $(AM_CFLAGS) + + +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CPPFLAGS = + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/src/debug/ptrace/options.c b/src/debug/ptrace/options.c new file mode 100644 index 0000000..6aa8a1c --- /dev/null +++ b/src/debug/ptrace/options.c @@ -0,0 +1,104 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * options.c - configuration du débogage ptrace() + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "options.h" + + +#include +#include +#include +#include + + + +/* ---------------------- OPTIONS POUR LE DEBOGAGE AVEC PTRACE ---------------------- */ + + +/* Description des options */ +struct _ptrace_options +{ + char *filename; /* Fichier à exécuter */ + char **argv; /* Argument à fournir */ + +}; + + + + + + +/* ---------------------------------------------------------------------------------- */ +/* OPTIONS POUR LE DEBOGAGE AVEC PTRACE */ +/* ---------------------------------------------------------------------------------- */ + + + +/****************************************************************************** +* * +* Paramètres : binary = élément binaire ciblé par le débogage. * +* * +* Description : Etablit les options par défaut pour un binaire donné. * +* * +* Retour : Structure mise en place (ou NULL en cas d'échec). * +* * +* Remarques : - * +* * +******************************************************************************/ + +ptrace_options *create_ptrace_options_from_binary(const openida_binary *binary) +{ + ptrace_options *result; + + result = (ptrace_options *)calloc(1, sizeof(ptrace_options)); + + result->filename = strdup(openida_binary_get_filename(binary)); + + result->argv = (char **)calloc(2, sizeof(char *)); + + result->argv[0] = basename(result->filename); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : options = options du débogage à consulter. * +* * +* Description : Lance le processus à déboguer via ptrace(). * +* * +* Retour : false en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool run_ptrace_options_process(const ptrace_options *options) +{ + execv(options->filename, options->argv); + perror("execlp"); + + return false; + +} diff --git a/src/debug/ptrace/options.h b/src/debug/ptrace/options.h new file mode 100644 index 0000000..e49f87c --- /dev/null +++ b/src/debug/ptrace/options.h @@ -0,0 +1,50 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * options.h - prototypes pour la configuration du débogage ptrace() + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _DEBUG_PTRACE_OPTIONS_H +#define _DEBUG_PTRACE_OPTIONS_H + + +#include + + +#include "../../binary.h" + + + +/* ---------------------- OPTIONS POUR LE DEBOGAGE AVEC PTRACE ---------------------- */ + + +/* Description des options */ +typedef struct _ptrace_options ptrace_options; + + +/* Etablit les options par défaut pour un binaire donné. */ +ptrace_options *create_ptrace_options_from_binary(const openida_binary *); + +/* Lance le processus à déboguer via ptrace(). */ +bool run_ptrace_options_process(const ptrace_options *); + + + +#endif /* _DEBUG_PTRACE_OPTIONS_H */ diff --git a/src/debug/ptrace/ptrace.c b/src/debug/ptrace/ptrace.c new file mode 100644 index 0000000..8840ce6 --- /dev/null +++ b/src/debug/ptrace/ptrace.c @@ -0,0 +1,449 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * ptrace.c - débogage à l'aide de ptrace() + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "ptrace.h" + + +#include +#include +#include +#include + + +#include "options.h" +#include "../debugger-int.h" +#include "../../panel/log.h" + + + + +/** Partie ptrace() **/ +#include +#include +//#include +#include /* For SYS_write etc */ +#include +/** Partie ptrace() **/ + + + + +#define _(str) str + + + + +/* Débogueur utilisant ptrace() (instance) */ +struct _GPtraceDebugger +{ + GBinaryDebugger parent; /* A laisser en premier */ + + GCond *cond; /* Poursuite du déroulement */ + GMutex *mutex; /* Accès à la condition */ + + ptrace_options *options; /* Configuration du débogage */ + + pid_t child; /* Processus suivi lancé */ + + gboolean run_again; /* Reprise du débogage */ + +}; + +/* Débogueur utilisant ptrace() (classe) */ +struct _GPtraceDebuggerClass +{ + GBinaryDebuggerClass parent; /* A laisser en premier */ + +}; + + +/* Met en marche le débogueur utilisant ptrace(). */ +bool g_ptrace_debugger_run(GPtraceDebugger *); + +/* Remet en marche le débogueur utilisant ptrace(). */ +bool g_ptrace_debugger_resume(GPtraceDebugger *); + +/* Tue le débogueur utilisant ptrace(). */ +bool g_ptrace_debugger_kill(GPtraceDebugger *); + +/* Procède à un débogage via ptrace(). */ +void *ptrace_thread(GPtraceDebugger *); + +/* Fournit la valeur des registres de l'architecture. */ +register_value *get_register_values_using_ptrace_debugger(GPtraceDebugger *, size_t *); + +/* Initialise la classe du débogueur utilisant ptrace(). */ +static void g_ptrace_debugger_class_init(GPtraceDebuggerClass *); + +/* Procède à l'initialisation du débogueur utilisant ptrace(). */ +static void g_ptrace_debugger_init(GPtraceDebugger *); + + + +/* Indique le type définit par la GLib pour le débogueur ptrace(). */ +G_DEFINE_TYPE(GPtraceDebugger, g_ptrace_debugger, G_TYPE_BINARY_DEBUGGER); + + + +/****************************************************************************** +* * +* Paramètres : klass = classe de débogueur à initialiser. * +* * +* Description : Initialise la classe du débogueur utilisant ptrace(). * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_ptrace_debugger_class_init(GPtraceDebuggerClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = instance de débogueur à préparer. * +* * +* Description : Procède à l'initialisation du débogueur utilisant ptrace(). * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_ptrace_debugger_init(GPtraceDebugger *debugger) +{ + GBinaryDebugger *parent; /* Instance parente */ + + parent = G_BINARY_DEBUGGER(debugger); + + parent->run = (basic_debugger_fc)g_ptrace_debugger_run; + parent->resume = (resume_debugger_fc)g_ptrace_debugger_resume; + parent->kill = (basic_debugger_fc)g_ptrace_debugger_kill; + + parent->get_reg_values = (get_register_values_fc)get_register_values_using_ptrace_debugger; + + debugger->cond = g_cond_new(); + debugger->mutex = g_mutex_new(); + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à lancer. * +* * +* Description : Met en marche le débogueur utilisant ptrace(). * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_ptrace_debugger_run(GPtraceDebugger *debugger) +{ + GError *error; /* Bilan de création de thread */ + + if (debugger->options == NULL) + debugger->options = create_ptrace_options_from_binary(G_BINARY_DEBUGGER(debugger)->binary); + + if (debugger->options == NULL) + return false; + + + + + if (!g_thread_create((GThreadFunc)ptrace_thread, debugger, FALSE, &error)) + { + printf ("Failed to create the thread: %s\n", error->message); + } + + + /* + printf("Start Debugger with bin :: %p\n", G_BINARY_DEBUGGER_GET_IFACE(debugger)->binary); + + g_signal_emit_by_name(debugger, "debugger-stopped", (uint64_t)0xdeadbeaf); + */ + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à relancer. * +* * +* Description : Remet en marche le débogueur utilisant ptrace(). * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_ptrace_debugger_resume(GPtraceDebugger *debugger) +{ + g_mutex_lock(debugger->mutex); + debugger->run_again = TRUE; + g_cond_signal(debugger->cond); + g_mutex_unlock(debugger->mutex); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à relancer. * +* * +* Description : Tue le débogueur utilisant ptrace(). * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_ptrace_debugger_kill(GPtraceDebugger *debugger) +{ + 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); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = encadrement associée à l'opération. * +* * +* Description : Procède à un débogage via ptrace(). * +* * +* Retour : ??? * +* * +* Remarques : - * +* * +******************************************************************************/ + +void *ptrace_thread(GPtraceDebugger *debugger) +{ + + + + long last_eip; /* Ancien point d'arrêt */ + long cur_eip; /* Point d'arrêt courant */ + + + long orig_eax; + int status; + + + pid_t pid; + + + bool first_run; /* Premier passage ? */ + + + debugger->child = fork(); + + switch (debugger->child) + { + case -1: + perror("fork"); + exit(-1); + break; + + case 0: + ptrace(PTRACE_TRACEME, 0, NULL, NULL); + run_ptrace_options_process(debugger->options); + _exit(-1); + break; + + default: + + gdk_threads_enter(); + + log_variadic_message(LMT_PROCESS, _("Starting to debug %s..."), + openida_binary_get_filename(G_BINARY_DEBUGGER(debugger)->binary)); + + gdk_flush (); + gdk_threads_leave(); + + first_run = true; + + while(1) + { + + + + + pid = waitpid(debugger->child, &status, 0/*WNOHANG*/); + //wait(&status); + + printf("Status :: %d\n", WIFEXITED(status)); + + if(WIFEXITED(status)) + break; + + orig_eax = ptrace(PTRACE_PEEKUSER, + debugger->child, 4 * ORIG_EAX, NULL); + if (orig_eax == -1) + { + //printf("errno :: %d vs %d\n", errno, ESRCH); + perror("ptrace()"); + } + + /* get GTK thread lock */ + gdk_threads_enter(); + + + //gtk_text_buffer_insert_at_cursor (info->buffer, "Thread waiting for resume...\n", -1); + + //gdk_flush (); + + /* release GTK thread lock */ + //gdk_threads_leave(); + + + /* Notification du point d'arrêt */ + + cur_eip = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * EIP, NULL); + + if (first_run) + { + last_eip = cur_eip; + first_run = false; + } + + g_signal_emit_by_name(debugger, "debugger-stopped", + (uint64_t)last_eip, (uint64_t)cur_eip); + + last_eip = cur_eip; + + /* release GTK thread lock */ + gdk_flush (); + + gdk_threads_leave(); + + g_mutex_lock(debugger->mutex); + while (!debugger->run_again) + g_cond_wait(debugger->cond, debugger->mutex); + debugger->run_again = FALSE; + g_mutex_unlock(debugger->mutex); + + + if (debugger->child == 0) break; + + + ptrace(PTRACE_SYSCALL, debugger->child, NULL, NULL); + + } + + log_variadic_message(LMT_PROCESS, _("Finished to debug %s..."), + openida_binary_get_filename(G_BINARY_DEBUGGER(debugger)->binary)); + + break; + + } + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : debugger = débogueur à utiliser. * +* count = nombre de transmissions effetuées. * +* * +* Description : Fournit la valeur des registres de l'architecture. * +* * +* Retour : Tableau de valeurs transmises à libérer de la mémoire / NULL.* +* * +* Remarques : - * +* * +******************************************************************************/ + +register_value *get_register_values_using_ptrace_debugger(GPtraceDebugger *debugger, size_t *count) +{ + register_value *result; /* Liste de valeurs renvoyées */ + long ret; /* Valeur de registre */ + + *count = 9; + result = (register_value *)calloc(*count, sizeof(register_value)); + + ret = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * EAX, NULL); + result[0].name = "eax"; + result[0].value = ret; + + ret = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * EBX, NULL); + result[1].name = "ebx"; + result[1].value = ret; + + ret = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * ECX, NULL); + result[2].name = "ecx"; + result[2].value = ret; + + ret = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * EDX, NULL); + result[3].name = "edx"; + result[3].value = ret; + + ret = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * ESI, NULL); + result[4].name = "esi"; + result[4].value = ret; + + ret = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * EDI, NULL); + result[5].name = "edi"; + result[5].value = ret; + + ret = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * EBP, NULL); + result[6].name = "ebp"; + result[6].value = ret; + + ret = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * UESP, NULL); + result[7].name = "esp"; + result[7].value = ret; + + ret = ptrace(PTRACE_PEEKUSER, debugger->child, 4 * EIP, NULL); + result[8].name = "eip"; + result[8].value = ret; + + return result; + +} diff --git a/src/debug/ptrace/ptrace.h b/src/debug/ptrace/ptrace.h new file mode 100644 index 0000000..f0e2c2b --- /dev/null +++ b/src/debug/ptrace/ptrace.h @@ -0,0 +1,55 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * ptrace.h - prototypes pour le débogage à l'aide de ptrace() + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _DEBUG_PTRACE_PTRACE_H +#define _DEBUG_PTRACE_PTRACE_H + + +#include + + +#include "../debuggers.h" + + + +#define G_TYPE_PTRACE_DEBUGGER (g_ptrace_debugger_get_type()) +#define G_PTRACE_DEBUGGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PTRACE_DEBUGGER, GPtraceDebugger)) +#define G_IS_PTRACE_DEBUGGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PTRACE_DEBUGGER)) +#define G_PTRACE_DEBUGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PTRACE_DEBUGGER, GPtraceDebuggerClass)) +#define G_IS_PTRACE_DEBUGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PTRACE_DEBUGGER)) +#define G_PTRACE_DEBUGGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PTRACE_DEBUGGER, GPtraceDebuggerClass)) + + +/* Débogueur utilisant ptrace() (instance) */ +typedef struct _GPtraceDebugger GPtraceDebugger; + +/* Débogueur utilisant ptrace() (classe) */ +typedef struct _GPtraceDebuggerClass GPtraceDebuggerClass; + + +/* Indique le type définit par la GLib pour le débogueur ptrace(). */ +GType g_ptrace_debugger_get_type(void); + + + +#endif /* _DEBUG_PTRACE_PTRACE_H */ diff --git a/src/easygtk.c b/src/easygtk.c index bcca8e4..d6f8dc4 100644 --- a/src/easygtk.c +++ b/src/easygtk.c @@ -192,6 +192,43 @@ GtkWidget *qck_create_label(GObject *object, const char *name, const char *capti } gtk_widget_show(result); + gtk_misc_set_alignment(GTK_MISC(result), 0, 0.5); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : object = espace dédié à l'inscription de références. * +* name = nom à donner au nouveau composant. * +* text = éventuel contenu initial du champ de saisie. * +* * +* Description : Crée et enregistre un composant 'GtkEntry'. * +* * +* Retour : Champ de saisie mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *qck_create_entry(GObject *object, const char *name, const char *text) +{ + GtkWidget *result; /* Résultat à renvoyer */ + + result = gtk_entry_new(); + + if (G_IS_OBJECT(object) && name != NULL) + { + gtk_widget_ref(result); + g_object_set_data_full(object, name, result, (GtkDestroyNotify)gtk_widget_unref); + } + + gtk_widget_show(result); + + if (text != NULL) + gtk_entry_set_text(GTK_ENTRY(result), text); return result; diff --git a/src/easygtk.h b/src/easygtk.h index 7b4554b..41b24e0 100644 --- a/src/easygtk.h +++ b/src/easygtk.h @@ -44,6 +44,9 @@ GtkWidget *qck_create_image(GObject *, const char *, gchar *); /* Crée un composant 'GtkLabel'. */ GtkWidget *qck_create_label(GObject *, const char *, const char *); +/* Crée et enregistre un composant 'GtkEntry'. */ +GtkWidget *qck_create_entry(GObject *, const char *, const char *); + /* Crée et enregistre un composant 'GtkButton'. */ GtkWidget *qck_create_button(GObject *, const char *, const char *, GCallback, gpointer); diff --git a/src/editor.c b/src/editor.c index e8ff222..888f1af 100644 --- a/src/editor.c +++ b/src/editor.c @@ -39,25 +39,20 @@ #include /** exemple GTK **/ -/** Partie ptrace() **/ -#include -#include -#include -#include -//#include -#include /* For SYS_write etc */ -/** Partie ptrace() **/ #include "binary.h" #include "dlg_sections.h" #include "easygtk.h" -#include "gtkbinview.h" -#include "gtksnippet.h" #include "pan_strings.h" #include "pan_symbols.h" +#include "gtkext/gtkbinview.h" #include "gtkext/gtkdockpanel.h" +#include "gtkext/gtksnippet.h" +#include "format/exe_format.h" #include "format/mangling/demangler.h" + +#include "debug/debuggers.h" #include "panel/panels.h" @@ -118,6 +113,22 @@ void mcb_select_sections(GtkMenuItem *, gpointer); void reload_menu_project(GObject *); +/*Réagit avec le menu "Débogage -> Démarrer". */ +void mcb_debug_start(GtkCheckMenuItem *, gpointer); + +/* Réagit avec le menu "Débogage -> Mettre en pause". */ +void mcb_debug_pause(GtkCheckMenuItem *, gpointer); + +/* Réagit avec le menu "Débogage -> Reprendre". */ +void mcb_debug_resume(GtkCheckMenuItem *, gpointer); + +/* Réagit avec le menu "Débogage -> Tuer". */ +void mcb_debug_kill(GtkCheckMenuItem *, gpointer); + +/* Met à jour l'accessibilité aux éléments du menu "Debogage". */ +void update_debug_menu_items(GObject *, gboolean); + + /****************************************************************************** @@ -163,6 +174,7 @@ int main(int argc, char **argv) /* Initialisation du programme */ init_all_demanglers(); + init_all_exe_formats(); /* Création de l'interface */ editor = create_editor(); @@ -183,210 +195,10 @@ int main(int argc, char **argv) -GCond* data_cond = NULL; /* Must be initialized somewhere */ -GMutex* data_mutex = NULL; /* Must be initialized somewhere */ -gboolean run_again = FALSE; - - - - -void -on_button1_clicked (GtkButton *button, - gpointer user_data); - - - - -GtkLabel *lbl_eax; -GtkLabel *lbl_ebx; -GtkLabel *lbl_ecx; -GtkLabel *lbl_edx; - - - - -typedef struct _th_info -{ - pid_t child; - GtkTextBuffer *buffer; - - - -} th_info; - - - -#include -#include - -#include -#include - -extern int errno; - - -void *argument_thread(void *args) -{ - th_info *info; - long orig_eax, eax; - long params; - int status; - - char buffer[12]; - - pid_t pid; - - - - - pid = fork(); - - - - if (pid > 0) - { - /*****/ - - } - else ptrace(PTRACE_TRACEME, 0, NULL, NULL); - - sleep(1); - - - if(pid == -1) - { - /* ouch, fork() failed */ - perror("fork"); - exit(-1); - } - else if(pid == 0) - { - // ptrace(PTRACE_TRACEME, 0, NULL, NULL); - execlp("ls", "ls", "-CF", "/", NULL); - - /* if exec() returns, there is something wrong */ - perror("execlp"); - - /* exit child. note the use of _exit() instead of exit() */ - _exit(-1); - } - else - { - info = (th_info *)args; - info->child = pid; - - /* parent */ - gtk_text_buffer_insert_at_cursor (info->buffer, "#PARENT# Fork() succeed !\n", -1); - - - while(1) - { - pid = waitpid(info->child, &status, 0/*WNOHANG*/); - //wait(&status); - - if(WIFEXITED(status)) - break; - - orig_eax = ptrace(PTRACE_PEEKUSER, - info->child, 4 * ORIG_EAX, NULL); - if (orig_eax == -1) - { - printf("errno :: %d vs %d\n", errno, ESRCH); - perror("ptrace()"); - } - - /* get GTK thread lock */ - gdk_threads_enter(); - - params = ptrace(PTRACE_PEEKUSER, info->child, 4 * EAX, NULL); - snprintf(buffer, 11, "0x%08lx", params); - gtk_label_set_text(lbl_eax, buffer); - - params = ptrace(PTRACE_PEEKUSER, info->child, 4 * EBX, NULL); - snprintf(buffer, 11, "0x%08lx", params); - gtk_label_set_text(lbl_ebx, buffer); - - params = ptrace(PTRACE_PEEKUSER, info->child, 4 * ECX, NULL); - snprintf(buffer, 11, "0x%08lx", params); - gtk_label_set_text(lbl_ecx, buffer); - - params = ptrace(PTRACE_PEEKUSER, info->child, 4 * EDX, NULL); - snprintf(buffer, 11, "0x%08lx", params); - gtk_label_set_text(lbl_edx, buffer); - - gtk_text_buffer_insert_at_cursor (info->buffer, "Thread waiting for resume...\n", -1); - - gdk_flush (); - - /* release GTK thread lock */ - gdk_threads_leave(); - - g_mutex_lock (data_mutex); - while (!run_again) - g_cond_wait (data_cond, data_mutex); - run_again = FALSE; - g_mutex_unlock (data_mutex); - - ptrace(PTRACE_SYSCALL, - info->child, NULL, NULL); - } - - - - } - - - - return NULL; - -} - - - - -void -on_button1_clicked (GtkButton *button, - gpointer data) -{ - GtkTextBuffer *buffer; - th_info *info; - GError *error = NULL; - - gtk_widget_set_state(GTK_WIDGET(button), GTK_STATE_INSENSITIVE); - - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (data)); - gtk_text_buffer_insert_at_cursor (buffer, "Hello, this is some text\n", -1); - - - info = (th_info *)calloc(1, sizeof(th_info)); - info->child = 0/*pid*/; - info->buffer = buffer; - - data_cond = g_cond_new (); - data_mutex = g_mutex_new (); - - if (!g_thread_create(argument_thread, info, FALSE, &error)) - { - printf ("Failed to create YES thread: %s\n", error->message); - } - -} - -void -on_button2_clicked (GtkButton *button, - gpointer data) -{ - - g_mutex_lock (data_mutex); - run_again = TRUE; - g_cond_signal (data_cond); - g_mutex_unlock (data_mutex); - -} @@ -409,6 +221,7 @@ GtkWidget *mywid; GtkWidget *create_editor(void) { GtkWidget *result; /* Fenêtre à renvoyer */ + GObject *ref; /* version de référence */ GtkWidget *menuboard; /* Barre de menus principale */ GtkWidget *menuitem; /* Elément de menu */ GtkWidget *menubar; /* Support pour éléments */ @@ -422,32 +235,6 @@ GtkWidget *create_editor(void) GtkWidget *hpaned1; GtkWidget *scrolledwindow2; GtkWidget *snippet; - GtkWidget *fixed1; - GtkWidget *label1; - GtkWidget *button2; - GtkWidget *image1; - GtkWidget *button1; - GtkWidget *table1; - GtkWidget *label3; - GtkWidget *label4; - GtkWidget *label5; - GtkWidget *label6; - GtkWidget *label7; - GtkWidget *label8; - GtkWidget *label9; - GtkWidget *label10; - GtkWidget *label11; - GtkWidget *label12; - GtkWidget *label14; - GtkWidget *label15; - GtkWidget *label16; - GtkWidget *label17; - GtkWidget *label18; - GtkWidget *label19; - GtkWidget *label20; - GtkWidget *label21; - GtkWidget *scrolledwindow1; - GtkWidget *textview1; GtkWidget *statusbar1; GtkWidget *binview; @@ -463,10 +250,6 @@ GtkWidget *create_editor(void) GtkWidget *dpanel; /* Support de panneaux */ GtkDockItem *ditem; /* Panneau avec ses infos. */ - GtkWidget *notebook; /* Support à onglets */ - GtkWidget *label; /* Etiquette pour onglet */ - - #if 0 GtkWidget *vbox; /* Support à divisions vert. */ @@ -479,6 +262,9 @@ GtkWidget *create_editor(void) #endif + openida_binary *binary; + + result = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_set_size_request(result, 800, 600); gtk_window_set_position(GTK_WINDOW(result), GTK_WIN_POS_CENTER); @@ -487,7 +273,7 @@ GtkWidget *create_editor(void) g_signal_connect(G_OBJECT(result), "destroy", G_CALLBACK(destroy_editor), NULL); - + ref = G_OBJECT(result); mywid = result; @@ -576,6 +362,50 @@ GtkWidget *create_editor(void) + menuitem = gtk_menu_item_new_with_mnemonic(_("_Debug")); + gtk_widget_show(menuitem); + gtk_container_add(GTK_CONTAINER(menuboard), menuitem); + + menubar = gtk_menu_new(); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), menubar); + + submenuitem = qck_create_menu_item(ref, "mnu_debug_start", _("Start process"), G_CALLBACK(mcb_debug_start), result); + gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + + submenuitem = qck_create_menu_item(ref, "mnu_debug_pause", _("Pause process"), G_CALLBACK(mcb_debug_pause), result); + gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + + submenuitem = qck_create_menu_item(ref, "mnu_debug_resume", _("Resume process"), G_CALLBACK(mcb_debug_resume), result); + gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + + submenuitem = qck_create_menu_item(ref, "mnu_debug_kill", _("Kill process"), G_CALLBACK(mcb_debug_kill), result); + gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + + submenuitem = qck_create_menu_separator(); + gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + + submenuitem = qck_create_menu_item(ref, "mnu_debug_into", _("Step into"), NULL/*G_CALLBACK()*/, result); + gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + + submenuitem = qck_create_menu_item(ref, "mnu_debug_over", _("Step over"), NULL/*G_CALLBACK()*/, result); + gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + + submenuitem = qck_create_menu_item(ref, "mnu_debug_ret", _("Run until ret"), NULL/*G_CALLBACK()*/, result); + gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + + submenuitem = qck_create_menu_separator(); + gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + + update_debug_menu_items(ref, FALSE); + + + + + + + + + load_recent_openida_projects_list(G_OBJECT(result), G_CALLBACK(mcb_open_recent_project)); @@ -664,182 +494,11 @@ GtkWidget *create_editor(void) ditem = gtk_dock_item_new(_("Symbols"), panel); gtk_dock_panel_add_item(dpanel, ditem); - - - - - fixed1 = gtk_fixed_new (); - gtk_widget_show (fixed1); - - ditem = gtk_dock_item_new(_("Dbg"), fixed1); + ditem = gtk_dock_item_new(_("Registers"), get_panel(PNT_REGISTERS)); gtk_dock_panel_add_item(dpanel, ditem); - label1 = gtk_label_new (_("Registres :")); - gtk_widget_show (label1); - gtk_fixed_put (GTK_FIXED (fixed1), label1, 16, 48); - gtk_widget_set_size_request (label1, 128, 16); - gtk_misc_set_alignment (GTK_MISC (label1), 0, 0.5); - - button2 = gtk_button_new (); - gtk_widget_show (button2); - gtk_fixed_put (GTK_FIXED (fixed1), button2, 80, 8); - gtk_widget_set_size_request (button2, 62, 29); - - image1 = gtk_image_new_from_stock ("gtk-media-play", GTK_ICON_SIZE_BUTTON); - gtk_widget_show (image1); - gtk_container_add (GTK_CONTAINER (button2), image1); - - button1 = gtk_button_new_with_mnemonic (_("Run")); - gtk_widget_show (button1); - gtk_fixed_put (GTK_FIXED (fixed1), button1, 8, 8); - gtk_widget_set_size_request (button1, 62, 29); - - table1 = gtk_table_new (9, 2, FALSE); - gtk_widget_show (table1); - gtk_fixed_put (GTK_FIXED (fixed1), table1, 8, 64); - gtk_widget_set_size_request (table1, 160, 176); - gtk_container_set_border_width (GTK_CONTAINER (table1), 8); - - label3 = gtk_label_new (_("eax :")); - gtk_widget_show (label3); - gtk_table_attach (GTK_TABLE (table1), label3, 0, 1, 0, 1, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label3), 0, 0.5); - - label4 = gtk_label_new (_("ebx :")); - gtk_widget_show (label4); - gtk_table_attach (GTK_TABLE (table1), label4, 0, 1, 1, 2, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label4), 0, 0.5); - - label5 = gtk_label_new (_("ecx :")); - gtk_widget_show (label5); - gtk_table_attach (GTK_TABLE (table1), label5, 0, 1, 2, 3, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label5), 0, 0.5); - - label6 = gtk_label_new (_("edx :")); - gtk_widget_show (label6); - gtk_table_attach (GTK_TABLE (table1), label6, 0, 1, 3, 4, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label6), 0, 0.5); - - label7 = gtk_label_new (_("esp :")); - gtk_widget_show (label7); - gtk_table_attach (GTK_TABLE (table1), label7, 0, 1, 4, 5, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label7), 0, 0.5); - - label8 = gtk_label_new (_("ebp :")); - gtk_widget_show (label8); - gtk_table_attach (GTK_TABLE (table1), label8, 0, 1, 5, 6, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label8), 0, 0.5); - - label9 = gtk_label_new (_("esi :")); - gtk_widget_show (label9); - gtk_table_attach (GTK_TABLE (table1), label9, 0, 1, 6, 7, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label9), 0, 0.5); - - label10 = gtk_label_new (_("edi :")); - gtk_widget_show (label10); - gtk_table_attach (GTK_TABLE (table1), label10, 0, 1, 7, 8, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label10), 0, 0.5); - - label11 = gtk_label_new (_("eip :")); - gtk_widget_show (label11); - gtk_table_attach (GTK_TABLE (table1), label11, 0, 1, 8, 9, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label11), 0, 0.5); - - label12 = gtk_label_new (_("0x00000000")); - gtk_widget_show (label12); - gtk_table_attach (GTK_TABLE (table1), label12, 1, 2, 0, 1, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label12), 0, 0.5); - - lbl_eax = label12; - gtk_widget_modify_font(lbl_eax, pango_font_description_from_string ("Monospace")); - - label14 = gtk_label_new (_("0x00000000")); - gtk_widget_show (label14); - gtk_table_attach (GTK_TABLE (table1), label14, 1, 2, 2, 3, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label14), 0, 0.5); - - lbl_ebx = label14; - gtk_widget_modify_font(lbl_ebx, pango_font_description_from_string ("Monospace 10")); - - label15 = gtk_label_new (_("0x00000000")); - gtk_widget_show (label15); - gtk_table_attach (GTK_TABLE (table1), label15, 1, 2, 3, 4, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label15), 0, 0.5); - - lbl_ecx = label15; - gtk_widget_modify_font(lbl_ecx, pango_font_description_from_string ("Monospace 10")); - - label16 = gtk_label_new (_("0x00000000")); - gtk_widget_show (label16); - gtk_table_attach (GTK_TABLE (table1), label16, 1, 2, 4, 5, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label16), 0, 0.5); - - lbl_edx = label16; - gtk_widget_modify_font(lbl_edx, pango_font_description_from_string ("Monospace 10")); - - label17 = gtk_label_new (_("0x00000000")); - gtk_widget_show (label17); - gtk_table_attach (GTK_TABLE (table1), label17, 1, 2, 5, 6, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label17), 0, 0.5); - - label18 = gtk_label_new (_("0x00000000")); - gtk_widget_show (label18); - gtk_table_attach (GTK_TABLE (table1), label18, 1, 2, 6, 7, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label18), 0, 0.5); - - label19 = gtk_label_new (_("0x00000000")); - gtk_widget_show (label19); - gtk_table_attach (GTK_TABLE (table1), label19, 1, 2, 7, 8, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label19), 0, 0.5); - - label20 = gtk_label_new (_("0x00000000")); - gtk_widget_show (label20); - gtk_table_attach (GTK_TABLE (table1), label20, 1, 2, 8, 9, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label20), 0, 0.5); - - label21 = gtk_label_new (_("0x00000000")); - gtk_widget_show (label21); - gtk_table_attach (GTK_TABLE (table1), label21, 1, 2, 1, 2, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label21), 0, 0.5); - @@ -904,26 +563,13 @@ GtkWidget *create_editor(void) - /* - g_signal_connect ((gpointer) button1, "clicked", - G_CALLBACK (on_button1_clicked), - textview1); - */ - - - - - g_signal_connect ((gpointer) button2, "clicked", - G_CALLBACK (on_button2_clicked), - NULL); - - - /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ - fill_snippet(snippet, _panel, panel); + binary = load_binary_file("/tmp/hello"); + gtk_snippet_set_rendering_lines(snippet, get_openida_binary_lines(binary)); + g_object_set_data(G_OBJECT(result), "current_binary", binary); return result; @@ -1320,3 +966,222 @@ void reload_menu_project(GObject *ref) gtk_widget_set_sensitive(menuitem, count > 0); } + + + +void debugger_stopped_cb(GBinaryDebugger *debugger, uint64_t last, uint64_t cur, gpointer data) +{ + + GObject *ref; + + openida_binary *binary; + GRenderingLine *line; + + + GtkWidget *submenuitem; /* Menu à rendre accessible */ + + register_value *values; + size_t count; + + + ref = G_OBJECT(data); + + + binary = g_object_get_data(ref, "current_binary"); + + + if (last != cur) + { + line = g_rendering_line_find_by_offset(get_openida_binary_lines(binary), last); + + if (line != NULL) + g_rendering_line_remove_flag(line, RLF_RUNNING_BP); + + } + + + printf("bp at 0x%016llx\n", cur); + + line = g_rendering_line_find_by_offset(get_openida_binary_lines(binary), cur); + + if (line != NULL) + g_rendering_line_add_flag(line, RLF_RUNNING_BP); + else + printf("no line at address !\n"); + + + values = g_binary_debugger_get_registers(debugger, &count); + + + + + + /* Mises à jour */ + + update_debug_menu_items(ref, TRUE); + + + + + + + + refresh_registers_panel_with_registers(get_panel(PNT_REGISTERS), values, count); + + + +} + + +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu ayant basculé. * +* data = adresse de l'espace de référencement global. * +* * +* Description : Réagit avec le menu "Débogage -> Démarrer". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void mcb_debug_start(GtkCheckMenuItem *menuitem, gpointer data) +{ + openida_binary *binary; /* Binaire à analyser */ + GBinaryDebugger *debugger; /* Débogueur offrant l'analyse */ + + + binary = g_object_get_data(G_OBJECT(data), "current_binary"); + + + + debugger = g_new_binary_debugger(DGT_PTRACE, binary); + g_object_set_data(G_OBJECT(data), "current_debugger", debugger); + + + g_signal_connect(debugger, "debugger-stopped", G_CALLBACK(debugger_stopped_cb), data); + + g_binary_debugger_run(debugger); + + +} + + +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu ayant basculé. * +* data = adresse de l'espace de référencement global. * +* * +* Description : Réagit avec le menu "Débogage -> Mettre en pause". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void mcb_debug_pause(GtkCheckMenuItem *menuitem, gpointer data) +{ + GBinaryDebugger *debugger; /* Débogueur offrant l'analyse */ + + + debugger = g_object_get_data(G_OBJECT(data), "current_debugger"); + + + + //g_binary_debugger_resume(debugger); + + + +} + + +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu ayant basculé. * +* data = adresse de l'espace de référencement global. * +* * +* Description : Réagit avec le menu "Débogage -> Reprendre". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void mcb_debug_resume(GtkCheckMenuItem *menuitem, gpointer data) +{ + GBinaryDebugger *debugger; /* Débogueur offrant l'analyse */ + + + debugger = g_object_get_data(G_OBJECT(data), "current_debugger"); + + + + g_binary_debugger_resume(debugger); + + + +} + + +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu ayant basculé. * +* data = adresse de l'espace de référencement global. * +* * +* Description : Réagit avec le menu "Débogage -> Tuer". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void mcb_debug_kill(GtkCheckMenuItem *menuitem, gpointer data) +{ + GBinaryDebugger *debugger; /* Débogueur offrant l'analyse */ + + debugger = g_object_get_data(G_OBJECT(data), "current_debugger"); + + g_binary_debugger_kill(debugger); + + /* TODO : retirer l'association binary <-> debugger */ + +} + + +/****************************************************************************** +* * +* Paramètres : ref = adresse de l'espace de référencement global. * +* stopped = indique l'état d'accessibilité des menus. * +* * +* Description : Met à jour l'accessibilité aux éléments du menu "Debogage". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void update_debug_menu_items(GObject *ref, gboolean stopped) +{ + GtkWidget *submenuitem; /* Menu à rendre accessible */ + + submenuitem = GTK_WIDGET(g_object_get_data(ref, "mnu_debug_pause")); + gtk_widget_set_sensitive(submenuitem, stopped); + + submenuitem = GTK_WIDGET(g_object_get_data(ref, "mnu_debug_resume")); + gtk_widget_set_sensitive(submenuitem, stopped); + + submenuitem = GTK_WIDGET(g_object_get_data(ref, "mnu_debug_into")); + gtk_widget_set_sensitive(submenuitem, stopped); + + submenuitem = GTK_WIDGET(g_object_get_data(ref, "mnu_debug_over")); + gtk_widget_set_sensitive(submenuitem, stopped); + + submenuitem = GTK_WIDGET(g_object_get_data(ref, "mnu_debug_ret")); + gtk_widget_set_sensitive(submenuitem, stopped); + +} diff --git a/src/format/elf/strings.c b/src/format/elf/strings.c index 049f6d4..3178d69 100644 --- a/src/format/elf/strings.c +++ b/src/format/elf/strings.c @@ -59,6 +59,8 @@ bool find_all_elf_strings(elf_format *format) Elf_Shdr *sections; /* Groupe de sections trouvées */ size_t count; /* Quantité de données */ size_t i; /* Boucle de parcours */ + off_t offset; /* Position physique */ + Elf_Phdr phdr; /* En-tête de programme ELF */ /* Données en lecture seule */ @@ -89,6 +91,23 @@ bool find_all_elf_strings(elf_format *format) parse_elf_string_data(format, str_start, str_size, str_vaddr); } + /* En désespoir de cause, on se rabbat sur les parties de programme directement */ + + if (format->str_count == 0 && format->header.e_shnum == 0 /* FIXME : cond. à garder ? */) + for (i = 0; i < format->header.e_phnum; i++) + { + offset = format->header.e_phoff + format->header.e_phentsize * i; + if ((offset + format->header.e_phentsize) >= EXE_FORMAT(format)->length) continue; + + memcpy(&phdr, &EXE_FORMAT(format)->content[offset], format->header.e_phentsize); + + if (ELF_PHDR(format, &phdr, p_flags) & PF_R && !(ELF_PHDR(format, &phdr, p_flags) & PF_X)) + parse_elf_string_data(format, ELF_PHDR(format, &phdr, p_offset), + ELF_PHDR(format, &phdr, p_filesz), + ELF_PHDR(format, &phdr, p_vaddr)); + + } + return true; } @@ -121,11 +140,11 @@ bool parse_elf_string_data(elf_format *format, const off_t start, const off_t si { for (end = i + 1; end < (start + size); end++) if (!isprint(EXE_FORMAT(format)->content[end])) break; - + format->strings = (elf_string *)realloc(format->strings, ++format->str_count * sizeof(elf_string)); - format->strings[format->str_count - 1].value = (const char *)&EXE_FORMAT(format)->content[i]; - format->strings[format->str_count - 1].len = end - start; + format->strings[format->str_count - 1].value = strndup((const char *)&EXE_FORMAT(format)->content[i], end - i); + format->strings[format->str_count - 1].len = end - i; format->strings[format->str_count - 1].vaddress = vaddress + i - start; i = end; diff --git a/src/format/exe_format.c b/src/format/exe_format.c index 89b0b3b..2b8f893 100644 --- a/src/format/exe_format.c +++ b/src/format/exe_format.c @@ -29,6 +29,9 @@ #include "exe_format-int.h" +#include "elf/e_elf.h" +#include "java/e_java.h" +#include "pe/e_pe.h" #include "../panel/log.h" @@ -57,6 +60,10 @@ static registered_exe_format *exe_formats = NULL; static size_t exe_formats_count = 0; +/* Enregistre la disponibilité d'un nouveau format exécutable. */ +void register_exe_format(const char *, exe_match_fc, exe_load_fc); + + /* ---------------------------------------------------------------------------------- */ @@ -220,6 +227,29 @@ int compare_bin_parts(const bin_part **a, const bin_part **b) /****************************************************************************** * * +* Paramètres : - * +* * +* Description : Procède au chargement des formats d'exécutables reconnus. * +* * +* Retour : true pour indiquer un chargement réussi, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool init_all_exe_formats(void) +{ + register_exe_format(_("ELF"), elf_is_matching, load_elf); + register_exe_format(_("Java"), java_is_matching, load_java); + register_exe_format(_("Portable Executable"), pe_is_matching, load_pe); + + return true; + +} + + +/****************************************************************************** +* * * Paramètres : name = désignation humaine associée. * * match = procédure de reconnaissance fournie. * * load = fonction de chargement fournie. * diff --git a/src/format/exe_format.h b/src/format/exe_format.h index efacfe2..13a37ee 100644 --- a/src/format/exe_format.h +++ b/src/format/exe_format.h @@ -79,8 +79,8 @@ typedef bool (* exe_match_fc) (const uint8_t *, off_t); typedef exe_format * (* exe_load_fc) (const uint8_t *, off_t); -/* Enregistre la disponibilité d'un nouveau format exécutable. */ -void register_exe_format(const char *, exe_match_fc, exe_load_fc); +/* Procède au chargement des formats d'exécutables reconnus. */ +bool init_all_exe_formats(void); /* Charge si possible un nouvel exécutable binaire. */ exe_format *load_new_exe_format(const uint8_t *, off_t); diff --git a/src/gtkbinview.c b/src/gtkbinview.c deleted file mode 100644 index 5ed6388..0000000 --- a/src/gtkbinview.c +++ /dev/null @@ -1,227 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * gtkbinview.c - affichage d'un ou de plusieurs morceaux de code - * - * Copyright (C) 2008 Cyrille Bagard - * - * This file is part of OpenIDA. - * - * OpenIDA is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * OpenIDA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#include "gtkbinview.h" - - -#include "gtksnippet.h" - - - - - -struct _GtkBinview -{ - GtkViewport viewport; - -}; - -struct _GtkBinviewClass -{ - GtkViewportClass parent_class; - -}; - - - - -/* Détermine le type du composant d'affichage des morceaux. */ -G_DEFINE_TYPE(GtkBinview, gtk_binview, GTK_TYPE_VIEWPORT) - - - - - - -/****************************************************************************** -* * -* Paramètres : class = classe GTK à initialiser. * -* * -* Description : Procède à l'initialisation de l'afficheur de morceaux. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_binview_class_init(GtkBinviewClass *class) -{ - GtkWidgetClass *widget_class; /* Classe de haut niveau */ - GtkViewportClass *viewport_class; /* Classe du niveau supérieur */ - - widget_class = GTK_WIDGET_CLASS(class); - viewport_class = GTK_VIEWPORT_CLASS(class); - -} - - -/****************************************************************************** -* * -* Paramètres : binview = composant GTK à initialiser. * -* * -* Description : Procède à l'initialisation de l'afficheur de morceaux. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_binview_init(GtkBinview *binview) -{ - - - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Crée un nouveau composant pour l'affichage de morceaux. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkWidget* gtk_binview_new(void) -{ - return g_object_new(GTK_TYPE_BIN_VIEW, NULL); - -} - - - - - - -/****************************************************************************** -* * -* Paramètres : binview = composant GTK à manipuler. * -* show = état de l'affichage auquel parvenir. * -* * -* Description : Choisit d'afficher les adresses virtuelles ou non. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_binview_show_vaddress(GtkBinview *binview, gboolean show) -{ - GList *list; /* Ensemble des enfants */ - GList *iter; /* Boucle de parcours */ - - list = gtk_container_get_children(GTK_CONTAINER(binview)); - - for (iter = g_list_first(list); iter != NULL; iter = g_list_next(iter)) - gtk_snippet_show_vaddress(GTK_SNIPPET(iter->data), show); - - g_list_free(list); - -} - - -/****************************************************************************** -* * -* Paramètres : binview = composant GTK à manipuler. * -* show = état de l'affichage auquel parvenir. * -* * -* Description : Choisit d'afficher le code brut ou non. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_binview_show_code(GtkBinview *binview, gboolean show) -{ - GList *list; /* Ensemble des enfants */ - GList *iter; /* Boucle de parcours */ - - list = gtk_container_get_children(GTK_CONTAINER(binview)); - - for (iter = g_list_first(list); iter != NULL; iter = g_list_next(iter)) - gtk_snippet_show_code(GTK_SNIPPET(iter->data), show); - - g_list_free(list); - -} - - - - - - - -/****************************************************************************** -* * -* Paramètres : binview = composant GTK à manipuler. * -* address = adresse à présenter à l'écran. * -* * -* Description : S'assure qu'une adresse donnée est visible à l'écran. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_binview_scroll_to_address(GtkBinview *binview, uint64_t address) -{ - GList *list; /* Ensemble des enfants */ - GList *iter; /* Boucle de parcours */ - GtkSnippet *snippet; /* Morceau de code présent */ - gint position; /* Position à garantir */ - GtkAdjustment *vadj; /* Défilement à mettre à jour */ - - list = gtk_container_get_children(GTK_CONTAINER(binview)); - - for (iter = g_list_first(list); iter != NULL; iter = g_list_next(iter)) - { - snippet = GTK_SNIPPET(iter->data); - - if (gtk_snippet_get_address_vposition(snippet, address, &position)) - { - vadj = GTK_VIEWPORT(binview)->vadjustment; - - gtk_adjustment_set_value(vadj, position); - - break; - - } - - } - - g_list_free(list); - -} - - - diff --git a/src/gtkbinview.h b/src/gtkbinview.h deleted file mode 100644 index 4fafad1..0000000 --- a/src/gtkbinview.h +++ /dev/null @@ -1,69 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * gtkbinview.h - prototypes pour l'affichage d'un ou de plusieurs morceaux de code - * - * Copyright (C) 2008 Cyrille Bagard - * - * This file is part of OpenIDA. - * - * OpenIDA is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * OpenIDA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#ifndef _GTK_BINVIEW_H -#define _GTK_BINVIEW_H - - -#include - - -#include - - - -#define GTK_TYPE_BIN_VIEW (gtk_binview_get_type()) -#define GTK_BIN_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BIN_VIEW, GtkBinview)) -#define GTK_BIN_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BIN_VIEW, GtkBinviewClass)) -#define GTK_IS_BIN_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BIN_VIEW)) -#define GTK_IS_BIN_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BIN_VIEW)) -#define GTK_BIN_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BIN_VIEW, GtkBinviewClass)) - - -typedef struct _GtkBinview GtkBinview; -typedef struct _GtkBinviewClass GtkBinviewClass; - - - -/* Détermine le type du composant d'affichage des morceaux. */ -GType gtk_binview_get_type(void); - -/* Crée un nouveau composant pour l'affichage de morceaux. */ -GtkWidget* gtk_binview_new(void); - - - -/* Choisit d'afficher les adresses virtuelles ou non. */ -void gtk_binview_show_vaddress(GtkBinview *, gboolean); - -/* Choisit d'afficher le code brut ou non. */ -void gtk_binview_show_code(GtkBinview *, gboolean); - - - -/* S'assure qu'une adresse donnée est visible à l'écran. */ -void gtk_binview_scroll_to_address(GtkBinview *, uint64_t); - - - -#endif /* _GTK_BINVIEW_H */ diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am index a42d77c..aa14cf5 100644 --- a/src/gtkext/Makefile.am +++ b/src/gtkext/Makefile.am @@ -1,10 +1,15 @@ +BUILT_SOURCES = iodamarshal.h iodamarshal.c + lib_LIBRARIES = libgtkext.a libgtkext_a_SOURCES = \ + gtkbinview.h gtkbinview.c \ gtkdockitem.h gtkdockitem.c \ gtkdockpanel.h gtkdockpanel.c \ - gtkdropwindow.h gtkdropwindow.c + gtkdropwindow.h gtkdropwindow.c \ + gtksnippet.h gtksnippet.c \ + iodamarshal.h iodamarshal.c libgtkext_a_CFLAGS = $(AM_CFLAGS) @@ -15,3 +20,9 @@ AM_CPPFLAGS = AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +iodamarshal.h: iodamarshal.list + glib-genmarshal --header $< > $@ + +iodamarshal.c: iodamarshal.list + glib-genmarshal --body $< > $@ diff --git a/src/gtkext/gtkbinview.c b/src/gtkext/gtkbinview.c new file mode 100644 index 0000000..5ed6388 --- /dev/null +++ b/src/gtkext/gtkbinview.c @@ -0,0 +1,227 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * gtkbinview.c - affichage d'un ou de plusieurs morceaux de code + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "gtkbinview.h" + + +#include "gtksnippet.h" + + + + + +struct _GtkBinview +{ + GtkViewport viewport; + +}; + +struct _GtkBinviewClass +{ + GtkViewportClass parent_class; + +}; + + + + +/* Détermine le type du composant d'affichage des morceaux. */ +G_DEFINE_TYPE(GtkBinview, gtk_binview, GTK_TYPE_VIEWPORT) + + + + + + +/****************************************************************************** +* * +* Paramètres : class = classe GTK à initialiser. * +* * +* Description : Procède à l'initialisation de l'afficheur de morceaux. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_binview_class_init(GtkBinviewClass *class) +{ + GtkWidgetClass *widget_class; /* Classe de haut niveau */ + GtkViewportClass *viewport_class; /* Classe du niveau supérieur */ + + widget_class = GTK_WIDGET_CLASS(class); + viewport_class = GTK_VIEWPORT_CLASS(class); + +} + + +/****************************************************************************** +* * +* Paramètres : binview = composant GTK à initialiser. * +* * +* Description : Procède à l'initialisation de l'afficheur de morceaux. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_binview_init(GtkBinview *binview) +{ + + + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un nouveau composant pour l'affichage de morceaux. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget* gtk_binview_new(void) +{ + return g_object_new(GTK_TYPE_BIN_VIEW, NULL); + +} + + + + + + +/****************************************************************************** +* * +* Paramètres : binview = composant GTK à manipuler. * +* show = état de l'affichage auquel parvenir. * +* * +* Description : Choisit d'afficher les adresses virtuelles ou non. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_binview_show_vaddress(GtkBinview *binview, gboolean show) +{ + GList *list; /* Ensemble des enfants */ + GList *iter; /* Boucle de parcours */ + + list = gtk_container_get_children(GTK_CONTAINER(binview)); + + for (iter = g_list_first(list); iter != NULL; iter = g_list_next(iter)) + gtk_snippet_show_vaddress(GTK_SNIPPET(iter->data), show); + + g_list_free(list); + +} + + +/****************************************************************************** +* * +* Paramètres : binview = composant GTK à manipuler. * +* show = état de l'affichage auquel parvenir. * +* * +* Description : Choisit d'afficher le code brut ou non. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_binview_show_code(GtkBinview *binview, gboolean show) +{ + GList *list; /* Ensemble des enfants */ + GList *iter; /* Boucle de parcours */ + + list = gtk_container_get_children(GTK_CONTAINER(binview)); + + for (iter = g_list_first(list); iter != NULL; iter = g_list_next(iter)) + gtk_snippet_show_code(GTK_SNIPPET(iter->data), show); + + g_list_free(list); + +} + + + + + + + +/****************************************************************************** +* * +* Paramètres : binview = composant GTK à manipuler. * +* address = adresse à présenter à l'écran. * +* * +* Description : S'assure qu'une adresse donnée est visible à l'écran. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_binview_scroll_to_address(GtkBinview *binview, uint64_t address) +{ + GList *list; /* Ensemble des enfants */ + GList *iter; /* Boucle de parcours */ + GtkSnippet *snippet; /* Morceau de code présent */ + gint position; /* Position à garantir */ + GtkAdjustment *vadj; /* Défilement à mettre à jour */ + + list = gtk_container_get_children(GTK_CONTAINER(binview)); + + for (iter = g_list_first(list); iter != NULL; iter = g_list_next(iter)) + { + snippet = GTK_SNIPPET(iter->data); + + if (gtk_snippet_get_address_vposition(snippet, address, &position)) + { + vadj = GTK_VIEWPORT(binview)->vadjustment; + + gtk_adjustment_set_value(vadj, position); + + break; + + } + + } + + g_list_free(list); + +} + + + diff --git a/src/gtkext/gtkbinview.h b/src/gtkext/gtkbinview.h new file mode 100644 index 0000000..4fafad1 --- /dev/null +++ b/src/gtkext/gtkbinview.h @@ -0,0 +1,69 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * gtkbinview.h - prototypes pour l'affichage d'un ou de plusieurs morceaux de code + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _GTK_BINVIEW_H +#define _GTK_BINVIEW_H + + +#include + + +#include + + + +#define GTK_TYPE_BIN_VIEW (gtk_binview_get_type()) +#define GTK_BIN_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BIN_VIEW, GtkBinview)) +#define GTK_BIN_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BIN_VIEW, GtkBinviewClass)) +#define GTK_IS_BIN_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BIN_VIEW)) +#define GTK_IS_BIN_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BIN_VIEW)) +#define GTK_BIN_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BIN_VIEW, GtkBinviewClass)) + + +typedef struct _GtkBinview GtkBinview; +typedef struct _GtkBinviewClass GtkBinviewClass; + + + +/* Détermine le type du composant d'affichage des morceaux. */ +GType gtk_binview_get_type(void); + +/* Crée un nouveau composant pour l'affichage de morceaux. */ +GtkWidget* gtk_binview_new(void); + + + +/* Choisit d'afficher les adresses virtuelles ou non. */ +void gtk_binview_show_vaddress(GtkBinview *, gboolean); + +/* Choisit d'afficher le code brut ou non. */ +void gtk_binview_show_code(GtkBinview *, gboolean); + + + +/* S'assure qu'une adresse donnée est visible à l'écran. */ +void gtk_binview_scroll_to_address(GtkBinview *, uint64_t); + + + +#endif /* _GTK_BINVIEW_H */ diff --git a/src/gtkext/gtksnippet.c b/src/gtkext/gtksnippet.c new file mode 100644 index 0000000..a48baf2 --- /dev/null +++ b/src/gtkext/gtksnippet.c @@ -0,0 +1,896 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * gtksnippet.c - affichage d'un fragment de code d'assemblage + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "gtksnippet.h" + + +#include +#include + + +#include "../common/dllist.h" + + + +#define CONTENT_BUFFER_LEN 64 + +#define MARGIN_SPACE 4 + + + + +/* Redessine l'affichage suite une mise à jour dans la marge. */ +void gtk_snippet_update_margin(GRenderingLine *, GtkSnippet *); + + + + + +/****************************************************************************** +* * +* Paramètres : offset = position de l'instruction à ajouter. * +* instr = instruction à représenter ou NULL. * +* comment = commentaire à imprimer ou NULL. * +* * +* Description : Crée une ligne de représentation insérable. * +* * +* Retour : Struture rassemblant les informations mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +code_line_info *create_code_line_info(uint64_t offset, asm_instr *instr, const char *comment) +{ + code_line_info *result; /* Structure à renvoyer */ + + result = (code_line_info *)calloc(1, sizeof(code_line_info)); + + result->offset = offset; + result->instr = instr; + result->comment = (comment != NULL ? strdup(comment) : NULL); + + result->bp_set = FALSE; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : line = informations à effacer de la mémoire. * +* * +* Description : Supprime une ligne de représentation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void delete_code_line_info(code_line_info *line) +{ + free(line->instr); + free(line->comment); + + free(line); + +} + + +/****************************************************************************** +* * +* Paramètres : a = premières informations à consulter. * +* b = secondes informations à consulter. * +* * +* Description : Etablit la comparaison entre deux lignes de représentation. * +* * +* Retour : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b). * +* * +* Remarques : - * +* * +******************************************************************************/ + +int compare_code_line_info(const code_line_info **a, const code_line_info **b) +{ + int result; /* Bilan à renvoyer */ + + if ((*a)->offset < (*b)->offset) result = -1; + else if((*a)->offset > (*b)->offset) result = 1; + else result = 0; + + return result; + +} + + + + + + +/* Réclame une nouvelle taille adaptée au contenu présent. */ +void gtk_snippet_recompute_size_request(GtkSnippet *); + + + + + + + + +static void gtk_snippet_class_init(GtkSnippetClass *klass); +static void gtk_snippet_init(GtkSnippet *cpu); +static void gtk_snippet_size_request(GtkWidget *widget, + GtkRequisition *requisition); +static void gtk_snippet_size_allocate(GtkWidget *widget, + GtkAllocation *allocation); +static void gtk_snippet_realize(GtkWidget *widget); + + +static gboolean gtk_snippet_button_press(GtkWidget *, GdkEventButton *event); + +static gboolean gtk_snippet_expose(GtkWidget *widget, + GdkEventExpose *event); +static void gtk_snippet_paint(GtkSnippet *snippet); +static void gtk_snippet_destroy(GtkObject *object); + + +GtkType +gtk_snippet_get_type(void) +{ + static GtkType gtk_snippet_type = 0; + + + if (!gtk_snippet_type) { + static const GtkTypeInfo gtk_snippet_info = { + "GtkSnippet", + sizeof(GtkSnippet), + sizeof(GtkSnippetClass), + (GtkClassInitFunc) gtk_snippet_class_init, + (GtkObjectInitFunc) gtk_snippet_init, + NULL, + NULL, + (GtkClassInitFunc) NULL + }; + gtk_snippet_type = gtk_type_unique(GTK_TYPE_WIDGET, >k_snippet_info); + } + + + return gtk_snippet_type; +} + + +GtkWidget * gtk_snippet_new(void) +{ + GtkSnippet *result; + + result = gtk_type_new(gtk_snippet_get_type()); + + return GTK_WIDGET(result); + +} + + +static void +gtk_snippet_class_init(GtkSnippetClass *klass) +{ + GtkWidgetClass *widget_class; + GtkObjectClass *object_class; + + + widget_class = (GtkWidgetClass *) klass; + object_class = (GtkObjectClass *) klass; + + + widget_class->button_press_event = gtk_snippet_button_press; + widget_class->realize = gtk_snippet_realize; + widget_class->size_request = gtk_snippet_size_request; + widget_class->size_allocate = gtk_snippet_size_allocate; + widget_class->expose_event = gtk_snippet_expose; + + object_class->destroy = gtk_snippet_destroy; +} + + +static void +gtk_snippet_init(GtkSnippet *snippet) +{ + snippet->sel = 0; +} + + +static void +gtk_snippet_size_request(GtkWidget *widget, + GtkRequisition *requisition) +{ + g_return_if_fail(widget != NULL); + g_return_if_fail(GTK_IS_SNIPPET(widget)); + g_return_if_fail(requisition != NULL); + + requisition->width = 80; + requisition->height = 100; +} + + +static void +gtk_snippet_size_allocate(GtkWidget *widget, + GtkAllocation *allocation) +{ + g_return_if_fail(widget != NULL); + g_return_if_fail(GTK_IS_SNIPPET(widget)); + g_return_if_fail(allocation != NULL); + + widget->allocation = *allocation; + + if (GTK_WIDGET_REALIZED(widget)) { + gdk_window_move_resize( + widget->window, + allocation->x, allocation->y, + allocation->width, allocation->height + ); + } +} + + +static void +gtk_snippet_realize(GtkWidget *widget) +{ + GdkWindowAttr attributes; + guint attributes_mask; + GdkColor white; /* Couleur de fond normale */ + + g_return_if_fail(widget != NULL); + g_return_if_fail(GTK_IS_SNIPPET(widget)); + + GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED); + + attributes.window_type = GDK_WINDOW_CHILD; + attributes.x = widget->allocation.x; + attributes.y = widget->allocation.y; + attributes.width = widget->allocation.width; + attributes.height = widget->allocation.height; + + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.event_mask = gtk_widget_get_events(widget) | GDK_BUTTON_PRESS_MASK | GDK_EXPOSURE_MASK; + + attributes_mask = GDK_WA_X | GDK_WA_Y; + + widget->window = gdk_window_new( + gtk_widget_get_parent_window (widget), + & attributes, attributes_mask + ); + + gdk_window_set_user_data(widget->window, widget); + + widget->style = gtk_style_attach(widget->style, widget->window); + + + gdk_color_white(gtk_widget_get_colormap(widget), &white); + gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &white); + + + GTK_SNIPPET(widget)->layout = gtk_widget_create_pango_layout(widget, NULL); + GTK_SNIPPET(widget)->gc = gdk_gc_new(GDK_DRAWABLE(widget->window)); + + gtk_snippet_build_content(GTK_SNIPPET(widget)); + +} + + +static gboolean gtk_snippet_button_press(GtkWidget *widget, GdkEventButton *event) +{ + gboolean result; /* Décision à retourner */ + GtkSnippet *snippet; /* Composant GTK réel */ + gdouble y; /* Position à manipuler */ + GRenderingLine *line; /* Ligne de rendu visée */ + + result = FALSE; + + snippet = GTK_SNIPPET(widget); + + y = event->y; + line = g_rendering_line_find_by_y(snippet->lines, &y); + + if (line != NULL) + { + /* Clic dans la marge */ + if (event->type == GDK_BUTTON_PRESS && event->x < (2 * MARGIN_SPACE + snippet->line_height)) + { + result = TRUE; + g_rendering_line_toggle_flag(line, RLF_BREAK_POINT); + } + + } + + if (result) + { + /* TODO: regions */ + gtk_snippet_paint(snippet); + } + + return result; + +} + + + +/****************************************************************************** +* * +* Paramètres : line = ligne dont un drapeau a évolué. * +* snippet = composant GTK à mettre à jour. * +* * +* Description : Redessine l'affichage suite une mise à jour dans la marge. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_snippet_update_margin(GRenderingLine *line, GtkSnippet *snippet) +{ + + + gtk_snippet_paint(snippet); + + + + +} + + + + + +static gboolean +gtk_snippet_expose(GtkWidget *widget, + GdkEventExpose *event) +{ + g_return_val_if_fail(widget != NULL, FALSE); + g_return_val_if_fail(GTK_IS_SNIPPET(widget), FALSE); + g_return_val_if_fail(event != NULL, FALSE); + + gtk_snippet_paint(GTK_SNIPPET(widget)); + + + + /* + + +gdk_gc_set_clip_region (GdkGC *gc, + const GdkRegion *region); + +gdk_window_invalidate_region (GdkWindow *window, + const GdkRegion *region, + gboolean invalidate_children); +gdk_window_begin_paint_region (GdkWindow *window, + const GdkRegion *region); +void gdk_window_end_paint (GdkWindow *window); + */ + + + + + + + return TRUE; + +} + + +static void +gtk_snippet_paint(GtkSnippet *snippet) +{ + GtkWidget *widget; /* Version GTK du composant */ + GdkGCValues values; /* Propriétés du contexte */ + GdkColor white; /* Couleur du fond */ + int width; /* Largeur de l'élément */ + int height; /* Hauteur de l'élément */ + GdkColor red; /* Couleur des arrêts */ + PangoLayoutIter *iter; /* Boucle de parcours */ + unsigned int index; /* Indice de la ligne visée */ + int y0; /* Ordonnée du haut d'une ligne*/ + int y1; /* Ordonnée du bas d'une ligne */ + + GRenderingLine *liter; + + + widget = GTK_WIDGET(snippet); + gdk_gc_get_values(snippet->gc, &values); + + gdk_color_white(gtk_widget_get_colormap(widget), &white); + gdk_gc_set_foreground(snippet->gc, &white); + + gtk_widget_get_size_request(widget, &width, &height); + + gdk_draw_rectangle(GDK_DRAWABLE(widget->window), GTK_SNIPPET(widget)->gc, + TRUE, 0, 0, width, height); + + gdk_color_parse("#ff0000", &red); + gdk_color_alloc(gtk_widget_get_colormap(widget), &red); + gdk_gc_set_foreground(snippet->gc, &red); + + + index = 0; + iter = pango_layout_get_iter(snippet->layout); + + for (; index < snippet->info_count; index++, pango_layout_iter_next_line(iter)) + { + if (!snippet->info[index].bp_set) continue; + + pango_layout_iter_get_line_yrange(iter, &y0, &y1); + + + + gdk_draw_arc(GDK_DRAWABLE(widget->window), GTK_SNIPPET(widget)->gc, + FALSE, MARGIN_SPACE, y0 / PANGO_SCALE, + snippet->line_height - 2, snippet->line_height - 2, + 0, 360 * 64); + + } + + pango_layout_iter_free(iter); + + gdk_gc_set_foreground(snippet->gc, &values.foreground); + + gdk_draw_layout(GDK_DRAWABLE(widget->window), snippet->gc, + 2 * MARGIN_SPACE + snippet->line_height, 0, + snippet->layout); + + + y0 = 0; + + for (/* l! */liter = snippet->lines; liter != NULL; liter = g_rendering_line_get_next_iter(snippet->lines, liter)) + { + g_rendering_line_draw(liter, GDK_DRAWABLE(widget->window), snippet->gc, + MARGIN_SPACE, 2 * MARGIN_SPACE + snippet->line_height, + y0, snippet->line_height); + + y0 += snippet->line_height; + + } + + +} + + +static void +gtk_snippet_destroy(GtkObject *object) +{ + GtkSnippet *cpu; + GtkSnippetClass *klass; + + g_return_if_fail(object != NULL); + g_return_if_fail(GTK_IS_SNIPPET(object)); + + cpu = GTK_SNIPPET(object); + + klass = gtk_type_class(gtk_widget_get_type()); + + if (GTK_OBJECT_CLASS(klass)->destroy) { + (* GTK_OBJECT_CLASS(klass)->destroy) (object); + } +} + + + + + + +/****************************************************************************** +* * +* Paramètres : snippet = composant GTK à mettre à jour. * +* show = état de l'affichage auquel parvenir. * +* * +* Description : Choisit d'afficher les adresses virtuelles ou non. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_snippet_show_vaddress(GtkSnippet *snippet, gboolean show) +{ + snippet->show_vaddress = show; + + gtk_snippet_build_content(snippet); + +} + + +/****************************************************************************** +* * +* Paramètres : snippet = composant GTK à mettre à jour. * +* show = état de l'affichage auquel parvenir. * +* * +* Description : Choisit d'afficher le code brut ou non. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_snippet_show_code(GtkSnippet *snippet, gboolean show) +{ + snippet->show_code = show; + + gtk_snippet_build_content(snippet); + +} + + + + + +/****************************************************************************** +* * +* Paramètres : snippet = composant GTK à mettre à jour. * +* format = format du binaire affiché. * +* * +* Description : Définit le format auquel le contenu est lié. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_snippet_set_format(GtkSnippet *snippet, const exe_format *format) +{ + snippet->format = format; + +} + + +/****************************************************************************** +* * +* Paramètres : snippet = composant GTK à mettre à jour. * +* proc = architecture à associer au contenu. * +* * +* Description : Définit l'architecture à laquelle le contenu est lié. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_snippet_set_processor(GtkSnippet *snippet, const asm_processor *proc) +{ + snippet->proc = proc; + +} + + +/****************************************************************************** +* * +* Paramètres : snippet = composant GTK à mettre à jour. * +* lines = informations à intégrer. * +* * +* Description : Définit les lignes du bloc de représentation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_snippet_set_rendering_lines(GtkSnippet *snippet, GRenderingLine *lines) +{ + GRenderingLine *iter; /* Boucle de parcours */ + + snippet->lines = lines; + + for (iter = lines; iter != NULL; iter = g_rendering_line_get_next_iter(lines, iter)) + g_signal_connect(iter, "rendering-line-flags-changed", + G_CALLBACK(gtk_snippet_update_margin), snippet); + + g_rendering_line_update_bin_len(lines); + + gtk_snippet_recompute_size_request(snippet); + +} + + + + + +/****************************************************************************** +* * +* Paramètres : snippet = composant GTK à mettre à jour. * +* * +* Description : Réclame une nouvelle taille adaptée au contenu présent. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_snippet_recompute_size_request(GtkSnippet *snippet) +{ + int width; /* Largeur de l'objet actuelle */ + int height; /* Hauteur de l'objet actuelle */ + + g_rendering_line_get_size(snippet->lines, &width, &height, &snippet->line_height); + + gtk_widget_set_size_request(GTK_WIDGET(snippet), + width + 2 * MARGIN_SPACE + snippet->line_height, + height); + +} + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : snippet = composant GTK à mettre à jour. * +* line = informations à intégrer. * +* * +* Description : Ajoute une ligne dans le bloc de représentation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_snippet_add_line(GtkSnippet *snippet, const code_line_info *line) +{ + snippet->info = (code_line_info *)realloc(snippet->info, ++snippet->info_count * sizeof(code_line_info)); + + snippet->info[snippet->info_count - 1] = *line; + +} + + +/****************************************************************************** +* * +* Paramètres : snippet = composant GTK à mettre à jour. * +* * +* Description : Définit le contenu visuel à partir des infos enregistrées. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_snippet_build_content(GtkSnippet *snippet) +{ + const uint8_t *exe_content; /* Contenu binaire global */ + off_t max_bin_len; /* Taille max du code brut */ + unsigned int i; /* Boucle de traitement */ + off_t bin_len; /* Taille d'instruction */ + char *bin_code; /* Tampon du code binaire */ + char *content; /* Contenu à définir */ + size_t content_len; /* Taille du contenu */ + AdressMode mode; /* Affichage des adresses */ + char buffer[CONTENT_BUFFER_LEN]; /* Zone tampon à utiliser */ + off_t bin_offset; /* Début de l'instruction */ + off_t k; /* Boucle de parcours #2 */ + off_t j; /* Boucle de parcours #1 */ + int width; /* Largeur de l'objet actuelle */ + int height; /* Hauteur de l'objet actuelle */ + PangoLayoutIter *iter; /* Boucle de parcours */ + int y0; /* Ordonnée du haut d'une ligne*/ + int y1; /* Ordonnée du bas d'une ligne */ + + /* Calcul de la largeur maximale brute si besoin est */ + if (snippet->show_code) + { + exe_content = get_exe_content(snippet->format, NULL); + + max_bin_len = 1; + + for (i = 0; i < snippet->info_count; i++) + { + /* Commentaire uniquement */ + if (snippet->info[i].instr == NULL) continue; + + get_asm_instr_offset_and_length(snippet->info[i].instr, NULL, &bin_len); + if (bin_len > max_bin_len) max_bin_len = bin_len; + + } + + max_bin_len = max_bin_len * 2 + (max_bin_len - 1); + bin_code = (char *)calloc(max_bin_len + 1, sizeof(char)); + + } + + content_len = strlen("") + 1; + content = (char *)calloc(content_len, sizeof(char)); + strcpy(content, ""); + + mode = ADM_32BITS; /* FIXME */ + + for (i = 0; i < snippet->info_count; i++) + { + if (i > 0) + { + content = (char *)realloc(content, ++content_len * sizeof(char)); + strcat(content, "\n"); + } + + /* Eventuelle adresse virtuelle */ + + if (snippet->show_vaddress) + { + switch (mode) + { + case ADM_32BITS: + snprintf(buffer, CONTENT_BUFFER_LEN, + "0x%08llx", + snippet->info[i].offset); + break; + + case ADM_64BITS: + snprintf(buffer, CONTENT_BUFFER_LEN, + "0x%16llx", + snippet->info[i].offset); + break; + + } + + content_len += strlen(buffer); + content = (char *)realloc(content, content_len * sizeof(char)); + strcat(content, buffer); + + } + + /* Eventuel code brut */ + + if (snippet->show_code) + { + k = 0; + + if (snippet->info[i].instr != NULL) + { + get_asm_instr_offset_and_length(snippet->info[i].instr, &bin_offset, &bin_len); + + for (j = 0; j < bin_len; j++) + { + if ((j + 1) < bin_len) + k += snprintf(&bin_code[j * (2 + 1)], 4, "%02hhx ", exe_content[bin_offset + j]); + else + k += snprintf(&bin_code[j * (2 + 1)], 3, "%02hhx", exe_content[bin_offset + j]); + } + + } + + for (; k < max_bin_len; k++) + snprintf(&bin_code[k], 2, " "); + + if (snippet->show_vaddress) content_len += strlen("\t"); + content_len += strlen(bin_code); + content = (char *)realloc(content, content_len * sizeof(char)); + if (snippet->show_vaddress) strcat(content, "\t"); + strcat(content, bin_code); + + } + + /* Eventuelle instruction */ + + if (snippet->info[i].instr != NULL) + { + print_hinstruction(snippet->proc, snippet->format, snippet->info[i].instr, buffer, CONTENT_BUFFER_LEN, ASX_INTEL); + + if (snippet->show_vaddress || snippet->show_code) content_len += strlen("\t"); + content_len += strlen(buffer); + + content = (char *)realloc(content, content_len * sizeof(char)); + if (snippet->show_vaddress || snippet->show_code) strcat(content, "\t"); + strcat(content, buffer); + + } + + /* Eventuel commantaire */ + + if (snippet->info[i].comment != NULL) + { + if (snippet->show_vaddress || snippet->show_code) content_len += strlen("\t"); + content_len += strlen("; ") + strlen(snippet->info[i].comment) + strlen(""); + + content = (char *)realloc(content, content_len * sizeof(char)); + if (snippet->show_vaddress || snippet->show_code) strcat(content, "\t"); + strcat(content, "; "); + strcat(content, snippet->info[i].comment); + strcat(content, ""); + + } + + } + + content_len += strlen(""); + content = (char *)realloc(content, content_len * sizeof(char)); + strcat(content, ""); + + if (snippet->show_code) free(bin_code); + + pango_layout_set_markup(snippet->layout, content, content_len - 1); + + pango_layout_get_pixel_size(snippet->layout, &width, &height); + + snippet->line_height = 0; + iter = pango_layout_get_iter(snippet->layout); + + do + { + pango_layout_iter_get_line_yrange(iter, &y0, &y1); + snippet->line_height = MAX(snippet->line_height, (y1 - y0) / PANGO_SCALE); + } + while (pango_layout_iter_next_line(iter)); + + pango_layout_iter_free(iter); + + //gtk_widget_set_size_request(GTK_WIDGET(snippet), width + 2 * MARGIN_SPACE + snippet->line_height, height); + +} + + + + + + + + +/****************************************************************************** +* * +* Paramètres : snippet = composant GTK à consulter. * +* address = adresse à présenter à l'écran. * +* position = position verticale au sein du composant. [OUT] * +* * +* Description : Indique la position verticale d'une adresse donnée. * +* * +* Retour : TRUE si l'adresse fait partie du composant, FALSE sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +gboolean gtk_snippet_get_address_vposition(GtkSnippet *snippet, uint64_t address, gint *position) +{ + unsigned int i; /* Boucle de parcours */ + + *position = 0; + + for (i = 0; i < snippet->info_count; i++) + { + if (snippet->info[i].offset == address) break; + else *position += snippet->line_height; + } + + return (i < snippet->info_count); + +} + diff --git a/src/gtkext/gtksnippet.h b/src/gtkext/gtksnippet.h new file mode 100644 index 0000000..41727bd --- /dev/null +++ b/src/gtkext/gtksnippet.h @@ -0,0 +1,156 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * gtksnippet.h - prototypes pour l'affichage d'un fragment de code d'assemblage + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _GTK_SNIPPET_H +#define _GTK_SNIPPET_H + + +#include +#include +#include + + +#include "../analysis/line.h" +#include "../arch/instruction.h" +#include "../arch/processor.h" +#include "../format/exe_format.h" + + + +typedef struct _code_line_info +{ + uint64_t offset; /* Position de l'instruction */ + asm_instr *instr; /* Eventuelle instruction */ + char *comment; /* Eventuel commentaire */ + + gboolean bp_set; /* Point d'arrêt défini */ + +} code_line_info; + + + + +/* Crée une ligne de représentation insérable. */ +code_line_info *create_code_line_info(uint64_t, asm_instr *, const char *); + +/* Supprime une ligne de représentation. */ +void delete_code_line_info(code_line_info *); + +/* Etablit la comparaison entre deux lignes de représentation. */ +int compare_code_line_info(const code_line_info **, const code_line_info **); + + + + + +G_BEGIN_DECLS + + +#define GTK_SNIPPET(obj) GTK_CHECK_CAST(obj, gtk_snippet_get_type (), GtkSnippet) +#define GTK_SNIPPET_CLASS(klass) GTK_CHECK_CLASS_CAST(klass, gtk_snippet_get_type(), GtkSnippetClass) +#define GTK_IS_SNIPPET(obj) GTK_CHECK_TYPE(obj, gtk_snippet_get_type()) + + +typedef struct _GtkSnippet GtkSnippet; +typedef struct _GtkSnippetClass GtkSnippetClass; + + + + + +struct _GtkSnippet { + + GtkWidget widget; /* Présence obligatoire en 1er */ + + AdressMode mode; /* Mode d'affichage */ + + bool show_vaddress; /* Affichage des adresses ? */ + bool show_code; /* Affichage du code brut ? */ + + PangoLayout *layout; /* Moteur de rendu du code ASM */ + GdkGC *gc; /* Contexte graphique du rendu */ + int line_height; /* Hauteur maximale des lignes */ + + const exe_format *format; /* Format du contenu bianire */ + const asm_processor *proc; /* Architecture utilisée */ + code_line_info *info; /* Contenu à représenter */ + unsigned int info_count; /* Quantité d'informations */ + + GRenderingLine *lines; /* Contenu à représenter */ + + + gint sel; +}; + +struct _GtkSnippetClass { + GtkWidgetClass parent_class; +}; + + +GtkType gtk_snippet_get_type(void); +void gtk_snippet_set_sel(GtkSnippet *cpu, gint sel); + +GtkWidget * gtk_snippet_new(void); + + + + +/* Choisit d'afficher les adresses virtuelles ou non. */ +void gtk_snippet_show_vaddress(GtkSnippet *, gboolean); + +/* Choisit d'afficher le code brut ou non. */ +void gtk_snippet_show_code(GtkSnippet *, gboolean); + + + + +/* Définit le format auquel le contenu est lié. */ +void gtk_snippet_set_format(GtkSnippet *, const exe_format *); + +/* Définit l'architecture à laquelle le contenu est lié. */ +void gtk_snippet_set_processor(GtkSnippet *, const asm_processor *); + +/* Ajoute une ligne dans le bloc de représentation. */ +void gtk_snippet_add_line(GtkSnippet *, const code_line_info *); + +/* Définit les lignes du bloc de représentation. */ +void gtk_snippet_set_rendering_lines(GtkSnippet *, GRenderingLine *); + +/* Définit le contenu visuel à partir des infos enregistrées. */ +void gtk_snippet_build_content(GtkSnippet *); + + + +/* Indique la position verticale d'une adresse donnée. */ +gboolean gtk_snippet_get_address_vposition(GtkSnippet *, uint64_t, gint *); + + + +G_END_DECLS + + + + + + +#endif /* _GTK_SNIPPET_H */ diff --git a/src/gtksnippet.c b/src/gtksnippet.c deleted file mode 100644 index f56ccd0..0000000 --- a/src/gtksnippet.c +++ /dev/null @@ -1,835 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * gtksnippet.c - affichage d'un fragment de code d'assemblage - * - * Copyright (C) 2008 Cyrille Bagard - * - * This file is part of OpenIDA. - * - * OpenIDA is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * OpenIDA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#include "gtksnippet.h" - - -#include -#include - - -#include "common/dllist.h" - - - -#define CONTENT_BUFFER_LEN 64 - -#define MARGIN_SPACE 4 - - - - - - -/****************************************************************************** -* * -* Paramètres : offset = position de l'instruction à ajouter. * -* instr = instruction à représenter ou NULL. * -* comment = commentaire à imprimer ou NULL. * -* * -* Description : Crée une ligne de représentation insérable. * -* * -* Retour : Struture rassemblant les informations mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -code_line_info *create_code_line_info(uint64_t offset, asm_instr *instr, const char *comment) -{ - code_line_info *result; /* Structure à renvoyer */ - - result = (code_line_info *)calloc(1, sizeof(code_line_info)); - - result->offset = offset; - result->instr = instr; - result->comment = (comment != NULL ? strdup(comment) : NULL); - - result->bp_set = FALSE; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : line = informations à effacer de la mémoire. * -* * -* Description : Supprime une ligne de représentation. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void delete_code_line_info(code_line_info *line) -{ - free(line->instr); - free(line->comment); - - free(line); - -} - - -/****************************************************************************** -* * -* Paramètres : a = premières informations à consulter. * -* b = secondes informations à consulter. * -* * -* Description : Etablit la comparaison entre deux lignes de représentation. * -* * -* Retour : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b). * -* * -* Remarques : - * -* * -******************************************************************************/ - -int compare_code_line_info(const code_line_info **a, const code_line_info **b) -{ - int result; /* Bilan à renvoyer */ - - if ((*a)->offset < (*b)->offset) result = -1; - else if((*a)->offset > (*b)->offset) result = 1; - else result = 0; - - return result; - -} - - - - - - -/* Réclame une nouvelle taille adaptée au contenu présent. */ -void gtk_snippet_recompute_size_request(GtkSnippet *); - - - - - - - - -static void gtk_snippet_class_init(GtkSnippetClass *klass); -static void gtk_snippet_init(GtkSnippet *cpu); -static void gtk_snippet_size_request(GtkWidget *widget, - GtkRequisition *requisition); -static void gtk_snippet_size_allocate(GtkWidget *widget, - GtkAllocation *allocation); -static void gtk_snippet_realize(GtkWidget *widget); - - -static gboolean gtk_snippet_button_press(GtkWidget *widget, GdkEventButton *event); - -static gboolean gtk_snippet_expose(GtkWidget *widget, - GdkEventExpose *event); -static void gtk_snippet_paint(GtkSnippet *snippet); -static void gtk_snippet_destroy(GtkObject *object); - - -GtkType -gtk_snippet_get_type(void) -{ - static GtkType gtk_snippet_type = 0; - - - if (!gtk_snippet_type) { - static const GtkTypeInfo gtk_snippet_info = { - "GtkSnippet", - sizeof(GtkSnippet), - sizeof(GtkSnippetClass), - (GtkClassInitFunc) gtk_snippet_class_init, - (GtkObjectInitFunc) gtk_snippet_init, - NULL, - NULL, - (GtkClassInitFunc) NULL - }; - gtk_snippet_type = gtk_type_unique(GTK_TYPE_WIDGET, >k_snippet_info); - } - - - return gtk_snippet_type; -} - - -GtkWidget *gtk_snippet_new(void) -{ - GtkSnippet *result; - - result = gtk_type_new(gtk_snippet_get_type()); - - return GTK_WIDGET(result); - -} - - -static void -gtk_snippet_class_init(GtkSnippetClass *klass) -{ - GtkWidgetClass *widget_class; - GtkObjectClass *object_class; - - - widget_class = (GtkWidgetClass *) klass; - object_class = (GtkObjectClass *) klass; - - - widget_class->button_press_event = gtk_snippet_button_press; - widget_class->realize = gtk_snippet_realize; - widget_class->size_request = gtk_snippet_size_request; - widget_class->size_allocate = gtk_snippet_size_allocate; - widget_class->expose_event = gtk_snippet_expose; - - object_class->destroy = gtk_snippet_destroy; -} - - -static void -gtk_snippet_init(GtkSnippet *snippet) -{ - snippet->sel = 0; -} - - -static void -gtk_snippet_size_request(GtkWidget *widget, - GtkRequisition *requisition) -{ - g_return_if_fail(widget != NULL); - g_return_if_fail(GTK_IS_SNIPPET(widget)); - g_return_if_fail(requisition != NULL); - - requisition->width = 80; - requisition->height = 100; -} - - -static void -gtk_snippet_size_allocate(GtkWidget *widget, - GtkAllocation *allocation) -{ - g_return_if_fail(widget != NULL); - g_return_if_fail(GTK_IS_SNIPPET(widget)); - g_return_if_fail(allocation != NULL); - - widget->allocation = *allocation; - - if (GTK_WIDGET_REALIZED(widget)) { - gdk_window_move_resize( - widget->window, - allocation->x, allocation->y, - allocation->width, allocation->height - ); - } -} - - -static void -gtk_snippet_realize(GtkWidget *widget) -{ - GdkWindowAttr attributes; - guint attributes_mask; - GdkColor white; /* Couleur de fond normale */ - - g_return_if_fail(widget != NULL); - g_return_if_fail(GTK_IS_SNIPPET(widget)); - - GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED); - - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = widget->allocation.x; - attributes.y = widget->allocation.y; - attributes.width = widget->allocation.width; - attributes.height = widget->allocation.height; - - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.event_mask = gtk_widget_get_events(widget) | GDK_BUTTON_PRESS_MASK | GDK_EXPOSURE_MASK; - - attributes_mask = GDK_WA_X | GDK_WA_Y; - - widget->window = gdk_window_new( - gtk_widget_get_parent_window (widget), - & attributes, attributes_mask - ); - - gdk_window_set_user_data(widget->window, widget); - - widget->style = gtk_style_attach(widget->style, widget->window); - - - gdk_color_white(gtk_widget_get_colormap(widget), &white); - gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &white); - - - GTK_SNIPPET(widget)->layout = gtk_widget_create_pango_layout(widget, NULL); - GTK_SNIPPET(widget)->gc = gdk_gc_new(GDK_DRAWABLE(widget->window)); - - gtk_snippet_build_content(GTK_SNIPPET(widget)); - -} - - -static gboolean gtk_snippet_button_press(GtkWidget *widget, GdkEventButton *event) -{ - GtkSnippet *snippet; /* COmposant GTK réel */ - unsigned int index; /* Indice de la ligne visée */ - PangoLayoutIter *iter; /* Boucle de parcours */ - int y0; /* Ordonnée du haut d'une ligne*/ - int y1; /* Ordonnée du bas d'une ligne */ - - snippet = GTK_SNIPPET(widget); - - index = 0; - iter = pango_layout_get_iter(snippet->layout); - - for (; index < snippet->info_count; index++, pango_layout_iter_next_line(iter)) - { - pango_layout_iter_get_line_yrange(iter, &y0, &y1); - if (y0 / PANGO_SCALE <= event->y && event->y < y1 / PANGO_SCALE) break; - } - - pango_layout_iter_free(iter); - - - if (event->x < (2 * MARGIN_SPACE + snippet->line_height)) - { - snippet->info[index].bp_set = !snippet->info[index].bp_set; - - /* TODO: regions */ - gtk_snippet_paint(snippet); - - } - - - return FALSE; - -} - - -static gboolean -gtk_snippet_expose(GtkWidget *widget, - GdkEventExpose *event) -{ - g_return_val_if_fail(widget != NULL, FALSE); - g_return_val_if_fail(GTK_IS_SNIPPET(widget), FALSE); - g_return_val_if_fail(event != NULL, FALSE); - - gtk_snippet_paint(GTK_SNIPPET(widget)); - - return FALSE; -} - - -static void -gtk_snippet_paint(GtkSnippet *snippet) -{ - GtkWidget *widget; /* Version GTK du composant */ - GdkGCValues values; /* Propriétés du contexte */ - GdkColor white; /* Couleur du fond */ - int width; /* Largeur de l'élément */ - int height; /* Hauteur de l'élément */ - GdkColor red; /* Couleur des arrêts */ - PangoLayoutIter *iter; /* Boucle de parcours */ - unsigned int index; /* Indice de la ligne visée */ - int y0; /* Ordonnée du haut d'une ligne*/ - int y1; /* Ordonnée du bas d'une ligne */ - - rendering_line *liter; - - - widget = GTK_WIDGET(snippet); - gdk_gc_get_values(snippet->gc, &values); - - gdk_color_white(gtk_widget_get_colormap(widget), &white); - gdk_gc_set_foreground(snippet->gc, &white); - - gtk_widget_get_size_request(widget, &width, &height); - - gdk_draw_rectangle(GDK_DRAWABLE(widget->window), GTK_SNIPPET(widget)->gc, - TRUE, 0, 0, width, height); - - gdk_color_parse("#ff0000", &red); - gdk_color_alloc(gtk_widget_get_colormap(widget), &red); - gdk_gc_set_foreground(snippet->gc, &red); - - - index = 0; - iter = pango_layout_get_iter(snippet->layout); - - for (; index < snippet->info_count; index++, pango_layout_iter_next_line(iter)) - { - if (!snippet->info[index].bp_set) continue; - - pango_layout_iter_get_line_yrange(iter, &y0, &y1); - - - - gdk_draw_arc(GDK_DRAWABLE(widget->window), GTK_SNIPPET(widget)->gc, - FALSE, MARGIN_SPACE, y0 / PANGO_SCALE, - snippet->line_height - 2, snippet->line_height - 2, - 0, 360 * 64); - - } - - pango_layout_iter_free(iter); - - gdk_gc_set_foreground(snippet->gc, &values.foreground); - - gdk_draw_layout(GDK_DRAWABLE(widget->window), snippet->gc, - 2 * MARGIN_SPACE + snippet->line_height, 0, - snippet->layout); - - - y0 = 0; - - for (/* l! */liter = snippet->lines; liter != NULL; liter = g_rendering_line_get_next_iter(snippet->lines, liter)) - { - draw_rendering_line(liter, GDK_DRAWABLE(widget->window), snippet->gc, - MARGIN_SPACE, 2 * MARGIN_SPACE + snippet->line_height, - y0, snippet->line_height); - - y0 += snippet->line_height; - - } - - -} - - -static void -gtk_snippet_destroy(GtkObject *object) -{ - GtkSnippet *cpu; - GtkSnippetClass *klass; - - g_return_if_fail(object != NULL); - g_return_if_fail(GTK_IS_SNIPPET(object)); - - cpu = GTK_SNIPPET(object); - - klass = gtk_type_class(gtk_widget_get_type()); - - if (GTK_OBJECT_CLASS(klass)->destroy) { - (* GTK_OBJECT_CLASS(klass)->destroy) (object); - } -} - - - - - - -/****************************************************************************** -* * -* Paramètres : snippet = composant GTK à mettre à jour. * -* show = état de l'affichage auquel parvenir. * -* * -* Description : Choisit d'afficher les adresses virtuelles ou non. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_snippet_show_vaddress(GtkSnippet *snippet, gboolean show) -{ - snippet->show_vaddress = show; - - gtk_snippet_build_content(snippet); - -} - - -/****************************************************************************** -* * -* Paramètres : snippet = composant GTK à mettre à jour. * -* show = état de l'affichage auquel parvenir. * -* * -* Description : Choisit d'afficher le code brut ou non. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_snippet_show_code(GtkSnippet *snippet, gboolean show) -{ - snippet->show_code = show; - - gtk_snippet_build_content(snippet); - -} - - - - - -/****************************************************************************** -* * -* Paramètres : snippet = composant GTK à mettre à jour. * -* format = format du binaire affiché. * -* * -* Description : Définit le format auquel le contenu est lié. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_snippet_set_format(GtkSnippet *snippet, const exe_format *format) -{ - snippet->format = format; - -} - - -/****************************************************************************** -* * -* Paramètres : snippet = composant GTK à mettre à jour. * -* proc = architecture à associer au contenu. * -* * -* Description : Définit l'architecture à laquelle le contenu est lié. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_snippet_set_processor(GtkSnippet *snippet, const asm_processor *proc) -{ - snippet->proc = proc; - -} - - -/****************************************************************************** -* * -* Paramètres : snippet = composant GTK à mettre à jour. * -* lines = informations à intégrer. * -* * -* Description : Définit les lignes du bloc de représentation. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_snippet_set_rendering_lines(GtkSnippet *snippet, rendering_line *lines) -{ - snippet->lines = lines; - - g_rendering_lines_update_bin_len(lines); - - gtk_snippet_recompute_size_request(snippet); - -} - - - - - -/****************************************************************************** -* * -* Paramètres : snippet = composant GTK à mettre à jour. * -* * -* Description : Réclame une nouvelle taille adaptée au contenu présent. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_snippet_recompute_size_request(GtkSnippet *snippet) -{ - int width; /* Largeur de l'objet actuelle */ - int height; /* Hauteur de l'objet actuelle */ - - g_rendering_lines_get_size(snippet->lines, &width, &height, &snippet->line_height); - - gtk_widget_set_size_request(GTK_WIDGET(snippet), - width + 2 * MARGIN_SPACE + snippet->line_height, - height); - -} - - - - - - - - - - -/****************************************************************************** -* * -* Paramètres : snippet = composant GTK à mettre à jour. * -* line = informations à intégrer. * -* * -* Description : Ajoute une ligne dans le bloc de représentation. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_snippet_add_line(GtkSnippet *snippet, const code_line_info *line) -{ - snippet->info = (code_line_info *)realloc(snippet->info, ++snippet->info_count * sizeof(code_line_info)); - - snippet->info[snippet->info_count - 1] = *line; - -} - - -/****************************************************************************** -* * -* Paramètres : snippet = composant GTK à mettre à jour. * -* * -* Description : Définit le contenu visuel à partir des infos enregistrées. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_snippet_build_content(GtkSnippet *snippet) -{ - const uint8_t *exe_content; /* Contenu binaire global */ - off_t max_bin_len; /* Taille max du code brut */ - unsigned int i; /* Boucle de traitement */ - off_t bin_len; /* Taille d'instruction */ - char *bin_code; /* Tampon du code binaire */ - char *content; /* Contenu à définir */ - size_t content_len; /* Taille du contenu */ - AdressMode mode; /* Affichage des adresses */ - char buffer[CONTENT_BUFFER_LEN]; /* Zone tampon à utiliser */ - off_t bin_offset; /* Début de l'instruction */ - off_t k; /* Boucle de parcours #2 */ - off_t j; /* Boucle de parcours #1 */ - int width; /* Largeur de l'objet actuelle */ - int height; /* Hauteur de l'objet actuelle */ - PangoLayoutIter *iter; /* Boucle de parcours */ - int y0; /* Ordonnée du haut d'une ligne*/ - int y1; /* Ordonnée du bas d'une ligne */ - - /* Calcul de la largeur maximale brute si besoin est */ - if (snippet->show_code) - { - exe_content = get_exe_content(snippet->format, NULL); - - max_bin_len = 1; - - for (i = 0; i < snippet->info_count; i++) - { - /* Commentaire uniquement */ - if (snippet->info[i].instr == NULL) continue; - - get_asm_instr_offset_and_length(snippet->info[i].instr, NULL, &bin_len); - if (bin_len > max_bin_len) max_bin_len = bin_len; - - } - - max_bin_len = max_bin_len * 2 + (max_bin_len - 1); - bin_code = (char *)calloc(max_bin_len + 1, sizeof(char)); - - } - - content_len = strlen("") + 1; - content = (char *)calloc(content_len, sizeof(char)); - strcpy(content, ""); - - mode = ADM_32BITS; /* FIXME */ - - for (i = 0; i < snippet->info_count; i++) - { - if (i > 0) - { - content = (char *)realloc(content, ++content_len * sizeof(char)); - strcat(content, "\n"); - } - - /* Eventuelle adresse virtuelle */ - - if (snippet->show_vaddress) - { - switch (mode) - { - case ADM_32BITS: - snprintf(buffer, CONTENT_BUFFER_LEN, - "0x%08llx", - snippet->info[i].offset); - break; - - case ADM_64BITS: - snprintf(buffer, CONTENT_BUFFER_LEN, - "0x%16llx", - snippet->info[i].offset); - break; - - } - - content_len += strlen(buffer); - content = (char *)realloc(content, content_len * sizeof(char)); - strcat(content, buffer); - - } - - /* Eventuel code brut */ - - if (snippet->show_code) - { - k = 0; - - if (snippet->info[i].instr != NULL) - { - get_asm_instr_offset_and_length(snippet->info[i].instr, &bin_offset, &bin_len); - - for (j = 0; j < bin_len; j++) - { - if ((j + 1) < bin_len) - k += snprintf(&bin_code[j * (2 + 1)], 4, "%02hhx ", exe_content[bin_offset + j]); - else - k += snprintf(&bin_code[j * (2 + 1)], 3, "%02hhx", exe_content[bin_offset + j]); - } - - } - - for (; k < max_bin_len; k++) - snprintf(&bin_code[k], 2, " "); - - if (snippet->show_vaddress) content_len += strlen("\t"); - content_len += strlen(bin_code); - content = (char *)realloc(content, content_len * sizeof(char)); - if (snippet->show_vaddress) strcat(content, "\t"); - strcat(content, bin_code); - - } - - /* Eventuelle instruction */ - - if (snippet->info[i].instr != NULL) - { - print_hinstruction(snippet->proc, snippet->format, snippet->info[i].instr, buffer, CONTENT_BUFFER_LEN, ASX_INTEL); - - if (snippet->show_vaddress || snippet->show_code) content_len += strlen("\t"); - content_len += strlen(buffer); - - content = (char *)realloc(content, content_len * sizeof(char)); - if (snippet->show_vaddress || snippet->show_code) strcat(content, "\t"); - strcat(content, buffer); - - } - - /* Eventuel commantaire */ - - if (snippet->info[i].comment != NULL) - { - if (snippet->show_vaddress || snippet->show_code) content_len += strlen("\t"); - content_len += strlen("; ") + strlen(snippet->info[i].comment) + strlen(""); - - content = (char *)realloc(content, content_len * sizeof(char)); - if (snippet->show_vaddress || snippet->show_code) strcat(content, "\t"); - strcat(content, "; "); - strcat(content, snippet->info[i].comment); - strcat(content, ""); - - } - - } - - content_len += strlen(""); - content = (char *)realloc(content, content_len * sizeof(char)); - strcat(content, ""); - - if (snippet->show_code) free(bin_code); - - pango_layout_set_markup(snippet->layout, content, content_len - 1); - - pango_layout_get_pixel_size(snippet->layout, &width, &height); - - snippet->line_height = 0; - iter = pango_layout_get_iter(snippet->layout); - - do - { - pango_layout_iter_get_line_yrange(iter, &y0, &y1); - snippet->line_height = MAX(snippet->line_height, (y1 - y0) / PANGO_SCALE); - } - while (pango_layout_iter_next_line(iter)); - - pango_layout_iter_free(iter); - - //gtk_widget_set_size_request(GTK_WIDGET(snippet), width + 2 * MARGIN_SPACE + snippet->line_height, height); - -} - - - - - - - - -/****************************************************************************** -* * -* Paramètres : snippet = composant GTK à consulter. * -* address = adresse à présenter à l'écran. * -* position = position verticale au sein du composant. [OUT] * -* * -* Description : Indique la position verticale d'une adresse donnée. * -* * -* Retour : TRUE si l'adresse fait partie du composant, FALSE sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -gboolean gtk_snippet_get_address_vposition(GtkSnippet *snippet, uint64_t address, gint *position) -{ - unsigned int i; /* Boucle de parcours */ - - *position = 0; - - for (i = 0; i < snippet->info_count; i++) - { - if (snippet->info[i].offset == address) break; - else *position += snippet->line_height; - } - - return (i < snippet->info_count); - -} - diff --git a/src/gtksnippet.h b/src/gtksnippet.h deleted file mode 100644 index ab7ad4f..0000000 --- a/src/gtksnippet.h +++ /dev/null @@ -1,156 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * gtksnippet.h - prototypes pour l'affichage d'un fragment de code d'assemblage - * - * Copyright (C) 2008 Cyrille Bagard - * - * This file is part of OpenIDA. - * - * OpenIDA is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * OpenIDA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - - -#ifndef _GTK_SNIPPET_H -#define _GTK_SNIPPET_H - - -#include -#include -#include - - -#include "analysis/line.h" -#include "arch/instruction.h" -#include "arch/processor.h" -#include "format/exe_format.h" - - - -typedef struct _code_line_info -{ - uint64_t offset; /* Position de l'instruction */ - asm_instr *instr; /* Eventuelle instruction */ - char *comment; /* Eventuel commentaire */ - - gboolean bp_set; /* Point d'arrêt défini */ - -} code_line_info; - - - - -/* Crée une ligne de représentation insérable. */ -code_line_info *create_code_line_info(uint64_t, asm_instr *, const char *); - -/* Supprime une ligne de représentation. */ -void delete_code_line_info(code_line_info *); - -/* Etablit la comparaison entre deux lignes de représentation. */ -int compare_code_line_info(const code_line_info **, const code_line_info **); - - - - - -G_BEGIN_DECLS - - -#define GTK_SNIPPET(obj) GTK_CHECK_CAST(obj, gtk_snippet_get_type (), GtkSnippet) -#define GTK_SNIPPET_CLASS(klass) GTK_CHECK_CLASS_CAST(klass, gtk_snippet_get_type(), GtkSnippetClass) -#define GTK_IS_SNIPPET(obj) GTK_CHECK_TYPE(obj, gtk_snippet_get_type()) - - -typedef struct _GtkSnippet GtkSnippet; -typedef struct _GtkSnippetClass GtkSnippetClass; - - - - - -struct _GtkSnippet { - - GtkWidget widget; /* Présence obligatoire en 1er */ - - AdressMode mode; /* Mode d'affichage */ - - bool show_vaddress; /* Affichage des adresses ? */ - bool show_code; /* Affichage du code brut ? */ - - PangoLayout *layout; /* Moteur de rendu du code ASM */ - GdkGC *gc; /* Contexte graphique du rendu */ - int line_height; /* Hauteur maximale des lignes */ - - const exe_format *format; /* Format du contenu bianire */ - const asm_processor *proc; /* Architecture utilisée */ - code_line_info *info; /* Contenu à représenter */ - unsigned int info_count; /* Quantité d'informations */ - - rendering_line *lines; /* Contenu à représenter */ - - - gint sel; -}; - -struct _GtkSnippetClass { - GtkWidgetClass parent_class; -}; - - -GtkType gtk_snippet_get_type(void); -void gtk_snippet_set_sel(GtkSnippet *cpu, gint sel); - -GtkWidget *gtk_snippet_new(void); - - - - -/* Choisit d'afficher les adresses virtuelles ou non. */ -void gtk_snippet_show_vaddress(GtkSnippet *, gboolean); - -/* Choisit d'afficher le code brut ou non. */ -void gtk_snippet_show_code(GtkSnippet *, gboolean); - - - - -/* Définit le format auquel le contenu est lié. */ -void gtk_snippet_set_format(GtkSnippet *, const exe_format *); - -/* Définit l'architecture à laquelle le contenu est lié. */ -void gtk_snippet_set_processor(GtkSnippet *, const asm_processor *); - -/* Ajoute une ligne dans le bloc de représentation. */ -void gtk_snippet_add_line(GtkSnippet *, const code_line_info *); - -/* Définit les lignes du bloc de représentation. */ -void gtk_snippet_set_rendering_lines(GtkSnippet *, rendering_line *); - -/* Définit le contenu visuel à partir des infos enregistrées. */ -void gtk_snippet_build_content(GtkSnippet *); - - - -/* Indique la position verticale d'une adresse donnée. */ -gboolean gtk_snippet_get_address_vposition(GtkSnippet *, uint64_t, gint *); - - - -G_END_DECLS - - - - - - -#endif /* _GTK_SNIPPET_H */ diff --git a/src/pan_symbols.c b/src/pan_symbols.c index a78bc44..05a162b 100644 --- a/src/pan_symbols.c +++ b/src/pan_symbols.c @@ -29,7 +29,7 @@ #include -#include "gtkbinview.h" +#include "gtkext/gtkbinview.h" diff --git a/src/panel/Makefile.am b/src/panel/Makefile.am index 19079d5..a74cfa0 100755 --- a/src/panel/Makefile.am +++ b/src/panel/Makefile.am @@ -3,12 +3,13 @@ lib_LIBRARIES = libpanel.a libpanel_a_SOURCES = \ log.h log.c \ - panels.h panels.c + panels.h panels.c \ + registers.h registers.c libpanel_a_CFLAGS = $(AM_CFLAGS) -INCLUDES = $(LIBGTK_CFLAGS) +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CPPFLAGS = diff --git a/src/panel/log.c b/src/panel/log.c index f98953f..94bb8a4 100644 --- a/src/panel/log.c +++ b/src/panel/log.c @@ -147,6 +147,13 @@ void log_simple_message(LogMessageType type, const char *msg) -1); break; + case LMT_PROCESS: + gtk_tree_store_set(store, &iter, + LGC_PICTURE, "gtk-execute", + LGC_STRING, msg, + -1); + break; + } } diff --git a/src/panel/log.h b/src/panel/log.h index 91e2c83..5ea95cc 100644 --- a/src/panel/log.h +++ b/src/panel/log.h @@ -35,6 +35,7 @@ typedef enum _LogMessageType { LMT_INFO, /* Information sur l'exécution */ LMT_BAD_BINARY, /* Binaire malformé */ + LMT_PROCESS, /* Début de tâche quelconque */ LMT_COUNT diff --git a/src/panel/panels.c b/src/panel/panels.c index a127825..eae6ba3 100644 --- a/src/panel/panels.c +++ b/src/panel/panels.c @@ -26,6 +26,7 @@ #include "log.h" +#include "registers.h" @@ -48,6 +49,7 @@ static GtkWidget *panel_list[PNT_COUNT]; void init_panels(void) { panel_list[PNT_LOG] = build_log_panel(); + panel_list[PNT_REGISTERS] = build_registers_panel(); } diff --git a/src/panel/panels.h b/src/panel/panels.h index 87ddfa6..e38f196 100644 --- a/src/panel/panels.h +++ b/src/panel/panels.h @@ -34,6 +34,7 @@ typedef enum _PanelType { PNT_LOG, /* Messages système */ + PNT_REGISTERS, /* Registres d'architecture */ PNT_COUNT diff --git a/src/panel/registers.c b/src/panel/registers.c new file mode 100644 index 0000000..ce27a71 --- /dev/null +++ b/src/panel/registers.c @@ -0,0 +1,236 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * registers.c - panneau d'affichage des registres d'architecture + * + * Copyright (C) 2006-2007 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "registers.h" + + +#include "../easygtk.h" + + + +#define _(str) str + + + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Construit le panneau d'affichage des registres. * +* * +* Retour : Adresse du panneau mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *build_registers_panel(void) +{ + GtkWidget *result; /* Panneau à retourner */ + + + GtkWidget *vbox1; + GtkWidget *label1; + GtkWidget *table1; + GtkWidget *label3; + GtkWidget *label4; + GtkWidget *label5; + GtkWidget *label6; + GtkWidget *label7; + GtkWidget *label8; + GtkWidget *label9; + GtkWidget *label10; + GtkWidget *label11; + GtkWidget *label12; + GtkWidget *label13; + GtkWidget *label14; + GtkWidget *label15; + GtkWidget *label16; + GtkWidget *entry1; + GtkWidget *entry2; + GtkWidget *entry3; + GtkWidget *entry4; + GtkWidget *entry6; + GtkWidget *entry5; + GtkWidget *entry7; + GtkWidget *label2; + + GtkWidget *label; /* Etiquette textuelle */ + GtkWidget *alignment; /* Décallage de contenu */ + GtkWidget *entry; /* Zone de saisie */ + + + + result = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_show(result); + + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(result), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(result), GTK_SHADOW_IN); + + + + + vbox1 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox1); + gtk_container_add (GTK_CONTAINER (result), vbox1); + + label1 = gtk_label_new (_("Registers:")); + gtk_widget_show (label1); + gtk_box_pack_start (GTK_BOX (vbox1), label1, FALSE, FALSE, 0); + gtk_misc_set_alignment (GTK_MISC (label1), 0, 0.5); + + + alignment = qck_create_padded_alignment(0, 0, 8, 0); + gtk_box_pack_start(GTK_BOX(vbox1), alignment, FALSE, TRUE, 0); + + table1 = gtk_table_new(7, 3, FALSE); + gtk_widget_show(table1); + gtk_container_add(GTK_CONTAINER(alignment), table1); + + label = qck_create_label(NULL, NULL, "eax: "); + gtk_table_attach(GTK_TABLE(table1), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0); + + entry = qck_create_entry(G_OBJECT(result), "eax", NULL); + gtk_entry_set_width_chars(GTK_ENTRY(entry), 8); + gtk_table_attach(GTK_TABLE(table1), entry, 1, 2, 0, 1, GTK_FILL, 0, 0, 0); + + label = qck_create_label(NULL, NULL, "ebx: "); + gtk_table_attach(GTK_TABLE(table1), label, 0, 1, 1, 2, GTK_FILL, 0, 0, 0); + + entry = qck_create_entry(G_OBJECT(result), "ebx", NULL); + gtk_entry_set_width_chars(GTK_ENTRY(entry), 8); + gtk_table_attach(GTK_TABLE(table1), entry, 1, 2, 1, 2, GTK_FILL, 0, 0, 0); + + label = qck_create_label(NULL, NULL, "ecx: "); + gtk_table_attach(GTK_TABLE(table1), label, 0, 1, 2, 3, GTK_FILL, 0, 0, 0); + + entry = qck_create_entry(G_OBJECT(result), "ecx", NULL); + gtk_entry_set_width_chars(GTK_ENTRY(entry), 8); + gtk_table_attach(GTK_TABLE(table1), entry, 1, 2, 2, 3, GTK_FILL, 0, 0, 0); + + label = qck_create_label(NULL, NULL, "edx: "); + gtk_table_attach(GTK_TABLE(table1), label, 0, 1, 3, 4, GTK_FILL, 0, 0, 0); + + entry = qck_create_entry(G_OBJECT(result), "edx", NULL); + gtk_entry_set_width_chars(GTK_ENTRY(entry), 8); + gtk_table_attach(GTK_TABLE(table1), entry, 1, 2, 3, 4, GTK_FILL, 0, 0, 0); + + label = qck_create_label(NULL, NULL, "esi: "); + gtk_table_attach(GTK_TABLE(table1), label, 0, 1, 4, 5, GTK_FILL, 0, 0, 0); + + entry = qck_create_entry(G_OBJECT(result), "esi", NULL); + gtk_entry_set_width_chars(GTK_ENTRY(entry), 8); + gtk_table_attach(GTK_TABLE(table1), entry, 1, 2, 4, 5, GTK_FILL, 0, 0, 0); + + label = qck_create_label(NULL, NULL, "edi: "); + gtk_table_attach(GTK_TABLE(table1), label, 0, 1, 5, 6, GTK_FILL, 0, 0, 0); + + entry = qck_create_entry(G_OBJECT(result), "edi", NULL); + gtk_entry_set_width_chars(GTK_ENTRY(entry), 8); + gtk_table_attach(GTK_TABLE(table1), entry, 1, 2, 5, 6, GTK_FILL, 0, 0, 0); + + label = qck_create_label(NULL, NULL, "ebp: "); + gtk_table_attach(GTK_TABLE(table1), label, 0, 1, 6, 7, GTK_FILL, 0, 0, 0); + + entry = qck_create_entry(G_OBJECT(result), "ebp", NULL); + gtk_entry_set_width_chars(GTK_ENTRY(entry), 8); + gtk_table_attach(GTK_TABLE(table1), entry, 1, 2, 6, 7, GTK_FILL, 0, 0, 0); + + label = qck_create_label(NULL, NULL, "esp: "); + gtk_table_attach(GTK_TABLE(table1), label, 0, 1, 7, 8, GTK_FILL, 0, 0, 0); + + entry = qck_create_entry(G_OBJECT(result), "esp", NULL); + gtk_entry_set_width_chars(GTK_ENTRY(entry), 8); + gtk_table_attach(GTK_TABLE(table1), entry, 1, 2, 7, 8, GTK_FILL, 0, 0, 0); + + label = qck_create_label(NULL, NULL, "eip: "); + gtk_table_attach(GTK_TABLE(table1), label, 0, 1, 8, 9, GTK_FILL, 0, 0, 0); + + entry = qck_create_entry(G_OBJECT(result), "eip", NULL); + gtk_entry_set_width_chars(GTK_ENTRY(entry), 8); + gtk_table_attach(GTK_TABLE(table1), entry, 1, 2, 8, 9, GTK_FILL, 0, 0, 0); + + + + + label2 = gtk_label_new (_("Segments:")); + gtk_widget_show (label2); + gtk_box_pack_start (GTK_BOX (vbox1), label2, FALSE, FALSE, 0); + gtk_misc_set_alignment (GTK_MISC (label2), 0, 0.5); + + + + + return result; + +} + + + + + + +/****************************************************************************** +* * +* Paramètres : panel = panneau contenant les champs utiles. * +* values = liste des registres avec leur valeur. * +* count = taille de cette liste. * +* * +* Description : Met à jour l'affichage des valeurs de registre. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void refresh_registers_panel_with_registers(GtkWidget *panel, register_value *values, size_t count) +{ + GObject *ref; /* Espace de référencement */ + size_t i; /* Boucle de parcours */ + GtkEntry *entry; /* Zone de texte */ + char buffer[32]; + + ref = G_OBJECT(panel); + + for (i = 0; i < count; i++) + { + entry = GTK_ENTRY(g_object_get_data(ref, values[i].name)); + if (entry == NULL) continue; + + snprintf(buffer, 32, "%08llx", values[i].value); + + gtk_entry_set_text(entry, buffer); + + + + + + } + + + +} diff --git a/src/panel/registers.h b/src/panel/registers.h new file mode 100644 index 0000000..7110414 --- /dev/null +++ b/src/panel/registers.h @@ -0,0 +1,47 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * registers.h - prototypes pour le panneau d'affichage des registres d'architecture + * + * Copyright (C) 2006-2007 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PANEL_REGISTERS_H +#define _PANEL_REGISTERS_H + + +#include + + +#include "../debug/debuggers.h" + + + +/* Construit le panneau d'affichage des registres. */ +GtkWidget *build_registers_panel(void); + + + +/* Met à jour l'affichage des valeurs de registre. */ +void refresh_registers_panel_with_registers(GtkWidget *, register_value *, size_t); + + + + +#endif /* _PANEL_REGISTERS_H */ -- cgit v0.11.2-87-g4458