diff options
Diffstat (limited to 'src/gtkext')
-rw-r--r-- | src/gtkext/Makefile.am | 1 | ||||
-rw-r--r-- | src/gtkext/gtkstatusstack.c | 609 | ||||
-rw-r--r-- | src/gtkext/gtkstatusstack.h | 79 |
3 files changed, 689 insertions, 0 deletions
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 <http://www.gnu.org/licenses/>. + */ + + +#include "gtkstatusstack.h" + + +#include <inttypes.h> +#include <malloc.h> +#include <string.h> + + +#include <i18n.h> + + +#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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GTKEXT_GTKSTATUSSTACK_H +#define _GTKEXT_GTKSTATUSSTACK_H + + + +#include <gtk/gtk.h> + + +#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 */ |