diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2009-04-12 19:15:35 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2009-04-12 19:15:35 (GMT) | 
| commit | 216a3d0121fabd678e50ea6b4fa2447ae9b921f0 (patch) | |
| tree | 395fcd91b674ff5652e34b46207ba08cc9e7af68 /src | |
| parent | edac614a164d9cac345d914f4320d71bdb16ab79 (diff) | |
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
Diffstat (limited to 'src')
48 files changed, 3232 insertions, 1295 deletions
| 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 <http://www.gnu.org/licenses/>. + */ + + +#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 <malloc.h>  #include <stdio.h>  #include <string.h> @@ -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("<b><span foreground='#003300'>"); -    len += strlen("; ") + strlen(line->comment); -    len += strlen("</span></b>"); - -    content = (char *)calloc(len + 1, sizeof(char)); - -    snprintf(content, len + 1, "<b><span foreground='#003300'>; %s</span></b>", 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("<tt>") + 1; -    content = (char *)calloc(len, sizeof(char)); -    strcpy(content, "<tt>"); +    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, -                         "<span foreground='#333333'>0x%08llx</span>", -                         RENDERING_LINE(line)->offset); -                break; - -            case ADM_64BITS: -                snprintf(buffer, CODE_BUFFER_LEN, -                         "<span foreground='#333333'>0x%16llx</span>", -                         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("<b><span foreground='#003300'>"); -    clen += strlen("; ") + strlen(line->comment); -    clen += strlen("</span></b>"); - -    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, "<b><span foreground='#003300'>; %s</span></b>", line->comment); - -    len += clen; - -    /* Finalisation */ - -    len += strlen("</tt>"); -    content = (char *)realloc(content, len * sizeof(char)); -    strcat(content, "</tt>"); - -    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("<tt>") + 1; -    content = (char *)calloc(len, sizeof(char)); -    strcpy(content, "<tt>"); - -    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, -                         "<span foreground='#333333'>0x%08llx</span>", -                         RENDERING_LINE(line)->offset); -                break; - -            case ADM_64BITS: -                snprintf(buffer, CODE_BUFFER_LEN, -                         "<span foreground='#333333'>0x%16llx</span>", -                         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("</tt>"); -    content = (char *)realloc(content, len * sizeof(char)); -    strcat(content, "</tt>"); - -    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 <http://www.gnu.org/licenses/>. + */ + + +#include "line_code.h" + + +#include <malloc.h> +#include <string.h> + + +#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("<tt>") + 1; +    content = (char *)calloc(len, sizeof(char)); +    strcpy(content, "<tt>"); + +    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, +                         "<span foreground='#333333'>0x%08llx</span>", +                         G_RENDERING_LINE(line)->offset); +                break; + +            case ADM_64BITS: +                snprintf(buffer, CODE_BUFFER_LEN, +                         "<span foreground='#333333'>0x%16llx</span>", +                         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("</tt>"); +    content = (char *)realloc(content, len * sizeof(char)); +    strcat(content, "</tt>"); + +    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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_LINE_CODE_H +#define _ANALYSIS_LINE_CODE_H + + +#include <glib-object.h> + + +#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 <http://www.gnu.org/licenses/>. + */ + + +#include "line_comment.h" + + +#include <malloc.h> +#include <string.h> + + +#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("<tt>") + 1; +    content = (char *)calloc(len, sizeof(char)); +    strcpy(content, "<tt>"); + +    /* Eventuelle adresse virtuelle */ + +    if (line->options->show_address) +    { +        switch (ADM_32BITS  /* FIXME */) +        { +            case ADM_32BITS: +                snprintf(buffer, CODE_BUFFER_LEN, +                         "<span foreground='#333333'>0x%08llx</span>", +                         G_RENDERING_LINE(line)->offset); +                break; + +            case ADM_64BITS: +                snprintf(buffer, CODE_BUFFER_LEN, +                         "<span foreground='#333333'>0x%16llx</span>", +                         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("<b><span foreground='#003300'>"); +    clen += strlen("; ") + strlen(line->comment); +    clen += strlen("</span></b>"); + +    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, "<b><span foreground='#003300'>; %s</span></b>", line->comment); + +    len += clen; + +    /* Finalisation */ + +    len += strlen("</tt>"); +    content = (char *)realloc(content, len * sizeof(char)); +    strcat(content, "</tt>"); + +    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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_LINE_COMMENT_H +#define _ANALYSIS_LINE_COMMENT_H + + +#include <glib-object.h> + + +#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 <http://www.gnu.org/licenses/>. + */ + + +#include "line_prologue.h" + + +#include <malloc.h> +#include <string.h> + + +#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("<b><span foreground='#003300'>"); +    len += strlen("; ") + strlen(line->comment); +    len += strlen("</span></b>"); + +    content = (char *)calloc(len + 1, sizeof(char)); + +    snprintf(content, len + 1, "<b><span foreground='#003300'>; %s</span></b>", 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_LINE_PROLOGUE_H +#define _ANALYSIS_LINE_PROLOGUE_H + + +#include <glib-object.h> + + +#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 <sys/types.h> +#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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _DEBUG_DEBUGGER_INT_H +#define _DEBUG_DEBUGGER_INT_H + + +#include "debuggers.h" + + +#include <gtk/gtk.h> + + + +/* 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 <http://www.gnu.org/licenses/>. + */ + + +#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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _DEBUG_DEBUGGER_H +#define _DEBUG_DEBUGGER_H + + +#include <glib-object.h> +#include <stdint.h> +#include <sys/types.h> + + +#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 <http://www.gnu.org/licenses/>. + */ + + +#include "options.h" + + +#include <libgen.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + + + +/* ---------------------- 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _DEBUG_PTRACE_OPTIONS_H +#define _DEBUG_PTRACE_OPTIONS_H + + +#include <stdbool.h> + + +#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 <http://www.gnu.org/licenses/>. + */ + + +#include "ptrace.h" + + +#include <malloc.h> +#include <unistd.h> +#include <signal.h> +#include <sys/types.h> + + +#include "options.h" +#include "../debugger-int.h" +#include "../../panel/log.h" + + + + +/** Partie ptrace() **/ +#include <sys/ptrace.h> +#include <sys/wait.h> +//#include <linux/user.h> +#include <sys/syscall.h>   /* For SYS_write etc */ +#include <sys/reg.h> +/** 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _DEBUG_PTRACE_PTRACE_H +#define _DEBUG_PTRACE_PTRACE_H + + +#include <glib-object.h> + + +#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 <unistd.h>  /** exemple GTK **/ -/** Partie ptrace() **/ -#include <sys/ptrace.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> -//#include <linux/user.h> -#include <sys/syscall.h>   /* 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 <asm/ptrace-abi.h> -#include <sys/reg.h> - -#include <error.h> -#include <errno.h> - -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/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/gtkbinview.c b/src/gtkext/gtkbinview.c index 5ed6388..5ed6388 100644 --- a/src/gtkbinview.c +++ b/src/gtkext/gtkbinview.c diff --git a/src/gtkbinview.h b/src/gtkext/gtkbinview.h index 4fafad1..4fafad1 100644 --- a/src/gtkbinview.h +++ b/src/gtkext/gtkbinview.h diff --git a/src/gtksnippet.c b/src/gtkext/gtksnippet.c index f56ccd0..a48baf2 100644 --- a/src/gtksnippet.c +++ b/src/gtkext/gtksnippet.c @@ -28,7 +28,7 @@  #include <string.h> -#include "common/dllist.h" +#include "../common/dllist.h" @@ -39,6 +39,11 @@ +/* Redessine l'affichage suite une mise à jour dans la marge. */ +void gtk_snippet_update_margin(GRenderingLine *, GtkSnippet *); + + +  /****************************************************************************** @@ -143,7 +148,7 @@ static void gtk_snippet_size_allocate(GtkWidget *widget,  static void gtk_snippet_realize(GtkWidget *widget); -static gboolean gtk_snippet_button_press(GtkWidget *widget, GdkEventButton *event); +static gboolean gtk_snippet_button_press(GtkWidget *, GdkEventButton *event);  static gboolean gtk_snippet_expose(GtkWidget *widget,      GdkEventExpose *event); @@ -176,7 +181,7 @@ gtk_snippet_get_type(void)  } -GtkWidget *gtk_snippet_new(void) +GtkWidget * gtk_snippet_new(void)  {      GtkSnippet *result; @@ -295,41 +300,69 @@ gtk_snippet_realize(GtkWidget *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 */ +    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); -    index = 0; -    iter = pango_layout_get_iter(snippet->layout); +    y = event->y; +    line = g_rendering_line_find_by_y(snippet->lines, &y); -    for (; index < snippet->info_count; index++, pango_layout_iter_next_line(iter)) +    if (line != NULL)      { -        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); +        /* 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 (event->x < (2 * MARGIN_SPACE + snippet->line_height)) +    if (result)      { -        snippet->info[index].bp_set = !snippet->info[index].bp_set; -          /* 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); + + -    return FALSE;  } + + +  static gboolean  gtk_snippet_expose(GtkWidget *widget,      GdkEventExpose *event) @@ -340,7 +373,29 @@ gtk_snippet_expose(GtkWidget *widget,    gtk_snippet_paint(GTK_SNIPPET(widget)); -  return FALSE; + + +  /* + + +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; +  } @@ -358,7 +413,7 @@ gtk_snippet_paint(GtkSnippet *snippet)      int y0;                                 /* Ordonnée du haut d'une ligne*/      int y1;                                 /* Ordonnée du bas d'une ligne */ -    rendering_line *liter; +    GRenderingLine *liter;      widget = GTK_WIDGET(snippet); @@ -408,9 +463,9 @@ gtk_snippet_paint(GtkSnippet *snippet)      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); +        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; @@ -543,11 +598,17 @@ void gtk_snippet_set_processor(GtkSnippet *snippet, const asm_processor *proc)  *                                                                             *  ******************************************************************************/ -void gtk_snippet_set_rendering_lines(GtkSnippet *snippet, rendering_line *lines) +void gtk_snippet_set_rendering_lines(GtkSnippet *snippet, GRenderingLine *lines)  { +    GRenderingLine *iter;                   /* Boucle de parcours          */ +      snippet->lines = lines; -    g_rendering_lines_update_bin_len(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); @@ -574,7 +635,7 @@ 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); +    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, diff --git a/src/gtksnippet.h b/src/gtkext/gtksnippet.h index ab7ad4f..41727bd 100644 --- a/src/gtksnippet.h +++ b/src/gtkext/gtksnippet.h @@ -30,10 +30,10 @@  #include <cairo.h> -#include "analysis/line.h" -#include "arch/instruction.h" -#include "arch/processor.h" -#include "format/exe_format.h" +#include "../analysis/line.h" +#include "../arch/instruction.h" +#include "../arch/processor.h" +#include "../format/exe_format.h" @@ -96,7 +96,7 @@ struct _GtkSnippet {      code_line_info *info;                   /* Contenu à représenter       */      unsigned int info_count;                /* Quantité d'informations     */ -    rendering_line *lines;                  /* Contenu à représenter       */ +    GRenderingLine *lines;                  /* Contenu à représenter       */    gint sel; @@ -110,7 +110,7 @@ struct _GtkSnippetClass {  GtkType gtk_snippet_get_type(void);  void gtk_snippet_set_sel(GtkSnippet *cpu, gint sel); -GtkWidget *gtk_snippet_new(void); +GtkWidget * gtk_snippet_new(void); @@ -134,7 +134,7 @@ void gtk_snippet_set_processor(GtkSnippet *, const asm_processor *);  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 *); +void gtk_snippet_set_rendering_lines(GtkSnippet *, GRenderingLine *);  /* Définit le contenu visuel à partir des infos enregistrées. */  void gtk_snippet_build_content(GtkSnippet *); 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 <stdlib.h> -#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 <gtk/gtk.h> + + +#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 */ | 
