diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2015-12-04 19:05:58 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2015-12-04 19:05:58 (GMT) |
commit | c476dae9b50d6ff218e903e3f8d40ad51003fa40 (patch) | |
tree | 5f3f53037c88c1f5762fef54dc21ac4be7b324ce /src/gui/dialogs | |
parent | 3b4cdd10d6adf9155054989f41bb32759a9541c5 (diff) |
Moved all files related to the GUI into the 'gui' directory.
Diffstat (limited to 'src/gui/dialogs')
-rw-r--r-- | src/gui/dialogs/Makefile.am | 21 | ||||
-rw-r--r-- | src/gui/dialogs/about.c | 166 | ||||
-rw-r--r-- | src/gui/dialogs/about.h | 37 | ||||
-rw-r--r-- | src/gui/dialogs/bookmark.c | 328 | ||||
-rw-r--r-- | src/gui/dialogs/bookmark.h | 44 | ||||
-rw-r--r-- | src/gui/dialogs/export.c | 790 | ||||
-rw-r--r-- | src/gui/dialogs/export.h | 40 | ||||
-rw-r--r-- | src/gui/dialogs/goto.c | 251 | ||||
-rw-r--r-- | src/gui/dialogs/goto.h | 43 | ||||
-rw-r--r-- | src/gui/dialogs/gotox.c | 500 | ||||
-rw-r--r-- | src/gui/dialogs/gotox.h | 47 | ||||
-rw-r--r-- | src/gui/dialogs/plugins.c | 313 | ||||
-rw-r--r-- | src/gui/dialogs/plugins.h | 40 | ||||
-rw-r--r-- | src/gui/dialogs/shellcode.c | 803 | ||||
-rw-r--r-- | src/gui/dialogs/shellcode.h | 37 | ||||
-rw-r--r-- | src/gui/dialogs/storage.c | 648 | ||||
-rw-r--r-- | src/gui/dialogs/storage.h | 40 |
17 files changed, 4148 insertions, 0 deletions
diff --git a/src/gui/dialogs/Makefile.am b/src/gui/dialogs/Makefile.am new file mode 100644 index 0000000..1fe821a --- /dev/null +++ b/src/gui/dialogs/Makefile.am @@ -0,0 +1,21 @@ + +noinst_LTLIBRARIES = libdialogs.la + +libdialogs_la_SOURCES = \ + about.h about.c \ + bookmark.h bookmark.c \ + export.h export.c \ + goto.h goto.c \ + gotox.h gotox.c \ + plugins.h plugins.c \ + shellcode.h shellcode.c \ + storage.h storage.c + +libdialogs_la_LDFLAGS = + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +SUBDIRS = diff --git a/src/gui/dialogs/about.c b/src/gui/dialogs/about.c new file mode 100644 index 0000000..0605b39 --- /dev/null +++ b/src/gui/dialogs/about.c @@ -0,0 +1,166 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * about.h - boîte de dialogue d'information sur le programme + * + * Copyright (C) 2010-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 "about.h" + + +#include <math.h> +#include <stdio.h> +#include <gdk/gdkkeysyms.h> + + +#include <config.h> +#include <i18n.h> + + +#include "../../gtkext/easygtk.h" +#include "../../gtkext/support.h" + + + +/* Réagit à l'appui d'une touche sur la fenêtre 'A propos'. */ +static gboolean close_about_window_on_escape(GtkWidget *, GdkEventKey *, gpointer); + + + +/****************************************************************************** +* * +* Paramètres : parent = fenêtre parente à surpasser. * +* * +* Description : Construit la fenêtre d'informations sur le logiciel. * +* * +* Retour : Adresse de la fenêtre mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *create_about_dialog(GtkWindow *parent) +{ + GtkWidget *result; /* Fenêtre à renvoyer */ + GdkRGBA color; /* Couleur de fond noire */ + GtkWidget *fixed; /* Support global */ + gchar *filename; /* Chemin d'accès au fichier */ + GtkWidget *image; /* Image chargée */ + unsigned int revision; /* Numéro de révision */ + unsigned int max; /* Nbre. de boucles à effectuer*/ + unsigned int i; /* Boucle de parcours */ + unsigned int level; /* Unité la plus importante */ + char buffer[16]; /* Nom d'image à forger */ + GtkWidget *label; /* Etiquette inférieure */ + + result = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_set_size_request(result, 350, 430); + gtk_container_set_border_width(GTK_CONTAINER(result), 0); + gtk_window_set_title(GTK_WINDOW(result), _("About")); + gtk_window_set_transient_for(GTK_WINDOW(result), parent); + gtk_window_set_default_size(GTK_WINDOW(result), 350, 430); + gtk_window_set_type_hint(GTK_WINDOW(result), GDK_WINDOW_TYPE_HINT_DIALOG); + + g_signal_connect(result, "key_press_event", G_CALLBACK(close_about_window_on_escape), NULL); + + gdk_rgba_parse(&color, "black"); + gtk_widget_override_background_color(GTK_WIDGET(result), GTK_STATE_FLAG_NORMAL, &color); + + fixed = gtk_fixed_new(); + gtk_widget_show(fixed); + gtk_container_add(GTK_CONTAINER(result), fixed); + + /* Images principales */ + + filename = find_pixmap_file("chrysalide-full.png"); + image = qck_create_image(NULL, NULL, filename); + gtk_fixed_put(GTK_FIXED(fixed), image, 10, 10); + gtk_widget_set_size_request(image, 330, 300); + + filename = find_pixmap_file("chrysalide_text.png"); + image = qck_create_image(NULL, NULL, filename); + gtk_fixed_put(GTK_FIXED(fixed), image, 48, 324); + gtk_widget_set_size_request(image, 253, 42); + + /* Numéro de révision */ + + filename = find_pixmap_file("revision.png"); + image = qck_create_image(NULL, NULL, filename); + gtk_fixed_put(GTK_FIXED(fixed), image, 149, 360); + gtk_widget_set_size_request(image, 14, 18); + + revision = REVISION; + max = log(revision) / log(10); + + for (i = 0; i <= max; i++) + { + level = pow(10, max - i); + + snprintf(buffer, 16, "revision_%u.png", revision / level); + + filename = find_pixmap_file(buffer); + image = qck_create_image(NULL, NULL, filename); + gtk_fixed_put(GTK_FIXED(fixed), image, 163 + i * 14, 360); + gtk_widget_set_size_request(image, 14, 18); + + revision %= level; + + } + + /* Copyright */ + + label = qck_create_label(NULL, NULL, "<span fgcolor='white'>Copyright (C) 2010-2014 Cyrille Bagard</span>"); + gtk_widget_set_halign(label, GTK_ALIGN_CENTER); + gtk_label_set_use_markup(GTK_LABEL(label), TRUE); + gtk_fixed_put(GTK_FIXED(fixed), label, 0, 400); + gtk_widget_set_size_request(label, 350, 20); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : window = fenêtre visée par la procédure. * +* event = informations liées à l'événement. * +* dummy = donnée non utilisée ici. * +* * +* Description : Réagit à l'appui d'une touche sur la fenêtre 'A propos'. * +* * +* Retour : TRUE pour poursuivre la propagation, FALSE autrement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean close_about_window_on_escape(GtkWidget *widget, GdkEventKey *event, gpointer dummy) +{ + gboolean result; /* Ordre à retourner */ + + if (event->keyval == GDK_KEY_Escape) + { + gtk_widget_destroy(widget); + result = TRUE; + } + else result = FALSE; + + return result; + +} diff --git a/src/gui/dialogs/about.h b/src/gui/dialogs/about.h new file mode 100644 index 0000000..6be0560 --- /dev/null +++ b/src/gui/dialogs/about.h @@ -0,0 +1,37 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * about.h - prototypes pour la boîte de dialogue d'information sur le programme + * + * Copyright (C) 2010 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 _GUI_DIALOGS_ABOUT_H +#define _GUI_DIALOGS_ABOUT_H + + +#include <gtk/gtk.h> + + + +/* Construit la fenêtre d'informations sur le logiciel. */ +GtkWidget *create_about_dialog(GtkWindow *); + + + +#endif /* _GUI_DIALOGS_ABOUT_H */ diff --git a/src/gui/dialogs/bookmark.c b/src/gui/dialogs/bookmark.c new file mode 100644 index 0000000..4a5757a --- /dev/null +++ b/src/gui/dialogs/bookmark.c @@ -0,0 +1,328 @@ + +/* 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 *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 */ + + sub_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + gtk_widget_show(sub_vbox); + + frame = qck_create_frame(_("<b>Localisation</b>"), sub_vbox, 8, 0, 12, 0); + gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0); + + /* 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 */ + + entry = qck_create_entry(G_OBJECT(result), "comment", NULL); + + frame = qck_create_frame(_("<b>Optional comment</b>"), entry, 8, 0, 12, 0); + gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0); + + /* 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/gui/dialogs/bookmark.h b/src/gui/dialogs/bookmark.h new file mode 100644 index 0000000..78ce45e --- /dev/null +++ b/src/gui/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 _GUI_DIALOGS_BOOKMARK_H +#define _GUI_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 /* _GUI_DIALOGS_BOOKMARK_H */ diff --git a/src/gui/dialogs/export.c b/src/gui/dialogs/export.c new file mode 100644 index 0000000..33fd0c5 --- /dev/null +++ b/src/gui/dialogs/export.c @@ -0,0 +1,790 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * export.c - assistant d'exportation de contenu binaire + * + * Copyright (C) 2010-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 "export.h" + + +#include <assert.h> +#include <fcntl.h> +#include <malloc.h> +#include <stdio.h> +#include <unistd.h> + + +#include <i18n.h> + + +#include "../../common/extstr.h" +#include "../../gtkext/easygtk.h" + + + +/* ------------------------ PARTIE PRINCIPALE DE L'ASSISTANT ------------------------ */ + + +/* Ferme l'assistant sans dérouler la procédure. */ +static void export_assistant_cancel(GtkAssistant *, gpointer); + +/* Ferme l'assistant et déroule la procédure. */ +static void export_assistant_close(GtkAssistant *, GObject *); + + + +/* ----------------------- DEFINITION DU FORMAT D'EXPORTATION ----------------------- */ + + +/* Ajoute le panneau de choix du format d'exportation. */ +static void register_format_panel(GtkAssistant *); + +/* Réagit un changement du format pour l'exportation. */ +static void on_export_format_changed(GtkComboBox *, GtkAssistant *); + +/* Interdit un champ de texte vide pour les options de texte. */ +static void forbid_text_empty_entry(GtkEntry *, GtkAssistant *); + +/* Interdit un champ de texte vide pour les options HTML. */ +static void forbid_html_empty_entry(GtkEntry *, GtkAssistant *); + + + +/* ------------------------- SELECTION DU CONTENU A TRAITER ------------------------- */ + + +/* Ajoute le panneau de sélection du contenu à exporter. */ +static void register_content_panel(GtkAssistant *); + + + +/* ------------------------ DEFINITION DE LA SORTIE ATTENDUE ------------------------ */ + + +/* Ajoute le panneau de choix du type de sortie. */ +static void register_output_panel(GtkAssistant *); + +/* Réagit un changement du nom de fichier pour l'exportation. */ +static void on_export_filename_changed(GtkEntry *, GtkAssistant *); + +/* Sélectionne ou non un nouveau fichier de sortie. */ +static void on_filename_browsing_clicked(GtkButton *, GObject *); + + + +/* ---------------------------------------------------------------------------------- */ +/* PARTIE PRINCIPALE DE L'ASSISTANT */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : binary = binaire chargé en mémoire à traiter. * +* parent = fenêtre principale de l'éditeur. * +* * +* Description : Crée et affiche un assistant d'aide à l'exportation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void run_export_assistant(GLoadedBinary *binary, GtkWindow *parent) +{ + GtkWidget *assistant; /* Fenêtre à afficher */ + GObject *ref; /* Espace de référencement */ + + assistant = gtk_assistant_new(); + gtk_widget_set_size_request(assistant, 500, 350); + gtk_window_set_position(GTK_WINDOW(assistant), GTK_WIN_POS_CENTER); + gtk_window_set_title(GTK_WINDOW(assistant), _("Export assistant")); + + gtk_window_set_modal(GTK_WINDOW(assistant), TRUE); + gtk_window_set_transient_for(GTK_WINDOW(assistant), parent); + + ref = G_OBJECT(assistant); + g_object_set_data(ref, "binary", binary); + + register_format_panel(GTK_ASSISTANT(assistant)); + register_content_panel(GTK_ASSISTANT(assistant)); + register_output_panel(GTK_ASSISTANT(assistant)); + + g_signal_connect(G_OBJECT(assistant), "cancel", G_CALLBACK(export_assistant_cancel), NULL); + g_signal_connect(G_OBJECT(assistant), "close", G_CALLBACK(export_assistant_close), ref); + + gtk_widget_show_all(assistant); + +} + + +/****************************************************************************** +* * +* Paramètres : assistant = fenêtre à compléter et référencement global. * +* data = adresse non utilisée ici. * +* * +* Description : Ferme l'assistant sans dérouler la procédure. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void export_assistant_cancel(GtkAssistant *assistant, gpointer data) +{ + GObject *support; /* Support interne à supprimer */ + + support = G_OBJECT(g_object_get_data(G_OBJECT(assistant), "text_options")); + if (support != NULL) g_object_unref(support); + + support = G_OBJECT(g_object_get_data(G_OBJECT(assistant), "html_options")); + if (support != NULL) g_object_unref(support); + + gtk_widget_destroy(GTK_WIDGET(assistant)); + +} + + +/****************************************************************************** +* * +* Paramètres : assistant = fenêtre à compléter et référencement global. * +* ref = adresse de l'espace de référencement global. * +* * +* Description : Ferme l'assistant et déroule la procédure. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void export_assistant_close(GtkAssistant *assistant, GObject *ref) +{ + GtkComboBox *combo; /* Selection du format */ + BufferExportType type; /* Type d'exportation requise */ + buffer_export_context ctx; /* Contexte à constituer */ + GtkEntry *entry; /* Zone de saisie */ + const gchar *filename; /* Chemin d'accès du fichier */ + GtkToggleButton *checkbutton; /* Coche à retrouver */ + bool display[BLC_DISPLAY]; /* Affichage à garantir */ + GLoadedBinary *binary; /* Binaire chargé à parcourir */ + GCodeBuffer *buffer; /* Tampon de code à traiter */ + GBufferView *view; /* Vue à exporter */ + GObject *support; /* Support interne à supprimer */ + + /* Type d'exportation */ + + combo = GTK_COMBO_BOX(g_object_get_data(ref, "format")); + + type = (BufferExportType)gtk_combo_box_get_active(combo); + + /* Fichier de sortie */ + + entry = GTK_ENTRY(g_object_get_data(ref, "filename")); + filename = gtk_entry_get_text(entry); + + switch (type) + { + case BET_TEXT: + case BET_HTML: + ctx.fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR); + if (ctx.fd == -1) + { + perror("open"); + return; + } + break; + + default: + assert(false); + break; + + } + + /* Eléments à afficher */ + + checkbutton = GTK_TOGGLE_BUTTON(g_object_get_data(ref, "physical_off")); + display[BLC_PHYSICAL] = gtk_toggle_button_get_active(checkbutton); + + checkbutton = GTK_TOGGLE_BUTTON(g_object_get_data(ref, "virtual_addr")); + display[BLC_VIRTUAL] = gtk_toggle_button_get_active(checkbutton); + + checkbutton = GTK_TOGGLE_BUTTON(g_object_get_data(ref, "binary_code")); + display[BLC_BINARY] = gtk_toggle_button_get_active(checkbutton); + + /* Options éventuelles */ + + switch (type) + { + case BET_TEXT: + entry = GTK_ENTRY(g_object_get_data(ref, "text_separator")); + ctx.sep = gtk_entry_get_text(entry); + if (strcmp(ctx.sep, "\\t") == 0) ctx.sep = "\t"; + break; + + case BET_HTML: + entry = GTK_ENTRY(g_object_get_data(ref, "html_font_name")); + ctx.font_name = gtk_entry_get_text(entry); + + entry = GTK_ENTRY(g_object_get_data(ref, "html_bg_color")); + ctx.bg_color = gtk_entry_get_text(entry); + + break; + + default: + break; + + } + + /* Programmation de la tâche */ + + binary = G_LOADED_BINARY(g_object_get_data(ref, "binary")); + + buffer = g_loaded_binary_get_disassembled_buffer(binary); + view = g_buffer_view_new(buffer, NULL); + + g_buffer_view_export(view, &ctx, type, display); + + /* Conclusion */ + + switch (type) + { + case BET_TEXT: + case BET_HTML: + close(ctx.fd); + break; + + default: + break; + + } + + g_object_unref(view); + + support = G_OBJECT(g_object_get_data(G_OBJECT(assistant), "text_options")); + if (support != NULL) g_object_unref(support); + + support = G_OBJECT(g_object_get_data(G_OBJECT(assistant), "html_options")); + if (support != NULL) g_object_unref(support); + + gtk_widget_destroy(GTK_WIDGET(assistant)); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION DU FORMAT D'EXPORTATION */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : assistant = fenêtre à compléter et référencement global. * +* * +* Description : Ajoute le panneau de choix du format d'exportation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void register_format_panel(GtkAssistant *assistant) +{ + GtkWidget *vbox; /* Support principal #1 */ + GtkWidget *hbox; /* Support principal #2 */ + GtkWidget *label; /* Etiquette d'indication */ + GtkWidget *combobox; /* Sélection du format */ + GtkWidget *options; /* Zone d'options */ + GtkWidget *content; /* Accueil desdites options */ + + vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + qck_set_margins(vbox, 8, 8, 8, 8); + gtk_widget_show(vbox); + + /* Format de sortie */ + + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + + label = qck_create_label(NULL, NULL, _("Format: ")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + combobox = qck_create_combobox(G_OBJECT(assistant), "format", G_CALLBACK(on_export_format_changed), assistant); + gtk_box_pack_start(GTK_BOX(hbox), combobox, TRUE, TRUE, 0); + + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combobox), _("Simple text")); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combobox), _("HTML")); + + /* Eventuelles options */ + + content = gtk_event_box_new(); + gtk_widget_show(content); + + options = qck_create_frame(_("<b>Options</b>"), content, 0, 12, 12, 0); + gtk_box_pack_start(GTK_BOX(vbox), options, FALSE, FALSE, 0); + + g_object_set_data(G_OBJECT(assistant), "options", content); + + /* Intégration */ + + gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), 1); + + gtk_assistant_append_page(assistant, vbox); + gtk_assistant_set_page_title(assistant, vbox, _("Format")); + gtk_assistant_set_page_type(assistant, vbox, GTK_ASSISTANT_PAGE_INTRO); + + gtk_assistant_set_page_complete(assistant, vbox, TRUE); + +} + + +/****************************************************************************** +* * +* Paramètres : combo = liste dont la sélection vient de changer. * +* assistant = fenêtre affichée et référencement global. * +* * +* Description : Réagit un changement du format pour l'exportation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_export_format_changed(GtkComboBox *combo, GtkAssistant *assistant) +{ + BufferExportType selected; /* Format attendu */ + GtkContainer *content; /* Accueil des options */ + GtkWidget *old; /* Ancien support à remplacer */ + GtkWidget *vbox; /* Support principal #1 */ + GtkWidget *hbox; /* Support principal #2 */ + GtkWidget *label; /* Etiquette d'indication */ + GtkWidget *entry; /* Zone de saisie de valeur */ + char *filename; /* Chemin à venir modifier */ + char *dot; /* Dernière occurence de point */ + + selected = (BufferExportType)gtk_combo_box_get_active(combo); + + content = GTK_CONTAINER(g_object_get_data(G_OBJECT(assistant), "options")); + + old = gtk_bin_get_child(GTK_BIN(content)); + if (old != NULL) + { + g_object_ref(G_OBJECT(old)); + gtk_container_remove(content, old); + } + + switch (selected) + { + case BET_TEXT: + + hbox = GTK_WIDGET(g_object_get_data(G_OBJECT(assistant), "text_options")); + + if (hbox == NULL) + { + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + g_object_ref(G_OBJECT(hbox)); + gtk_widget_show(hbox); + g_object_set_data(G_OBJECT(assistant), "text_options", hbox); + + label = qck_create_label(NULL, NULL, _("String between columns: ")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + entry = qck_create_entry(G_OBJECT(assistant), "text_separator", NULL); + g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(forbid_text_empty_entry), assistant); + gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); + gtk_entry_set_text(GTK_ENTRY(entry), "\\t"); + + } + + gtk_container_add(content, hbox); + + break; + + case BET_HTML: + + vbox = GTK_WIDGET(g_object_get_data(G_OBJECT(assistant), "html_options")); + + if (vbox == NULL) + { + vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + g_object_ref(G_OBJECT(vbox)); + gtk_widget_show(vbox); + g_object_set_data(G_OBJECT(assistant), "html_options", vbox); + + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + + label = qck_create_label(NULL, NULL, _("HTML table font name: ")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + entry = qck_create_entry(G_OBJECT(assistant), "html_font_name", NULL); + g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(forbid_html_empty_entry), assistant); + gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); + gtk_entry_set_text(GTK_ENTRY(entry), "monospace"); + + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + + label = qck_create_label(NULL, NULL, _("HTML table background color: ")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + entry = qck_create_entry(G_OBJECT(assistant), "html_bg_color", NULL); + g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(forbid_html_empty_entry), assistant); + gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); + gtk_entry_set_text(GTK_ENTRY(entry), "#2c2c2c"); + + } + + gtk_container_add(content, vbox); + + break; + + default: + break; + + } + + /* Mise à jour de l'extension du fichier de sortie, si possible */ + + entry = GTK_WIDGET(g_object_get_data(G_OBJECT(assistant), "filename")); + + if (entry != NULL) + { + filename = strdup(gtk_entry_get_text(GTK_ENTRY(entry))); + + dot = strrchr(filename, '.'); + if (dot == NULL) goto oefc_no_dot; + + *dot = '\0'; + + switch (selected) + { + case BET_TEXT: + filename = stradd(filename, ".txt"); + break; + case BET_HTML: + filename = stradd(filename, ".html"); + break; + default: + break; + } + + gtk_entry_set_text(GTK_ENTRY(entry), filename); + + oefc_no_dot: + + free(filename); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : entry = zone de texte dont le contenu vient de changer. * +* assistant = fenêtre affichée et référencement global. * +* * +* Description : Interdit un champ de texte vide pour les options HTML. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void forbid_text_empty_entry(GtkEntry *entry, GtkAssistant *assistant) +{ + const gchar *text; /* Texte saisi dans la zone */ + gint num; /* Etape courante */ + GtkWidget *page; /* Support de cette étape */ + + text = gtk_entry_get_text(entry); + + num = gtk_assistant_get_current_page(assistant); + page = gtk_assistant_get_nth_page(assistant, num); + + gtk_assistant_set_page_complete(assistant, page, (strlen(text) > 0)); + +} + + +/****************************************************************************** +* * +* Paramètres : _entry = zone de texte dont le contenu vient de changer. * +* assistant = fenêtre affichée et référencement global. * +* * +* Description : Interdit un champ de texte vide pour les options de texte. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void forbid_html_empty_entry(GtkEntry *_entry, GtkAssistant *assistant) +{ + bool status; /* Etat final à remonter */ + GtkEntry *entry; /* Zone de texte générique */ + const gchar *text; /* Texte saisi dans la zone */ + gint num; /* Etape courante */ + GtkWidget *page; /* Support de cette étape */ + + status = true; + + /* Police de caractère */ + + entry = GTK_ENTRY(g_object_get_data(G_OBJECT(assistant), "html_font_name")); + text = gtk_entry_get_text(entry); + + status &= (strlen(text) > 0); + + /* Couleur de fond */ + + entry = GTK_ENTRY(g_object_get_data(G_OBJECT(assistant), "html_bg_color")); + + if (entry != NULL) + { + text = gtk_entry_get_text(entry); + + status &= (strlen(text) > 0); + + } + + /* Mise à jour graphique */ + + num = gtk_assistant_get_current_page(assistant); + + if (num != -1) + { + page = gtk_assistant_get_nth_page(assistant, num); + + gtk_assistant_set_page_complete(assistant, page, status); + + } + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* SELECTION DU CONTENU A TRAITER */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : assistant = fenêtre à compléter et référencement global. * +* * +* Description : Ajoute le panneau de sélection du contenu à exporter. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void register_content_panel(GtkAssistant *assistant) +{ + GtkWidget *vbox; /* Support principal */ + GtkWidget *frame; /* Support avec encadrement */ + GtkWidget *sub_vbox; /* Division verticale */ + GtkWidget *checkbutton; /* Coche pour une option */ + + vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + qck_set_margins(vbox, 8, 8, 8, 8); + gtk_widget_show(vbox); + + /* Eléments à afficher */ + + sub_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + gtk_widget_show(sub_vbox); + + frame = qck_create_frame(_("<b>Items to display</b>"), sub_vbox, 0, 12, 12, 0); + gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0); + + checkbutton = qck_create_check_button(G_OBJECT(assistant), "physical_off", _("Physical offset"), NULL, NULL); + gtk_box_pack_start(GTK_BOX(sub_vbox), checkbutton, FALSE, FALSE, 0); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TRUE); + + checkbutton = qck_create_check_button(G_OBJECT(assistant), "virtual_addr", _("Virtual address"), NULL, NULL); + gtk_box_pack_start(GTK_BOX(sub_vbox), checkbutton, FALSE, FALSE, 0); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TRUE); + + checkbutton = qck_create_check_button(G_OBJECT(assistant), "binary_code", _("Binary code"), NULL, NULL); + gtk_box_pack_start(GTK_BOX(sub_vbox), checkbutton, FALSE, FALSE, 0); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TRUE); + + /* Intégration */ + + gtk_assistant_append_page(assistant, vbox); + gtk_assistant_set_page_title(assistant, vbox, _("Exported content")); + gtk_assistant_set_page_type(assistant, vbox, GTK_ASSISTANT_PAGE_CONTENT); + + gtk_assistant_set_page_complete(assistant, vbox, TRUE); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION DE LA SORTIE ATTENDUE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : assistant = fenêtre à compléter et référencement global. * +* * +* Description : Ajoute le panneau de choix du type de sortie. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void register_output_panel(GtkAssistant *assistant) +{ + GtkWidget *vbox; /* Support principal #1 */ + GtkWidget *label; /* Etiquette d'indication */ + GtkWidget *hbox; /* Support principal #2 */ + GtkWidget *entry; /* Zone de saisie de texte */ + GtkWidget *button; /* Sélection de fichier */ + GLoadedBinary *binary; /* Binaire chargé à parcourir */ + const char *filename; /* Chemin d'accès par défaut */ + + vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + qck_set_margins(vbox, 8, 8, 8, 8); + gtk_widget_show(vbox); + + /* Fichier de sortie */ + + label = qck_create_label(NULL, NULL, _("File: ")); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); + + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + + entry = qck_create_entry(G_OBJECT(assistant), "filename", NULL); + gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); + + button = qck_create_button(NULL, NULL, "...", G_CALLBACK(on_filename_browsing_clicked), assistant); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); + + /* Intégration */ + + gtk_assistant_append_page(assistant, vbox); + gtk_assistant_set_page_title(assistant, vbox, _("Output")); + gtk_assistant_set_page_type(assistant, vbox, GTK_ASSISTANT_PAGE_CONFIRM); + + gtk_assistant_set_page_complete(assistant, vbox, TRUE); + + /* Choix par défaut */ + + binary = G_LOADED_BINARY(g_object_get_data(G_OBJECT(assistant), "binary")); + filename = g_loaded_binary_get_name(binary, true); + + gtk_entry_set_text(GTK_ENTRY(entry), filename); + gtk_editable_insert_text(GTK_EDITABLE(entry), ".html", -1, (gint []) { strlen(filename) }); + + g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(on_export_filename_changed), assistant); + +} + + +/****************************************************************************** +* * +* Paramètres : entry = zone de texte dont le contenu vient de changer. * +* assistant = fenêtre affichée et référencement global. * +* * +* Description : Réagit un changement du nom de fichier pour l'exportation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_export_filename_changed(GtkEntry *entry, GtkAssistant *assistant) +{ + const gchar *text; /* Texte saisi dans la zone */ + gint num; /* Etape courante */ + GtkWidget *page; /* Support de cette étape */ + + text = gtk_entry_get_text(entry); + + num = gtk_assistant_get_current_page(assistant); + page = gtk_assistant_get_nth_page(assistant, num); + + gtk_assistant_set_page_complete(assistant, page, (strlen(text) > 0)); + +} + + +/****************************************************************************** +* * +* Paramètres : button = bouton d'édition de la sélection. * +* ref = espace de référencement principal. * +* * +* Description : Sélectionne ou non un nouveau fichier de sortie. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_filename_browsing_clicked(GtkButton *button, GObject *ref) +{ + GtkWidget *dialog; /* Boîte à afficher */ + gchar *filename; /* Nom du fichier à intégrer */ + GtkEntry *entry; /* Zone de saisie à maj. */ + + dialog = gtk_file_chooser_dialog_new(_("Choose an output filename"), GTK_WINDOW(ref), + GTK_FILE_CHOOSER_ACTION_SAVE, + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_Save"), GTK_RESPONSE_ACCEPT, + NULL); + + entry = GTK_ENTRY(g_object_get_data(ref, "filename")); + gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), gtk_entry_get_text(entry)); + + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) + { + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + + gtk_entry_set_text(GTK_ENTRY(entry), filename); + + g_free(filename); + + } + + gtk_widget_destroy(dialog); + +} diff --git a/src/gui/dialogs/export.h b/src/gui/dialogs/export.h new file mode 100644 index 0000000..9989971 --- /dev/null +++ b/src/gui/dialogs/export.h @@ -0,0 +1,40 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * export.h - prototypes pour l'assistant d'exportation de contenu binaire + * + * Copyright (C) 2010-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/>. + */ + + +#ifndef _GUI_DIALOGS_EXPORT_H +#define _GUI_DIALOGS_EXPORT_H + + +#include <gtk/gtk.h> + + +#include "../../analysis/binary.h" + + + +/* Crée et affiche un assistant d'aide à l'exportation. */ +void run_export_assistant(GLoadedBinary *, GtkWindow *); + + + +#endif /* _GUI_DIALOGS_EXPORT_H */ diff --git a/src/gui/dialogs/goto.c b/src/gui/dialogs/goto.c new file mode 100644 index 0000000..8eb6411 --- /dev/null +++ b/src/gui/dialogs/goto.c @@ -0,0 +1,251 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * goto.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 "goto.h" + + +#include <ctype.h> + + +#include <i18n.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. * +* * +* 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 #1 */ + GtkWidget *label; /* Message d'introduction */ + GtkWidget *combobox; /* Liste de sélection */ + GtkWidget *entry; /* Zone de saisie principale */ + GtkWidget *hbox; /* Support à construire #2 */ + GtkWidget *radio; /* Définition de localisation */ + + 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_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); + + /* Zone de saisie principale */ + + 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_combobox_with_entry(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"); + + + /* Propriétés de la localisation */ + + 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), "phy", _("Address is physical"), + NULL, NULL, NULL); + gtk_box_pack_start(GTK_BOX(hbox), radio, TRUE, TRUE, 0); + + radio = qck_create_radio_button(G_OBJECT(result), "virt", _("Address is virtual"), + GTK_RADIO_BUTTON(radio), NULL, NULL); + gtk_box_pack_start(GTK_BOX(hbox), radio, TRUE, TRUE, 0); + + /* 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); + + 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 : - * +* * +******************************************************************************/ + +vmpa2t *get_address_from_goto_dialog(GtkWidget *dialog) +{ + vmpa2t *result; /* Adresse à retourner */ + GtkWidget *combobox; /* Liste de sélection */ + GtkWidget *entry; /* Zone de saisie principale */ + 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)); + + text = gtk_entry_get_text(GTK_ENTRY(entry)); + + radio = GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(dialog), "phy")); + + if (gtk_toggle_button_get_active(radio)) + result = string_to_vmpa_phy(text); + else + result = string_to_vmpa_virt(text); + + return result; + +} diff --git a/src/gui/dialogs/goto.h b/src/gui/dialogs/goto.h new file mode 100644 index 0000000..7d8cd54 --- /dev/null +++ b/src/gui/dialogs/goto.h @@ -0,0 +1,43 @@ + +/* Chrysalide - 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 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 _GUI_DIALOGS_GOTO_H +#define _GUI_DIALOGS_GOTO_H + + +#include <gtk/gtk.h> + + +#include "../../arch/vmpa.h" + + + +/* Construit la fenêtre de saut à une adresse. */ +GtkWidget *create_goto_dialog(GtkWindow *); + +/* Fournit l'adresse obtenue par la saisie de l'utilisateur. */ +vmpa2t *get_address_from_goto_dialog(GtkWidget *); + + + +#endif /* _GUI_DIALOGS_GOTO_H */ diff --git a/src/gui/dialogs/gotox.c b/src/gui/dialogs/gotox.c new file mode 100644 index 0000000..fd05100 --- /dev/null +++ b/src/gui/dialogs/gotox.c @@ -0,0 +1,500 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * goto.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 "gotox.h" + + +#include <cairo-gobject.h> +#include <malloc.h> + + +#include <i18n.h> + + +#include "../../gtkext/easygtk.h" +#include "../../gtkext/support.h" + + + +/* Colonnes de la liste des symboles */ +typedef enum _GotoXColumn +{ + GXC_PHYSICAL, /* Correspondance physique */ + GXC_VIRTUAL, /* Correspondance virtuelle */ + + GXC_PICTURE, /* Image de représentation */ + GXC_ADDRESS, /* Adresse mémoire du symbole */ + GXC_NAME, /* Désignation humaine */ + GXC_CONTENT, /* Contenu de la ligne visée */ + + GXC_COUNT /* Nombre de colonnes */ + +} GotoXColumn; + + +/* Réagit à une validation d'une ligne affichée. */ +static void on_gotox_row_activated(GtkTreeView *, GtkTreePath *, GtkTreeViewColumn *, GtkDialog *); + +/* Construit la fenêtre de sélection d'adresses. */ +static GtkWidget *create_gotox_dialog(GtkWindow *, GtkTreeStore **); + +/* Ajoute une nouvelle localisation de destination. */ +static void add_new_location_to_list(GtkTreeStore *, GLoadedBinary *, const vmpa2t *, GBinSymbol *); + + + +/****************************************************************************** +* * +* Paramètres : treeview = composant graphique manipulé par l'utilisateur. * +* path = chemin d'accès à la ligne activée. * +* column = colonne impactée par l'action. * +* dialog = boîte de dialogue affichant la liste éditée. * +* * +* Description : Réagit à une validation d'une ligne affichée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_gotox_row_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *column, GtkDialog *dialog) +{ + gtk_dialog_response(dialog, GTK_RESPONSE_OK); + +} + + +/****************************************************************************** +* * +* Paramètres : parent = fenêtre parente à surpasser. * +* store = modèle de gestion pour les éléments de liste. [OUT] * +* * +* Description : Construit la fenêtre de sélection d'adresses. * +* * +* Retour : Adresse de la fenêtre mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GtkWidget *create_gotox_dialog(GtkWindow *parent, GtkTreeStore **store) +{ + GtkWidget *result; /* Fenêtre à renvoyer */ + GtkWidget *dlgvbox; /* Zone principale de la boîte */ + GtkWidget *vbox; /* Support à construire #1 */ + GtkWidget *scrollwnd; /* Support défilant */ + GtkWidget *treeview; /* Affichage de la liste */ + GtkCellRenderer *renderer; /* Moteur de rendu de colonne */ + GtkTreeViewColumn *column; /* Colonne de la liste */ + + result = gtk_dialog_new(); + gtk_window_set_default_size(GTK_WINDOW(result), 600, 350); + 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); + + /* Liste arborescente ou linéaire */ + + scrollwnd = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_show(scrollwnd); + gtk_box_pack_start(GTK_BOX(vbox), scrollwnd, TRUE, TRUE, 0); + + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwnd), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwnd), GTK_SHADOW_IN); + + *store = gtk_tree_store_new(GXC_COUNT, + G_TYPE_UINT64, G_TYPE_UINT64, + CAIRO_GOBJECT_TYPE_SURFACE, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + + treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(*store)); + gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), TRUE); + gtk_tree_view_set_enable_tree_lines(GTK_TREE_VIEW(treeview), TRUE); + + g_signal_connect(treeview, "row-activated", G_CALLBACK(on_gotox_row_activated), result); + + g_object_set_data(G_OBJECT(result), "treeview", treeview); + + gtk_widget_show(treeview); + gtk_container_add(GTK_CONTAINER(scrollwnd), treeview); + + /* Cellules d'affichage */ + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Address"), renderer, + "markup", GXC_ADDRESS, + NULL); + gtk_tree_view_column_set_sort_column_id(column, GXC_ADDRESS); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + column = gtk_tree_view_column_new(); + + gtk_tree_view_column_set_title(column, _("Name")); + + renderer = gtk_cell_renderer_pixbuf_new(); + gtk_tree_view_column_pack_start(column, renderer, FALSE); + gtk_tree_view_column_set_attributes(column, renderer, + "surface", GXC_PICTURE, + NULL); + + g_object_set(G_OBJECT(renderer), "xpad", 4, NULL); + + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(column, renderer, TRUE); + gtk_tree_view_column_set_attributes(column, renderer, + "text", GXC_NAME, + NULL); + + gtk_tree_view_column_set_sort_column_id(column, GXC_NAME); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Content"), renderer, + "markup", GXC_CONTENT, + NULL); + gtk_tree_view_column_set_sort_column_id(column, GXC_CONTENT); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + /* Zone de validation */ + + gtk_dialog_add_button(GTK_DIALOG(result), _("_Cancel"), GTK_RESPONSE_CANCEL); + gtk_dialog_add_button(GTK_DIALOG(result), _("_Go"), GTK_RESPONSE_OK); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : parent = fenêtre parente à surpasser. * +* binary = binaire dont les points d'entrée sont à afficher. * +* * +* Description : Construit la fenêtre de sélection des points d'entrée. * +* * +* Retour : Adresse de la fenêtre mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *create_gotox_dialog_for_entry_points(GtkWindow *parent, GLoadedBinary *binary) +{ + GtkWidget *result; /* Fenêtre à renvoyer */ + GtkTreeStore *store; /* Modèle de gestion */ + GBinFormat *format; /* Format associé au binaire */ + GBinSymbol **symbols; /* Symboles à représenter */ + size_t sym_count; /* Qté de symboles présents */ + bool has_entry_points; /* Présences d'insertions ? */ + size_t i; /* Boucle de parcours */ + vmpa2t addr; /* Localisation de symbole */ + + /* Mise en place de la boîte de dialogue */ + + result = create_gotox_dialog(parent, &store); + + gtk_window_set_title(GTK_WINDOW(result), _("Binary's entry points")); + + /* Affichage de tous les points d'entrées */ + + format = G_BIN_FORMAT(g_loaded_binary_get_format(binary)); + + symbols = g_binary_format_get_symbols(format, &sym_count); + + has_entry_points = false; + + for (i = 0; i < sym_count; i++) + { + if (g_binary_symbol_get_target_type(symbols[i]) != STP_ENTRY_POINT) + continue; + + copy_vmpa(&addr, get_mrange_addr(g_binary_symbol_get_range(symbols[i]))); + + add_new_location_to_list(store, binary, &addr, symbols[i]); + + has_entry_points = true; + + } + + g_object_unref(G_OBJECT(store)); + + gtk_dialog_set_response_sensitive(GTK_DIALOG(result), GTK_RESPONSE_OK, has_entry_points); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : parent = fenêtre parente à surpasser. * +* binary = binaire dont les points d'entrée sont à afficher. * +* instr = instruction de référence sur laquelle s'appuyer. * +* back = sens de la récupérations des instructions visées. * +* * +* Description : Construit la fenêtre de sélection des références croisées. * +* * +* Retour : Adresse de la fenêtre mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *create_gotox_dialog_for_cross_references(GtkWindow *parent, GLoadedBinary *binary, const GArchInstruction *instr, bool back) +{ + GtkWidget *result; /* Fenêtre à renvoyer */ + GtkTreeStore *store; /* Modèle de gestion */ + GArchInstruction **list; /* Liste d'instructions */ + size_t count; /* Nombre d'éléments présents */ + size_t i; /* Boucle de parcours */ + const vmpa2t *addr; /* Adresse à considérer */ + + /* Mise en place de la boîte de dialogue */ + + result = create_gotox_dialog(parent, &store); + + if (back) + gtk_window_set_title(GTK_WINDOW(result), _("List of backward cross references")); + else + gtk_window_set_title(GTK_WINDOW(result), _("List of forward cross references")); + + /* Affichage de toutes les instructions référencées */ + + if (back) + count = g_arch_instruction_get_sources(instr, &list, NULL); + else + count = g_arch_instruction_get_destinations(instr, &list, NULL, NULL); + + for (i = 0; i < count; i++) + { + addr = get_mrange_addr(g_arch_instruction_get_range(list[i])); + + add_new_location_to_list(store, binary, addr, NULL); + + } + + g_object_unref(G_OBJECT(store)); + + gtk_dialog_set_response_sensitive(GTK_DIALOG(result), GTK_RESPONSE_OK, count > 0); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : store = modèle de gestionnaire pour la liste affichée. * +* binary = représentation du binaire chargé en mémoire. * +* addr = localisation à venir ajouter à la liste. * +* hint = éventuel symbole à venir retrouver à l'adresse. * +* * +* Description : Ajoute une nouvelle localisation de destination. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void add_new_location_to_list(GtkTreeStore *store, GLoadedBinary *binary, const vmpa2t *addr, GBinSymbol *hint) +{ + GCodeBuffer *buffer; /* Tampon de désassemblage */ + GBufferLine *line; /* Ligne présente à l'adresse */ + char *virtual; /* Transcription d'adresse */ + const char *label; /* Etiquette de symbole trouvé */ + GBinFormat *format; /* Format associé au binaire */ + GBinSymbol *symbol; /* Symbole associé à l'adresse */ + phys_t diff; /* Décalage vis à vis du début */ + char *name; /* Désignation humaine */ + gchar *filename; /* Chemin d'accès à utiliser */ + cairo_surface_t *icon; /* Image pour les symboles */ + char *content; /* Contenu de la ligne visée */ + GtkTreeIter iter; /* Point d'insertion */ + + /* Adresse en mémoire virtuelle */ + + buffer = g_loaded_binary_get_disassembled_buffer(binary); + line = g_code_buffer_find_line_by_addr(buffer, addr, BLF_HAS_CODE, NULL); + + if (line != NULL) + virtual = g_buffer_line_get_text(line, BLC_VIRTUAL, BLC_VIRTUAL + 1, true); + else + virtual = strdup(_("<line address not found>")); + + /* Désignation humaine de l'adresse */ + + if (hint != NULL) + { + symbol = hint; + g_object_ref(G_OBJECT(symbol)); + + label = g_binary_symbol_get_label(hint); + + name = make_symbol_offset(label, 0); + + } + else + { + format = G_BIN_FORMAT(g_loaded_binary_get_format(binary)); + + if (g_binary_format_resolve_symbol(format, addr, &symbol, &diff)) + { + label = g_binary_symbol_get_label(symbol); + + /** + * Un symbole ne possède pas toujours d'étiquette. + * C'est le cas par exemple pour les valeurs chargées par + * les instructions ARM de type 'ldr'. + */ + if (label == NULL) + name = strdup(_("<no symbol found>")); + + else + name = make_symbol_offset(label, diff); + + } + else + { + symbol = NULL; + + name = strdup(_("<no symbol found>")); + + } + + } + + /* Image de représentation */ + + if (symbol == NULL) + filename = NULL; + + else + switch (g_binary_symbol_get_target_type(symbol)) + { + case STP_ENTRY_POINT: + filename = find_pixmap_file("entrypoint.png"); + break; + + default: + filename = NULL; + break; + + } + + if (filename != NULL) + { + icon = cairo_image_surface_create_from_png(filename); + g_free(filename); + } + else + icon = NULL; + + /* Contenu d'assemblage */ + + if (line != NULL) + content = g_buffer_line_get_text(line, BLC_ASSEMBLY_HEAD, BLC_COUNT, true); + else + content = strdup(_("<assembly line not found>")); + + /* Insertion finale */ + + gtk_tree_store_append(store, &iter, NULL); + + gtk_tree_store_set(store, &iter, + GXC_PHYSICAL, PHYS_CAST(get_phy_addr(addr)), + GXC_VIRTUAL, VIRT_CAST(get_virt_addr(addr)), + GXC_PICTURE, icon, + GXC_ADDRESS, virtual, + GXC_NAME, name, + GXC_CONTENT, content, + -1); + + if (symbol != NULL) + g_object_unref(G_OBJECT(symbol)); + + if (virtual != NULL) free(virtual); + if (icon != NULL) cairo_surface_destroy(icon); + free(name); + if (content != NULL) free(content); + + if (line != NULL) + g_object_unref(G_OBJECT(line)); + +} + + +/****************************************************************************** +* * +* 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 ou NULL si rien.* +* * +* Remarques : - * +* * +******************************************************************************/ + +vmpa2t *get_address_from_gotox_dialog(GtkWidget *dialog) +{ + vmpa2t *result; /* Adresse à retourner */ + GtkTreeView *treeview; /* Liste d'adresses à lire */ + GtkTreeSelection *selection; /* Sélection courante */ + GtkTreeModel *model; /* Modèle de gestionnaire */ + GList *selected; /* Liste des sélections */ + GtkTreeIter iter; /* Tête de lecture */ + G_TYPE_PHYS phys; /* Position physique */ + G_TYPE_VIRT virt; /* Adresse virtuelle */ + + treeview = GTK_TREE_VIEW(g_object_get_data(G_OBJECT(dialog), "treeview")); + + selection = gtk_tree_view_get_selection(treeview); + + selected = gtk_tree_selection_get_selected_rows(selection, &model); + if (selected == NULL) return NULL; + + if (!gtk_tree_model_get_iter(model, &iter, (GtkTreePath *)selected->data)) + return NULL; + + gtk_tree_model_get(model, &iter, + GXC_PHYSICAL, &phys, + GXC_VIRTUAL, &virt, + -1); + + result = make_vmpa(phys, virt); + + g_list_free_full(selected, (GDestroyNotify)gtk_tree_path_free); + + return result; + +} diff --git a/src/gui/dialogs/gotox.h b/src/gui/dialogs/gotox.h new file mode 100644 index 0000000..ab17d42 --- /dev/null +++ b/src/gui/dialogs/gotox.h @@ -0,0 +1,47 @@ + +/* Chrysalide - 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 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 _GUI_DIALOGS_GOTOX_H +#define _GUI_DIALOGS_GOTOX_H + + +#include <gtk/gtk.h> + + +#include "../../analysis/binary.h" +#include "../../arch/vmpa.h" + + + +/* Construit la fenêtre de sélection des points d'entrée. */ +GtkWidget *create_gotox_dialog_for_entry_points(GtkWindow *, GLoadedBinary *); + +/* Construit la fenêtre de sélection des références croisées. */ +GtkWidget *create_gotox_dialog_for_cross_references(GtkWindow *, GLoadedBinary *, const GArchInstruction *, bool); + +/* Fournit l'adresse obtenue par la saisie de l'utilisateur. */ +vmpa2t *get_address_from_gotox_dialog(GtkWidget *); + + + +#endif /* _GUI_DIALOGS_GOTOX_H */ diff --git a/src/gui/dialogs/plugins.c b/src/gui/dialogs/plugins.c new file mode 100644 index 0000000..68e6011 --- /dev/null +++ b/src/gui/dialogs/plugins.c @@ -0,0 +1,313 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * plugins.c - boîte de dialogue permettant une sélection des greffons + * + * Copyright (C) 2010-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/>. + */ + + +#include "plugins.h" + + +#include <i18n.h> + + +#include "../../gtkext/easygtk.h" + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : binary = informations sur le binaire actuellement ouvert. * +* 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_plugins_selection_dialog(GLoadedBinary *binary, GtkWindow *parent) +{ + GtkWidget *result; /* Fenêtre à renvoyer */ + GObject *ref; /* Espace de référencements */ + + + + + GtkWidget *vbox1; + GtkWidget *hbox3; + GtkWidget *scrolledwindow1; + GtkWidget *treeview1; + GtkWidget *vbox2; + GtkWidget *vbuttonbox1; + GtkWidget *button7; + GtkWidget *image3; + GtkWidget *button8; + GtkWidget *image4; + GtkWidget *hseparator1; + GtkWidget *vbuttonbox2; + GtkWidget *button9; + GtkWidget *image5; + GtkWidget *button10; + GtkWidget *image6; + GtkWidget *scrolledwindow2; + GtkWidget *treeview2; + GtkWidget *expander1; + GtkWidget *hbox4; + GtkWidget *vbox3; + GtkWidget *label; /* Etiquette d'introduction */ + GtkWidget *label8; + GtkWidget *label9; + GtkWidget *label10; + GtkWidget *frame1; + GtkWidget *label12; + GtkWidget *label11; + GtkWidget *label3; + GtkWidget *hseparator2; + GtkWidget *hbuttonbox1; + GtkWidget *button1; + GtkWidget *hbox1; + GtkWidget *image1; + GtkWidget *label1; + GtkWidget *button2; + GtkWidget *hbox2; + GtkWidget *image2; + GtkWidget *label2; + + result = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_set_size_request(result, 600, 400); + gtk_container_set_border_width(GTK_CONTAINER(result), 8); + gtk_window_set_title(GTK_WINDOW(result), _("Plugins selection")); + gtk_window_set_transient_for(GTK_WINDOW(result), parent); + gtk_window_set_default_size(GTK_WINDOW(result), 600, 400); + gtk_window_set_type_hint(GTK_WINDOW(result), GDK_WINDOW_TYPE_HINT_DIALOG); + + ref= G_OBJECT(result); + g_object_set_data(ref, "binary", binary); + + + + + vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + gtk_widget_show(vbox1); + gtk_container_add(GTK_CONTAINER(result), vbox1); + gtk_container_set_border_width(GTK_CONTAINER(vbox1), 8); + + hbox3 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + gtk_widget_show(hbox3); + gtk_box_pack_start(GTK_BOX(vbox1), hbox3, TRUE, TRUE, 0); + + scrolledwindow1 = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_show(scrolledwindow1); + gtk_box_pack_start(GTK_BOX(hbox3), scrolledwindow1, TRUE, TRUE, 0); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow1), GTK_SHADOW_IN); + + treeview1 = gtk_tree_view_new(); + gtk_widget_show(treeview1); + gtk_container_add(GTK_CONTAINER(scrolledwindow1), treeview1); + + vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + gtk_widget_show(vbox2); + gtk_box_pack_start(GTK_BOX(hbox3), vbox2, FALSE, FALSE, 0); + + vbuttonbox1 = gtk_button_box_new(GTK_ORIENTATION_VERTICAL); + gtk_widget_show(vbuttonbox1); + gtk_box_pack_start(GTK_BOX(vbox2), vbuttonbox1, FALSE, FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(vbuttonbox1), 8); + gtk_button_box_set_layout(GTK_BUTTON_BOX(vbuttonbox1), GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(vbuttonbox1), 8); + + button7 = gtk_button_new(); + gtk_widget_show(button7); + gtk_container_add(GTK_CONTAINER(vbuttonbox1), button7); + + image3 = gtk_image_new_from_icon_name("gtk-add", GTK_ICON_SIZE_BUTTON); + gtk_widget_show(image3); + gtk_container_add(GTK_CONTAINER(button7), image3); + + button8 = gtk_button_new(); + gtk_widget_show(button8); + gtk_container_add(GTK_CONTAINER(vbuttonbox1), button8); + + image4 = gtk_image_new_from_icon_name("gtk-remove", GTK_ICON_SIZE_BUTTON); + gtk_widget_show(image4); + gtk_container_add(GTK_CONTAINER(button8), image4); + + hseparator1 = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL); + gtk_widget_show(hseparator1); + gtk_box_pack_start(GTK_BOX(vbox2), hseparator1, FALSE, FALSE, 0); + + vbuttonbox2 = gtk_button_box_new(GTK_ORIENTATION_VERTICAL); + gtk_widget_show(vbuttonbox2); + gtk_box_pack_start(GTK_BOX(vbox2), vbuttonbox2, FALSE, FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(vbuttonbox2), 8); + gtk_box_set_spacing(GTK_BOX(vbuttonbox2), 8); + + button9 = gtk_button_new(); + gtk_widget_show(button9); + gtk_container_add(GTK_CONTAINER(vbuttonbox2), button9); + + image5 = gtk_image_new_from_icon_name("gtk-go-up", GTK_ICON_SIZE_BUTTON); + gtk_widget_show(image5); + gtk_container_add(GTK_CONTAINER(button9), image5); + + button10 = gtk_button_new(); + gtk_widget_show(button10); + gtk_container_add(GTK_CONTAINER(vbuttonbox2), button10); + + image6 = gtk_image_new_from_icon_name("gtk-go-down", GTK_ICON_SIZE_BUTTON); + gtk_widget_show(image6); + gtk_container_add(GTK_CONTAINER(button10), image6); + + scrolledwindow2 = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_show(scrolledwindow2); + gtk_box_pack_start(GTK_BOX(hbox3), scrolledwindow2, TRUE, TRUE, 0); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow2), GTK_SHADOW_IN); + + treeview2 = gtk_tree_view_new(); + gtk_widget_show(treeview2); + gtk_container_add(GTK_CONTAINER(scrolledwindow2), treeview2); + + expander1 = gtk_expander_new(NULL); + gtk_widget_show(expander1); + gtk_box_pack_start(GTK_BOX(vbox1), expander1, FALSE, FALSE, 0); + gtk_expander_set_expanded(GTK_EXPANDER(expander1), TRUE); + + hbox4 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + gtk_widget_show(hbox4); + gtk_container_add(GTK_CONTAINER(expander1), hbox4); + + vbox3 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + gtk_widget_show(vbox3); + gtk_box_pack_start(GTK_BOX(hbox4), vbox3, TRUE, TRUE, 0); + + label = qck_create_label(NULL, NULL, _("Author:")); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(vbox3), label, FALSE, FALSE, 0); + + label8 = gtk_label_new(_("label8")); + gtk_widget_show(label8); + gtk_box_pack_start(GTK_BOX(vbox3), label8, FALSE, FALSE, 0); + + label = qck_create_label(NULL, NULL, _("Version:")); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(vbox3), label, FALSE, FALSE, 0); + + label9 = gtk_label_new(_("label9")); + gtk_widget_show(label9); + gtk_box_pack_start(GTK_BOX(vbox3), label9, FALSE, FALSE, 0); + + label = qck_create_label(NULL, NULL, _("URL:")); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(vbox3), label, FALSE, FALSE, 0); + + label10 = gtk_label_new(_("label10")); + gtk_widget_show(label10); + gtk_box_pack_start(GTK_BOX(vbox3), label10, FALSE, FALSE, 0); + + frame1 = gtk_frame_new(NULL); + gtk_widget_show(frame1); + gtk_box_pack_start(GTK_BOX(hbox4), frame1, TRUE, TRUE, 0); + gtk_frame_set_shadow_type(GTK_FRAME(frame1), GTK_SHADOW_NONE); + + label12 = gtk_label_new(_("label12")); + qck_set_alignment(label12, GTK_ALIGN_CENTER, GTK_ALIGN_CENTER); + qck_set_margins(label12, 0, 0, 12, 0); + gtk_widget_show(label12); + gtk_container_add(GTK_CONTAINER(frame1), label12); + + label11 = gtk_label_new(_("<b>Action</b>")); + gtk_widget_show(label11); + gtk_frame_set_label_widget(GTK_FRAME(frame1), label11); + gtk_label_set_use_markup(GTK_LABEL(label11), TRUE); + + label3 = gtk_label_new(_("<b>Details:</b>")); + gtk_widget_show(label3); + gtk_expander_set_label_widget(GTK_EXPANDER(expander1), label3); + gtk_label_set_use_markup(GTK_LABEL(label3), TRUE); + + hseparator2 = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL); + gtk_widget_show(hseparator2); + gtk_box_pack_start(GTK_BOX(vbox1), hseparator2, FALSE, FALSE, 0); + + hbuttonbox1 = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL); + gtk_widget_show(hbuttonbox1); + gtk_box_pack_start(GTK_BOX(vbox1), hbuttonbox1, FALSE, FALSE, 0); + gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox1), GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(hbuttonbox1), 8); + + button1 = gtk_button_new(); + gtk_widget_show(button1); + gtk_container_add(GTK_CONTAINER(hbuttonbox1), button1); + + hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + qck_set_alignment(hbox1, GTK_ALIGN_CENTER, GTK_ALIGN_CENTER); + gtk_widget_show(hbox1); + gtk_container_add(GTK_CONTAINER(button1), hbox1); + + image1 = gtk_image_new_from_icon_name("gtk-apply", GTK_ICON_SIZE_BUTTON); + gtk_widget_show(image1); + gtk_box_pack_start(GTK_BOX(hbox1), image1, FALSE, FALSE, 0); + + label1 = gtk_label_new_with_mnemonic(_("Apply")); + gtk_widget_show(label1); + gtk_box_pack_start(GTK_BOX(hbox1), label1, FALSE, FALSE, 0); + + button2 = gtk_button_new(); + gtk_widget_show(button2); + gtk_container_add(GTK_CONTAINER(hbuttonbox1), button2); + + hbox2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + qck_set_alignment(hbox2, GTK_ALIGN_CENTER, GTK_ALIGN_CENTER); + gtk_widget_show(hbox2); + gtk_container_add(GTK_CONTAINER(button2), hbox2); + + image2 = gtk_image_new_from_icon_name("gtk-cancel", GTK_ICON_SIZE_BUTTON); + gtk_widget_show(image2); + gtk_box_pack_start(GTK_BOX(hbox2), image2, FALSE, FALSE, 0); + + label2 = gtk_label_new_with_mnemonic(_("Cancel")); + gtk_widget_show(label2); + gtk_box_pack_start(GTK_BOX(hbox2), label2, FALSE, FALSE, 0); + + + + + + + return result; + +} + + + + + + + + diff --git a/src/gui/dialogs/plugins.h b/src/gui/dialogs/plugins.h new file mode 100644 index 0000000..44e1d48 --- /dev/null +++ b/src/gui/dialogs/plugins.h @@ -0,0 +1,40 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * plugins.h - prototypes pour la boîte de dialogue permettant une sélection des greffons + * + * Copyright (C) 2010-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 _GUI_DIALOGS_PLUGINS_H +#define _GUI_DIALOGS_PLUGINS_H + + +#include <gtk/gtk.h> + + +#include "../../analysis/binary.h" + + + +/* Construit la fenêtre de sélection des sections. */ +GtkWidget *create_plugins_selection_dialog(GLoadedBinary *, GtkWindow *); + + + +#endif /* _GUI_DIALOGS_PLUGINS_H */ diff --git a/src/gui/dialogs/shellcode.c b/src/gui/dialogs/shellcode.c new file mode 100644 index 0000000..8466ab2 --- /dev/null +++ b/src/gui/dialogs/shellcode.c @@ -0,0 +1,803 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * export.c - assistant d'exportation de contenu binaire + * + * Copyright (C) 2011-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 "shellcode.h" + + +#include <i18n.h> + + +#include <malloc.h> +#include <regex.h> +#include <stdio.h> +#include <string.h> + + +#include "../../gtkext/easygtk.h" + + + + +#include "../../analysis/roptions.h" // A garder ? + + + + + + +/* ------------------------ PARTIE PRINCIPALE DE L'ASSISTANT ------------------------ */ + + +/* Ferme l'assistant sans dérouler la procédure. */ +static void export_assistant_cancel(GtkAssistant *, gpointer); + +/* Ferme l'assistant et déroule la procédure. */ +static void export_assistant_close(GtkAssistant *, GObject *); + + + +/* -------------------------- RECUPERATION DU CODE BINAIRE -------------------------- */ + + +/* Ajoute le panneau de consitution du code binaire. */ +static void register_bincode_panel(GtkAssistant *); + +/* Fournit si possible le code binaire utilisateur. */ +static bool extract_shell_code(GObject *, bin_t **, off_t *); + +/* Réagit à une modification du code binaire. */ +static void on_bincode_changed(GtkTextBuffer *, GObject *); + + + +/* ----------------------- DEFINITION DE L'ARCHITECTURE VISEE ----------------------- */ + + +/* Ajoute le panneau de spécification de l'architecture. */ +static void register_archi_panel(GtkAssistant *); + + + + + +/* -------------------- DEFINITION DES REGLAGES DE L'EXPORTATION -------------------- */ + + +/* Ajoute le panneau de choix du type de sortie. */ +static void register_output_panel(GtkAssistant *); + +/* Réagit un changement du nom de fichier pour l'exportation. */ +static void on_export_filename_changed(GtkEntry *, GtkAssistant *); + +/* Sélectionne ou non un nouveau fichier de sortie. */ +static void on_filename_browsing_clicked(GtkButton *, GObject *); + + + +/* ------------------------- SELECTION DU CONTENU A TRAITER ------------------------- */ + + +/* Ajoute le panneau de sélection du contenu à exporter. */ +static void register_content_panel(GtkAssistant *); + + + +/* ---------------------------------------------------------------------------------- */ +/* PARTIE PRINCIPALE DE L'ASSISTANT */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : project = projet courant à compléter. * +* parent = fenêtre principale de l'éditeur. * +* * +* Description : Crée et affiche un assistant d'ajout de binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void run_shellcode_assistant(GStudyProject *project, GtkWindow *parent) +{ + GtkWidget *assistant; /* Fenêtre à afficher */ + GObject *ref; /* Espace de référencement */ + + assistant = gtk_assistant_new(); + gtk_widget_set_size_request(assistant, 450, 300); + gtk_window_set_position(GTK_WINDOW(assistant), GTK_WIN_POS_CENTER); + gtk_window_set_title(GTK_WINDOW(assistant), _("Shellcode assistant")); + + gtk_window_set_modal(GTK_WINDOW(assistant), TRUE); + gtk_window_set_transient_for(GTK_WINDOW(assistant), parent); + + ref = G_OBJECT(assistant); + //g_object_set_data(ref, "binary", binary); + + register_bincode_panel(GTK_ASSISTANT(assistant)); + register_archi_panel(GTK_ASSISTANT(assistant)); + //register_output_panel(GTK_ASSISTANT(assistant)); + //register_content_panel(GTK_ASSISTANT(assistant)); + + g_signal_connect(G_OBJECT(assistant), "cancel", G_CALLBACK(export_assistant_cancel), NULL); + g_signal_connect(G_OBJECT(assistant), "close", G_CALLBACK(export_assistant_close), ref); + + gtk_widget_show_all(assistant); + +} + + +/****************************************************************************** +* * +* Paramètres : assistant = fenêtre à compléter et référencement global. * +* data = adresse non utilisée ici. * +* * +* Description : Ferme l'assistant sans dérouler la procédure. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void export_assistant_cancel(GtkAssistant *assistant, gpointer data) +{ + gtk_widget_destroy(GTK_WIDGET(assistant)); + +} + + +/****************************************************************************** +* * +* Paramètres : assistant = fenêtre à compléter et référencement global. * +* ref = adresse de l'espace de référencement global. * +* * +* Description : Ferme l'assistant et déroule la procédure. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void export_assistant_close(GtkAssistant *assistant, GObject *ref) +{ + GLoadedBinary *binary; /* Binaire chargé à parcourir */ + GExeFormat *format; /* Format du binaire */ + GRenderingOptions *options; /* Options d'exportation */ + GtkToggleButton *checkbutton; /* Coche à retrouver */ + gboolean state; /* Valeur à prendre en compte */ + GtkEntry *entry; /* Zone de saisie */ + const gchar *filename; /* Chemin d'accès du fichier */ + + //binary = G_LOADED_BINARY(g_object_get_data(ref, "binary")); + + format = g_loaded_binary_get_format(binary); + options = g_rendering_options_new(format); + + /* Eléments à afficher */ + + checkbutton = GTK_TOGGLE_BUTTON(g_object_get_data(ref, "virtual_addr")); + state = gtk_toggle_button_get_active(checkbutton); + g_rendering_options_show_address(options, MRD_BLOCK, state); + + checkbutton = GTK_TOGGLE_BUTTON(g_object_get_data(ref, "binary_code")); + state = gtk_toggle_button_get_active(checkbutton); + g_rendering_options_show_code(options, MRD_BLOCK, state); + + checkbutton = GTK_TOGGLE_BUTTON(g_object_get_data(ref, "assembly_code")); + state = gtk_toggle_button_get_active(checkbutton); + + /* Programmation de la tâche */ + /* + entry = GTK_ENTRY(g_object_get_data(ref, "filename")); + filename = gtk_entry_get_text(entry); + + export = g_delayed_export_new(filename, binary, options); + + queue = get_work_queue(); + g_work_queue_schedule_work(queue, G_DELAYED_WORK(export)); + */ + gtk_widget_destroy(GTK_WIDGET(assistant)); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* RECUPERATION DU CODE BINAIRE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : assistant = fenêtre à compléter et référencement global. * +* * +* Description : Ajoute le panneau de consitution du code binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void register_bincode_panel(GtkAssistant *assistant) +{ + GtkWidget *vbox; /* Support principal */ + GtkWidget *scrolledwindow; /* Support avec défilement */ + GtkWidget *textview; /* Zone de texte */ + GtkWidget *label; /* Etiquette du bilan */ + + vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + qck_set_margins(vbox, 8, 8, 8, 8); + gtk_widget_show(vbox); + + /* Réception du code */ + + label = qck_create_label(NULL, NULL, _("Paste here the raw C code containing the shellcode.\r\n" + "All content between quotes will be extracted.")); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); + + scrolledwindow = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_show(scrolledwindow); + gtk_box_pack_start(GTK_BOX(vbox), scrolledwindow, TRUE, TRUE, 0); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow), GTK_SHADOW_IN); + + textview = qck_create_textview(G_OBJECT(assistant), "bincode", + G_CALLBACK(on_bincode_changed), assistant); + gtk_container_add(GTK_CONTAINER(scrolledwindow), textview); + + /* Validation */ + + label = qck_create_label(G_OBJECT(assistant), "status", _("No code")); + gtk_widget_set_halign(label, GTK_ALIGN_CENTER); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); + + /* Intégration */ + + gtk_assistant_append_page(assistant, vbox); + gtk_assistant_set_page_title(assistant, vbox, _("Code")); + gtk_assistant_set_page_type(assistant, vbox, GTK_ASSISTANT_PAGE_INTRO); + + gtk_assistant_set_page_complete(assistant, vbox, TRUE); + +} + + +/****************************************************************************** +* * +* Paramètres : ref = espace de référencement global. * +* code = code binaire recomposé. [OUT] * +* length = taille de ce code. [OUT] * +* * +* Description : Fournit si possible le code binaire utilisateur. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool extract_shell_code(GObject *ref, bin_t **code, off_t *length) +{ + bool result; /* Bilan à retourner */ + GtkTextView *textview; /* Zone de texte */ + GtkTextBuffer *buffer; /* Tampon gérant le texte */ + GtkTextIter start; /* Début de la zone à traiter */ + GtkTextIter end; /* Fin de la zone à traiter */ + gchar *bincode; /* Code à filtrer */ + regex_t preg; /* Recherche d'un bloc */ + int ret; /* Bilan d'un appel */ + regoff_t pos; /* Point de départ de lecture */ + regmatch_t pmatch[3]; /* Localisation de trouvailles */ + regoff_t i; /* Boucle de parcours */ + char hex[3]; /* Valeur hexadécimale */ + + result = true; + + *code = NULL; + *length = 0; + + /* Détermination des cibles */ + + ret = regcomp(&preg, "[^'\"]*(['\"])([^'\"]*)\\1", REG_EXTENDED); + if (ret != 0) return false; + + /* Constitution du contexte */ + + textview = GTK_TEXT_VIEW(g_object_get_data(ref, "bincode")); + buffer = gtk_text_view_get_buffer(textview); + + gtk_text_buffer_get_bounds(buffer, &start, &end); + bincode = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); + + /* Recomposition du code */ + + pos = 0; + + ret = regexec(&preg, &bincode[pos], 3, pmatch, 0); + + while (ret != REG_NOMATCH && result) + { + bincode[pos + pmatch[2].rm_eo] = '\0'; + + for (i = pos + pmatch[2].rm_so; i < (pos + pmatch[2].rm_eo) && result; i++) + { + *code = (bin_t *)realloc(*code, ++(*length) * sizeof(bin_t)); + + switch (bincode[i]) + { + case '\\': + if (++i >= (pos + pmatch[2].rm_eo)) + { + result = false; + break; + } + + if (bincode[i] == 'x') + { + if (++i >= (pos + pmatch[2].rm_eo)) + { + result = false; + break; + } + + if ((i + 2) > (pos + pmatch[2].rm_eo)) + { + result = false; + break; + } + + memcpy(hex, &bincode[i], 2); + hex[2] = '\0'; + + (*code)[*length - 1] = strtol(hex, NULL, 16); + + i++; + + } + else (*code)[*length - 1] = bincode[i]; + + break; + + default: + (*code)[*length - 1] = bincode[i]; + break; + + } + + } + + if (result) + { + pos += pmatch[2].rm_eo + 1; + ret = regexec(&preg, &bincode[pos], 3, pmatch, 0); + } + + } + + g_free(bincode); + + if (!result && *code != NULL) + { + *length = 0; + free(*code); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : textbuffer = composant concerné par l'action. * +* ref = espace de référencement global. * +* * +* Description : Réagit à une modification du code binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_bincode_changed(GtkTextBuffer *textbuffer, GObject *ref) +{ + bin_t *code; /* Code binaire extrait */ + off_t length; /* Taille des données lues */ + bool status; /* Bilan de l'extraction */ + GtkLabel *label; /* Etiquette à mettre à jour */ + char *markup; /* Affichage étendu */ + GtkAssistant *assistant; /* Assistant en première ligne */ + gint index; /* Indice de la page courante */ + GtkWidget *page; /* Cotenu de la page courante */ + + status = extract_shell_code(ref, &code, &length); + + label = GTK_LABEL(g_object_get_data(ref, "status")); + + if (!status) + gtk_label_set_markup(label, _("<span color=\"red\"><b>Error while decoding</b></span>")); + + else if (length > 0) + { + markup = g_markup_printf_escaped(_("<span color=\"#00cc00\"><b>Decoding OK (" + OFF_FMT " %s)</b></span>"), + OFF_CAST(length), length > 1 ? _("bytes") : _("byte")); + gtk_label_set_markup(label, markup); + g_free(markup); + } + + else + { + gtk_label_set_markup(label, _("No code")); + status = false; + } + + if (length > 0) + free(code); + + /* Poursuite des opérations ? */ + + assistant = GTK_ASSISTANT(ref); + + index = gtk_assistant_get_current_page(assistant); + page = gtk_assistant_get_nth_page(assistant, index); + + gtk_assistant_set_page_complete(assistant, page, status); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION DE L'ARCHITECTURE VISEE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : assistant = fenêtre à compléter et référencement global. * +* * +* Description : Ajoute le panneau de spécification de l'architecture. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void register_archi_panel(GtkAssistant *assistant) +{ + GtkWidget *vbox; /* Support principal */ + GtkWidget *label; /* Etiquette d'indication */ + GtkWidget *combobox; /* Sélection du format */ + + vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + qck_set_margins(vbox, 8, 8, 8, 8); + gtk_widget_show(vbox); + + /* Choix de l'architecture */ + + label = qck_create_label(NULL, NULL, _("Architecture:")); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); + + combobox = qck_create_combobox(G_OBJECT(assistant), "archi", G_CALLBACK(NULL), NULL); + gtk_box_pack_start(GTK_BOX(vbox), combobox, TRUE, FALSE, 0); + + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combobox), _("x86")); + + gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), 0); + + /* Taille de registre */ + + label = qck_create_label(NULL, NULL, _("Register size:")); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); + + combobox = qck_create_combobox(G_OBJECT(assistant), "rsize", G_CALLBACK(NULL), NULL); + gtk_box_pack_start(GTK_BOX(vbox), combobox, TRUE, FALSE, 0); + + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combobox), _("32 bits")); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combobox), _("16 bits")); + + gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), 0); + + /* Intégration */ + + gtk_assistant_append_page(assistant, vbox); + gtk_assistant_set_page_title(assistant, vbox, _("Architecture")); + gtk_assistant_set_page_type(assistant, vbox, GTK_ASSISTANT_PAGE_CONFIRM); + + gtk_assistant_set_page_complete(assistant, vbox, TRUE); + +} + + + + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION DES REGLAGES DE L'EXPORTATION */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : assistant = fenêtre à compléter et référencement global. * +* * +* Description : Ajoute le panneau de choix du type de sortie. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void register_output_panel(GtkAssistant *assistant) +{ + GtkWidget *vbox; /* Support principal #1 */ + GtkWidget *hbox; /* Support principal #2 */ + GtkWidget *label; /* Etiquette d'indication */ + GtkWidget *combobox; /* Sélection du format */ + GtkWidget *entry; /* Zone de saisie de texte */ + GtkWidget *button; /* Sélection de fichier */ + GLoadedBinary *binary; /* Binaire chargé à parcourir */ + const char *filename; /* Chemin d'accès par défaut */ + + vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + qck_set_margins(vbox, 8, 8, 8, 8); + gtk_widget_show(vbox); + + /* Format de sortie */ + + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + + label = qck_create_label(NULL, NULL, _("Format : ")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + combobox = qck_create_combobox(NULL, NULL, G_CALLBACK(NULL), NULL); + gtk_box_pack_start(GTK_BOX(hbox), combobox, TRUE, TRUE, 0); + + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combobox), _("Simple text")); + + gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), 0); + + /* Fichier de sortie */ + + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + + label = qck_create_label(NULL, NULL, _("File : ")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + entry = qck_create_entry(G_OBJECT(assistant), "filename", NULL); + gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); + + button = qck_create_button(NULL, NULL, "...", G_CALLBACK(on_filename_browsing_clicked), assistant); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); + + /* Intégration */ + + gtk_assistant_append_page(assistant, vbox); + gtk_assistant_set_page_title(assistant, vbox, _("Output")); + gtk_assistant_set_page_type(assistant, vbox, GTK_ASSISTANT_PAGE_CONTENT); + + gtk_assistant_set_page_complete(assistant, vbox, TRUE); + + /* Choix par défaut */ + /* + binary = G_LOADED_BINARY(g_object_get_data(G_OBJECT(assistant), "binary")); + filename = g_loaded_binary_get_name(binary); + + gtk_entry_set_text(GTK_ENTRY(entry), filename); + gtk_entry_append_text(GTK_ENTRY(entry), ".txt"); + + g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(on_export_filename_changed), assistant); + */ +} + + +/****************************************************************************** +* * +* Paramètres : entry = zone de texte dont le contenu vient de changer. * +* assistant = fenêtre affichée et référencement global. * +* * +* Description : Réagit un changement du nom de fichier pour l'exportation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_export_filename_changed(GtkEntry *entry, GtkAssistant *assistant) +{ + const gchar *text; /* Texte saisi dans la zone */ + gint num; /* Etape courante */ + GtkWidget *page; /* Support de cette étape */ + + text = gtk_entry_get_text(entry); + + num = gtk_assistant_get_current_page(assistant); + page = gtk_assistant_get_nth_page(assistant, num); + + gtk_assistant_set_page_complete(assistant, page, (strlen(text) > 0)); + +} + + +/****************************************************************************** +* * +* Paramètres : button = bouton d'édition de la sélection. * +* ref = espace de référencement principal. * +* * +* Description : Sélectionne ou non un nouveau fichier de sortie. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_filename_browsing_clicked(GtkButton *button, GObject *ref) +{ + GtkWidget *dialog; /* Boîte à afficher */ + gchar *filename; /* Nom du fichier à intégrer */ + GtkEntry *entry; /* Zone de saisie à maj. */ + + dialog = gtk_file_chooser_dialog_new(_("Choose an output filename"), GTK_WINDOW(ref), + GTK_FILE_CHOOSER_ACTION_SAVE, + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_Save"), GTK_RESPONSE_ACCEPT, + NULL); + + entry = GTK_ENTRY(g_object_get_data(ref, "filename")); + gtk_file_chooser_set_filename(dialog, gtk_entry_get_text(entry)); + + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) + { + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + + gtk_entry_set_text(GTK_ENTRY(entry), filename); + + g_free(filename); + + } + + gtk_widget_destroy(dialog); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* SELECTION DU CONTENU A TRAITER */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : assistant = fenêtre à compléter et référencement global. * +* * +* Description : Ajoute le panneau de sélection du contenu à exporter. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void register_content_panel(GtkAssistant *assistant) +{ + GtkWidget *vbox; /* Support principal */ + GtkWidget *frame; /* Support avec encadrement */ + GtkWidget *subvbox; /* Support secondaire */ + GtkWidget *checkbutton; /* Coche pour une option */ + + vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + qck_set_margins(vbox, 8, 8, 8, 8); + gtk_widget_show(vbox); + + /* Lignes à traiter */ + + subvbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + gtk_widget_show(subvbox); + + frame = qck_create_frame(_("<b>Lines to process</b>"), subvbox, 0, 0, 12, 0); + gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0); + + checkbutton = qck_create_check_button(G_OBJECT(assistant), "prologue", _("Prologue"), NULL, NULL); + gtk_box_pack_start(GTK_BOX(subvbox), checkbutton, FALSE, FALSE, 0); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TRUE); + + checkbutton = qck_create_check_button(G_OBJECT(assistant), "code", _("Code"), NULL, NULL); + gtk_box_pack_start(GTK_BOX(subvbox), checkbutton, FALSE, FALSE, 0); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TRUE); + + checkbutton = qck_create_check_button(G_OBJECT(assistant), "comments", _("Comments"), NULL, NULL); + gtk_box_pack_start(GTK_BOX(subvbox), checkbutton, FALSE, FALSE, 0); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TRUE); + + /* Eléments à afficher */ + + subvbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + gtk_widget_show(subvbox); + + frame = qck_create_frame(_("<b>Items to display</b>"), subvbox, 0, 0, 12, 0); + gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0); + + checkbutton = qck_create_check_button(G_OBJECT(assistant), "virtual_addr", _("Virtual address"), NULL, NULL); + gtk_box_pack_start(GTK_BOX(subvbox), checkbutton, FALSE, FALSE, 0); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TRUE); + + checkbutton = qck_create_check_button(G_OBJECT(assistant), "binary_code", _("Binary code"), NULL, NULL); + gtk_box_pack_start(GTK_BOX(subvbox), checkbutton, FALSE, FALSE, 0); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TRUE); + + checkbutton = qck_create_check_button(G_OBJECT(assistant), "assembly_code", _("Assembly code"), NULL, NULL); + gtk_box_pack_start(GTK_BOX(subvbox), checkbutton, FALSE, FALSE, 0); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TRUE); + + /* Intégration */ + + gtk_assistant_append_page(assistant, vbox); + gtk_assistant_set_page_title(assistant, vbox, _("Exported content")); + gtk_assistant_set_page_type(assistant, vbox, GTK_ASSISTANT_PAGE_CONFIRM); + + gtk_assistant_set_page_complete(assistant, vbox, TRUE); + +} + + + + + + + + + /* Choix par défaut */ + /* + binary = G_LOADED_BINARY(g_object_get_data(G_OBJECT(assistant), "binary")); + filename = g_loaded_binary_get_name(binary); + + gtk_entry_set_text(GTK_ENTRY(entry), filename); + gtk_entry_append_text(GTK_ENTRY(entry), ".txt"); + + g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(on_export_filename_changed), assistant); + */ + + + diff --git a/src/gui/dialogs/shellcode.h b/src/gui/dialogs/shellcode.h new file mode 100644 index 0000000..776b7a6 --- /dev/null +++ b/src/gui/dialogs/shellcode.h @@ -0,0 +1,37 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * export.h - prototypes pour l'assistant d'exportation de contenu binaire + * + * Copyright (C) 2011-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/>. + */ + + +#ifndef _GUI_DIALOGS_EXPORT_H +#define _GUI_DIALOGS_EXPORT_H + + +#include "../../analysis/project.h" + + + +/* Crée et affiche un assistant d'ajout de binaire. */ +void run_shellcode_assistant(GStudyProject *, GtkWindow *); + + + +#endif /* _GUI_DIALOGS_EXPORT_H */ diff --git a/src/gui/dialogs/storage.c b/src/gui/dialogs/storage.c new file mode 100644 index 0000000..2e97ca2 --- /dev/null +++ b/src/gui/dialogs/storage.c @@ -0,0 +1,648 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * storage.c - définition des modes d'enregistrement pour binaires + * + * Copyright (C) 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 "storage.h" + + +#include <i18n.h> + + +#include "../../analysis/db/protocol.h" +#include "../../common/cpp.h" +#include "../../gtkext/easygtk.h" + + + +/* --------------------------- CORPS PRINCIPAL DU CONTENU --------------------------- */ + + +/* Enumération des colonnes de la liste affichée */ +typedef enum StorageColumnTypes +{ + SCT_FEATURE_ID, /* Désignation interne */ + SCT_FEATURE_NAME, /* Désignation humaine */ + SCT_FEATURE_STORAGE, /* Type d'enregistrement */ + SCT_COMBO_COLUMN, /* Fonctionnement du combo */ + + SCT_COUNT + +} StorageColumnTypes; + + +/* Construit l'affichage en liste des enregistrements. */ +static GtkWidget *build_features_list(void); + +/* Sauvegarde l'état des enregistrements et clôt la fenêtre. */ +static void save_storage_params(GtkButton *, GObject *); + + + +/* ---------------------- NOM D'UTILISATEUR ASSOCIE AU BINAIRE ---------------------- */ + + +/* Charge le nom de l'utilisateur associé au binaire. */ +static void load_storage_username(GLoadedBinary *, GObject *); + +/* Sauvegarde le nom de l'utilisateur associé au binaire. */ +static void save_storage_username(GLoadedBinary *, GObject *); + + + +/* ----------------------- SERVEUR DISTANT ASSOCIE AU BINAIRE ----------------------- */ + + +/* Charge la définition du serveur distant associé au binaire. */ +static void load_storage_remote_server(GLoadedBinary *, GObject *); + +/* Sauvegarde la définition du serveur distant du binaire. */ +static void save_storage_remote_server(GLoadedBinary *, GObject *); + +/* Met à jour l'accès aux paramètres du serveur distant. */ +static void on_server_usage_toggle(GtkToggleButton *, GObject *); + + + +/* ------------------------- TRAITEMENT DES FONCTIONNALITES ------------------------- */ + + +/* Remplit la vue présentant les fonctionnalités à traiter. */ +static void fill_storage_features(GtkTreeView *, GLoadedBinary *); + +/* Sauvegarde les statuts d'enregistrement des fonctionnalités. */ +static void save_storage_features(GLoadedBinary *, GObject *); + +/* Met à jour un type d'enregistrement. */ +static void storage_combo_edited_cb(GtkCellRendererText *, const gchar *, const gchar *, GtkListStore *); + + + +/* ---------------------------------------------------------------------------------- */ +/* CORPS PRINCIPAL DU CONTENU */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Construit l'affichage en liste des enregistrements. * +* * +* Retour : Composant graphique prêt à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GtkWidget *build_features_list(void) +{ + GtkListStore *store; + GtkWidget *view; + GtkCellRenderer *renderer; + GtkListStore *combo_store; + GtkTreeIter iter; + + store = gtk_list_store_new(SCT_COUNT, + G_TYPE_UINT, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_UINT); + + view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); + + g_object_unref(store); + + /* Intitulé des fonctionnalités */ + + renderer = gtk_cell_renderer_text_new(); + + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1, + _("Features"), renderer, + "text", SCT_FEATURE_NAME, + NULL); + + /* Type d'enregistrement associé */ + + renderer = gtk_cell_renderer_combo_new(); + + combo_store = gtk_list_store_new(1, G_TYPE_STRING); + gtk_list_store_append(combo_store, &iter); + gtk_list_store_set(combo_store, &iter, 0, _("Local storage"), -1); + gtk_list_store_append(combo_store, &iter); + gtk_list_store_set(combo_store, &iter, 0, _("Remote storage"), -1); + gtk_list_store_append(combo_store, &iter); + gtk_list_store_set(combo_store, &iter, 0, _("Local storage with remote access"), -1); + + g_object_set(G_OBJECT(renderer), "model", combo_store, + "editable", TRUE, "has-entry", FALSE, NULL); + g_signal_connect(G_OBJECT(renderer), "edited", G_CALLBACK(storage_combo_edited_cb), store); + + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1, + _("Storage"), renderer, + "text", SCT_FEATURE_STORAGE, + "text-column", SCT_COMBO_COLUMN, + NULL); + + return view; + +} + + +/****************************************************************************** +* * +* Paramètres : binary = binaire chargé en mémoire à traiter. * +* parent = fenêtre principale de l'éditeur. * +* * +* Description : Propose une définition des propriétés d'enregistrement. * +* * +* Retour : Adresse de la fenêtre mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *create_storage_dialog(GLoadedBinary *binary, GtkWindow *parent) +{ + GtkWidget *result; /* Fenêtre à renvoyer */ + GtkWidget *content; /* Zone principale de la boîte */ + GtkWidget *vbox; /* Support à construire #1 */ + GtkWidget *frame; /* Support avec encadrement */ + GtkWidget *hbox; /* Support à construire #2 */ + GtkWidget *label; /* Etiquette d'indication */ + GtkWidget *entry; /* Zone de saisie de texte */ + GtkWidget *checkbutton; /* Activation de la distance */ + GtkWidget *subvbox; /* Support à construire #3 */ + GtkWidget *scrolledwindow; /* Zone de défilement */ + GtkWidget *treeview; /* Liste des fonctionnalités */ + + result = gtk_dialog_new(); + gtk_window_set_title(GTK_WINDOW(result), _("Storage")); + gtk_widget_set_size_request(result, 400, 360); + gtk_window_set_position(GTK_WINDOW(result), GTK_WIN_POS_CENTER); + gtk_window_set_type_hint(GTK_WINDOW(result), GDK_WINDOW_TYPE_HINT_DIALOG); + + gtk_window_set_modal(GTK_WINDOW(result), TRUE); + gtk_window_set_transient_for(GTK_WINDOW(result), parent); + + g_object_ref(G_OBJECT(binary)); + g_object_set_data_full(G_OBJECT(result), "binary", binary, g_object_unref); + + content = gtk_dialog_get_content_area(GTK_DIALOG(result)); + gtk_widget_show(content); + + vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + gtk_widget_show(vbox); + gtk_box_pack_start(GTK_BOX(content), vbox, TRUE, TRUE, 0); + gtk_container_set_border_width(GTK_CONTAINER(vbox), 8); + + /* Définition de l'identité de l'utilisateur */ + + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4); + gtk_widget_show(hbox); + + frame = qck_create_frame(_("<b>Identity</b>"), hbox, 0, 0, 12, 0); + gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, TRUE, 0); + + label = qck_create_label(NULL, NULL, _("Username: ")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + entry = qck_create_entry(G_OBJECT(result), "username", NULL); + gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); + + /* Définition du serveur distant */ + + subvbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_widget_show(subvbox); + + frame = qck_create_frame(_("<b>Server to contact</b>"), subvbox, 0, 0, 12, 0); + gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, TRUE, 0); + + checkbutton = qck_create_check_button(G_OBJECT(result), "use_remote", + _("Use a remote server:"), + G_CALLBACK(on_server_usage_toggle), result); + gtk_widget_show(checkbutton); + gtk_box_pack_start(GTK_BOX(subvbox), checkbutton, FALSE, FALSE, 0); + + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(subvbox), hbox, TRUE, TRUE, 0); + + label = qck_create_label(G_OBJECT(result), "host", _("Host: ")); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + entry = qck_create_entry(G_OBJECT(result), "remote_host", NULL); + gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); + + label = qck_create_label(G_OBJECT(result), "port", _("Port:")); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + entry = qck_create_entry(G_OBJECT(result), "remote_port", NULL); + gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, TRUE, 0); + + /* Affichage des propriétés */ + + scrolledwindow = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_show(scrolledwindow); + gtk_box_pack_start(GTK_BOX(vbox), scrolledwindow, TRUE, TRUE, 0); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow), GTK_SHADOW_IN); + + treeview = build_features_list(); + g_object_set_data(G_OBJECT(result), "treeview", treeview); + gtk_widget_show(treeview); + gtk_container_add(GTK_CONTAINER(scrolledwindow), treeview); + + /* Zone de contrôle */ + + gtk_dialog_add_button(GTK_DIALOG(result), _("_Cancel"), GTK_RESPONSE_CANCEL); + gtk_dialog_add_button(GTK_DIALOG(result), _("_Ok"), GTK_RESPONSE_OK); + + /* Chargement des données actuelles */ + + load_storage_username(binary, G_OBJECT(result)); + + load_storage_remote_server(binary, G_OBJECT(result)); + + fill_storage_features(GTK_TREE_VIEW(treeview), binary); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : button = bouton 'OK'. * +* ref = espace de référencement principal. * +* * +* Description : Sauvegarde l'état des enregistrements et clôt la fenêtre. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void save_storage_params(GtkButton *button, GObject *ref) +{ + GLoadedBinary *binary; /* Binaire en cours d'édition */ + + binary = G_LOADED_BINARY(g_object_get_data(ref, "binary")); + + save_storage_username(binary, ref); + + save_storage_remote_server(binary, ref); + + save_storage_features(binary, ref); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* NOM D'UTILISATEUR ASSOCIE AU BINAIRE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : binary = binaire chargé en mémoire à traiter. * +* ref = espace de référencement global. * +* * +* Description : Charge le nom de l'utilisateur associé au binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void load_storage_username(GLoadedBinary *binary, GObject *ref) +{ + GtkEntry *entry; /* Zone de saisie de texte */ + + entry = GTK_ENTRY(g_object_get_data(ref, "username")); + + gtk_entry_set_text(entry, g_loaded_binary_get_username(binary)); + +} + + +/****************************************************************************** +* * +* Paramètres : binary = binaire chargé en mémoire à traiter. * +* ref = espace de référencement global. * +* * +* Description : Sauvegarde le nom de l'utilisateur associé au binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void save_storage_username(GLoadedBinary *binary, GObject *ref) +{ + GtkEntry *entry; /* Zone de saisie de texte */ + const gchar *text; /* Texte à récupérer */ + + entry = GTK_ENTRY(g_object_get_data(ref, "username")); + text = gtk_entry_get_text(entry); + + g_loaded_binary_set_username(binary, text); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* SERVEUR DISTANT ASSOCIE AU BINAIRE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : binary = binaire chargé en mémoire à traiter. * +* ref = espace de référencement global. * +* * +* Description : Charge la définition du serveur distant associé au binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void load_storage_remote_server(GLoadedBinary *binary, GObject *ref) +{ + const char *host; /* Hôte à contacter */ + unsigned short port; /* Port de connexion */ + char port_str[sizeof(XSTR(USHRT_MAX)) + 1]; /* Version chaînée */ + bool use_remote; /* Utilisation du serveur ? */ + GtkEntry *entry; /* Zone de saisie de texte */ + GtkToggleButton *checkbutton; /* Activation de la distance */ + + use_remote = g_loaded_binary_get_remote_server(binary, &host, &port); + sprintf(port_str, "%hu", port); + + entry = GTK_ENTRY(g_object_get_data(ref, "remote_host")); + + gtk_entry_set_text(entry, host); + + entry = GTK_ENTRY(g_object_get_data(ref, "remote_port")); + + gtk_entry_set_text(entry, port_str); + + checkbutton = GTK_TOGGLE_BUTTON(g_object_get_data(ref, "use_remote")); + + gtk_toggle_button_set_active(checkbutton, !use_remote); + gtk_toggle_button_set_active(checkbutton, use_remote); + +} + + +/****************************************************************************** +* * +* Paramètres : binary = binaire chargé en mémoire à traiter. * +* ref = espace de référencement global. * +* * +* Description : Sauvegarde la définition du serveur distant du binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void save_storage_remote_server(GLoadedBinary *binary, GObject *ref) +{ + GtkEntry *entry; /* Zone de saisie de texte */ + const gchar *text; /* Texte à récupérer */ + unsigned short port; /* Port de connexion */ + GtkToggleButton *checkbutton; /* Activation de la distance */ + + entry = GTK_ENTRY(g_object_get_data(ref, "remote_port")); + text = gtk_entry_get_text(entry); + port = atoi(text); + + entry = GTK_ENTRY(g_object_get_data(ref, "remote_host")); + text = gtk_entry_get_text(entry); + + checkbutton = GTK_TOGGLE_BUTTON(g_object_get_data(ref, "use_remote")); + + g_loaded_binary_set_remote_server(binary, text, port, + gtk_toggle_button_get_active(checkbutton)); + +} + + +/****************************************************************************** +* * +* Paramètres : button = oche dont le status vient de changer. * +* ref = espace de référencement global. * +* * +* Description : Met à jour l'accès aux paramètres du serveur distant. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_server_usage_toggle(GtkToggleButton *button, GObject *ref) +{ + gboolean state; /* Etat du bouton courant */ + GtkWidget *widget; /* Element dont l'accès change */ + + state = gtk_toggle_button_get_active(button); + + widget = GTK_WIDGET(g_object_get_data(ref, "host")); + if (widget != NULL) + gtk_widget_set_sensitive(widget, state); + + widget = GTK_WIDGET(g_object_get_data(ref, "remote_host")); + if (widget != NULL) + gtk_widget_set_sensitive(widget, state); + + widget = GTK_WIDGET(g_object_get_data(ref, "port")); + if (widget != NULL) + gtk_widget_set_sensitive(widget, state); + + widget = GTK_WIDGET(g_object_get_data(ref, "remote_port")); + if (widget != NULL) + gtk_widget_set_sensitive(widget, state); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* TRAITEMENT DES FONCTIONNALITES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : treeview = vue à compléter. * +* binary = binaire à manipuler. * +* * +* Description : Remplit la vue présentant les fonctionnalités à traiter. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void fill_storage_features(GtkTreeView *treeview, GLoadedBinary *binary) +{ + GtkListStore *store; /* Gestionnaire de liste */ + DBFeatures i; /* Boucle de parcours */ + DBStorage storage; /* Type d'enregistrement */ + char *human_feature; /* Description humaine #1 */ + char *human_value; /* Description humaine #2 */ + GtkTreeIter iter; /* Point d'insertion */ + + store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview)); + + for (i = 0; i < DBF_COUNT; i++) + { + storage = g_loaded_binary_get_storage(binary, i); + + switch (i) + { + case DBF_COMMENTS: + human_feature = _("Comments"); + break; + case DBF_DISPLAY_SWITCHERS: + human_feature = _("Segments display"); + break; + case DBF_BOOKMARKS: + human_feature = _("Bookmarks"); + break; + default: /* Pour GCC... */ + break; + } + + switch (storage) + { + case DBS_ALL_LOCAL: + human_value = _("Local storage"); + break; + case DBS_ALL_REMOTE: + human_value = _("Remote storage"); + break; + case DBS_LOCAL_AND_REMOTE: + human_value = _("Local storage with remote access"); + break; + } + + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + SCT_FEATURE_ID, i, + SCT_FEATURE_NAME, human_feature, + SCT_FEATURE_STORAGE, human_value, + -1); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : binary = binaire chargé en mémoire à traiter. * +* ref = espace de référencement global. * +* * +* Description : Sauvegarde les statuts d'enregistrement des fonctionnalités. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void save_storage_features(GLoadedBinary *binary, GObject *ref) +{ + GtkTreeView *treeview; /* Liste des fonctionnalités */ + GtkTreeModel *store; /* Gestionnaire de liste */ + GtkTreeIter iter; /* Point de lecture */ + gboolean valid; /* Point courant valide ? */ + DBFeatures feature; /* Fonctionnalité traitée */ + char *human_value; /* Description humaine */ + DBStorage storage; /* Type d'enregistrement */ + + treeview = GTK_TREE_VIEW(g_object_get_data(ref, "treeview")); + store = GTK_TREE_MODEL(gtk_tree_view_get_model(treeview)); + + for (valid = gtk_tree_model_get_iter_first(store, &iter); + valid; + valid = gtk_tree_model_iter_next(store, &iter)) + { + gtk_tree_model_get(store, &iter, + SCT_FEATURE_ID, &feature, + SCT_FEATURE_STORAGE, &human_value, + -1); + + if (g_strcmp0(human_value, _("Remote storage")) == 0) + storage = DBS_ALL_REMOTE; + else if (g_strcmp0(human_value, _("Local storage with remote access")) == 0) + storage = DBS_LOCAL_AND_REMOTE; + else + storage = DBS_ALL_LOCAL; + + g_loaded_binary_set_storage(binary, feature, storage); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : cell = cellule du tableau à mettre à jour. * +* path = chemin d'accès à l'élément concerné. * +* value = nouvelle valeur à prendre en compte. * +* store = gestionnaire de liste sur lequel s'appuyer. * +* * +* Description : Met à jour un type d'enregistrement. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void storage_combo_edited_cb(GtkCellRendererText *cell, const gchar *path, const gchar *value, GtkListStore *store) +{ + GtkTreePath *tpath; /* Chemin instancié */ + GtkTreeIter iter; /* Point d'accès pour la maj */ + + tpath = gtk_tree_path_new_from_string(path); + + if (gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, tpath)) + gtk_list_store_set(store, &iter, SCT_FEATURE_STORAGE, value, -1); + + gtk_tree_path_free(tpath); + +} diff --git a/src/gui/dialogs/storage.h b/src/gui/dialogs/storage.h new file mode 100644 index 0000000..5cca73b --- /dev/null +++ b/src/gui/dialogs/storage.h @@ -0,0 +1,40 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * storage.h - prototypes pour la définition des modes d'enregistrement pour binaires + * + * Copyright (C) 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/>. + */ + + +#ifndef _GUI_DIALOGS_STORAGE_H +#define _GUI_DIALOGS_STORAGE_H + + +#include <gtk/gtk.h> + + +#include "../../analysis/binary.h" + + + +/* Propose une définition des propriétés d'enregistrement. */ +GtkWidget *create_storage_dialog(GLoadedBinary *, GtkWindow *); + + + +#endif /* _GUI_DIALOGS_STORAGE_H */ |