From 36be37f57a66515444ffbfec6242b991f8346c09 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Mon, 31 Dec 2012 21:47:47 +0000 Subject: Added a dialog box to jump to a given address git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@314 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 31 ++++++ src/arch/archbase.c | 22 ++++- src/arch/archbase.h | 6 +- src/dialogs/Makefile.am | 1 + src/dialogs/goto.c | 235 ++++++++++++++++++++++++++++++++++++++++++++++ src/dialogs/goto.h | 43 +++++++++ src/gtkext/easygtk.c | 32 +++++++ src/gtkext/easygtk.h | 3 +- src/gui/editem.c | 19 ++++ src/gui/editem.h | 3 + src/gui/menus/Makefile.am | 1 + src/gui/menus/edition.c | 111 ++++++++++++++++++++++ src/gui/menus/edition.h | 41 ++++++++ src/gui/menus/menubar.c | 7 ++ 14 files changed, 552 insertions(+), 3 deletions(-) create mode 100644 src/dialogs/goto.c create mode 100644 src/dialogs/goto.h create mode 100644 src/gui/menus/edition.c create mode 100644 src/gui/menus/edition.h diff --git a/ChangeLog b/ChangeLog index 0463c1a..322b5f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +12-12-31 Cyrille Bagard + + * src/arch/archbase.c: + * src/arch/archbase.h: + Convert strings to addresses. + + * src/dialogs/goto.c: + * src/dialogs/goto.h: + New entries: add a dialog box to jump to a given address. + + * src/dialogs/Makefile.am: + Add the 'goto.[ch]' files to libdialogs_la_SOURCES. + + * src/gtkext/easygtk.c: + * src/gtkext/easygtk.h: + Provide a combobox widget from recent GTK versions. + + * src/gui/editem.c: + * src/gui/editem.h: + Provide the global reference pointer. + + * src/gui/menus/edition.c: + * src/gui/menus/edition.h: + New entries: create an Edition menu and go to given addresses. + + * src/gui/menus/Makefile.am: + Add the 'edition.[ch]' files to libguimenus_la_SOURCES. + + * src/gui/menus/menubar.c: + Load the new menu. + 12-12-29 Cyrille Bagard * plugins/androhelpers/switch.c: diff --git a/src/arch/archbase.c b/src/arch/archbase.c index e422971..9d11c3f 100644 --- a/src/arch/archbase.c +++ b/src/arch/archbase.c @@ -2,7 +2,7 @@ /* OpenIDA - Outil d'analyse de fichiers binaires * archbase.c - définitions de base pour les architectures * - * Copyright (C) 2009 Cyrille Bagard + * Copyright (C) 2009-2012 Cyrille Bagard * * This file is part of OpenIDA. * @@ -26,6 +26,7 @@ #include #include +#include @@ -109,3 +110,22 @@ size_t vmpa_to_string(vmpa_t addr, MemoryDataSize msize, char buffer[VMPA_MAX_SI return result; } + + +/****************************************************************************** +* * +* Paramètres : buffer = chaîne de caractères à consulter. * +* * +* Description : Transforme une chaîne de caractères en adresse. * +* * +* Retour : Adresse obtenue. * +* * +* Remarques : - * +* * +******************************************************************************/ + +vmpa_t string_to_vmpa(const char *buffer) +{ + return (vmpa_t)strtoull(buffer, NULL, 16); + +} diff --git a/src/arch/archbase.h b/src/arch/archbase.h index b21d52c..ee12674 100644 --- a/src/arch/archbase.h +++ b/src/arch/archbase.h @@ -2,7 +2,7 @@ /* OpenIDA - Outil d'analyse de fichiers binaires * archbase.h - prototypes des définitions de base pour les architectures * - * Copyright (C) 2009-2010 Cyrille Bagard + * Copyright (C) 2009-2012 Cyrille Bagard * * This file is part of OpenIDA. * @@ -86,5 +86,9 @@ int compare_vmpa(const vmpa_t *, const vmpa_t *); /* Transforme une adresse en chaîne de caractères. */ size_t vmpa_to_string(vmpa_t, MemoryDataSize, char [VMPA_MAX_SIZE]); +/* Transforme une chaîne de caractères en adresse. */ +vmpa_t string_to_vmpa(const char *); + + #endif /* _ARCH_ARCHBASE_H */ diff --git a/src/dialogs/Makefile.am b/src/dialogs/Makefile.am index 16b2dc7..70642b2 100644 --- a/src/dialogs/Makefile.am +++ b/src/dialogs/Makefile.am @@ -6,6 +6,7 @@ libdialogs_la_SOURCES = \ add_shellcode.h add_shellcode.c \ binparts.h binparts.c \ export.h export.c \ + goto.h goto.c \ plugins.h plugins.c libdialogs_la_LDFLAGS = diff --git a/src/dialogs/goto.c b/src/dialogs/goto.c new file mode 100644 index 0000000..d280809 --- /dev/null +++ b/src/dialogs/goto.c @@ -0,0 +1,235 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * goto.c - boîte de dialogue pour les sauts à une adresse donnée + * + * Copyright (C) 2012 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "goto.h" + + +#include + + +#include + + +#include "../gtkext/easygtk.h" + + + +/* Filtre les adresses en hexadécimal pendant l'édition. */ +static void filter_addresses(GtkEntry *, const gchar *, gint, gint *, gpointer); + +/* Clôture l'édition d'une adresse. */ +static void validate_addresses(GtkEntry *, GtkDialog *); + + + +/****************************************************************************** +* * +* Paramètres : entry = composant GTK concerné par la procédure. * +* text = nouveau texte inséré. * +* length = taille de ce texte. * +* position = point d'insertion. * +* data = adresse non utilisée ici. * +* * +* Description : Filtre les adresses en hexadécimal pendant l'édition. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void filter_addresses(GtkEntry *entry, const gchar *text, gint length, gint *position, gpointer data) +{ + gboolean has_hex; /* Préfixe '0x' déjà présent ? */ + gchar *filtered; /* Contenu nouveau approuvé */ + gint count; /* Nouvelle taille validée */ + gint i; /* Boucle de parcours */ + + /** + * On cherche à empêcher l'édition avant un '0x' présent, + * ce qui viendrait fausser le fitrage. + */ + has_hex = g_str_has_prefix(gtk_entry_get_text(entry), "0x"); + + filtered = g_new(gchar, length); + + count = 0; + + for (i = 0; i < length; i++) + switch (text[i]) + { + case '0' ... '9': + case 'a' ... 'f': + if (!has_hex || ((i + *position) >= 2)) + filtered[count++] = text[i]; + break; + case 'A' ... 'F': + if (!has_hex || ((i + *position) >= 2)) + filtered[count++] = tolower(text[i]); + break; + case 'x': + case 'X': + if ((i + *position) == 1) + filtered[count++] = 'x'; + break; + } + + if (count > 0) + { + g_signal_handlers_block_by_func(G_OBJECT(entry), G_CALLBACK(filter_addresses), data); + gtk_editable_insert_text(GTK_EDITABLE(entry), filtered, count, position); + g_signal_handlers_unblock_by_func(G_OBJECT(entry), G_CALLBACK(filter_addresses), data); + } + + g_signal_stop_emission_by_name(G_OBJECT(entry), "insert_text"); + + g_free(filtered); + +} + + +/****************************************************************************** +* * +* Paramètres : entry = composant GTK concerné par la procédure. * +* dialog = boîte de dialogue à valider. * +* * +* Description : Clôture l'édition d'une adresse. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void validate_addresses(GtkEntry *entry, GtkDialog *dialog) +{ + gtk_dialog_response(dialog, GTK_RESPONSE_OK); + +} + + +/****************************************************************************** +* * +* Paramètres : parent = fenêtre parente à surpasser. * +* * +* Description : Construit la fenêtre de sélection des sections. * +* * +* Retour : Adresse de la fenêtre mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *create_goto_dialog(GtkWindow *parent) +{ + GtkWidget *result; /* Fenêtre à renvoyer */ + GtkWidget *dlgvbox; /* Zone principale de la boîte */ + GtkWidget *vbox; /* Support à construire */ + GtkWidget *label; /* Message d'introduction */ + GtkWidget *combobox; /* Liste de sélection */ + GtkWidget *entry; /* Zone de saisie principale */ + GtkWidget *dialog_action_area1; + GtkWidget *button; /* Bouton de contrôle */ + + result = gtk_dialog_new(); + gtk_window_set_title(GTK_WINDOW(result), _("Go to address")); + gtk_window_set_position(GTK_WINDOW(result), GTK_WIN_POS_CENTER); + gtk_window_set_modal(GTK_WINDOW(result), TRUE); + gtk_window_set_type_hint(GTK_WINDOW(result), GDK_WINDOW_TYPE_HINT_DIALOG); + + dlgvbox = GTK_DIALOG(result)->vbox; + gtk_widget_show(dlgvbox); + + vbox = gtk_vbox_new(FALSE, 8); + gtk_widget_show(vbox); + gtk_box_pack_start(GTK_BOX(dlgvbox), vbox, TRUE, TRUE, 0); + gtk_container_set_border_width(GTK_CONTAINER(vbox), 8); + + label = qck_create_label(NULL, NULL, _("Enter the value of the target address:")); + gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); + + combobox = qck_create_combobox2(G_OBJECT(result), "combobox", NULL, NULL); + gtk_box_pack_start(GTK_BOX(vbox), combobox, TRUE, TRUE, 0); + + entry = gtk_bin_get_child(GTK_BIN(combobox)); + + g_signal_connect(G_OBJECT(entry), "insert_text", + G_CALLBACK(filter_addresses), NULL); + g_signal_connect(G_OBJECT(entry), "activate", + G_CALLBACK(validate_addresses), GTK_DIALOG(result)); + + + /* TODO */ + //gtk_combo_box_append_text(combobox, "test"); + + + + dialog_action_area1 = GTK_DIALOG(result)->action_area; + gtk_widget_show(dialog_action_area1); + gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog_action_area1), GTK_BUTTONBOX_END); + + + button = qck_create_button_from_stock(NULL, NULL, "gtk-cancel", NULL, NULL); + gtk_dialog_add_action_widget(GTK_DIALOG(result), button, GTK_RESPONSE_CANCEL); + + button = qck_create_button_from_stock(NULL, NULL, "gtk-ok", NULL, NULL); + gtk_dialog_add_action_widget(GTK_DIALOG(result), button, GTK_RESPONSE_OK); + + gtk_entry_set_text(GTK_ENTRY(entry), "0x"); + gtk_widget_grab_focus (entry); + gtk_editable_set_position(GTK_EDITABLE(entry), -1); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : dialog = boîte de dialogue ayant reçu une validation. * +* * +* Description : Fournit l'adresse obtenue par la saisie de l'utilisateur. * +* * +* Retour : Adresse reccueillie par la boîte de dialogue. * +* * +* Remarques : - * +* * +******************************************************************************/ + +vmpa_t get_address_from_goto_dialog(GtkWidget *dialog) +{ + vmpa_t result; /* Adresse à retourner */ + GtkWidget *combobox; /* Liste de sélection */ + GtkWidget *entry; /* Zone de saisie principale */ + const gchar *text; /* Adresse en version texte */ + + combobox = GTK_WIDGET(g_object_get_data(G_OBJECT(dialog), "combobox")); + entry = gtk_bin_get_child(GTK_BIN(combobox)); + + text = gtk_entry_get_text(GTK_ENTRY(entry)); + + result = string_to_vmpa(text); + + return result; + +} diff --git a/src/dialogs/goto.h b/src/dialogs/goto.h new file mode 100644 index 0000000..80b72a3 --- /dev/null +++ b/src/dialogs/goto.h @@ -0,0 +1,43 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * goto.h - prototypes pour la boîte de dialogue pour les sauts à une adresse donnée + * + * Copyright (C) 2012 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _DIALOGS_GOTO_H +#define _DIALOGS_GOTO_H + + +#include + + +#include "../arch/archbase.h" + + + +/* Construit la fenêtre de saut à une adresse. */ +GtkWidget *create_goto_dialog(GtkWindow *); + +/* Fournit l'adresse obtenue par la saisie de l'utilisateur. */ +vmpa_t get_address_from_goto_dialog(GtkWidget *); + + + +#endif /* _DIALOGS_GOTO_H */ diff --git a/src/gtkext/easygtk.c b/src/gtkext/easygtk.c index 8aea549..29fdec6 100644 --- a/src/gtkext/easygtk.c +++ b/src/gtkext/easygtk.c @@ -510,9 +510,41 @@ GtkWidget *qck_create_combobox(GObject *object, const char *name, GCallback hand } +/****************************************************************************** +* * +* Paramètres : object = espace dédié à l'inscription de références. * +* name = nom à donner au nouveau composant. * +* handler = éventuelle fonction de sélection associée. * +* data = données à transmettre avec l'événement si besoin. * +* * +* Description : Crée et enregistre un composant 'GtkComboBox'. * +* * +* Retour : Composant mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *qck_create_combobox2(GObject *object, const char *name, GCallback handler, gpointer data) +{ + GtkWidget *result; /* Résultat à renvoyer */ + result = gtk_combo_box_text_new_with_entry(); + if (G_IS_OBJECT(object) && name != NULL) + { + g_object_ref(G_OBJECT(result)); + g_object_set_data_full(object, name, result, (GDestroyNotify)g_object_unref); + } + gtk_widget_show(result); + + if (handler != NULL) + g_signal_connect(result, "changed", handler, data); + + return result; + +} /****************************************************************************** diff --git a/src/gtkext/easygtk.h b/src/gtkext/easygtk.h index ea234e0..e811274 100644 --- a/src/gtkext/easygtk.h +++ b/src/gtkext/easygtk.h @@ -71,7 +71,8 @@ GtkWidget *qck_create_check_button(GObject *, const char *, const char *, GCallb /* Crée et enregistre un composant 'GtkComboBox'. */ GtkWidget *qck_create_combobox(GObject *, const char *, GCallback, gpointer); - +/* Crée et enregistre un composant 'GtkComboBox'. */ +GtkWidget *qck_create_combobox2(GObject *, const char *, GCallback, gpointer); /* Crée et enregistre un composant 'GtkMenuItem'. */ diff --git a/src/gui/editem.c b/src/gui/editem.c index ad14e42..d658428 100644 --- a/src/gui/editem.c +++ b/src/gui/editem.c @@ -98,6 +98,25 @@ static void g_editor_item_init(GEditorItem *item) * * * Paramètres : item = instance à consulter. * * * +* Description : Fournit l'adresse de l'espace de référencement global. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +GObject *g_editor_item_get_global_ref(const GEditorItem *item) +{ + return item->ref; + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à consulter. * +* * * Description : Fournit le composant GTK associé à l'élément réactif. * * * * Retour : - * diff --git a/src/gui/editem.h b/src/gui/editem.h index 9b9ee20..5321600 100644 --- a/src/gui/editem.h +++ b/src/gui/editem.h @@ -56,6 +56,9 @@ typedef struct _GEditorItemClass GEditorItemClass; /* Indique le type défini pour un élément réactif d'éditeur. */ GType g_editor_item_get_type(void); +/* Fournit l'adresse de l'espace de référencement global. */ +GObject *g_editor_item_get_global_ref(const GEditorItem *); + /* Fournit le composant GTK associé à l'élément réactif. */ GtkWidget *g_editor_item_get_widget(const GEditorItem *); diff --git a/src/gui/menus/Makefile.am b/src/gui/menus/Makefile.am index 3aebdc0..ba38f0f 100644 --- a/src/gui/menus/Makefile.am +++ b/src/gui/menus/Makefile.am @@ -4,6 +4,7 @@ noinst_LTLIBRARIES = libguimenus.la libguimenus_la_SOURCES = \ binary.h binary.c \ debug.h debug.c \ + edition.h edition.c \ file.h file.c \ help.h help.c \ menubar.h menubar.c \ diff --git a/src/gui/menus/edition.c b/src/gui/menus/edition.c new file mode 100644 index 0000000..89ecf74 --- /dev/null +++ b/src/gui/menus/edition.c @@ -0,0 +1,111 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * edition.c - gestion du menu 'Edition' + * + * Copyright (C) 2012 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 "edition.h" + + +#include + + +#include "../../dialogs/goto.h" +#include "../../gtkext/easygtk.h" + + + +/* Réagit avec le menu "Edition -> Aller à l'adresse...". */ +static void mcb_edition_goto(GtkMenuItem *, GMenuBar *); + + + +/****************************************************************************** +* * +* Paramètres : ref = espace de référencement global. * +* accgroup = groupe d'accélérateurs pour les menus. * +* bar = barre de menu parente. * +* * +* Description : Construit le menu "Edition". * +* * +* Retour : Panneau de menus mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *build_menu_edition(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar) +{ + GtkWidget *result; /* Support à retourner */ + GtkWidget *menubar; /* Support pour éléments */ + GtkWidget *submenuitem; /* Sous-élément de menu */ + + result = gtk_menu_item_new_with_mnemonic(_("_Edition")); + gtk_widget_show(result); + + menubar = gtk_menu_new(); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(result), menubar); + + submenuitem = qck_create_menu_item(NULL, NULL, _("Go to address..."), + G_CALLBACK(mcb_edition_goto), bar); + add_accelerator_to_menu_item(submenuitem, "G", accgroup); + gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu sélectionné. * +* bar = barre de menu parente. * +* * +* Description : Réagit avec le menu "Edition -> Aller à l'adresse...". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void mcb_edition_goto(GtkMenuItem *menuitem, GMenuBar *bar) +{ + GObject *ref; /* Espace de référencements */ + GtkWidget *dialog; /* Boîte de dialogue à montrer */ + vmpa_t addr; /* Adresse de destination */ + GtkViewPanel *vpanel; /* Afficheur effectif de code */ + + ref = g_editor_item_get_global_ref(G_EDITOR_ITEM(bar)); + dialog = create_goto_dialog(GTK_WINDOW(ref)); + + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) + { + addr = get_address_from_goto_dialog(dialog); + + vpanel = g_editor_item_get_current_view(G_EDITOR_ITEM(bar)); + gtk_view_panel_scroll_to_address(vpanel, addr); + + } + + gtk_widget_destroy(dialog); + +} diff --git a/src/gui/menus/edition.h b/src/gui/menus/edition.h new file mode 100644 index 0000000..319bd4b --- /dev/null +++ b/src/gui/menus/edition.h @@ -0,0 +1,41 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * edition.h - prototypes pour la gestion du menu 'Edition' + * + * Copyright (C) 2012 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 _GUI_MENUS_EDITION_H +#define _GUI_MENUS_EDITION_H + + +#include + + +#include "menubar.h" + + + +/* Construit le menu "Edition". */ +GtkWidget *build_menu_edition(GObject *, GtkAccelGroup *, GMenuBar *); + + + +#endif /* _GUI_MENUS_EDITION_H */ diff --git a/src/gui/menus/menubar.c b/src/gui/menus/menubar.c index cb6e58a..a9ae07f 100644 --- a/src/gui/menus/menubar.c +++ b/src/gui/menus/menubar.c @@ -27,6 +27,7 @@ #include "binary.h" #include "debug.h" +#include "edition.h" #include "file.h" #include "help.h" #include "project.h" @@ -41,6 +42,7 @@ struct _GMenuBar GEditorItem parent; /* A laisser en premier */ GtkWidget *file; /* Menu "Fichier" */ + GtkWidget *edition; /* Menu "Edition" */ GtkWidget *view; /* Menu "Affichage" */ GtkWidget *project; /* Menu "Projet" */ GtkWidget *binary; /* Menu "Binaire" */ @@ -155,6 +157,11 @@ GEditorItem *g_menu_bar_new(GObject *ref, GtkAccelGroup *accgroup) result->file = build_menu_file(ref, accgroup); gtk_container_add(GTK_CONTAINER(item->widget), result->file); + /* Edition */ + + result->edition = build_menu_edition(ref, accgroup, result); + gtk_container_add(GTK_CONTAINER(item->widget), result->edition); + /* Affichage */ result->view = build_menu_view(ref, accgroup, result); -- cgit v0.11.2-87-g4458