summaryrefslogtreecommitdiff
path: root/src/dialogs
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-02-09 22:07:42 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-02-09 22:07:42 (GMT)
commit1d79469f69bba33a2280d4bd531652b71148029f (patch)
treee81c094d6e829fb1a79d4c413c1cd162e14868a3 /src/dialogs
parent8d326041a0379b87e54be44506d544367567e89b (diff)
Created a dialog box to create new bookmarks.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@468 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/dialogs')
-rw-r--r--src/dialogs/Makefile.am1
-rw-r--r--src/dialogs/bookmark.c331
-rw-r--r--src/dialogs/bookmark.h44
-rw-r--r--src/dialogs/goto.c2
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));