summaryrefslogtreecommitdiff
path: root/plugins/ropgadgets/select.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-05-11 00:58:05 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-05-11 00:58:05 (GMT)
commit46bcc7f122245f22772fd3e38d16e6afa7bd5881 (patch)
treed3c2ba1a9999e373428954f24d0e60c1ea63b756 /plugins/ropgadgets/select.c
parent1bda6c517d30d873ff0d92a96380946ef944c9ae (diff)
Provided a way to look for ROP gadgets in binary code.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@533 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'plugins/ropgadgets/select.c')
-rw-r--r--plugins/ropgadgets/select.c1845
1 files changed, 1845 insertions, 0 deletions
diff --git a/plugins/ropgadgets/select.c b/plugins/ropgadgets/select.c
new file mode 100644
index 0000000..2889eb5
--- /dev/null
+++ b/plugins/ropgadgets/select.c
@@ -0,0 +1,1845 @@
+
+/* 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 "select.h"
+
+
+#include <fcntl.h>
+#include <malloc.h>
+#include <regex.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+
+#include <i18n.h>
+
+
+#include <project.h>
+#include <common/cpp.h>
+#include <common/extstr.h>
+#include <core/formats.h>
+#include <core/processors.h>
+#include <gtkext/easygtk.h>
+
+
+#include "finder.h"
+
+
+
+/* ------------------------ PARTIE PRINCIPALE DE L'ASSISTANT ------------------------ */
+
+
+/* Colonnes de la liste des binaires */
+typedef enum _CurrentProjectBinaries
+{
+ CPB_BINARY, /* Instance GLib du bianire */
+ CPB_FILENAME, /* Chemin d'accès au fichier */
+
+ CPB_COUNT /* Nombre de colonnes */
+
+} CurrentProjectBinaries;
+
+
+/* Ferme l'assistant sans dérouler la procédure. */
+static void rop_finder_assistant_cancel(GtkAssistant *, gpointer);
+
+/* Ferme l'assistant et déroule la procédure. */
+static void rop_finder_assistant_apply(GtkAssistant *, GObject *);
+
+/* Accompagne le chargement de certaines pages de l'assistant. */
+static void rop_finder_assistant_prepare(GtkAssistant *, GtkWidget *, GObject *);
+
+
+
+/* ------------------------ DEFINITION DES ENTREES / SORTIES ------------------------ */
+
+
+/* Ajoute le panneau de choix quant aux fichiers d'E/S. */
+static void register_input_output_panel(GtkAssistant *, GObject *);
+
+/* Construit la sélection d'un binaire déjà chargé. */
+static GtkWidget *load_and_populate_current_project_binaries(GObject *);
+
+/* Met à jour l'accès à la sélection du type d'entrée. */
+static void on_input_type_toggle(GtkToggleButton *, GObject *);
+
+/* Réagit à un changement de sélection du binaire d'entrée. */
+static void on_loaded_binary_selection_change(GtkComboBox *, GObject *);
+
+/* Réagit à un changement de fichier binaire d'entrée. */
+static void on_input_filename_change(GtkEditable *, GObject *);
+
+/* Sélectionne ou non un nouveau fichier d'entrée. */
+static void on_input_filename_browsing_clicked(GtkButton *, GObject *);
+
+/* Met à jour l'accès à la définition d'un fichier de sortie. */
+static void on_output_need_toggle(GtkToggleButton *, GObject *);
+
+/* Sélectionne ou non un nouveau fichier de sortie. */
+static void on_output_filename_browsing_clicked(GtkButton *, GObject *);
+
+
+
+/* ------------------------- SUIVI DE LA PHASE DE RECHERCHE ------------------------- */
+
+
+/* Ajoute le panneau de suivi des opérations de recherche. */
+static void register_search_display_panel(GtkAssistant *, GObject *);
+
+/* Initialise une ligne de rapport quant aux opérations menées. */
+static void init_rop_search_step(GtkGrid *, gint, GObject *, const char *, const char *, GtkWidget *);
+
+/* Réinitialise tous les rapports de recherches imprimés. */
+static void reset_rop_search_steps(GObject *);
+
+
+/* Description d'une évolution du processus */
+typedef struct _search_step
+{
+ GObject *ref; /* Espace de référencements */
+
+ union
+ {
+ struct
+ {
+ const char *key; /* Clef d'accès partielle */
+ bool dynamic; /* Mémoire à libérer ? */
+ union
+ {
+ const char *msg; /* Message de conclusion */
+ char *dmsg; /* Message de conclusion */
+ };
+ bool success; /* Indication claire */
+ };
+
+ gdouble fraction; /* Avancée du désasssemblage */
+
+ struct
+ {
+ GBinFormat *format; /* Format binaire chargé */
+ found_rop_list *list; /* Liste de gadgets ROP trouvés*/
+ size_t count; /* Nombre de gadgets trouvés */
+ };
+
+ };
+
+} search_step;
+
+
+/* Affiche un message de statut quant aux recherches en cours. */
+static gboolean print_status_of_rop_search_step(search_step *);
+
+/* Affiche un message de statut quant aux recherches en cours. */
+static void push_status_printing_of_rop_search_step(GObject *, const char *, const char *, bool);
+
+/* Affiche un message de statut quant aux recherches en cours. */
+static void push_dyn_status_printing_of_rop_search_step(GObject *, const char *, char *, bool);
+
+/* Actualise la barre de progression affichée. */
+static gboolean update_progress_bar_fraction(search_step *);
+
+/* Lance l'actualisation de la barre de progression affichée. */
+static void push_new_progress_fraction(GObject *, gdouble);
+
+/* Enregistre une référence vers les gadgets trouvés. */
+static gboolean register_found_rop_gadgets(search_step *);
+
+/* Lance une conservation des gadgets trouvés. */
+static void push_found_rop_gadgets(GObject *, GBinFormat *, found_rop_list *, size_t);
+
+/* Charge un format binaire interne déjà chargé. */
+static GBinFormat *load_internal_format_for_rop_gadgets(GObject *);
+
+/* Charge un format binaire externe. */
+static GBinFormat *load_external_format_for_rop_gadgets(GObject *);
+
+/* Procède à la recherche de gadgets de façon séparée. */
+static gpointer look_for_rop_gadgets(GObject *);
+
+
+
+/* ----------------------- MISE EN FORME DES GADGETS PRESENTS ----------------------- */
+
+
+/* Colonnes de la liste des symboles */
+typedef enum _FoundROPGadget
+{
+ FRG_CATEGORY, /* Catégorie d'appartenance */
+ FRG_RAW_VIRTUAL, /* Correspondance virtuelle */
+ FRG_RAW, /* Brut pour recherche */
+
+ FRG_VIRTUAL, /* Correspondance virtuelle */
+ FRG_CONTENT, /* Contenu des lignes visées */
+
+ FRG_COUNT /* Nombre de colonnes */
+
+} FoundROPGadget;
+
+
+/* Ajoute le panneau de sélection des gadgets ROP identifiés. */
+static void register_rop_list_panel(GtkAssistant *, GObject *);
+
+/* Lance l'actualisation du filtrage des gadgets ROP. */
+static void on_rop_gadgets_category_changed(GtkComboBox *, GObject *);
+
+/* Lance l'actualisation du filtrage des gadgets ROP. */
+static void on_rop_gadgets_filter_changed(GtkSearchEntry *, GObject *);
+
+/* Détermine la visibilité de tel ou tel gadget ROP. */
+static gboolean filter_visible_rop_gadgets(GtkTreeModel *, GtkTreeIter *, GObject *);
+
+/* Ajoute de nouvelles chaînes de gadgets localisées. */
+static void add_new_gadgets_for_category(GBinFormat *, GtkComboBoxText *, GtkTreeStore *, const char *, GArchInstruction **, size_t);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* PARTIE PRINCIPALE DE L'ASSISTANT */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : global = espace de référencements global. *
+* parent = fenêtre principale de l'éditeur. *
+* *
+* Description : Crée et affiche un assistant de sélection de gadgets ROP. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void run_rop_finder_assistant(GObject *global, GtkWindow *parent)
+{
+ GtkWidget *assistant; /* Fenêtre à afficher */
+ GObject *ref; /* Espace de référencement */
+
+ assistant = gtk_assistant_new();
+ gtk_widget_set_size_request(assistant, 900, 550);
+ 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, "global", global);
+
+ register_input_output_panel(GTK_ASSISTANT(assistant), ref);
+ register_search_display_panel(GTK_ASSISTANT(assistant), ref);
+ register_rop_list_panel(GTK_ASSISTANT(assistant), ref);
+
+ g_signal_connect(G_OBJECT(assistant), "cancel", G_CALLBACK(rop_finder_assistant_cancel), NULL);
+ g_signal_connect(G_OBJECT(assistant), "close", G_CALLBACK(rop_finder_assistant_cancel), NULL);
+ g_signal_connect(G_OBJECT(assistant), "apply", G_CALLBACK(rop_finder_assistant_apply), ref);
+ g_signal_connect(G_OBJECT(assistant), "prepare", G_CALLBACK(rop_finder_assistant_prepare), ref);
+
+ gtk_widget_show_all(assistant);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : assistant = fenêtre d'assistance à traiter. *
+* data = adresse non utilisée ici. *
+* *
+* Description : Ferme l'assistant sans dérouler la procédure. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void rop_finder_assistant_cancel(GtkAssistant *assistant, gpointer data)
+{
+ gtk_widget_destroy(GTK_WIDGET(assistant));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : assistant = fenêtre d'assistance à traiter. *
+* ref = adresse de l'espace de référencement global. *
+* *
+* Description : Ferme l'assistant et déroule la procédure. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void rop_finder_assistant_apply(GtkAssistant *assistant, GObject *ref)
+{
+ GtkEntry *entry; /* Zone de saisie */
+ const gchar *filename; /* Chemin d'accès du fichier */
+ int fd; /* Flux ouvert en écriture */
+ GtkTreeView *treeview; /* Arborescence à actualiser */
+ GtkTreeModel *model; /* Modèle de gestion */
+ GtkTreeIter iter; /* Boucle de parcours */
+ gboolean loop; /* Poursuite de la boucle ? */
+ gchar *virtual; /* Adresse correspondante */
+ gchar *raw; /* ROP en format texte simple */
+
+ /* Fichier de sortie */
+
+ entry = GTK_ENTRY(g_object_get_data(ref, "output_filename"));
+ filename = gtk_entry_get_text(entry);
+
+ fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR);
+ if (fd == -1)
+ {
+ perror("open");
+ return;
+ }
+
+ /* Boucle de parcours */
+
+ treeview = GTK_TREE_VIEW(g_object_get_data(ref, "treeview"));
+ model = gtk_tree_view_get_model(treeview);
+
+ for (loop = gtk_tree_model_get_iter_first(model, &iter);
+ loop;
+ loop = gtk_tree_model_iter_next(model, &iter))
+ {
+ gtk_tree_model_get(model, &iter, FRG_RAW_VIRTUAL, &virtual, FRG_RAW, &raw, -1);
+
+ dprintf(fd, "%s\t%s\n", virtual, raw);
+
+ g_free(virtual);
+ g_free(raw);
+
+ }
+
+ /* Conclusion */
+
+ close(fd);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : assistant = fenêtre d'assistance à traiter. *
+* page = élément de l'assistant à préparer. *
+* ref = adresse de l'espace de référencement global. *
+* *
+* Description : Accompagne le chargement de certaines pages de l'assistant. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void rop_finder_assistant_prepare(GtkAssistant *assistant, GtkWidget *page, GObject *ref)
+{
+ GtkWidget *test; /* Reconnaissance à l'aveugle */
+ GThread *thread; /* Tâche de fond à programmer */
+
+ test = gtk_assistant_get_nth_page(assistant, 1);
+
+ if (test == page)
+ {
+ reset_rop_search_steps(ref);
+
+ thread = g_thread_new("gadgets_finder", (GThreadFunc)look_for_rop_gadgets, ref);
+ g_thread_unref(thread);
+
+ }
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION DES ENTREES / SORTIES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : assistant = fenêtre d'assistance à compléter. *
+* ref = espace de référencements inter-panneaux. *
+* *
+* Description : Ajoute le panneau de choix quant aux fichiers d'E/S. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void register_input_output_panel(GtkAssistant *assistant, GObject *ref)
+{
+ GtkWidget *vbox; /* Support principal */
+ GtkWidget *frame; /* Support avec encadrement */
+ GtkWidget *alignment; /* Disposition sur le support */
+ GtkWidget *sub_vbox; /* Division verticale */
+ GtkWidget *radio; /* Choix du type d'entrée */
+ GtkWidget *combobox; /* Sélection du binaire interne*/
+ GtkWidget *sub_hbox; /* Division horizontale */
+ GtkWidget *entry; /* Zone de saisie de texte */
+ GtkWidget *button; /* Sélection de fichier */
+ GtkWidget *checkbutton; /* Coche pour une option */
+
+ vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 16);
+ gtk_widget_show(vbox);
+
+ /* Fichier de sortie */
+
+ frame = qck_create_frame(_("<b>Input binary</b>"), &alignment, 0, 0, 12, 8);
+ gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, TRUE, 0);
+
+ sub_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+ gtk_widget_show(sub_vbox);
+ gtk_container_add(GTK_CONTAINER(alignment), sub_vbox);
+
+ radio = qck_create_radio_button(ref, "loaded_as_input", _("Use a binary from the current project:"),
+ NULL, G_CALLBACK(on_input_type_toggle), ref);
+ gtk_box_pack_start(GTK_BOX(sub_vbox), radio, FALSE, FALSE, 0);
+
+ combobox = load_and_populate_current_project_binaries(ref);
+ gtk_box_pack_start(GTK_BOX(sub_vbox), combobox, TRUE, TRUE, 0);
+
+ radio = qck_create_radio_button(ref, "extern_as_input", _("Open a new binary file:"),
+ GTK_RADIO_BUTTON(radio), G_CALLBACK(on_input_type_toggle), ref);
+ gtk_box_pack_start(GTK_BOX(sub_vbox), radio, FALSE, FALSE, 0);
+
+ sub_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
+ gtk_widget_show(sub_hbox);
+ gtk_box_pack_start(GTK_BOX(sub_vbox), sub_hbox, FALSE, FALSE, 0);
+
+ entry = qck_create_entry(ref, "input_filename", NULL);
+ g_signal_connect(entry, "changed", G_CALLBACK(on_input_filename_change), ref);
+ gtk_box_pack_start(GTK_BOX(sub_hbox), entry, TRUE, TRUE, 0);
+
+ button = qck_create_button(ref, "input_browser", _("Browse..."),
+ G_CALLBACK(on_input_filename_browsing_clicked), assistant);
+ gtk_box_pack_start(GTK_BOX(sub_hbox), button, FALSE, FALSE, 0);
+
+ /* Actualisation des accès */
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE);
+ on_input_type_toggle(GTK_TOGGLE_BUTTON(radio), ref);
+
+ /* Fichier de sortie */
+
+ frame = qck_create_frame(_("<b>Ouput results</b>"), &alignment, 0, 0, 12, 8);
+ gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, TRUE, 0);
+
+ sub_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+ gtk_widget_show(sub_vbox);
+ gtk_container_add(GTK_CONTAINER(alignment), sub_vbox);
+
+ checkbutton = qck_create_check_button(ref, "use_output",
+ _("Save selected ROP gadgets in a file:"),
+ G_CALLBACK(on_output_need_toggle), ref);
+ gtk_widget_show(checkbutton);
+
+ gtk_box_pack_start(GTK_BOX(sub_vbox), checkbutton, FALSE, FALSE, 0);
+
+ sub_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
+ gtk_widget_show(sub_hbox);
+ gtk_box_pack_start(GTK_BOX(sub_vbox), sub_hbox, FALSE, TRUE, 0);
+
+ entry = qck_create_entry(ref, "output_filename", NULL);
+ gtk_box_pack_start(GTK_BOX(sub_hbox), entry, TRUE, TRUE, 0);
+
+ button = qck_create_button(ref, "output_browser", _("Browse..."),
+ G_CALLBACK(on_output_filename_browsing_clicked), assistant);
+ gtk_box_pack_start(GTK_BOX(sub_hbox), button, FALSE, FALSE, 0);
+
+ /* Actualisation des accès */
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), FALSE);
+ on_output_need_toggle(GTK_TOGGLE_BUTTON(checkbutton), ref);
+
+ /* Intégration */
+
+ gtk_assistant_append_page(assistant, vbox);
+ gtk_assistant_set_page_title(assistant, vbox, _("Input / output"));
+ gtk_assistant_set_page_type(assistant, vbox, GTK_ASSISTANT_PAGE_INTRO);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ref = espace de référencements inter-panneaux. *
+* *
+* Description : Construit la sélection d'un binaire déjà chargé. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GtkWidget *load_and_populate_current_project_binaries(GObject *ref)
+{
+ GtkWidget *result; /* Composant à retourner */
+ GObject *global; /* Espace de référencements */
+ GLoadedBinary *current; /* Binaire actif courant */
+ gint selected; /* Indice à sélectionner */
+ GtkListStore *store; /* Modèle de gestion en liste */
+ GLoadedBinary **binaries; /* Liste de binaires */
+ size_t count; /* Taille de cette liste */
+ size_t i; /* Boucle de parcours */
+ GtkTreeIter iter; /* Point d'insertion */
+ GtkCellRenderer *renderer; /* Moteur de rendu de colonne */
+
+ /* Récupération du binaire courant */
+
+ global = G_OBJECT(g_object_get_data(ref, "global"));
+
+ current = G_LOADED_BINARY(g_object_get_data(global, "current_binary"));
+
+ /* Constitution d'une liste de binaires courants */
+
+ selected = -1;
+
+ store = gtk_list_store_new(CPB_COUNT, G_TYPE_OBJECT, G_TYPE_STRING);
+
+ binaries = g_study_project_get_binaries(get_current_project(), &count);
+
+ if (binaries != NULL)
+ {
+ for (i = 0; i < count; i++)
+ {
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ CPB_BINARY, binaries[i],
+ CPB_FILENAME, g_loaded_binary_get_name(binaries[i], true),
+ -1);
+
+ if (binaries[i] == current)
+ selected = i;
+
+ g_object_unref(G_OBJECT(binaries[i]));
+
+ }
+
+ free(binaries);
+
+ }
+
+ /* Mise en place d'un affichage graphique */
+
+ result = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
+ g_object_set_data(ref, "input_binary", result);
+
+ g_signal_connect(result, "changed", G_CALLBACK(on_loaded_binary_selection_change), ref);
+
+ gtk_widget_show(result);
+
+ gtk_combo_box_set_active(GTK_COMBO_BOX(result), selected);
+
+ renderer = gtk_cell_renderer_text_new();
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(result), renderer, TRUE);
+ gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(result), renderer,
+ "text", CPB_FILENAME,
+ NULL);
+
+ g_object_unref(G_OBJECT(store));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : button = oche dont le status vient de changer. *
+* ref = espace de référencements inter-panneaux. *
+* *
+* Description : Met à jour l'accès à la sélection du type d'entrée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_input_type_toggle(GtkToggleButton *button, GObject *ref)
+{
+ GtkToggleButton *internal; /* Bouton de sélection interne */
+ gboolean state; /* Etat du bouton courant */
+ GtkWidget *widget; /* Element dont l'accès change */
+
+ internal = GTK_TOGGLE_BUTTON(g_object_get_data(ref, "loaded_as_input"));
+ state = gtk_toggle_button_get_active(internal);
+
+ /* Elément de sélection interne */
+
+ widget = GTK_WIDGET(g_object_get_data(ref, "input_binary"));
+
+ if (widget != NULL)
+ {
+ gtk_widget_set_sensitive(widget, state);
+
+ if (state)
+ on_loaded_binary_selection_change(GTK_COMBO_BOX(widget), ref);
+
+ }
+
+ /* Elément de sélection externe */
+
+ widget = GTK_WIDGET(g_object_get_data(ref, "input_filename"));
+
+ if (widget != NULL)
+ {
+ gtk_widget_set_sensitive(widget, !state);
+
+ if (!state)
+ on_input_filename_change(GTK_EDITABLE(widget), ref);
+
+ }
+
+ widget = GTK_WIDGET(g_object_get_data(ref, "input_browser"));
+ if (widget != NULL)
+ gtk_widget_set_sensitive(widget, !state);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : combo = composant graphique de sélection concerné. *
+* ref = espace de référencement principal. *
+* *
+* Description : Réagit à un changement de sélection du binaire d'entrée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_loaded_binary_selection_change(GtkComboBox *combo, GObject *ref)
+{
+ gint selected; /* Indice sélectionné */
+ GtkWidget *page; /* Page de la partie terminée */
+
+ selected = gtk_combo_box_get_active(combo);
+
+ page = gtk_assistant_get_nth_page(GTK_ASSISTANT(ref), 0);
+
+ if (page != NULL)
+ gtk_assistant_set_page_complete(GTK_ASSISTANT(ref), page, selected != -1);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : editable = composant graphique d'édition concerné. *
+* ref = espace de référencement principal. *
+* *
+* Description : Réagit à un changement de fichier binaire d'entrée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_input_filename_change(GtkEditable *editable, GObject *ref)
+{
+ guint16 length; /* Taille du texte fourni */
+ GtkWidget *page; /* Page de la partie terminée */
+
+ length = gtk_entry_get_text_length(GTK_ENTRY(editable));
+
+ page = gtk_assistant_get_nth_page(GTK_ASSISTANT(ref), 0);
+
+ if (page != NULL)
+ gtk_assistant_set_page_complete(GTK_ASSISTANT(ref), page, length > 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 d'entrée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_input_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 input filename"), GTK_WINDOW(ref),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ _("_Cancel"), GTK_RESPONSE_CANCEL,
+ _("_Open"), GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ entry = GTK_ENTRY(g_object_get_data(ref, "input_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);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : button = coche dont le status vient de changer. *
+* ref = espace de référencements inter-panneaux. *
+* *
+* Description : Met à jour l'accès à la définition d'un fichier de sortie. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_output_need_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, "output_filename"));
+ if (widget != NULL)
+ gtk_widget_set_sensitive(widget, state);
+
+ widget = GTK_WIDGET(g_object_get_data(ref, "output_browser"));
+ if (widget != NULL)
+ gtk_widget_set_sensitive(widget, state);
+
+}
+
+
+/******************************************************************************
+* *
+* 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_output_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, "output_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);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* SUIVI DE LA PHASE DE RECHERCHE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : assistant = fenêtre d'assistance à compléter. *
+* ref = espace de référencements inter-panneaux. *
+* *
+* Description : Ajoute le panneau de suivi des opérations de recherche. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void register_search_display_panel(GtkAssistant *assistant, GObject *ref)
+{
+ GtkGrid *grid; /* Table de résumé */
+ GtkWidget *pbar; /* barre de progression */
+
+ grid = GTK_GRID(gtk_grid_new());
+ gtk_grid_set_column_spacing(grid, 8);
+ gtk_grid_set_row_spacing(grid, 8);
+
+ g_object_set(G_OBJECT(grid),
+ "halign", GTK_ALIGN_CENTER,
+ "valign", GTK_ALIGN_CENTER,
+ "margin-bottom", 100, NULL);
+
+ /* Représentation des étapes */
+
+ init_rop_search_step(grid, 0, ref, "loading", _("Loading the input binary..."), NULL);
+
+ init_rop_search_step(grid, 1, ref, "format", _("Detecting the proper format..."), NULL);
+
+ pbar = gtk_progress_bar_new();
+ g_object_set(G_OBJECT(pbar), "valign", GTK_ALIGN_CENTER, NULL);
+ gtk_widget_show(pbar);
+
+ init_rop_search_step(grid, 2, ref, "gadgets", _("Looking for all ROP gadgets..."), pbar);
+
+ init_rop_search_step(grid, 3, ref, "final", _("Results:"), NULL);
+
+ /* Intégration */
+
+ gtk_assistant_append_page(assistant, GTK_WIDGET(grid));
+ gtk_assistant_set_page_title(assistant, GTK_WIDGET(grid), _("Search process"));
+ gtk_assistant_set_page_type(assistant, GTK_WIDGET(grid), GTK_ASSISTANT_PAGE_PROGRESS);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ref = espace de référencements inter-panneaux. *
+* key = clef partielle d'accès aux composants concernés. *
+* info = message d'information annonçant la conclusion. *
+* pbar = éventuel composant de statut ou NULL. *
+* *
+* Description : Initialise une ligne de rapport quant aux opérations menées. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void init_rop_search_step(GtkGrid *grid, gint top, GObject *ref, const char *key, const char *info, GtkWidget *pbar)
+{
+ char *access; /* Chemin d'accès final */
+ GtkWidget *render; /* Image de statut à afficher */
+ GtkWidget *label; /* Etiquette d'indication */
+
+ /* Icone de représentation */
+
+ access = strdup("process_");
+ access = stradd(access, key);
+ access = stradd(access, "_icon");
+
+ render = gtk_image_new_from_icon_name("dialog-question", GTK_ICON_SIZE_DND);
+ g_object_set_data(ref, access, render);
+ gtk_widget_show(render);
+ gtk_grid_attach(grid, render, 0, top, 1, 1);
+
+ free(access);
+
+ /* Désignation humaine d'indicatif */
+
+ access = strdup("process_");
+ access = stradd(access, key);
+ access = stradd(access, "_caption");
+
+ label = qck_create_label(ref, access, info);
+ gtk_grid_attach(grid, label, 1, top, 1, 1);
+
+ free(access);
+
+ /* Statut final */
+
+ access = strdup("process_");
+ access = stradd(access, key);
+ access = stradd(access, "_status");
+
+ if (pbar == NULL)
+ {
+ label = qck_create_label(ref, access, "done");
+ gtk_grid_attach(grid, label, 2, top, 1, 1);
+ }
+ else
+ {
+ g_object_set_data(ref, access, pbar);
+ gtk_grid_attach(grid, pbar, 2, top, 1, 1);
+ }
+
+ free(access);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ref = espace de référencements inter-panneaux. *
+* *
+* Description : Réinitialise tous les rapports de recherches imprimés. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void reset_rop_search_steps(GObject *ref)
+{
+ size_t i; /* Boucle de parcours */
+ char *access; /* Chemin d'accès final */
+ GObject *render; /* Image de statut à afficher */
+ GtkLabel *label; /* Etiquette d'indication */
+ GtkProgressBar *pbar; /* Barre à mettre à jour */
+
+ static const char *icon_keys[] = { "loading", "format", "gadgets", "final" };
+ static const char *status_keys[] = { "loading", "format", "final" };
+
+ /* Réinitialisation des images */
+
+ for (i = 0; i < ARRAY_SIZE(icon_keys); i++)
+ {
+ access = strdup("process_");
+ access = stradd(access, icon_keys[i]);
+ access = stradd(access, "_icon");
+
+ render = G_OBJECT(g_object_get_data(ref, access));
+ g_object_set(render, "icon-name", "dialog-question", NULL);
+
+ free(access);
+
+ }
+
+ /* Statut final */
+
+ for (i = 0; i < ARRAY_SIZE(status_keys); i++)
+ {
+ access = strdup("process_");
+ access = stradd(access, status_keys[i]);
+ access = stradd(access, "_status");
+
+ label = GTK_LABEL(g_object_get_data(ref, access));
+ gtk_label_set_text(label, "");
+
+ free(access);
+
+ }
+
+ /* Progression des recherches */
+
+ pbar = GTK_PROGRESS_BAR(g_object_get_data(ref, "process_gadgets_status"));
+
+ gtk_progress_bar_set_fraction(pbar, 0.0);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : step = informations quant à l'étape avancée. *
+* *
+* Description : Affiche un message de statut quant aux recherches en cours. *
+* *
+* Retour : FALSE pour ne pas reprogrammer l'exécution de la tâche. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gboolean print_status_of_rop_search_step(search_step *step)
+{
+ char *access; /* Chemin d'accès final */
+ GObject *render; /* Image de statut à afficher */
+ GtkLabel *status; /* Bilan à faire paraître */
+
+ /* Icone de représentation */
+
+ access = strdup("process_");
+ access = stradd(access, step->key);
+ access = stradd(access, "_icon");
+
+ render = G_OBJECT(g_object_get_data(step->ref, access));
+ g_object_set(render, "icon-name", step->success ? "face-smile" : "face-sad", NULL);
+
+ free(access);
+
+ /* Mot de la fin */
+
+ if (step->msg != NULL)
+ {
+ access = strdup("process_");
+ access = stradd(access, step->key);
+ access = stradd(access, "_status");
+
+ status = GTK_LABEL(g_object_get_data(step->ref, access));
+ gtk_label_set_text(status, step->msg);
+
+ free(access);
+
+ }
+
+ /* Nettoyage final */
+
+ if (step->dynamic)
+ free(step->dmsg);
+
+ free(step);
+
+ return FALSE;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ref = espace de référencements inter-panneaux. *
+* key = clef partielle d'accès aux composants concernés. *
+* msg = message d'information accompagnant la conclusion. *
+* success = indication quant à la réussite de l'opération. *
+* *
+* Description : Affiche un message de statut quant aux recherches en cours. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void push_dyn_status_printing_of_rop_search_step(GObject *ref, const char *key, char *dmsg, bool success)
+{
+ search_step *step; /* Informations d'étape */
+
+ step = (search_step *)calloc(1, sizeof(search_step));
+
+ step->ref = ref;
+
+ step->key = key;
+ step->dynamic = true;
+ step->dmsg = dmsg;
+ step->success = success;
+
+ g_idle_add((GSourceFunc)print_status_of_rop_search_step, step);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ref = espace de référencements inter-panneaux. *
+* key = clef partielle d'accès aux composants concernés. *
+* msg = message d'information accompagnant la conclusion. *
+* success = indication quant à la réussite de l'opération. *
+* *
+* Description : Affiche un message de statut quant aux recherches en cours. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void push_status_printing_of_rop_search_step(GObject *ref, const char *key, const char *msg, bool success)
+{
+ search_step *step; /* Informations d'étape */
+
+ step = (search_step *)calloc(1, sizeof(search_step));
+
+ step->ref = ref;
+
+ step->key = key;
+ step->dynamic = false;
+ step->msg = msg;
+ step->success = success;
+
+ g_idle_add((GSourceFunc)print_status_of_rop_search_step, step);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : step = informations quant à l'étape avancée. *
+* *
+* Description : Actualise la barre de progression affichée. *
+* *
+* Retour : FALSE pour ne pas reprogrammer l'exécution de la tâche. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gboolean update_progress_bar_fraction(search_step *step)
+{
+ GtkProgressBar *pbar; /* Barre à mettre à jour */
+
+ pbar = GTK_PROGRESS_BAR(g_object_get_data(step->ref, "process_gadgets_status"));
+
+ gtk_progress_bar_set_fraction(pbar, step->fraction);
+
+ /* Nettoyage final */
+
+ free(step);
+
+ return FALSE;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ref = espace de référencements inter-panneaux. *
+* fraction = avancée globale du désassemblage en cours. *
+* *
+* Description : Lance l'actualisation de la barre de progression affichée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void push_new_progress_fraction(GObject *ref, gdouble fraction)
+{
+ search_step *step; /* Informations d'étape */
+
+ step = (search_step *)calloc(1, sizeof(search_step));
+
+ step->ref = ref;
+
+ step->fraction = fraction;
+
+ g_idle_add((GSourceFunc)update_progress_bar_fraction, step);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : step = informations quant à l'étape avancée. *
+* *
+* Description : Enregistre une référence vers les gadgets trouvés. *
+* *
+* Retour : FALSE pour ne pas reprogrammer l'exécution de la tâche. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gboolean register_found_rop_gadgets(search_step *step)
+{
+ GtkComboBoxText *combo; /* Sélection d'une catégorie */
+ GtkTreeView *treeview; /* Arborescence à actualiser */
+ GtkTreeModelFilter *filter; /* Modèle de gestion associé */
+ size_t i; /* Boucle de parcours */
+ GtkWidget *page; /* Page de la partie terminée */
+
+ /* Affichage des résulats */
+
+ if (step->format != NULL)
+ {
+ combo = GTK_COMBO_BOX_TEXT(g_object_get_data(step->ref, "filter_cat"));
+
+ treeview = GTK_TREE_VIEW(g_object_get_data(step->ref, "treeview"));
+ filter = GTK_TREE_MODEL_FILTER(gtk_tree_view_get_model(treeview));
+
+ for (i = 0; i < step->count; i++)
+ add_new_gadgets_for_category(step->format,
+ combo, GTK_TREE_STORE(gtk_tree_model_filter_get_model(filter)),
+ step->list[i].category, step->list[i].gadgets, step->list[i].count);
+
+ if (step->list != NULL)
+ free(step->list);
+
+ }
+
+ /* Déverrouillage des accès à la suite */
+
+ page = gtk_assistant_get_nth_page(GTK_ASSISTANT(step->ref), 1);
+
+ gtk_assistant_set_page_complete(GTK_ASSISTANT(step->ref), page, TRUE);
+
+ /* Nettoyage final */
+
+ free(step);
+
+ return FALSE;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ref = espace de référencements inter-panneaux. *
+* format = format binaire chargé. *
+* list = liste de liste de gadgets pour ROP. *
+* count = taille de cette liste. *
+* *
+* Description : Lance une conservation des gadgets trouvés. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void push_found_rop_gadgets(GObject *ref, GBinFormat *format, found_rop_list *list, size_t count)
+{
+ search_step *step; /* Informations d'étape */
+
+ step = (search_step *)calloc(1, sizeof(search_step));
+
+ step->ref = ref;
+
+ step->format = format;
+ step->list = list;
+ step->count = count;
+
+ g_idle_add((GSourceFunc)register_found_rop_gadgets, step);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ref = espace de référencements inter-panneaux. *
+* *
+* Description : Charge un format binaire interne déjà chargé. *
+* *
+* Retour : Nouveau format au contenu à fouiller ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GBinFormat *load_internal_format_for_rop_gadgets(GObject *ref)
+{
+ GBinFormat *result; /* Format chargé à retourner */
+ GtkComboBox *combo; /* Composant de sélection */
+ GtkTreeIter iter; /* Tête de lecture à placer */
+ GtkTreeModel *model; /* Modèle de gestion */
+ GLoadedBinary *binary; /* Binaire chargé à utiliser */
+
+ combo = GTK_COMBO_BOX(g_object_get_data(ref, "input_binary"));
+
+ if (!gtk_combo_box_get_active_iter(combo, &iter))
+ {
+ push_status_printing_of_rop_search_step(ref, "loading", _("unable to get the current binary"), false);
+ return NULL;
+ }
+
+ model = gtk_combo_box_get_model(combo);
+ gtk_tree_model_get(model, &iter, CPB_BINARY, &binary, -1);
+
+ push_status_printing_of_rop_search_step(ref, "loading", _("done"), true);
+
+ result = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
+
+ push_status_printing_of_rop_search_step(ref, "format", _("already loaded"), true);
+
+ g_object_ref(G_OBJECT(result));
+ g_object_unref(G_OBJECT(binary));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ref = espace de référencements inter-panneaux. *
+* *
+* Description : Charge un format binaire externe. *
+* *
+* Retour : Nouveau format au contenu à fouiller ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GBinFormat *load_external_format_for_rop_gadgets(GObject *ref)
+{
+ GBinFormat *result; /* Format chargé à retourner */
+ GtkEntry *entry; /* Zone de saisie de texte */
+ const gchar *filename; /* Nom du fichier à charger */
+ GBinContent *content; /* Contenu binaire chargé */
+ const char *target; /* Sous-traitance requise */
+ const char *desc; /* Description humaine associée*/
+
+ /* Récupération du nom de fichier */
+
+ entry = GTK_ENTRY(g_object_get_data(ref, "input_filename"));
+
+ filename = gtk_entry_get_text(entry);
+
+ /* Récupération du contenu binaire */
+
+ content = g_binary_content_new_from_file(filename);
+ if (content == NULL)
+ {
+ push_status_printing_of_rop_search_step(ref, "loading", _("unable to get the binary content"), false);
+ goto leffrg_error;
+ }
+
+ push_status_printing_of_rop_search_step(ref, "loading", _("done"), true);
+
+ /* Récupération du format de fichier associé */
+
+ target = find_matching_format(content);
+ desc = get_binary_format_name(target);
+
+ if (desc == NULL)
+ {
+ g_object_unref(G_OBJECT(content));
+ push_status_printing_of_rop_search_step(ref, "format", _("unknown binary format"), false);
+ goto leffrg_error;
+ }
+
+ result = load_new_named_format(target, content);
+
+ if (result == NULL)
+ {
+ push_status_printing_of_rop_search_step(ref, "format", _("error while loading the binary"), false);
+ goto leffrg_error;
+ }
+
+ push_status_printing_of_rop_search_step(ref, "format", desc, true);
+
+ return result;
+
+ leffrg_error:
+
+ return NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ref = espace de référencements inter-panneaux. *
+* *
+* Description : Procède à la recherche de gadgets de façon séparée. *
+* *
+* Retour : ? *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gpointer look_for_rop_gadgets(GObject *ref)
+{
+ GtkToggleButton *internal; /* Bouton de sélection interne */
+ gboolean state; /* Etat du bouton courant */
+ GBinFormat *format; /* Format du binaire à traiter */
+ found_rop_list *list; /* Liste de gadgets ROP trouvés*/
+ size_t count; /* Nombre de ces listes */
+ size_t found; /* Nombre de gadgets trouvés */
+ size_t i; /* Boucle de parcours */
+ char *msg; /* Message final à faire passer*/
+
+ internal = GTK_TOGGLE_BUTTON(g_object_get_data(ref, "loaded_as_input"));
+ state = gtk_toggle_button_get_active(internal);
+
+ if (state)
+ format = load_internal_format_for_rop_gadgets(ref);
+ else
+ format = load_external_format_for_rop_gadgets(ref);
+
+ if (format == NULL) goto lfrg_unlock;
+
+ list = list_all_gadgets(format, 7, push_new_progress_fraction, ref, &count);
+
+ push_status_printing_of_rop_search_step(ref, "gadgets", NULL, true);
+
+ found = 0;
+
+ for (i = 0; i < count; i++)
+ found += list[i].count;
+
+ switch (found)
+ {
+ case 0:
+ msg = strdup(_("No ROP gadget has been found."));
+ break;
+
+ case 1:
+ msg = strdup(_("1 ROP gadget has been found."));
+ break;
+
+ default:
+ asprintf(&msg, _("%zu gadgets have been found."), found);
+ break;
+
+ }
+
+ push_dyn_status_printing_of_rop_search_step(ref, "final", msg, count > 0);
+
+ lfrg_unlock:
+
+ push_found_rop_gadgets(ref, format, list, count);
+
+ return NULL;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* MISE EN FORME DES GADGETS PRESENTS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : assistant = fenêtre d'assistance à compléter. *
+* ref = espace de référencements inter-panneaux. *
+* *
+* Description : Ajoute le panneau de sélection des gadgets ROP identifiés. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void register_rop_list_panel(GtkAssistant *assistant, GObject *ref)
+{
+ GtkWidget *vbox; /* Support principal */
+ GtkWidget *hbox; /* Petite barre supérieure */
+ GtkWidget *label; /* Etiquette d'indication */
+ GtkWidget *comboboxentry; /* Liste de sélection simple */
+ GtkWidget *vseparator; /* Barre de séparation */
+ GtkWidget *filter; /* Zone de recherche */
+ GtkWidget *scrollwnd; /* Support défilant */
+ GtkTreeStore *store; /* Modèle de gestion */
+ GtkTreeModel *model; /* Modèle de gestion supérieur */
+ GtkWidget *treeview; /* Affichage de la liste */
+ GtkCellRenderer *renderer; /* Moteur de rendu de colonne */
+ GtkTreeViewColumn *column; /* Colonne de la liste */
+
+ vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8);
+ gtk_widget_show(vbox);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 8);
+
+ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
+ gtk_widget_show(hbox);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
+
+ /* Choix de la catégorie */
+
+ label = gtk_label_new(_("ROP selection:"));
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ comboboxentry = qck_create_combobox(ref, "filter_cat", G_CALLBACK(on_rop_gadgets_category_changed), ref);
+ gtk_box_pack_start(GTK_BOX(hbox), comboboxentry, FALSE, TRUE, 0);
+
+ /* Séparation fine */
+
+ vseparator = gtk_separator_new(GTK_ORIENTATION_VERTICAL);
+ gtk_widget_show(vseparator);
+ gtk_box_pack_start(GTK_BOX(hbox), vseparator, FALSE, FALSE, 0);
+
+ /* Espace de recherche */
+
+ label = gtk_label_new(_("Filter:"));
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ filter = gtk_search_entry_new();
+ g_object_set_data(ref, "filter_rop", filter);
+ gtk_widget_set_tooltip_text(filter, _("Filter gadgets using POSIX extended regular expressions"));
+
+ g_signal_connect(filter, "search-changed", G_CALLBACK(on_rop_gadgets_filter_changed), ref);
+ gtk_widget_show(filter);
+ gtk_widget_set_hexpand(filter, TRUE);
+
+ gtk_box_pack_start(GTK_BOX(hbox), filter, TRUE, TRUE, 0);
+
+ /* 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(FRG_COUNT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING);
+
+ model = gtk_tree_model_filter_new(GTK_TREE_MODEL(store), NULL);
+
+ gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(model),
+ (GtkTreeModelFilterVisibleFunc)filter_visible_rop_gadgets,
+ ref, NULL);
+
+ treeview = gtk_tree_view_new_with_model(model);
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), TRUE);
+ gtk_tree_view_set_enable_tree_lines(GTK_TREE_VIEW(treeview), TRUE);
+
+ g_object_set_data(ref, "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", FRG_VIRTUAL,
+ NULL);
+ gtk_tree_view_column_set_sort_column_id(column, FRG_VIRTUAL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(_("Gadgets"), renderer,
+ "markup", FRG_CONTENT,
+ NULL);
+ gtk_tree_view_column_set_sort_column_id(column, FRG_CONTENT);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+
+ /* Intégration */
+
+ gtk_assistant_append_page(assistant, vbox);
+ gtk_assistant_set_page_title(assistant, vbox, _("ROP Gadgets"));
+ gtk_assistant_set_page_type(assistant, vbox, GTK_ASSISTANT_PAGE_CONFIRM);
+
+ gtk_assistant_set_page_complete(assistant, vbox, TRUE);
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : combo = composant de choix contenant le filtre brut. *
+* ref = espace de référencements inter-panneaux. *
+* *
+* Description : Lance l'actualisation du filtrage des gadgets ROP. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_rop_gadgets_category_changed(GtkComboBox *combo, GObject *ref)
+{
+ GtkTreeView *treeview; /* Arborescence à actualiser */
+ GtkTreeModelFilter *filter; /* Modèle de gestion associé */
+
+ treeview = GTK_TREE_VIEW(g_object_get_data(ref, "treeview"));
+
+ filter = GTK_TREE_MODEL_FILTER(gtk_tree_view_get_model(treeview));
+
+ gtk_tree_model_filter_refilter(filter);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : entry = entrée de texte contenant le filtre brut. *
+* ref = espace de référencements inter-panneaux. *
+* *
+* Description : Lance l'actualisation du filtrage des gadgets ROP. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_rop_gadgets_filter_changed(GtkSearchEntry *entry, GObject *ref)
+{
+ regex_t preg; /* Expression régulière de test*/
+ const gchar *text; /* Texte de l'utilisateur */
+ int ret; /* Bilan de mise en place */
+ GdkRGBA error; /* Couleur d'erreur */
+ GtkTreeView *treeview; /* Arborescence à actualiser */
+ GtkTreeModelFilter *filter; /* Modèle de gestion associé */
+
+ text = gtk_entry_get_text(GTK_ENTRY(entry));
+
+ if (text[0] != '\0')
+ {
+ ret = regcomp(&preg, text, REG_EXTENDED);
+
+ if (ret != 0)
+ {
+ error.red = 1.0;
+ error.green = 0.0;
+ error.blue = 0.0;
+ error.alpha = 1.0;
+ gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, &error);
+
+ return;
+
+ }
+
+ regfree(&preg);
+
+ }
+
+ gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, NULL);
+
+ treeview = GTK_TREE_VIEW(g_object_get_data(ref, "treeview"));
+
+ filter = GTK_TREE_MODEL_FILTER(gtk_tree_view_get_model(treeview));
+
+ gtk_tree_model_filter_refilter(filter);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : model = gestionnaire des lignes et colonnes affichées. *
+* iter = ligne concernée par l'analyse à mener. *
+* ref = espace de référencements inter-panneaux. *
+* *
+* Description : Détermine la visibilité de tel ou tel gadget ROP. *
+* *
+* Retour : Indication d'affichage pour une ligne donnée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gboolean filter_visible_rop_gadgets(GtkTreeModel *model, GtkTreeIter *iter, GObject *ref)
+{
+ gboolean result; /* Visibilité à retourner */
+ gchar *category; /* Catégorie d'appartenance */
+ gchar *raw; /* Brut pour recherche */
+ GtkComboBoxText *combo; /* Sélection à choix multiples */
+ gchar *selected; /* Texte de l'utilisateur #1 */
+ GtkEntry *entry; /* Zone de texte à utiliser */
+ const gchar *text; /* Texte de l'utilisateur #2 */
+ regex_t preg; /* Expression régulière de test*/
+ int ret; /* Bilan de mise en place */
+ regmatch_t match; /* Récupération des trouvailles*/
+
+ result = TRUE;
+
+ gtk_tree_model_get(model, iter, FRG_CATEGORY, &category, FRG_RAW, &raw, -1);
+
+ if (category == NULL || raw == NULL) return FALSE;
+
+ /* Filtre sur les catégories */
+
+ combo = g_object_get_data(ref, "filter_cat");
+
+ selected = gtk_combo_box_text_get_active_text(combo);
+
+ result &= (g_strcmp0(category, selected) == 0);
+
+ g_free(selected);
+
+ /* Filtre sur les gadgets ROP */
+
+ entry = g_object_get_data(ref, "filter_rop");
+
+ text = gtk_entry_get_text(GTK_ENTRY(entry));
+
+ ret = regcomp(&preg, text, REG_EXTENDED);
+ result &= (ret == 0);
+
+ if (ret == 0)
+ {
+ ret = regexec(&preg, raw, 1, &match, 0);
+ result &= (ret != REG_NOMATCH);
+
+ regfree(&preg);
+
+ }
+
+ /* Nettoyages finaux */
+
+ g_free(category);
+ g_free(raw);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = format binaire chargé sur lequel se reposer. *
+* combo = composant de sélection des catégories à compléter.*
+* store = modèle de gestionnaire pour la liste affichée. *
+* category = représentation du binaire chargé en mémoire. *
+* gadgets = liste de listes d'instructions de ROP. *
+* count = taille de cette liste. *
+* *
+* Description : Ajoute de nouvelles chaînes de gadgets localisées. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void add_new_gadgets_for_category(GBinFormat *format, GtkComboBoxText *combo, GtkTreeStore *store, const char *category, GArchInstruction **gadgets, size_t count)
+{
+ const char *target; /* Sous-traitance requise */
+ GArchProcessor *proc; /* Architecture du binaire */
+ MemoryDataSize msize; /* Taille du bus d'adresses */
+ const bin_t *content; /* Contenu binaire global */
+ GCodeBuffer *buffer; /* Tampon de rassemblement */
+ size_t i; /* Boucle de parcours */
+ GArchInstruction *instr; /* Elément de liste de gadgets */
+ GBufferLine *line; /* Ligne présente à l'adresse */
+ char *raw_virtual; /* Transcription pour export */
+ char *virtual; /* Transcription d'adresse */
+ char *partial_raw; /* Contenu de la ligne visée */
+ char *partial_markup; /* Contenu de la ligne visée */
+ char *content_raw; /* Contenu assemblé de chaîne */
+ char *content_markup; /* Contenu assemblé de chaîne */
+ GtkTreeIter iter; /* Point d'insertion */
+
+ /* Définition de l'écosystème nécessaire */
+
+ target = g_exe_format_get_target_machine(G_EXE_FORMAT(format));
+ proc = get_arch_processor_for_type(target);
+
+ msize = g_arch_processor_get_memory_size(proc);
+
+ g_object_unref(G_OBJECT(proc));
+
+ content = g_binary_format_get_content(G_BIN_FORMAT(format), NULL);
+
+ /* Conversion en contenu textuel */
+
+ buffer = g_code_buffer_new(BLC_ASSEMBLY);
+
+ for (i = 0; i < count; i++)
+ {
+ /* Parcours des différentes lignes */
+
+ content_raw = NULL;
+ content_markup = NULL;
+
+ for (instr = gadgets[i]; instr != NULL; instr = g_arch_instruction_get_next_iter(gadgets[i], instr, ~0))
+ {
+ line = g_arch_instruction_print(instr, buffer, msize, content, ASX_INTEL);
+ if (line == NULL) continue;
+
+ if (instr == gadgets[i])
+ {
+ raw_virtual = g_buffer_line_get_text(line, BLC_VIRTUAL, BLC_VIRTUAL + 1, false);
+ virtual = g_buffer_line_get_text(line, BLC_VIRTUAL, BLC_VIRTUAL + 1, true);
+ }
+
+ partial_raw = g_buffer_line_get_text(line, BLC_ASSEMBLY_HEAD, BLC_COUNT, false);
+ partial_markup = g_buffer_line_get_text(line, BLC_ASSEMBLY_HEAD, BLC_COUNT, true);
+
+ if (content_raw != NULL)
+ content_raw = stradd(content_raw, " ; ");
+
+ content_raw = stradd(content_raw, partial_raw);
+
+ if (content_markup != NULL)
+ content_markup = stradd(content_markup, " ; ");
+
+ content_markup = stradd(content_markup, partial_markup);
+
+ free(partial_raw);
+ free(partial_markup);
+
+ }
+
+ /* Insertion finale */
+
+ gtk_tree_store_append(store, &iter, NULL);
+
+ gtk_tree_store_set(store, &iter,
+ FRG_CATEGORY, category,
+ FRG_RAW_VIRTUAL, raw_virtual,
+ FRG_RAW, content_raw,
+ FRG_VIRTUAL, virtual,
+ FRG_CONTENT, content_markup,
+ -1);
+
+ /* Nettoyage de la mémoire */
+
+ free(raw_virtual);
+ free(virtual);
+ free(content_raw);
+ free(content_markup);
+
+ }
+
+ g_object_unref(G_OBJECT(buffer));
+
+ /* Rajout de la catégorie et filtre au besoin */
+
+ gtk_combo_box_text_append_text(combo, category);
+
+ if (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)) == -1)
+ gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
+
+}