diff options
Diffstat (limited to 'src/dialogs')
-rw-r--r-- | src/dialogs/Makefile.am | 16 | ||||
-rw-r--r-- | src/dialogs/binparts.c | 327 | ||||
-rw-r--r-- | src/dialogs/binparts.h | 2 |
3 files changed, 268 insertions, 77 deletions
diff --git a/src/dialogs/Makefile.am b/src/dialogs/Makefile.am new file mode 100644 index 0000000..181f418 --- /dev/null +++ b/src/dialogs/Makefile.am @@ -0,0 +1,16 @@ + +lib_LIBRARIES = libdialogs.a + +libdialogs_a_SOURCES = \ + binparts.h binparts.c + +libdialogs_a_LDFLAGS = + + +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CPPFLAGS = + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +SUBDIRS = diff --git a/src/dialogs/binparts.c b/src/dialogs/binparts.c index 1135348..a88232e 100644 --- a/src/dialogs/binparts.c +++ b/src/dialogs/binparts.c @@ -24,6 +24,9 @@ #include "binparts.h" +#include <stdio.h> + + #include "../format/format.h" #include "../gtkext/easygtk.h" @@ -46,7 +49,6 @@ typedef enum _PartsColumn } PartsColumn; - /* Mémoire d'un modèle */ typedef struct _parts_model { @@ -56,15 +58,17 @@ typedef struct _parts_model } parts_model; +/* Sélectionne ou non tous les éléments de la liste courante. */ +static void select_all_items_or_none(GtkButton *, GObject *); +/* Sauvegarde l'état courant des sélections et clôt la fenêtre. */ +static void save_current_selection(GtkButton *, GObject *); +/* Ferme la fenêtre de dialogue. */ +static void close_editor(GtkButton *, GtkWidget *); -/* Charge les sections sélectionnées pour le projet courant. */ -void load_project_sections(void *, GObject *); - - - - +/* Charge les parties courantes d'un binaire donné. */ +static void load_binary_current_parts(GOpenidaBinary *binary, GObject *ref); /* Affiche les parties désassemblées par défaut. */ static void load_default_parts(GObject *); @@ -85,6 +89,7 @@ static void on_part_selection_toggle(GtkCellRendererToggle *, gchar *, GObject * /****************************************************************************** * * * Paramètres : binary = informations sur le binaire actuellement ouvert. * +* parent = fenêtre parente à surpasser. * * * * Description : Construit la fenêtre de sélection des sections. * * * @@ -94,7 +99,7 @@ static void on_part_selection_toggle(GtkCellRendererToggle *, gchar *, GObject * * * ******************************************************************************/ -GtkWidget *create_sections_dialog(GOpenidaBinary *binary) +GtkWidget *create_sections_dialog(GOpenidaBinary *binary, GtkWindow *parent) { GtkWidget *result; /* Fenêtre à renvoyer */ GObject *ref; /* Espace de référencements */ @@ -104,19 +109,13 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary) GtkWidget *vbox1; - //GtkWidget *hbox1; - - - GtkWidget *label; /* Etiquette à afficher */ - - GtkWidget *combobox; - GtkWidget *alignment; /* Adaptation de disposition */ - GtkWidget *frame; /* Support avec encadrement */ GtkWidget *vbox2; GtkWidget *hbox2; + GtkWidget *label; /* Etiquette à afficher */ + GtkWidget *comboboxentry; GtkWidget *hbox3; GtkWidget *scrolledwindow1; @@ -131,14 +130,15 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary) GtkWidget *hbuttonbox1; GtkWidget *button; /* Bouton de commande */ + GtkWidget *sep; /* Barre de séparation */ - 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), _("Sections selection")); - gtk_window_set_position(GTK_WINDOW(result), GTK_WIN_POS_CENTER); - gtk_window_set_default_size(GTK_WINDOW(result), 600, 400); - gtk_window_set_type_hint(GTK_WINDOW(result), GDK_WINDOW_TYPE_HINT_DIALOG); + 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), _("Content to display")); + 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); @@ -147,28 +147,11 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary) gtk_widget_show(vbox1); gtk_container_add(GTK_CONTAINER(result), vbox1); - /* - hbox1 = gtk_hbox_new(FALSE, 8); - gtk_widget_show(hbox1); - gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 0); - - label = qck_create_label(NULL, NULL, _("Binary :")); - gtk_box_pack_start(GTK_BOX(hbox1), label, FALSE, FALSE, 0); - - combobox = gtk_combo_box_new_text(); - gtk_widget_show(combobox); - gtk_box_pack_start(GTK_BOX(hbox1), combobox, TRUE, TRUE, 0); - */ - - frame = qck_create_frame(_("<b>Content to display</b>"), &alignment, 4, 4, 12, 0); - gtk_box_pack_start(GTK_BOX(vbox1), frame, TRUE, TRUE, 0); - - - - vbox2 = gtk_vbox_new(FALSE, 8); gtk_widget_show(vbox2); - gtk_container_add(GTK_CONTAINER(alignment), vbox2); + gtk_container_add(GTK_CONTAINER(vbox1), vbox2); + + hbox2 = gtk_hbox_new(FALSE, 8); gtk_widget_show(hbox2); @@ -182,9 +165,11 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary) button = qck_create_button_with_img(NULL, NULL, "gtk-add", G_CALLBACK(NULL), NULL); + gtk_widget_set_sensitive(button, FALSE); gtk_box_pack_start(GTK_BOX(hbox2), button, FALSE, FALSE, 0); button = qck_create_button_with_img(NULL, NULL, "gtk-remove", G_CALLBACK(NULL), NULL); + gtk_widget_set_sensitive(button, FALSE); gtk_box_pack_start(GTK_BOX(hbox2), button, FALSE, FALSE, 0); @@ -244,19 +229,32 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary) + /* Boutons d'édition de la liste */ + + vbuttonbox1 = gtk_vbutton_box_new(); + gtk_widget_show(vbuttonbox1); + gtk_box_pack_start(GTK_BOX(hbox3), vbuttonbox1, FALSE, FALSE, 0); + gtk_button_box_set_layout(GTK_BUTTON_BOX(vbuttonbox1), GTK_BUTTONBOX_SPREAD); - vbuttonbox1 = gtk_vbutton_box_new(); - gtk_widget_show(vbuttonbox1); - gtk_box_pack_start(GTK_BOX(hbox3), vbuttonbox1, FALSE, FALSE, 0); - gtk_button_box_set_layout(GTK_BUTTON_BOX(vbuttonbox1), GTK_BUTTONBOX_SPREAD); + button = qck_create_button_with_img(NULL, NULL, "gtk-add", G_CALLBACK(select_all_items_or_none), ref); + gtk_container_add(GTK_CONTAINER(vbuttonbox1), button); + g_object_set_data(G_OBJECT(button), "all", button); + + button = qck_create_button_with_img(NULL, NULL, "gtk-remove", G_CALLBACK(select_all_items_or_none), ref); + gtk_container_add(GTK_CONTAINER(vbuttonbox1), button); + sep = gtk_hseparator_new(); + gtk_widget_show(sep); + gtk_container_add(GTK_CONTAINER(vbuttonbox1), sep); button = qck_create_button_with_img(NULL, NULL, "gtk-add", G_CALLBACK(NULL), NULL); + gtk_widget_set_sensitive(button, FALSE); gtk_container_add(GTK_CONTAINER(vbuttonbox1), button); button = qck_create_button_with_img(NULL, NULL, "gtk-remove", G_CALLBACK(NULL), NULL); + gtk_widget_set_sensitive(button, FALSE); gtk_container_add(GTK_CONTAINER(vbuttonbox1), button); @@ -269,16 +267,15 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary) gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox1), GTK_BUTTONBOX_END); - button = qck_create_button_from_stock(NULL, NULL, "gtk-ok", G_CALLBACK(NULL), NULL); - gtk_container_add(GTK_CONTAINER(hbuttonbox1), button); + /* Boutons de contrôle principaux */ - button = qck_create_button_from_stock(NULL, NULL, "gtk-cancel", G_CALLBACK(NULL), NULL); + button = qck_create_button_from_stock(NULL, NULL, "gtk-ok", G_CALLBACK(save_current_selection), ref); gtk_container_add(GTK_CONTAINER(hbuttonbox1), button); + button = qck_create_button_from_stock(NULL, NULL, "gtk-cancel", G_CALLBACK(close_editor), result); + gtk_container_add(GTK_CONTAINER(hbuttonbox1), button); - - - + /* Actualisation de l'interface */ g_signal_connect(G_OBJECT(comboboxentry), "changed", G_CALLBACK(on_model_change), ref); @@ -286,22 +283,52 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary) gtk_combo_box_append_text(GTK_COMBO_BOX(comboboxentry), _("Routines")); gtk_combo_box_append_text(GTK_COMBO_BOX(comboboxentry), _("User")); + load_binary_current_parts(binary, ref); + return result; } +/****************************************************************************** +* * +* Paramètres : button = bouton d'édition de la sélection. * +* ref = espace de référencement principal. * +* * +* Description : Sélectionne ou non tous les éléments de la liste courante. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +static void select_all_items_or_none(GtkButton *button, GObject *ref) +{ + gboolean state; /* Etat de sélection à donner */ + GtkTreeModel *model; /* Modèle de représentation */ + GtkTreeIter iter; /* Point de modification */ + + state = (g_object_get_data(G_OBJECT(button), "all") != NULL); + + model = GTK_TREE_MODEL(g_object_get_data(ref, "store")); + if (gtk_tree_model_get_iter_first(model, &iter)) + do + gtk_tree_store_set(GTK_TREE_STORE(model), &iter, + PTC_ACTIVE, state, + -1); + while (gtk_tree_model_iter_next(model, &iter)); +} /****************************************************************************** * * -* Paramètres : project = informations sur le project actuellement ouvert. * -* ref = espace de référencement principal. * +* Paramètres : button = bouton 'OK'. * +* ref = espace de référencement principal. * * * -* Description : Charge les sections sélectionnées pour le projet courant. * +* Description : Sauvegarde l'état courant des sélections et clôt la fenêtre. * * * * Retour : - * * * @@ -309,27 +336,189 @@ GtkWidget *create_sections_dialog(GOpenidaBinary *binary) * * ******************************************************************************/ -void load_project_sections(void *project, GObject *ref) +static void save_current_selection(GtkButton *button, GObject *ref) { - /* - gtk_combo_box_append_text(GTK_COMBO_BOX(combobox), _("Never automatically")); - gtk_combo_box_append_text(GTK_COMBO_BOX(combobox), _("When the window gets the focus")); - gtk_combo_box_append_text(GTK_COMBO_BOX(combobox), _("On click on the window")); - */ + + + + GOpenidaBinary *binary; /* Binaire à traiter */ + + GExeFormat *format; /* Format associé au binaire */ + GArchProcessor *proc; /* Architecture utilisée */ + + + GBinPart **parts; /* Parcelles à désassembler */ + size_t parts_count; /* Quantité de ces parcelles */ + GBinPart *part; /* Nouvelle partie à lister */ + + + GBinRoutine **routines; /* Liste des routines trouvées */ + size_t routines_count; /* Nombre de ces routines */ + parts_model *model; /* Mémoire du modèle */ + size_t i; /* Boucle de parcours */ + off_t offset; /* Position dans le binaire */ + + + binary = G_OPENIDA_BINARY(g_object_get_data(ref, "binary")); + + format = g_openida_binary_get_format(binary); + proc = get_arch_processor_from_format(format); + + + + + /* Routines */ + + parts = NULL; + parts_count = 0; + + routines = g_binary_format_get_routines(G_BIN_FORMAT(format), &routines_count); + qsort(routines, routines_count, sizeof(GBinRoutine *), g_binary_routine_compare); + + model = (parts_model *)g_object_get_data(ref, "routines_model"); + + for (i = 0; i < routines_count; i++) + { + if (!model->selected[i]) continue; + + part = g_binary_part_new(); + + g_binary_part_set_name(part, g_binary_routine_get_name(routines[i])); + + g_exe_format_translate_address_into_offset(format, + g_binary_routine_get_address(routines[i]), + &offset); + + g_binary_part_set_values(part, offset, + g_binary_routine_get_size(routines[i]), + g_binary_routine_get_address(routines[i])); + + parts = (GBinPart **)realloc(parts, ++parts_count * sizeof(GBinPart *)); + parts[parts_count - 1] = part; + + } + + g_openida_binary_set_parts(binary, BPM_ROUTINES, parts, parts_count); + + + + + + + + + /* Fin */ + + gtk_widget_destroy(GTK_WIDGET(ref)); } +/****************************************************************************** +* * +* Paramètres : button = bouton 'Annuler'. * +* widget = adresse de la fenêtre de l'éditeur à fermer. * +* * +* Description : Ferme la fenêtre de dialogue. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +static void close_editor(GtkButton *button, GtkWidget *widget) +{ + gtk_widget_destroy(widget); +} +/****************************************************************************** +* * +* Paramètres : binary = informations sur le binaire actuellement ouvert. * +* ref = espace de référencement principal. * +* * +* Description : Charge les parties courantes d'un binaire donné. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +static void load_binary_current_parts(GOpenidaBinary *binary, GObject *ref) +{ + GtkTreeModel *store; /* Modèle de représentation */ + GBinPart ***list; /* Tableau de parties choisies */ + BinaryPartModel model; /* Sélection courante */ + size_t *count; /* Taille de chaque liste */ + unsigned int i; /* Boucle de parcours #1 */ + parts_model *parts; /* Liste de sélection courante */ + size_t j; /* Boucle de parcours #2 */ + GtkTreeIter iter; /* Lieu de lecture d'adresse */ + char path[11 /* UINT_MAX */]; /* Chemin d'accès pour GTK */ + gchar *value; /* Valeur d'adresse présentée */ + vmpa_t addr_dlg; /* Adresse côté local */ + size_t k; /* Boucle de parcours #3 */ + vmpa_t addr_bin; /* Adresse côté binaire */ + GtkComboBox *combo; /* Liste de tous les modèles */ + + /* Lecture des sélections courantes */ + + store = GTK_TREE_MODEL(g_object_get_data(ref, "store")); + + list = g_openida_binary_get_parts(binary, &model, &count); + + for (i = 0; i < (BPM_COUNT - 1 /* TODO*/); i++) + { + gtk_tree_store_clear(GTK_TREE_STORE(store)); + + switch (i) + { + case BPM_DEFAULT: + load_default_parts(ref); + parts = (parts_model *)g_object_get_data(ref, "default_model"); + break; + case BPM_ROUTINES: + load_routines_parts(ref); + parts = (parts_model *)g_object_get_data(ref, "routines_model"); + break; + case BPM_USER: + //parts = + break; + } + + for (j = 0; j < parts->count; j++) + { + snprintf(path, 11, "%u", j); + + gtk_tree_model_get_iter_from_string(store, &iter, path); + gtk_tree_model_get(store, &iter, PTC_START, &value, -1); + addr_dlg = strtoll(value, NULL, 16); + g_free(value); + + for (k = 0; k < count[i]; k++) + { + g_binary_part_get_values(list[i][k], NULL, NULL, &addr_bin); + if (addr_bin == addr_dlg) break; + } + parts->selected[j] = (count[i] == 0 || k < count[i]); + + } + + } + + /* Sélection courante */ + combo = GTK_COMBO_BOX(g_object_get_data(ref, "models")); + gtk_combo_box_set_active(combo, model); + +} /****************************************************************************** @@ -483,20 +672,6 @@ static void load_routines_parts(GObject *ref) -static void user_function(GtkButton *button, GObject *ref) -{ - - - - - - - - -} - - - diff --git a/src/dialogs/binparts.h b/src/dialogs/binparts.h index dd7fa5e..8a86bf6 100644 --- a/src/dialogs/binparts.h +++ b/src/dialogs/binparts.h @@ -33,7 +33,7 @@ /* Construit la fenêtre de sélection des sections. */ -GtkWidget *create_sections_dialog(GOpenidaBinary *); +GtkWidget *create_sections_dialog(GOpenidaBinary *, GtkWindow *); |