diff options
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 */ |