From 7c40b70d6c1e1e13dadf876c8dda60b525616d47 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 16 Dec 2015 18:20:06 +0100 Subject: Built a new improved status bar for instructions information. --- ChangeLog | 25 ++ src/analysis/disass/area.c | 5 +- src/format/format.c | 126 +++++---- src/format/format.h | 6 +- src/glibext/gbinportion.c | 2 +- src/gtkext/Makefile.am | 1 + src/gtkext/gtkstatusstack.c | 609 ++++++++++++++++++++++++++++++++++++++++++++ src/gtkext/gtkstatusstack.h | 79 ++++++ src/gui/editor.c | 2 +- src/gui/status.c | 163 +----------- 10 files changed, 802 insertions(+), 216 deletions(-) create mode 100644 src/gtkext/gtkstatusstack.c create mode 100644 src/gtkext/gtkstatusstack.h diff --git a/ChangeLog b/ChangeLog index bb9f0d5..f116419 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +15-12-16 Cyrille Bagard + + * src/analysis/disass/area.c: + Update code. + + * src/format/format.c: + * src/format/format.h: + Remove old code for resolving symbols and improve the current one. + + * src/glibext/gbinportion.c: + Typo. + + * src/gtkext/Makefile.am: + Add the 'gtkstatusstack.[ch]' files from libgtkext_la_SOURCES. + + * src/gtkext/gtkstatusstack.c: + * src/gtkext/gtkstatusstack.h: + New entries: build a new improved status bar for instructions information. + + * src/gui/editor.c: + Give less space between widgets. + + * src/gui/status.c: + Update code. + 15-12-15 Cyrille Bagard * src/arch/arm/v7/instruction.c: diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index 86c41d3..d2a03c6 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -1485,7 +1485,6 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, phys_t start, ph static void update_address_as_routine(GBinFormat *format, const vmpa2t *addr) { GBinSymbol *symbol; /* Symbole présent ou créé */ - phys_t offset; /* Décallage trouvé */ bool found; /* Détection de symbole */ SymbolType sym_type; /* Type de symbole en place */ bool wrong_type; /* Analyse plus fine de ce type*/ @@ -1494,7 +1493,7 @@ static void update_address_as_routine(GBinFormat *format, const vmpa2t *addr) char name[5 + VMPA_MAX_LEN]; /* Nom de symbole nouveau */ GBinRoutine *routine; /* Nouvelle routine trouvée */ - found = g_binary_format_resolve_symbol(format, addr, &symbol, &offset); + found = g_binary_format_find_symbol_at(format, addr, &symbol); if (found) { @@ -1502,7 +1501,7 @@ static void update_address_as_routine(GBinFormat *format, const vmpa2t *addr) wrong_type = (sym_type != STP_ROUTINE && sym_type != STP_ENTRY_POINT); } - if (!found || (found && offset == 0 && wrong_type)) + if (!found || (found && wrong_type)) { init_mrange(&range, addr, 0); diff --git a/src/format/format.c b/src/format/format.c index 9c42508..82d9e42 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -52,6 +52,9 @@ static void g_binary_format_init(GBinFormat *); /* Retire un symbole de la collection du format binaire. */ static void _g_binary_format_remove_symbol(GBinFormat *, size_t); +/* Recherche le symbole associé à une adresse. */ +static bool _g_binary_format_find_symbol(const GBinFormat *, const vmpa2t *, __compar_fn_t, GBinSymbol **); + /* Indique le type défini pour un format binaire générique. */ @@ -623,9 +626,10 @@ bool g_binary_format_find_symbol_by_label(const GBinFormat *format, const char * * * * Paramètres : format = informations chargées à consulter. * * addr = adresse à cibler lors des recherches. * +* fn = méthode de comparaison des symboles. * * symbol = éventuel symbole trouvé à déréfenrencer. [OUT] * * * -* Description : Recherche le symbole correspondant à une adresse. * +* Description : Recherche le symbole associé à une adresse. * * * * Retour : true si l'opération a été un succès, false sinon. * * * @@ -633,7 +637,7 @@ bool g_binary_format_find_symbol_by_label(const GBinFormat *format, const char * * * ******************************************************************************/ -bool g_binary_format_find_symbol_at(const GBinFormat *format, const vmpa2t *addr, GBinSymbol **symbol) +static bool _g_binary_format_find_symbol(const GBinFormat *format, const vmpa2t *addr, __compar_fn_t fn, GBinSymbol **symbol) { bool result; /* Bilan à retourner */ void *found; /* Résultat de recherches */ @@ -642,6 +646,40 @@ bool g_binary_format_find_symbol_at(const GBinFormat *format, const vmpa2t *addr *symbol = NULL; /* TODO : vérifier les doublons côtés appelants */ + found = bsearch(addr, format->symbols, format->symbols_count, sizeof(GBinSymbol *), fn); + + if (found != NULL) + { + *symbol = *(GBinSymbol **)found; + + g_object_ref(G_OBJECT(*symbol)); + result = true; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* addr = adresse à cibler lors des recherches. * +* symbol = éventuel symbole trouvé à déréfenrencer. [OUT] * +* * +* Description : Recherche le symbole correspondant à une adresse. * +* * +* Retour : true si l'opération a été un succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_format_find_symbol_at(const GBinFormat *format, const vmpa2t *addr, GBinSymbol **symbol) +{ + bool result; /* Bilan à retourner */ + int find_symbol(const vmpa2t *addr, const GBinSymbol **sym) { const mrange_t *range; /* Espace mémoire parcouru */ @@ -652,19 +690,43 @@ bool g_binary_format_find_symbol_at(const GBinFormat *format, const vmpa2t *addr } - found = bsearch(addr, format->symbols, - format->symbols_count, sizeof(GBinSymbol *), - (__compar_fn_t)find_symbol); + result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, symbol); - if (found != NULL) + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* addr = adresse à cibler lors des recherches. * +* symbol = éventuel symbole trouvé à déréfenrencer. [OUT] * +* * +* Description : Recherche le symbole contenant une adresse. * +* * +* Retour : true si l'opération a été un succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_format_find_symbol_for(const GBinFormat *format, const vmpa2t *addr, GBinSymbol **symbol) +{ + bool result; /* Bilan à retourner */ + + int find_symbol(const vmpa2t *addr, const GBinSymbol **sym) { - *symbol = *(GBinSymbol **)found; + const mrange_t *range; /* Espace mémoire parcouru */ - g_object_ref(G_OBJECT(*symbol)); - result = true; + range = g_binary_symbol_get_range(*sym); + + return cmp_mrange_with_vmpa(range, addr); } + result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, symbol); + return result; } @@ -734,7 +796,7 @@ bool g_binary_format_resolve_symbol(const GBinFormat *format, const vmpa2t *addr bool result; /* Bilan à retourner */ const mrange_t *range; /* Espace mémoire parcouru */ - result = g_binary_format_find_symbol_at(format, addr, symbol); + result = g_binary_format_find_symbol_for(format, addr, symbol); if (result) { @@ -916,47 +978,3 @@ void g_binary_format_decompile(const GBinFormat *format, GCodeBuffer *buffer, co } } - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* label = étiquette du symbole si trouvé. [OUT] * -* address = adresse à cibler, puis décallage final. [OUT] * -* * -* Description : Recherche une position dans une routine selon une adresse. * -* * -* Retour : true si l'opération a été un succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_binary_format_resolve_relative_routine(const GBinFormat *format, const char **label, vmpa_t *address) -{ - bool result; /* Bilan à retourner */ - size_t i; /* Boucle de parcours */ - vmpa_t addr; /* Adresse de symbole */ - off_t size; /* Taille du symole */ - - result = false; - - for (i = 0; i < format->routines_count && !result; i++) - { - addr = g_binary_routine_get_address(format->routines[i]); - size = g_binary_routine_get_size(format->routines[i]); - - if (addr <= *address && *address < (addr + size)) - { - *label = g_binary_routine_get_long_name(format->routines[i]); - *address -= addr; - - result = true; - - } - - } - - return result; - -} diff --git a/src/format/format.h b/src/format/format.h index 314306e..18dfda1 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -86,6 +86,9 @@ bool g_binary_format_find_symbol_by_label(const GBinFormat *, const char *, GBin /* Recherche le symbole correspondant à une adresse. */ bool g_binary_format_find_symbol_at(const GBinFormat *, const vmpa2t *, GBinSymbol **); +/* Recherche le symbole contenant une adresse. */ +bool g_binary_format_find_symbol_for(const GBinFormat *, const vmpa2t *, GBinSymbol **); + /* Recherche le symbole suivant celui lié à une adresse. */ bool g_binary_format_find_next_symbol_at(const GBinFormat *, const vmpa2t *, GBinSymbol **); @@ -107,9 +110,6 @@ const char * const *g_binary_format_get_source_files(const GBinFormat *, size_t /* Procède à la décompilation complète du format. */ void g_binary_format_decompile(const GBinFormat *, GCodeBuffer *, const char *filename); -/* Recherche une position dans une routine selon une adresse. */ -bool g_binary_format_resolve_relative_routine(const GBinFormat *, const char **, vmpa_t *); - #endif /* _FORMAT_FORMAT_H */ diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c index bd4702b..920fcfe 100644 --- a/src/glibext/gbinportion.c +++ b/src/glibext/gbinportion.c @@ -578,7 +578,7 @@ GBinPortion *g_binary_portion_find_at_addr(GBinPortion *portion, const vmpa2t *a result = NULL; - for (i = 0; i < portion->sub_count && !result; i++) + for (i = 0; i < portion->sub_count && result == NULL; i++) { sub = portion->sub_portions[i]; diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am index 6849585..bdd0a31 100644 --- a/src/gtkext/Makefile.am +++ b/src/gtkext/Makefile.am @@ -13,6 +13,7 @@ libgtkext_la_SOURCES = \ gtkdockstation.h gtkdockstation.c \ gtkgraphview.h gtkgraphview.c \ gtksourceview.h gtksourceview.c \ + gtkstatusstack.h gtkstatusstack.c \ gtkviewpanel-int.h \ gtkviewpanel.h gtkviewpanel.c \ support.h support.c \ diff --git a/src/gtkext/gtkstatusstack.c b/src/gtkext/gtkstatusstack.c new file mode 100644 index 0000000..e9a61d8 --- /dev/null +++ b/src/gtkext/gtkstatusstack.c @@ -0,0 +1,609 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gtkstatusstack.c - empilement d'informations de statut + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "gtkstatusstack.h" + + +#include +#include +#include + + +#include + + +#include "easygtk.h" +#include "../common/extstr.h" + + + +/* ------------------------- GESTION EXTERIEURE DE LA BARRE ------------------------- */ + + +/* Navigation au sein d'assemblage */ +typedef struct _assembly_info assembly_info; + + +/* Abstration d'une gestion de barre de statut (instance) */ +struct _GtkStatusStack +{ + GtkBin parent; /* A laisser en premier */ + + GtkWidget *asm_status; /* Barre de status d'assemblage*/ + assembly_info *asm_info; /* Informations courantes */ + +}; + +/* Abstration d'une gestion de barre de statut (classe) */ +struct _GtkStatusStackClass +{ + GtkBinClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des barres de statut améliorées. */ +static void gtk_status_stack_class_init(GtkStatusStackClass *); + +/* Initialise une instance de barre de statut améliorée. */ +static void gtk_status_stack_init(GtkStatusStack *); + +/* Supprime toutes les références externes. */ +static void gtk_status_stack_dispose(GtkStatusStack *); + +/* Procède à la libération totale de la mémoire. */ +static void gtk_status_stack_finalize(GtkStatusStack *); + +/* S'assure de l'affichage du niveau de pile attendu. */ +static void gtk_status_stack_switch(GtkStatusStack *, GtkWidget *); + + + +/* -------------------- STATUT DES INFORMATIONS DE DESASSEMBLAGE -------------------- */ + + +/* Navigation au sein d'assemblage */ +struct _assembly_info +{ + mrange_t current; /* Emplacement correspondant */ + + char *segment; /* Segment d'appartenance */ + + VMPA_BUFFER(phys); /* Localisation physique */ + VMPA_BUFFER(virt); /* Localisation virtuelle */ + + char *symbol; /* Eventuel symbole concerné */ + + const char *encoding; /* Encodage de l'instruction */ + phys_t size; /* Taille de l'instruction */ + +}; + + +/* Supprime l'empreinte mémoire d'informations d'assemblage. */ +static void reset_assembly_info(assembly_info *); + +/* Construit une barre d'état pour language d'assemblage. */ +static GtkWidget *build_assembly_status_stack(GtkStatusStack *); + +/* Réagit à un redimensionnement de la barre de désassemblage. */ +static void on_size_allocate_for_asm_status(GtkWidget *, GdkRectangle *, GObject *); + +/* Réagit à un clic sur l'icône de zoom. */ +static void on_zoom_icon_press(GtkEntry *, GtkEntryIconPosition, GdkEventButton *, GtkStatusStack *); + +/* S'assure de l'affichage à jour de la partie "assemblage". */ +static void gtk_status_stack_show_current_instruction(GtkStatusStack *); + + + +/* ---------------------------------------------------------------------------------- */ +/* GESTION EXTERIEURE DE LA BARRE */ +/* ---------------------------------------------------------------------------------- */ + + +/* Détermine le type de la barre de statut améliorée. */ +G_DEFINE_TYPE(GtkStatusStack, gtk_status_stack, GTK_TYPE_BIN) + + +/****************************************************************************** +* * +* Paramètres : klass = classe GTK à initialiser. * +* * +* Description : Initialise la classe des barres de statut améliorées. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_status_stack_class_init(GtkStatusStackClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)gtk_status_stack_dispose; + object->finalize = (GObjectFinalizeFunc)gtk_status_stack_finalize; + +} + + +/****************************************************************************** +* * +* Paramètres : stack = instance GTK à initialiser. * +* * +* Description : Initialise une instance de barre de statut améliorée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_status_stack_init(GtkStatusStack *stack) +{ + stack->asm_status = build_assembly_status_stack(stack); + stack->asm_info = (assembly_info *)calloc(1, sizeof(assembly_info)); + +} + + +/****************************************************************************** +* * +* Paramètres : view = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_status_stack_dispose(GtkStatusStack *stack) +{ + g_object_unref(G_OBJECT(stack->asm_status)); + + G_OBJECT_CLASS(gtk_status_stack_parent_class)->dispose(G_OBJECT(stack)); + +} + + +/****************************************************************************** +* * +* Paramètres : view = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_status_stack_finalize(GtkStatusStack *stack) +{ + reset_assembly_info(stack->asm_info); + + free(stack->asm_info); + + G_OBJECT_CLASS(gtk_status_stack_parent_class)->finalize(G_OBJECT(stack)); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée une nouvelle instance de barre de statut. * +* * +* Retour : Composant GTK mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *gtk_status_stack_new(void) +{ + return g_object_new(GTK_TYPE_STATUS_STACK, NULL); + +} + + +/****************************************************************************** +* * +* Paramètres : stack = pile de statuts à considérer. * +* next = niveau de pile à afficher désormais. * +* * +* Description : S'assure de l'affichage du niveau de pile attendu. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_status_stack_switch(GtkStatusStack *stack, GtkWidget *next) +{ + GtkWidget *child; /* Support courant */ + + child = gtk_bin_get_child(GTK_BIN(stack)); + + if (child != next) + { + if (child != NULL) + gtk_container_remove(GTK_CONTAINER(stack), child); + + g_object_ref(G_OBJECT(next)); + gtk_container_add(GTK_CONTAINER(stack), next); + + } + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* STATUT DES INFORMATIONS DE DESASSEMBLAGE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : info = informations à réinitialiser. * +* * +* Description : Supprime l'empreinte mémoire d'informations d'assemblage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void reset_assembly_info(assembly_info *info) +{ + if (info->segment != NULL) + { + free(info->segment); + info->segment = NULL; + } + + if (info->symbol != NULL) + { + free(info->symbol); + info->symbol = NULL; + } + +} + + +/****************************************************************************** +* * +* Paramètres : stack = composant global en cours de construction. * +* * +* Description : Construit une barre d'état pour language d'assemblage. * +* * +* Retour : Composant GTK mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GtkWidget *build_assembly_status_stack(GtkStatusStack *stack) +{ + GtkWidget *result; /* Support à retourner */ + GObject *ref; /* Espace de référencements */ + GtkWidget *hbox; /* Sous-division horizontale */ + GtkWidget *label; /* Etiquette pour impression */ + GtkWidget *zoom; /* Sélection du zoom courant */ + + result = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + gtk_widget_show(result); + + ref = G_OBJECT(result); + + g_signal_connect(result, "size-allocate", G_CALLBACK(on_size_allocate_for_asm_status), ref); + + /* Première partie : navigation */ + + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 16); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(result), hbox, TRUE, TRUE, 8); + + label = qck_create_label(ref, "segment", NULL); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + label = qck_create_label(ref, "phys", NULL); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + label = qck_create_label(ref, "virt", NULL); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + label = qck_create_label(ref, "offset", NULL); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + /* Seconde partie : architecture */ + + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + g_object_set_data(ref, "arch_box", hbox); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(result), hbox, FALSE, TRUE, 8); + + label = qck_create_label(ref, "arch", NULL); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + label = qck_create_label(ref, "size", NULL); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + /* Troisième partie : affichage */ + + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(result), hbox, FALSE, FALSE, 8); + + zoom = qck_create_entry(ref, "zoom", "100%"); + gtk_entry_set_icon_from_icon_name(GTK_ENTRY(zoom), GTK_ENTRY_ICON_SECONDARY, "go-up-symbolic"); + + g_signal_connect(zoom, "icon-press", G_CALLBACK(on_zoom_icon_press), stack); + + gtk_box_pack_start(GTK_BOX(hbox), zoom, FALSE, TRUE, 0); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant graphique qui vient d'évoluer. * +* allocation = espace réservé pour le composant visé. * +* ref = espace de référencement global. * +* * +* Description : Réagit à un redimensionnement de la barre de désassemblage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_size_allocate_for_asm_status(GtkWidget *widget, GdkRectangle *allocation, GObject *ref) +{ + GtkWidget *hbox; /* Sous-division horizontale */ + + hbox = GTK_WIDGET(g_object_get_data(ref, "arch_box")); + + gtk_widget_set_size_request(hbox, (allocation->width * 40) / 100, -1); + + /** + * On intervient après que le containeur soit passer collecter les tailles + * de ses enfants lors de son redimensionnement. + * + * Donc on force un prise en compte des changements. + */ + gtk_container_check_resize(GTK_CONTAINER(widget)); + +} + + +/****************************************************************************** +* * +* Paramètres : entry = zone de texte visée par la procédure. * +* icon_pos = position de l'image associée à l'entrée. * +* event = informations liées à l'événement. * +* stack = composant graphique de gestion des statuts. * +* * +* Description : Réagit à un clic sur l'icône de zoom. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_zoom_icon_press(GtkEntry *entry, GtkEntryIconPosition icon_pos, GdkEventButton *event, GtkStatusStack *stack) +{ + GtkWidget *popup; /* Popup à faire surgir */ + GdkRectangle rect; /* Zone précise à cibler */ + + if (event->button != GDK_BUTTON_PRIMARY) + return; + + popup = gtk_popover_new(GTK_WIDGET(entry)); + + gtk_entry_get_icon_area(entry, GTK_ENTRY_ICON_SECONDARY, &rect); + gtk_popover_set_pointing_to(GTK_POPOVER(popup), &rect); + + gtk_widget_show(popup); + +} + + +/****************************************************************************** +* * +* Paramètres : stack = barre de statut à actualiser. * +* binary = binaire chargé rassemblant l'ensemble des infos. * +* instr = instruction désassemblée ciblée graphiquement. * +* * +* Description : Actualise les informations liées une position d'assemblage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_status_stack_update_current_instruction(GtkStatusStack *stack, const GLoadedBinary *binary, const GArchInstruction *instr) +{ + assembly_info *info; /* Informations à constituer */ + GExeFormat *format; /* Format de binaire à traiter */ + const mrange_t *range; /* Emplacement d'instruction */ + const vmpa2t *addr; /* Localisation de départ */ + GBinPortion *portions; /* Portions binaires existantes*/ + GBinPortion *portion; /* Zone mémoire d'appartenance */ + const char *text; /* Texte au contenu à copier */ + GBinSymbol *symbol; /* Symbole présent à l'adresse */ + phys_t diff; /* Décallage de l'adresse */ + const char *label; /* Description d'un symbole */ + vmpa2t tmp; /* Zone de construction temp. */ + VMPA_BUFFER(offset); /* Décalage physique */ + + info = stack->asm_info; + + format = g_loaded_binary_get_format(binary); + + /* Bascule vers une zone courante nouvelle ? */ + + range = g_arch_instruction_get_range(instr); + addr = get_mrange_addr(range); + + if (cmp_mrange(&info->current, range) == 0) + goto gssuci_useless; + + /* Réinitialisation */ + + reset_assembly_info(info); + + copy_mrange(&info->current, range); + + /* Zone d'appartenance */ + + portions = g_exe_format_get_portions(format); + + portion = g_binary_portion_find_at_addr(portions, addr, (GdkRectangle []) { }); + + text = g_binary_portion_get_desc(portion); + + if (text != NULL) + info->segment = strdup(text); + else + info->segment = strdup(_("Binary")); + + /* Adresses de base */ + + vmpa2_phys_to_string(addr, MDS_UNDEFINED, info->phys, NULL); + + vmpa2_virt_to_string(addr, MDS_UNDEFINED, info->virt, NULL); + + info->encoding = g_arch_instruction_get_encoding(instr); + + info->size = get_mrange_length(range); + + /* Symbole concerné */ + + if (g_binary_format_resolve_symbol(G_BIN_FORMAT(format), addr, &symbol, &diff)) + { + label = g_binary_symbol_get_label(symbol); + + if (label != NULL) + { + info->symbol = strdup(label); + + info->symbol = stradd(info->symbol, "+"); + + init_vmpa(&tmp, diff, VMPA_NO_VIRTUAL); + vmpa2_phys_to_string(&tmp, MDS_UNDEFINED, offset, NULL); + + info->symbol = stradd(info->symbol, offset); + + } + + g_object_unref(G_OBJECT(symbol)); + + } + + /* Nettoyage et conclusion */ + + gtk_status_stack_show_current_instruction(stack); + + gssuci_useless: + + //g_object_unref(G_OBJECT(format)); + + ; + +} + + +/****************************************************************************** +* * +* Paramètres : stack = pile de statuts à manipuler. * +* * +* Description : S'assure de l'affichage à jour de la partie "assemblage". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_status_stack_show_current_instruction(GtkStatusStack *stack) +{ + GObject *ref; /* Espace de référencements */ + assembly_info *info; /* Informations à consulter */ + GtkLabel *label; /* Etiquette à actualiser */ + char raw_pos[6 + VMPA_MAX_LEN + 1]; /* Formatage final en direct */ + char *content; /* Contenu dynamique */ + + gtk_status_stack_switch(stack, stack->asm_status); + + ref = G_OBJECT(stack->asm_status); + info = stack->asm_info; + + /* Première partie : navigation */ + + label = GTK_LABEL(g_object_get_data(ref, "segment")); + gtk_label_set_text(label, info->segment); + + snprintf(raw_pos, sizeof(raw_pos), "phys: %s", info->phys); + + label = GTK_LABEL(g_object_get_data(ref, "phys")); + gtk_label_set_text(label, raw_pos); + + snprintf(raw_pos, sizeof(raw_pos), "virt: %s", info->virt); + + label = GTK_LABEL(g_object_get_data(ref, "virt")); + gtk_label_set_text(label, raw_pos); + + label = GTK_LABEL(g_object_get_data(ref, "offset")); + gtk_label_set_text(label, info->symbol != NULL ? info->symbol : ""); + + /* Seconde partie : architecture */ + + label = GTK_LABEL(g_object_get_data(ref, "arch")); + gtk_label_set_text(label, info->encoding); + + if (info->size > 1) + asprintf(&content, "%" PRIu64 " %s", (uint64_t)info->size, _("bytes")); + else + asprintf(&content, "%" PRIu64 " %s", (uint64_t)info->size, _("byte")); + + label = GTK_LABEL(g_object_get_data(ref, "size")); + gtk_label_set_text(label, content); + + free(content); + +} diff --git a/src/gtkext/gtkstatusstack.h b/src/gtkext/gtkstatusstack.h new file mode 100644 index 0000000..9d25c8f --- /dev/null +++ b/src/gtkext/gtkstatusstack.h @@ -0,0 +1,79 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gtkstatusstack.h - prototypes pour un empilement d'informations de statut + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _GTKEXT_GTKSTATUSSTACK_H +#define _GTKEXT_GTKSTATUSSTACK_H + + + +#include + + +#include "../analysis/binary.h" + + + +/* FIXME */ +typedef int bstatus_id_t; + + + + +/* ------------------------- GESTION EXTERIEURE DE LA BARRE ------------------------- */ + + +#define GTK_TYPE_STATUS_STACK (gtk_status_stack_get_type()) +#define GTK_STATUS_STACK(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, GTK_TYPE_STATUS_STACK, GtkStatusStack)) +#define GTK_STATUS_STACK_CLASS(klass) (G_LOADED_BINARY_GET_CLASS(klass, GTK_TYPE_STATUS_STACK, GtkStatusStackClass)) +#define GTK_IS_STATUS_STACK(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, GTK_TYPE_STATUS_STACK)) +#define GTK_IS_STATUS_STACK_CLASS(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, GTK_TYPE_STATUS_STACK)) +#define GTK_STATUS_STACK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_STATUS_STACK, GtkStatusStackClass)) + + +/* Abstration d'une gestion de barre de statut (instance) */ +typedef struct _GtkStatusStack GtkStatusStack; + +/* Abstration d'une gestion de barre de statut (classe) */ +typedef struct _GtkStatusStackClass GtkStatusStackClass; + + +/* Détermine le type de la barre de statut améliorée. */ +GType gtk_status_stack_get_type(void); + +/* Crée une nouvelle instance de barre de statut. */ +GtkWidget *gtk_status_stack_new(void); + + + +/* -------------------- STATUT DES INFORMATIONS DE DESASSEMBLAGE -------------------- */ + + +/* Actualise les informations liées une position d'assemblage. */ +void gtk_status_stack_update_current_instruction(GtkStatusStack *, const GLoadedBinary *, const GArchInstruction *); + + + + + + +#endif /* _GTKEXT_GTKSTATUSSTACK_H */ diff --git a/src/gui/editor.c b/src/gui/editor.c index 1742596..bc4f144 100644 --- a/src/gui/editor.c +++ b/src/gui/editor.c @@ -177,7 +177,7 @@ GtkWidget *create_editor(void) - vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); gtk_widget_show(vbox1); gtk_container_add(GTK_CONTAINER(result), vbox1); diff --git a/src/gui/status.c b/src/gui/status.c index 41cad1a..f466193 100644 --- a/src/gui/status.c +++ b/src/gui/status.c @@ -36,7 +36,7 @@ #include "../common/extstr.h" #include "../gtkext/gtkbufferview.h" #include "../gtkext/gtkblockview.h" -#include "../gtkext/gtkextstatusbar.h" +#include "../gtkext/gtkstatusstack.h" @@ -136,7 +136,7 @@ static void g_status_info_init(GStatusInfo *bar) item->name = "status"; - item->widget = gtk_extended_status_bar_new(); + item->widget = gtk_status_stack_new(); gtk_widget_show(item->widget); } @@ -271,89 +271,12 @@ static void track_caret_address_on_buffer_views(GtkBufferView *view, const vmpa2 { GEditorItem *item; /* Autre version de l'élément */ GLoadedBinary *binary; /* Binaire courant */ - GExeFormat *format; /* Format du fichier binaire */ - GArchProcessor *proc; /* Architecture du binaire */ - MemoryDataSize msize; /* Taille par défaut */ - char *msg; /* Message à transmettre */ - VMPA_BUFFER(conv); /* Zone de conversion */ - - vmpa_t rel; /* Adresse relative à un symb. */ - const char *label; /* Désignation d'un symbole */ item = G_EDITOR_ITEM(info); binary = g_editor_item_get_current_binary(item); - proc = g_loaded_binary_get_processor(binary); - msize = g_arch_processor_get_memory_size(proc); - g_object_unref(G_OBJECT(proc)); - - /* Réinitiation seule si il n'y a plus d'adresse... */ - - if (addr == NULL) - { - if (info->msg_id > 0) - gtk_extended_status_bar_remove(GTK_EXT_STATUS_BAR(item->widget), info->msg_id); - - return; - - } - - /* Adresse brute */ - - msize = g_arch_processor_get_memory_size(proc); - - msg = strdup(_("Location phys:")); - - vmpa2_phys_to_string(addr, msize, conv, NULL); - msg = stradd(msg, conv); - - msg = stradd(msg, " virt:"); - - vmpa2_virt_to_string(addr, msize, conv, NULL); - msg = stradd(msg, conv); - - - -#if 0 - - /* Relation avec les symboles */ - - binary = G_LOADED_BINARY(g_object_get_data(item->ref, "current_binary")); - format = g_loaded_binary_get_format(binary); - - rel = addr; - - if (g_binary_format_resolve_relative_routine(G_BIN_FORMAT(format), &label, &rel)) - { - msg = stradd(msg, _(" at ")); - msg = stradd(msg, label); - msg = stradd(msg, _("+")); - - snprintf(tmp, VMPA_MAX_SIZE, VMPA_FMT, rel); - msg = stradd(msg, tmp); - - } - -#endif - - - /* Impression */ - - if (info->msg_id > 0) - gtk_extended_status_bar_remove(GTK_EXT_STATUS_BAR(item->widget), info->msg_id); - - info->msg_id = gtk_extended_status_bar_push(GTK_EXT_STATUS_BAR(item->widget), msg, FALSE); - - - printf("---- moved to 0x%08llx\n", addr); - - printf(" MSG '%s'\n", msg); - - //update_menu_project_for_project(bar->project, project, bar); - - - free(msg); + focus_address_in_status_info(info, binary, addr); } @@ -374,85 +297,17 @@ static void track_caret_address_on_buffer_views(GtkBufferView *view, const vmpa2 static void focus_address_in_status_info(GStatusInfo *info, GLoadedBinary *binary, const vmpa2t *addr) { - GExeFormat *format; /* Format associé au binaire */ GArchProcessor *proc; /* Architecture du binaire */ - MemoryDataSize msize; /* Taille du bus d'adresses */ - char *msg; /* Message à transmettre */ - VMPA_BUFFER(tmp); /* Traduction d'adresses */ - GBinSymbol *symbol; /* Symbole présent à l'adresse */ - phys_t diff; /* Décallage de l'adresse */ - const char *label; /* Description d'un symbole */ - GBinPortion *portions; /* Portions binaires existantes*/ - GBinPortion *portion; /* Zone mémoire d'appartenance */ - size_t len; /* Caractère à faire basculer */ - - format = g_loaded_binary_get_format(binary); + GArchInstruction *instr; /* Instruction présente */ + GEditorItem *item; /* Autre version de l'élément */ proc = g_loaded_binary_get_processor(binary); - msize = g_arch_processor_get_memory_size(proc); - g_object_unref(G_OBJECT(proc)); - - msg = strdup(_("Localisation:")); - - /* Adresses de base */ - - msg = stradd(msg, " phys:"); - vmpa2_phys_to_string(addr, msize, tmp, NULL); - msg = stradd(msg, tmp); - - msg = stradd(msg, " virt:"); - vmpa2_virt_to_string(addr, msize, tmp, NULL); - msg = stradd(msg, tmp); - - /* Symbole présent ? */ - - if (g_binary_format_resolve_symbol(G_BIN_FORMAT(format), addr, &symbol, &diff)) - { - label = g_binary_symbol_get_label(symbol); - - if (label != NULL) - { - msg = stradd(msg, _(" at ")); - msg = stradd(msg, label); - msg = stradd(msg, _("+")); - snprintf(tmp, VMPA_MAX_SIZE, "0x%x", diff); - msg = stradd(msg, tmp); + instr = g_arch_processor_find_instr_by_address(proc, addr); - } - - g_object_unref(G_OBJECT(symbol)); - - } - - /* Zone d'appartenance */ - - portions = g_exe_format_get_portions(format); - - portion = g_binary_portion_find_at_addr(portions, addr, (GdkRectangle []) { }); - - label = g_binary_portion_get_desc(portion); - - msg = stradd(msg, _(" (")); - - /** - * Pas très propre : on bascule de majuscule en minuscule ici... - * FIXME ? - */ - - len = strlen(msg); - msg = stradd(msg, label); - msg[len] = tolower(msg[len]); - - msg = stradd(msg, _(")")); - - /* Impression */ - - if (info->msg_id > 0) - gtk_extended_status_bar_remove(GTK_EXT_STATUS_BAR(G_EDITOR_ITEM(info)->widget), info->msg_id); - - info->msg_id = gtk_extended_status_bar_push(GTK_EXT_STATUS_BAR(G_EDITOR_ITEM(info)->widget), msg, FALSE); + item = G_EDITOR_ITEM(info); + gtk_status_stack_update_current_instruction(GTK_STATUS_STACK(item->widget), binary, instr); - free(msg); + g_object_unref(G_OBJECT(proc)); } -- cgit v0.11.2-87-g4458