diff options
Diffstat (limited to 'src/dialogs')
-rw-r--r-- | src/dialogs/Makefile.am | 1 | ||||
-rw-r--r-- | src/dialogs/bookmark.c | 331 | ||||
-rw-r--r-- | src/dialogs/bookmark.h | 44 | ||||
-rw-r--r-- | src/dialogs/goto.c | 2 |
4 files changed, 377 insertions, 1 deletions
diff --git a/src/dialogs/Makefile.am b/src/dialogs/Makefile.am index 9adb0f6..54b6fa2 100644 --- a/src/dialogs/Makefile.am +++ b/src/dialogs/Makefile.am @@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libdialogs.la libdialogs_la_SOURCES = \ about.h about.c \ + bookmark.h bookmark.c \ export.h export.c \ goto.h goto.c \ plugins.h plugins.c \ diff --git a/src/dialogs/bookmark.c b/src/dialogs/bookmark.c new file mode 100644 index 0000000..abff500 --- /dev/null +++ b/src/dialogs/bookmark.c @@ -0,0 +1,331 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * bookmark.c - boîte de dialogue pour les sauts à une adresse donnée + * + * Copyright (C) 2012-2014 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 "bookmark.h" + + +#include <ctype.h> +#include <string.h> + + +#include <i18n.h> + + +#include "..//analysis/db/items/bookmark.h" +#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. * +* addr = localisation du point à consigner. * +* * +* Description : Construit la fenêtre de création de signet. * +* * +* Retour : Adresse de la fenêtre mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *create_bookmark_dialog(GtkWindow *parent, const vmpa2t *addr) +{ + GtkWidget *result; /* Fenêtre à renvoyer */ + GtkWidget *dlgvbox; /* Zone principale de la boîte */ + GtkWidget *vbox; /* Support à construire #1 */ + GtkWidget *alignment; /* Support véritable interne */ + GtkWidget *frame; /* Support avec encadrement */ + GtkWidget *sub_vbox; /* Support à construire #2 */ + GtkWidget *hbox; /* Support à construire #3 */ + GtkWidget *label; /* Message d'introduction */ + GtkWidget *entry; /* Zone de saisie principale */ + GtkWidget *radio; /* Définition de localisation */ + VMPA_BUFFER(target); /* Désignation humaine de cible*/ + + result = gtk_dialog_new(); + gtk_window_set_title(GTK_WINDOW(result), _("Add a bookmark")); + 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_get_content_area(GTK_DIALOG(result)); + gtk_widget_show(dlgvbox); + + vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 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); + + /* Localisation dans l'espace */ + + frame = qck_create_frame(_("<b>Localisation</b>"), &alignment, 8, 0, 12, 0); + gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0); + + sub_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + gtk_widget_show(sub_vbox); + gtk_container_add(GTK_CONTAINER(alignment), sub_vbox); + + /* 1) Adresse */ + + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(sub_vbox), hbox, FALSE, TRUE, 0); + + label = qck_create_label(NULL, NULL, _("Target:")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + entry = qck_create_entry(G_OBJECT(result), "addr", NULL); + //g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(forbid_text_empty_entry), assistant); + gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, TRUE, 0); + + /* 2) Type d'adresse */ + + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); + gtk_container_set_border_width(GTK_CONTAINER(hbox), 8); + + radio = qck_create_radio_button(G_OBJECT(result), "phys", _("Value is physical offset"), + NULL, NULL, NULL); + gtk_box_pack_start(GTK_BOX(hbox), radio, TRUE, TRUE, 0); + + radio = qck_create_radio_button(G_OBJECT(result), "virt", _("Value is virtual address"), + GTK_RADIO_BUTTON(radio), NULL, NULL); + gtk_box_pack_start(GTK_BOX(hbox), radio, TRUE, TRUE, 0); + + /* Commentaire éventuel */ + + frame = qck_create_frame(_("<b>Optional comment</b>"), &alignment, 8, 0, 12, 0); + gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0); + + entry = qck_create_entry(G_OBJECT(result), "comment", NULL); + gtk_container_add(GTK_CONTAINER(alignment), entry); + + /* Zone de validation */ + + gtk_dialog_add_button(GTK_DIALOG(result), _("_Cancel"), GTK_RESPONSE_CANCEL); + gtk_dialog_add_button(GTK_DIALOG(result), _("_Ok"), GTK_RESPONSE_OK); + + /* Remplissage avec les valeurs fournies */ + + entry = GTK_WIDGET(g_object_get_data(G_OBJECT(result), "addr")); + + if (addr != NULL && has_virt_addr(addr)) + { + vmpa2_virt_to_string(addr, MDS_UNDEFINED, target, NULL); + radio = GTK_WIDGET(g_object_get_data(G_OBJECT(result), "virt")); + } + + else if (addr != NULL && has_phys_addr(addr)) + { + vmpa2_virt_to_string(addr, MDS_UNDEFINED, target, NULL); + radio = GTK_WIDGET(g_object_get_data(G_OBJECT(result), "virt")); + } + + else + radio = NULL; + + if (radio == NULL) + { + gtk_entry_set_text(GTK_ENTRY(entry), "0x"); + gtk_editable_set_position(GTK_EDITABLE(entry), -1); + gtk_widget_grab_focus(entry); + } + + else + { + gtk_entry_set_text(GTK_ENTRY(entry), target); + gtk_editable_set_position(GTK_EDITABLE(entry), -1); + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE); + + } + + if (radio != NULL) + { + entry = GTK_WIDGET(g_object_get_data(G_OBJECT(result), "comment")); + gtk_widget_grab_focus(entry); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : dialog = boîte de dialogue ayant reçu une validation. * +* * +* Description : Fournit le signet conçu via la saisie de l'utilisateur. * +* * +* Retour : Adresse reccueillie par la boîte de dialogue. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDbItem *get_item_from_bookmark_dialog(GtkWidget *dialog) +{ + GDbItem *result; /* Signet nouveau à retourner */ + GObject *ref; /* Espace de référencements */ + vmpa2t *orig; /* Copie de valeur originale */ + vmpa2t addr; /* Localisation finale utilisée*/ + GtkWidget *entry; /* Zone de saisie principale */ + const gchar *text; /* Adresse en version texte */ + GtkToggleButton *radio; /* Définition de localisation */ + + ref = G_OBJECT(dialog); + + /* Si la valeur d'origine a été conservée intacte... */ + + orig = (vmpa2t *)g_object_get_data(ref, "orig"); + + if (orig == NULL) + { + entry = GTK_WIDGET(g_object_get_data(ref, "addr")); + text = gtk_entry_get_text(GTK_ENTRY(entry)); + + radio = GTK_TOGGLE_BUTTON(g_object_get_data(ref, "phys")); + + if (gtk_toggle_button_get_active(radio)) + orig = string_to_vmpa_phy(text); + else + orig = string_to_vmpa_virt(text); + + + + } + + copy_vmpa(&addr, orig); + delete_vmpa(orig); + + /* Récupération du commentaire éventuel */ + + entry = GTK_WIDGET(g_object_get_data(ref, "comment")); + text = gtk_entry_get_text(GTK_ENTRY(entry)); + + /* Mise en place du signet défini */ + + if (strlen(text) > 0) + result = G_DB_ITEM(g_db_bookmark_new(&addr, text)); + else + result = G_DB_ITEM(g_db_bookmark_new(&addr, NULL)); + + return result; + +} diff --git a/src/dialogs/bookmark.h b/src/dialogs/bookmark.h new file mode 100644 index 0000000..0afdb4c --- /dev/null +++ b/src/dialogs/bookmark.h @@ -0,0 +1,44 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * bookmark.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 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 _DIALOGS_BOOKMARK_H +#define _DIALOGS_BOOKMARK_H + + +#include <gtk/gtk.h> + + +#include "../arch/vmpa.h" +#include "../analysis/db/item.h" + + + +/* Construit la fenêtre de création de signet. */ +GtkWidget *create_bookmark_dialog(GtkWindow *, const vmpa2t *); + +/* Fournit le signet conçu via la saisie de l'utilisateur. */ +GDbItem *get_item_from_bookmark_dialog(GtkWidget *); + + + +#endif /* _DIALOGS_BOOKMARK_H */ diff --git a/src/dialogs/goto.c b/src/dialogs/goto.c index dc607d0..847fa9a 100644 --- a/src/dialogs/goto.c +++ b/src/dialogs/goto.c @@ -231,8 +231,8 @@ vmpa2t *get_address_from_goto_dialog(GtkWidget *dialog) vmpa2t *result; /* Adresse à retourner */ GtkWidget *combobox; /* Liste de sélection */ GtkWidget *entry; /* Zone de saisie principale */ - GtkToggleButton *radio; /* Définition de localisation */ const gchar *text; /* Adresse en version texte */ + GtkToggleButton *radio; /* Définition de localisation */ combobox = GTK_WIDGET(g_object_get_data(G_OBJECT(dialog), "combobox")); entry = gtk_bin_get_child(GTK_BIN(combobox)); |