diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/panels/Makefile.am | 1 | ||||
-rw-r--r-- | src/gui/panels/bookmarks.c | 1179 | ||||
-rw-r--r-- | src/gui/panels/bookmarks.h | 65 | ||||
-rw-r--r-- | src/gui/panels/panel.c | 4 | ||||
-rw-r--r-- | src/gui/panels/regedit.c | 2 |
5 files changed, 1250 insertions, 1 deletions
diff --git a/src/gui/panels/Makefile.am b/src/gui/panels/Makefile.am index 0f7768c..ad8c6b2 100644 --- a/src/gui/panels/Makefile.am +++ b/src/gui/panels/Makefile.am @@ -2,6 +2,7 @@ noinst_LTLIBRARIES = libguipanels.la libguipanels_la_SOURCES = \ + bookmarks.h bookmarks.c \ glance.h glance.c \ log.h log.c \ panel.h panel.c \ diff --git a/src/gui/panels/bookmarks.c b/src/gui/panels/bookmarks.c new file mode 100644 index 0000000..a61f6bc --- /dev/null +++ b/src/gui/panels/bookmarks.c @@ -0,0 +1,1179 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * bookmarks.c - panneau d'affichage des signets d'un binaire + * + * 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "bookmarks.h" + + +#include <assert.h> +#include <malloc.h> +#include <regex.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <cairo-gobject.h> +#include <gtk/gtk.h> + + +#include "panel-int.h" +#include "../../analysis/db/items/bookmark.h" +#include "../../core/params.h" +#include "../../common/cpp.h" +#include "../../common/extstr.h" +#include "../../gtkext/easygtk.h" +#include "../../gtkext/support.h" + + + +/* -------------------------- PARTIE PRINCIPALE DU PANNEAU -------------------------- */ + + +/* Panneau d'affichage des signets liés à un binaire (instance) */ +struct _GBookmarksPanel +{ + GPanelItem parent; /* A laisser en premier */ + + GtkTreeView *treeview; /* Composant d'affichage */ + regex_t *filter; /* Filtre appliqué ou NULL */ + + GtkMenu *menu; /* Menu contextuel pour param. */ + + GLoadedBinary *binary; /* Binaire en cours d'analyse */ + +}; + +/* Panneau d'affichage des signets liés à un binaire (classe) */ +struct _GBookmarksPanelClass +{ + GPanelItemClass parent; /* A laisser en premier */ + + cairo_surface_t *bookmark_img; /* Image pour les signets */ + +}; + + +/* Colonnes de la liste visuelle */ +typedef enum _BookmarkColumn +{ + BMC_BOOKMARK, /* Elément GLib représenté */ + + BMC_PICTURE, /* Image d'agrément */ + BMC_PHYSICAL, /* Adresse phyisque */ + BMC_VIRTUAL, /* Adresse virtuelle */ + BMC_COMMENT, /* Commentaire associé */ + + BMC_COUNT /* Nombre de colonnes */ + +} CfgParamColumn; + + + + +/* Initialise la classe des panneaux des paramètres de config. */ +static void g_bookmarks_panel_class_init(GBookmarksPanelClass *); + +/* Initialise une instance de panneau de paramètres de config. */ +static void g_bookmarks_panel_init(GBookmarksPanel *); + +/* Supprime toutes les références externes. */ +static void g_bookmarks_panel_dispose(GBookmarksPanel *); + +/* Procède à la libération totale de la mémoire. */ +static void g_bookmarks_panel_finalize(GBookmarksPanel *); + + + +/* ------------------------- AFFICHAGE A L'AIDE D'UNE LISTE ------------------------- */ + + +/* Recharge une collection de signets à l'affichage. */ +static void reload_bookmarks_into_treeview(GBookmarksPanel *, GLoadedBinary *); + + + + +/* Actualise l'affichage des données d'un paramètre modifié. */ +static void on_config_param_modified(GCfgParam *, GBookmarksPanel *); + +/* Actualise la valeur affichée d'un paramètre de configuration. */ +static void update_config_param_value(GtkTreeStore *, GtkTreeIter *); + +/* Etablit une comparaison entre deux lignes de paramètres. */ +static gint compare_bookmarks_list_columns(GtkTreeModel *, GtkTreeIter *, GtkTreeIter *, gpointer); + +/* Réagit à une pression sur <Shift+F2> et simule l'édition. */ +static gboolean on_key_pressed_over_params(GtkTreeView *, GdkEventKey *, GBookmarksPanel *); + +/* Réagit à une édition de la valeur d'un paramètre. */ +static void on_param_value_edited(GtkCellRendererText *, gchar *, gchar *, GtkTreeStore *); + + + +/* ------------------------- FILTRAGE DES SYMBOLES PRESENTS ------------------------- */ + + +/* Démarre l'actualisation du filtrage des paramètres. */ +static void on_param_search_changed(GtkSearchEntry *, GBookmarksPanel *); + +/*Détermine si un paramètre doit être filtré ou non. */ +static bool is_param_filtered(GBookmarksPanel *, const char *); + + + +/* ------------------------ ATTRIBUTION D'UN MENU CONTEXTUEL ------------------------ */ + + +/* Assure la gestion des clics de souris sur les signets. */ +static gboolean on_button_press_over_bookmarks(GtkWidget *, GdkEventButton *, GBookmarksPanel *); + +/* Construit le menu contextuel pour les signets. */ +GtkMenu *build_bookmarks_panel_menu(GBookmarksPanel *); + +/* Fournit le signet sélectionné dans la liste. */ +static GDbBookmark *get_selected_panel_bookmark(GtkTreeView *, GtkTreeIter *); + +/* Réagit avec le menu "Editer". */ +static void mcb_bookmarks_panel_edit(GtkMenuItem *, GBookmarksPanel *); + +/* Réagit avec le menu "Supprimer". */ +static void mcb_bookmarks_panel_delete(GtkMenuItem *, GBookmarksPanel *); + +/* Réagit avec le menu "Filtrer...". */ +static void mcb_bookmarks_panel_filter(GtkMenuItem *, GBookmarksPanel *); + + + +/* ---------------------------------------------------------------------------------- */ +/* PARTIE PRINCIPALE DU PANNEAU */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type définit pour un panneau d'affichage des signets liés à un binaire. */ +G_DEFINE_TYPE(GBookmarksPanel, g_bookmarks_panel, G_TYPE_PANEL_ITEM); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des panneaux des paramètres de config. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_bookmarks_panel_class_init(GBookmarksPanelClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GEditorItemClass *editem; /* Encore une autre vision... */ + gchar *filename; /* Chemin d'accès à utiliser */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_bookmarks_panel_dispose; + object->finalize = (GObjectFinalizeFunc)g_bookmarks_panel_finalize; + + editem = G_EDITOR_ITEM_CLASS(klass); + + editem->update_binary = (update_item_binary_fc)reload_bookmarks_into_treeview; + + filename = find_pixmap_file("bookmark.png"); + /* assert(filename != NULL); */ + + klass->bookmark_img = cairo_image_surface_create_from_png(filename); + + g_free(filename); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = instance à initialiser. * +* * +* Description : Initialise une instance de panneau de paramètres de config. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_bookmarks_panel_init(GBookmarksPanel *panel) +{ + GEditorItem *base; /* Version basique d'instance */ + GObject *ref; /* Espace de référencement */ + GtkWidget *label; /* Etiquette à utiliser */ + GtkWidget *search; /* Zone de recherche */ + GtkWidget *scrolled; /* Fenêtre défilante */ + GtkTreeStore *store; /* Modèle de gestion */ + GtkWidget *treeview; /* Affichage de la liste */ + GtkCellRenderer *renderer; /* Moteur de rendu de colonne */ + GtkTreeViewColumn *column; /* Colonne de la liste */ + GtkTreeSortable *sortable; /* Autre vision de la liste */ + + base = G_EDITOR_ITEM(panel); + + base->widget = gtk_grid_new(); + gtk_widget_show(base->widget); + + gtk_grid_set_row_spacing(GTK_GRID(base->widget), 8); + + ref = G_OBJECT(base->widget); + g_object_set_data(ref, "panel", panel); + + /* Partie recherche */ + + label = qck_create_label(NULL, NULL, _("Look for:")); + g_object_set(label, "margin", 8, NULL); + gtk_grid_attach(GTK_GRID(base->widget), label, 0, 0, 1, 1); + + search = gtk_search_entry_new(); + ///g_signal_connect(search, "search-changed", G_CALLBACK(on_param_search_changed), panel); + gtk_widget_show(search); + gtk_widget_set_hexpand(search, TRUE); + gtk_grid_attach_next_to(GTK_GRID(base->widget), search, label, GTK_POS_RIGHT, 1, 1); + + /* Partie paramètres */ + + scrolled = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_show(scrolled); + gtk_widget_set_vexpand(scrolled, TRUE); + gtk_grid_attach_next_to(GTK_GRID(base->widget), scrolled, label, GTK_POS_BOTTOM, 2, 1); + + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN); + + store = gtk_tree_store_new(BMC_COUNT, G_TYPE_OBJECT, + 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_rules_hint(GTK_TREE_VIEW(treeview), TRUE); + panel->treeview = GTK_TREE_VIEW(treeview); + + g_signal_connect(G_OBJECT(treeview), "button-press-event", + G_CALLBACK(on_button_press_over_bookmarks), panel); + g_signal_connect(G_OBJECT(treeview), "key-press-event", + G_CALLBACK(on_key_pressed_over_params), panel); + + gtk_widget_show(treeview); + gtk_container_add(GTK_CONTAINER(scrolled), treeview); + + g_object_unref(G_OBJECT(store)); + + /* Cellules d'affichage */ + + renderer = gtk_cell_renderer_pixbuf_new(); + column = gtk_tree_view_column_new_with_attributes("", renderer, + "surface", BMC_PICTURE, + NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Physical address"), renderer, + "text", BMC_VIRTUAL, + NULL); + gtk_tree_view_column_set_sort_column_id(column, BMC_PHYSICAL); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Virtual address"), renderer, + "text", BMC_VIRTUAL, + NULL); + gtk_tree_view_column_set_sort_column_id(column, BMC_VIRTUAL); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + renderer = gtk_cell_renderer_text_new(); + g_object_set(G_OBJECT(renderer), "editable", TRUE, NULL); + ///g_signal_connect(renderer, "edited", G_CALLBACK(on_param_value_edited), store); + column = gtk_tree_view_column_new_with_attributes(_("Comment"), renderer, + "text", BMC_COMMENT, + NULL); + gtk_tree_view_column_set_sort_column_id(column, BMC_COMMENT); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + /* Tri de la liste */ + + sortable = GTK_TREE_SORTABLE(store); + + gtk_tree_sortable_set_sort_func(sortable, BMC_PHYSICAL, compare_bookmarks_list_columns, + GINT_TO_POINTER(BMC_PHYSICAL), NULL); + + gtk_tree_sortable_set_sort_func(sortable, BMC_VIRTUAL, compare_bookmarks_list_columns, + GINT_TO_POINTER(BMC_VIRTUAL), NULL); + + gtk_tree_sortable_set_sort_func(sortable, BMC_COMMENT, compare_bookmarks_list_columns, + GINT_TO_POINTER(BMC_COMMENT), NULL); + + gtk_tree_sortable_set_sort_column_id(sortable, BMC_COMMENT, GTK_SORT_ASCENDING); + + /* Préparation du menu contextuel */ + + panel->menu = build_bookmarks_panel_menu(panel); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_bookmarks_panel_dispose(GBookmarksPanel *panel) +{ + if (panel->binary != NULL) + g_object_unref(G_OBJECT(panel->binary)); + + G_OBJECT_CLASS(g_bookmarks_panel_parent_class)->dispose(G_OBJECT(panel)); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_bookmarks_panel_finalize(GBookmarksPanel *panel) +{ + if (panel->filter != NULL) + regfree(panel->filter); + + G_OBJECT_CLASS(g_bookmarks_panel_parent_class)->finalize(G_OBJECT(panel)); + +} + + +/****************************************************************************** +* * +* Paramètres : ref = espace de référencement global. * +* * +* Description : Crée un panneau d'affichage des paramètres de configuration. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GEditorItem *g_bookmarks_panel_new(GObject *ref) +{ + GEditorItem *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_BOOKMARKS_PANEL, NULL); + + g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_BOOKMARKS_ID, + _("Bookmarks"), G_EDITOR_ITEM(result)->widget, "SE"); + + //reload_config_into_treeview(G_BOOKMARKS_PANEL(result), get_main_configuration()); + + + //GDbCollection *g_loaded_binary_find_collection(GLoadedBinary *binary, DBFeatures feature) + + + + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : ref = espace de référencement global. * +* * +* Description : Construit le panneau d'affichage des signets courants. * +* * +* Retour : Adresse du panneau mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GPanelItem *create_bookmarks_panel(GObject *ref) +{ + GEditorItem *result; /* Elément réactif à renvoyer */ + + result = g_bookmarks_panel_new(ref); + + /* Enregistre correctement le tout */ + register_editor_item(result); + + return G_PANEL_ITEM(result); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* AFFICHAGE A L'AIDE D'UNE LISTE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : panel = panneau d'affichage des signets liés à un binaire. * +* binary = propriétaire de la collection à présenter. * +* * +* Description : Recharge une collection de signets à l'affichage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void reload_bookmarks_into_treeview(GBookmarksPanel *panel, GLoadedBinary *binary) +{ + GtkTreeStore *store; /* Modèle de gestion */ + GDbCollection *collec; /* Collection à lister ici */ + GList *items; /* Liste des éléments groupés */ + GList *b; /* Boucle de parcours */ + GDbBookmark *bookmark; /* Signet en cours d'étude */ + vmpa2t *addr; /* Adressse associée au signet */ + GtkTreeIter iter; /* Point d'insertion */ + + printf("RELOAD :: %p\n", binary); + + /* Basculement du binaire utilisé */ + + if (panel->binary != NULL) + g_object_unref(G_OBJECT(panel->binary)); + + panel->binary = binary; + + if (panel->binary != NULL) + g_object_ref(G_OBJECT(binary)); + + store = GTK_TREE_STORE(gtk_tree_view_get_model(panel->treeview)); + gtk_tree_store_clear(store); + + /* Si le panneau actif ne représente pas un binaire... */ + + if (binary == NULL) return; + + /* Actualisation de l'affichage */ + + sleep(1); + + collec = g_loaded_binary_find_collection(binary, DBF_BOOKMARKS); + + g_db_collection_rlock(collec); + + items = g_db_collection_list_items(collec); + + + printf(" ... items = %p\n", items); + + /* + gtk_tree_store_append(store, &iter, NULL); + gtk_tree_store_set(store, &iter, + BMC_BOOKMARK, bookmark, + BMC_PICTURE, G_BOOKMARKS_PANEL_GET_CLASS(panel)->bookmark_img, + BMC_PHYSICAL, "0x01", + BMC_VIRTUAL, "0x02", + BMC_COMMENT, "desc", + -1); + */ + + + for (b = g_list_first(items); b != NULL; b = g_list_next(b)) + { + bookmark = G_DB_BOOKMARK(b->data); + + + printf("Adding // %p\n", bookmark); + + //printf("add.virt = %s\n", vmpa2_virt_to_string(&addr, MDS_32_BITS)); + + fflush(NULL); + + + addr = g_db_bookmark_get_address(bookmark); + + gtk_tree_store_append(store, &iter, NULL); + gtk_tree_store_set(store, &iter, + BMC_BOOKMARK, bookmark, + BMC_PICTURE, G_BOOKMARKS_PANEL_GET_CLASS(panel)->bookmark_img, + BMC_PHYSICAL, "vmpa2_phy_to_string(addr, MDS_32_BITS)", /* FIXME : pareil qu'en bas */ + BMC_VIRTUAL, "vmpa2_virt_to_string(&addr, MDS_32_BITS)", /* FIXME : choisir en fonction de l'architecture */ + BMC_COMMENT, "g_db_bookmark_get_comment(bookmark)", + -1); + + } + + g_db_collection_runlock(collec); + + + +#if 0 + GtkTreeStore *store; /* Modèle de gestion */ + GList *params; /* Paramètres de configuration */ + GCfgParam *param; /* Paramètre en cours d'étude */ + GList *p; /* Boucle de parcours */ + char *type_desc; /* Type de paramètre */ + GtkTreeIter iter; /* Point d'insertion */ + + store = GTK_TREE_STORE(gtk_tree_view_get_model(panel->treeview)); + gtk_tree_store_clear(store); + + g_generic_config_rlock(config); + + params = g_generic_config_list_params(config); + + for (p = g_list_first(params); p != NULL; p = g_list_next(p)) + { + param = G_CFG_PARAM(p->data); + + if (is_param_filtered(panel, g_config_param_get_path(param))) + continue; + + switch (g_config_param_get_ptype(param)) + { + case CPT_BOOLEAN: + type_desc = _("Boolean"); + break; + + case CPT_INTEGER: + type_desc = _("Integer"); + break; + + case CPT_STRING: + type_desc = _("String"); + break; + + default: + type_desc = _("<Unknown type>"); + break; + + } + + gtk_tree_store_append(store, &iter, NULL); + gtk_tree_store_set(store, &iter, + CPC_BOOKMARK, param, + CPC_PATH, g_config_param_get_path(param), + CPC_TYPE, type_desc, + -1); + + update_config_param_value(store, &iter); + + g_signal_connect(param, "modified", G_CALLBACK(on_config_param_modified), panel); + + } + + g_generic_config_runlock(config); +#endif +} + + +/****************************************************************************** +* * +* Paramètres : param = instance dont le contenu a évolué. * +* panel = panneau d'affichage de paramètres à mettre à jour. * +* * +* Description : Actualise l'affichage des données d'un paramètre modifié. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_config_param_modified(GCfgParam *param, GBookmarksPanel *panel) +{ + GtkTreeModel *model; /* Gestionnaire de données */ + GtkTreeIter iter; /* Point de recherche */ + gboolean looping; /* Autorisation de bouclage */ + GCfgParam *item; /* Elément de la liste */ + + model = gtk_tree_view_get_model(panel->treeview); + + for (looping = gtk_tree_model_get_iter_first (model, &iter); + looping; + looping = gtk_tree_model_iter_next(model, &iter)) + { + gtk_tree_model_get(model, &iter, BMC_BOOKMARK, &item, -1); + + if (item == param) + { + update_config_param_value(GTK_TREE_STORE(model), &iter); + break; + } + + } + +} + + +/****************************************************************************** +* * +* Paramètres : store = gestionnaire du tableau de données. * +* iter = point de modification dans les lignes. * +* param = paramètre dont la valeur est à afficher. * +* * +* Description : Actualise la valeur affichée d'un paramètre de configuration.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void update_config_param_value(GtkTreeStore *store, GtkTreeIter *iter) +{ + GCfgParam *param; /* Paramètre à consulter */ + ConfigParamState state; /* Etat du paramètre */ + char *state_desc; /* Version chaînée de l'état */ + bool boolean; /* Valeur booléenne */ + int integer; /* Valeur entière */ + char int_val[sizeof(XSTR(INT_MIN)) + 1];/* Valeur en chaîne de carac. */ + char *string; /* Chaîne de caractères */ + char *desc; /* Description à afficher */ + + gtk_tree_model_get(GTK_TREE_MODEL(store), iter, BMC_BOOKMARK, ¶m, -1); + + state = g_config_param_get_state(param); + + if (state & CPS_DEFAULT) + state_desc = strdup(_("By default")); + else + state_desc = strdup(_("Changed")); + + if (state & CPS_EMPTY) + state_desc = stradd(state_desc, _(" + empty")); + + if (state & CPS_EMPTY) + desc = ""; + + else + switch (g_config_param_get_ptype(param)) + { + case CPT_BOOLEAN: + g_config_param_get_value(param, &boolean); + desc = (boolean ? _("true") : _("false")); + break; + + case CPT_INTEGER: + g_config_param_get_value(param, &integer); + snprintf(int_val, sizeof(int_val), "%d", integer); + desc = int_val; + break; + + case CPT_STRING: + g_config_param_get_value(param, &string); + desc = (string != NULL ? string : ""); + break; + + default: + assert(false); + desc = "???"; + break; + + } + + /* + gtk_tree_store_set(store, iter, + CPC_BOLD, state & CPS_DEFAULT ? 400 : 800, + CPC_STATUS, state_desc, + CPC_VALUE, desc, -1); + */ + + free(state_desc); + + g_object_unref(G_OBJECT(param)); + +} + + +/****************************************************************************** +* * +* Paramètres : model = gestionnaire du tableau de données. * +* a = première ligne de données à traiter. * +* b = seconde ligne de données à traiter. * +* column = indice de la colonne à considérer, encodée. * +* * +* Description : Etablit une comparaison entre deux lignes de signets. * +* * +* Retour : Indication de tri entre les deux lignes fournies. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gint compare_bookmarks_list_columns(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer column) +{ + gint result; /* Valeur calculée à retourner */ + gchar *value_a; /* Cellule de la ligne 'a' */ + gchar *value_b; /* Cellule de la ligne 'b' */ + + gtk_tree_model_get(model, a, GPOINTER_TO_INT(column), &value_a, -1); + gtk_tree_model_get(model, b, GPOINTER_TO_INT(column), &value_b, -1); + + if (value_a == NULL || value_b == NULL) + { + if (value_a == NULL && value_b == NULL) + result = 0; + else + result = (value_a == NULL ? -1 : 1); + } + else + result = g_utf8_collate(value_a,value_b); + + g_free(value_a); + g_free(value_b); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : treeview = composant graphique présentant les paramètres. * +* event = informations liées à l'événement. * +* panel = panneau d'affichage sur lequel s'appuyer. * +* * +* Description : Réagit à une pression sur <Shift+F2> et simule l'édition. * +* * +* Retour : FALSE pour poursuivre la propagation de l'événement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean on_key_pressed_over_params(GtkTreeView *treeview, GdkEventKey *event, GBookmarksPanel *panel) +{ + const gchar *accelerator; /* Combinaison de raccourci */ + guint accel_key; /* Touche de raccourci */ + GdkModifierType accel_mod; /* Modifiateurs attendus aussi */ + GtkTreeIter iter; /* Point de la sélection */ + GtkTreeModel *model; /* Gestionnaire de données */ + GtkTreePath *path; /* Chemin d'accès à ce point */ + + if (!g_generic_config_get_value(get_main_configuration(), MPK_KEYBINDINGS_EDIT, &accelerator)) + return FALSE; + + if (accelerator == NULL) + return FALSE; + + gtk_accelerator_parse(accelerator, &accel_key, &accel_mod); + + if (event->keyval == accel_key && event->state == accel_mod) + { + /* FIXME : unref(result) */ + if (get_selected_panel_bookmark(treeview, &iter) != NULL) + { + model = gtk_tree_view_get_model(treeview); + path = gtk_tree_model_get_path(model, &iter); + + gtk_tree_view_set_cursor(treeview, path, + gtk_tree_view_get_column(treeview, BMC_COMMENT - BMC_PHYSICAL), + TRUE); + + gtk_tree_path_free(path); + + } + + } + + return FALSE; + +} + + +/****************************************************************************** +* * +* Paramètres : renderer = moteur de rendu pour la cellule. * +* path = chemin d'accès vers la cellule éditée. * +* new = nouvelle valeur sous forme de texte à valider. * +* store = gestionnaire des données de la liste affichée. * +* * +* Description : Réagit à une édition de la valeur d'un paramètre. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_param_value_edited(GtkCellRendererText *renderer, gchar *path, gchar *new, GtkTreeStore *store) +{ + GtkTreePath *tree_path; /* Chemin d'accès natif */ + GtkTreeIter iter; /* Point de la modification */ + GCfgParam *param; /* Paramètre à actualiser */ + bool boolean; /* Valeur booléenne */ + int integer; /* Valeur entière */ + char *end; /* Pointeur vers '\0' final ? */ + + tree_path = gtk_tree_path_new_from_string(path); + if (tree_path == NULL) return; + + if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, tree_path)) + goto opve_bad_iter; + + gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, BMC_BOOKMARK, ¶m, -1); + + switch (g_config_param_get_ptype(param)) + { + case CPT_BOOLEAN: + + if (strcmp(new, "true") != 0 && strcmp(new, "false") != 0) + goto opve_bad_value; + + boolean = (strcmp(new, "true") == 0); + g_config_param_set_value(param, boolean); + + break; + + case CPT_INTEGER: + + integer = strtol(new, &end, 10); + if (*end != '\0') goto opve_bad_value; + + g_config_param_set_value(param, integer); + + break; + + case CPT_STRING: + g_config_param_set_value(param, new); + break; + + default: + assert(false); + goto opve_bad_value; + break; + + } + + opve_bad_value: + + g_object_unref(G_OBJECT(param)); + + opve_bad_iter: + + gtk_tree_path_free(tree_path); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* FILTRAGE DES SYMBOLES PRESENTS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : entry = entrée de texte contenant le filtre brut. * +* panel = panneau assurant l'affichage des paramètres. * +* * +* Description : Démarre l'actualisation du filtrage des paramètres. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_param_search_changed(GtkSearchEntry *entry, GBookmarksPanel *panel) +{ + const gchar *text; /* Texte de l'utilisateur */ + int ret; /* Bilan de mise en place */ + GdkRGBA error; /* Couleur d'erreur */ + + if (panel->filter != NULL) + { + regfree(panel->filter); + free(panel->filter); + panel->filter = NULL; + } + + text = gtk_entry_get_text(GTK_ENTRY(entry)); + + if (strlen(text) > 0) + { + panel->filter = (regex_t *)calloc(1, sizeof(regex_t)); + ret = regcomp(panel->filter, text, REG_EXTENDED); + + if (ret != 0) + { + free(panel->filter); + panel->filter = NULL; + + 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; + + } + + } + + gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, NULL); + + reload_config_into_treeview(panel, get_main_configuration()); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = panneau assurant l'affichage des paramètres. * +* name = chemin d'accès au paramètre à traiter. * +* * +* Description : Détermine si un paramètre doit être filtré ou non. * +* * +* Retour : true si le paramètre ne doit pas être affiché, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool is_param_filtered(GBookmarksPanel *panel, const char *name) +{ + regmatch_t match; /* Récupération des trouvailles*/ + int ret; /* Bilan du filtrage */ + + if (panel->filter == NULL) + return false; + + ret = regexec(panel->filter, name, 1, &match, 0); + if (ret == REG_NOMATCH) + return true; + + return false; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* ATTRIBUTION D'UN MENU CONTEXTUEL */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : widget = composant GTK visé par l'opération. * +* event = informations liées à l'événement. * +* panel = informations liées au panneau associé. * +* * +* Description : Assure la gestion des clics de souris sur les signets. * +* * +* Retour : FALSE pour poursuivre la propagation de l'événement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean on_button_press_over_bookmarks(GtkWidget *widget, GdkEventButton *event, GBookmarksPanel *panel) +{ + if (event->button == 3) + gtk_menu_popup(panel->menu, NULL, NULL, NULL, NULL, event->button, event->time); + + return FALSE; + +} + + +/****************************************************************************** +* * +* Paramètres : panel = panneau d'affichage des signets liés à un binaire. * +* * +* Description : Construit le menu contextuel pour les signets. * +* * +* Retour : Panneau de menus mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkMenu *build_bookmarks_panel_menu(GBookmarksPanel *panel) +{ + GtkWidget *result; /* Support à retourner */ + GtkWidget *submenuitem; /* Sous-élément de menu */ + + result = gtk_menu_new(); + + submenuitem = qck_create_menu_item(NULL, NULL, _("Edit"), G_CALLBACK(mcb_bookmarks_panel_edit), panel); + gtk_container_add(GTK_CONTAINER(result), submenuitem); + + submenuitem = qck_create_menu_item(NULL, NULL, _("Delete"), G_CALLBACK(mcb_bookmarks_panel_delete), panel); + gtk_container_add(GTK_CONTAINER(result), submenuitem); + + submenuitem = qck_create_menu_separator(); + gtk_container_add(GTK_CONTAINER(result), submenuitem); + + submenuitem = qck_create_menu_item(NULL, NULL, _("Filter..."), G_CALLBACK(mcb_bookmarks_panel_filter), panel); + gtk_container_add(GTK_CONTAINER(result), submenuitem); + + return GTK_MENU(result); + +} + + +/****************************************************************************** +* * +* Paramètres : treeview = liste d'affichage à consulter. * +* save = zone de conservation du point de trouvaille. [OUT]* +* * +* Description : Fournit le signet sélectionné dans la liste. * +* * +* Retour : Signet en cours d'édition ou NULL en cas de soucis. * +* * +* Remarques : Le résultat non nul est à déréférencer après usage. * +* * +******************************************************************************/ + +static GDbBookmark *get_selected_panel_bookmark(GtkTreeView *treeview, GtkTreeIter *save) +{ + GDbBookmark *result; /* Paramètre à renvoyer */ + GtkTreeSelection *selection; /* Représentation de sélection */ + GtkTreeModel *model; /* Gestionnaire des données */ + GtkTreeIter iter; /* Point de la sélection */ + + result = NULL; + + selection = gtk_tree_view_get_selection(treeview); + + if (gtk_tree_selection_get_selected(selection, &model, &iter)) + gtk_tree_model_get(model, &iter, BMC_BOOKMARK, &result, -1); + + if (save != NULL) + *save = iter; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu sélectionné. * +* panel = panneau d'affichage des signets liés à un binaire.* +* * +* Description : Réagit avec le menu "Editer". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void mcb_bookmarks_panel_edit(GtkMenuItem *menuitem, GBookmarksPanel *panel) +{ + GtkTreeIter iter; /* Point de la sélection */ + GDbBookmark *mark; /* Signet sélectionné */ + GtkTreeModel *model; /* Gestionnaire de données */ + GtkTreePath *path; /* Chemin d'accès à ce point */ + + mark = get_selected_panel_bookmark(panel->treeview, &iter); + if (mark == NULL) return; + + model = gtk_tree_view_get_model(panel->treeview); + path = gtk_tree_model_get_path(model, &iter); + + gtk_tree_view_set_cursor(panel->treeview, path, + gtk_tree_view_get_column(panel->treeview, BMC_COMMENT - BMC_PHYSICAL), + TRUE); + + gtk_tree_path_free(path); + + g_object_unref(G_OBJECT(mark)); + +} + + +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu sélectionné. * +* panel = panneau d'affichage des signets liés à un binaire.* +* * +* Description : Réagit avec le menu "Supprimer". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void mcb_bookmarks_panel_delete(GtkMenuItem *menuitem, GBookmarksPanel *panel) +{ + GDbBookmark *mark; /* Signet sélectionné */ + + mark = get_selected_panel_bookmark(panel->treeview, NULL); + if (mark == NULL) return; + + g_loaded_binary_remove_from_collection(panel->binary, DBF_BOOKMARKS, G_DB_ITEM(mark)); + + g_object_unref(G_OBJECT(mark)); + +} + + +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu sélectionné. * +* panel = panneau d'affichage des signets liés à un binaire.* +* * +* Description : Réagit avec le menu "Filtrer...". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void mcb_bookmarks_panel_filter(GtkMenuItem *menuitem, GBookmarksPanel *panel) +{ +#if 0 + GCfgParam *param; /* Paramètre sélectionné */ + + param = get_selected_panel_bookmark(panel->treeview, NULL); + if (param == NULL) return; + + g_config_param_make_empty(param); + + g_object_unref(G_OBJECT(param)); +#endif +} diff --git a/src/gui/panels/bookmarks.h b/src/gui/panels/bookmarks.h new file mode 100644 index 0000000..507cc09 --- /dev/null +++ b/src/gui/panels/bookmarks.h @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * bookmarks.h - prototypes pour le panneau d'affichage des signets d'un binaire + * + * 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _GUI_PANELS_BOOKMARKS_H +#define _GUI_PANELS_BOOKMARKS_H + + +#include <i18n.h> + + +#include "panel.h" + + + +#define PANEL_BOOKMARKS_ID _("Bookmarks") + + +#define G_TYPE_BOOKMARKS_PANEL g_bookmarks_panel_get_type() +#define G_BOOKMARKS_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_bookmarks_panel_get_type(), GBookmarksPanel)) +#define G_IS_BOOKMARKS_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_bookmarks_panel_get_type())) +#define G_BOOKMARKS_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BOOKMARKS_PANEL, GBookmarksPanelClass)) +#define G_IS_BOOKMARKS_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BOOKMARKS_PANEL)) +#define G_BOOKMARKS_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BOOKMARKS_PANEL, GBookmarksPanelClass)) + + +/* Panneau d'affichage des signets liés à un binaire (instance) */ +typedef struct _GBookmarksPanel GBookmarksPanel; + +/* Panneau d'affichage des signets liés à un binaire (classe) */ +typedef struct _GBookmarksPanelClass GBookmarksPanelClass; + + +/* Indique le type définit pour un panneau d'affichage des signets liés à un binaire. */ +GType g_bookmarks_panel_get_type(void); + +/* Crée un panneau d'affichage des paramètres de configuration. */ +GEditorItem *g_bookmarks_panel_new(GObject *); + +/* Construit le panneau d'affichage des signets courants. */ +GPanelItem *create_bookmarks_panel(GObject *); + + + +#endif /* _GUI_PANELS_BOOKMARKS_H */ diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c index 5a7fc53..06be865 100644 --- a/src/gui/panels/panel.c +++ b/src/gui/panels/panel.c @@ -30,6 +30,7 @@ #include <sys/param.h> +#include "bookmarks.h" #include "glance.h" #include "log.h" #include "panel-int.h" @@ -388,6 +389,9 @@ void load_main_panels(GObject *ref) item = create_glance_panel(ref); g_panel_item_dock(item); + item = create_bookmarks_panel(ref); + g_panel_item_dock(item); + } diff --git a/src/gui/panels/regedit.c b/src/gui/panels/regedit.c index 77fea39..159a4d0 100644 --- a/src/gui/panels/regedit.c +++ b/src/gui/panels/regedit.c @@ -263,7 +263,7 @@ static void g_regedit_panel_init(GRegeditPanel *panel) g_object_unref(G_OBJECT(store)); - /* Cellule d'affichage */ + /* Cellules d'affichage */ renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Access path"), renderer, |