From 0846c211ca24bc4e88bbc517362e1e08deb837b5 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Mon, 31 Dec 2018 18:03:56 +0100 Subject: Remembered the target locations used in the Goto dialog box. --- src/analysis/binary.c | 281 +++++++++++++++++++++++++++++++++++++++++++++- src/analysis/binary.h | 8 ++ src/analysis/loaded-int.h | 2 +- src/analysis/loaded.c | 2 +- src/analysis/loaded.h | 2 +- src/gui/dialogs/goto.c | 42 ++++++- src/gui/menus/edition.c | 6 + 7 files changed, 332 insertions(+), 11 deletions(-) diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 4d6c8ba..c38a725 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -88,6 +88,10 @@ struct _GLoadedBinary GDisplayOptions *options[BVW_COUNT]; /* Options d'affichage */ + vmpa2t *old_gotos; /* Conservation de destinations*/ + size_t goto_count; /* Taille de cette liste */ + GMutex goto_access; /* Encadrement des accès */ + }; /* Description de fichier binaire (classe) */ @@ -138,6 +142,17 @@ static bool g_loaded_binary_connect_remote(GLoadedBinary *); +/* -------------------- SAUVEGARDE ET RESTAURATION DE PARAMETRES -------------------- */ + + +/* Charge en mémoire les anciennes destinations visitées. */ +static bool g_loaded_binary_load_old_gotos(GLoadedBinary *, xmlXPathContext *, const char *); + +/* Ecrit les anciennes destinations visitées dans du XML. */ +static bool g_loaded_binary_save_old_gotos(GLoadedBinary *, xmlDoc *, xmlXPathContext *, const char *); + + + /* ---------------------- GESTION SOUS FORME DE CONTENU CHARGE ---------------------- */ @@ -145,7 +160,7 @@ static bool g_loaded_binary_connect_remote(GLoadedBinary *); static bool g_loaded_binary_restore(GLoadedBinary *, xmlDoc *, xmlXPathContext *, const char *); /* Ecrit une sauvegarde du binaire dans un fichier XML. */ -static bool g_loaded_binary_save(const GLoadedBinary *, xmlDoc *, xmlXPathContext *, const char *); +static bool g_loaded_binary_save(GLoadedBinary *, xmlDoc *, xmlXPathContext *, const char *); /* Fournit le contenu représenté de l'élément chargé. */ static GBinContent *g_loaded_binary_get_content(const GLoadedBinary *); @@ -253,6 +268,8 @@ static void g_loaded_binary_init(GLoadedBinary *binary) g_display_options_add(binary->options[BVW_GRAPH], _("Virtual address"), false); g_display_options_add(binary->options[BVW_GRAPH], _("Binary code"), false); + g_mutex_init(&binary->goto_access); + } @@ -319,6 +336,8 @@ static void g_loaded_binary_dispose(GLoadedBinary *binary) for (i = 0; i < BVW_COUNT; i++) g_clear_object(&binary->options[i]); + g_mutex_clear(&binary->goto_access); + G_OBJECT_CLASS(g_loaded_binary_parent_class)->dispose(G_OBJECT(binary)); } @@ -1288,6 +1307,258 @@ GBufferCache *g_loaded_binary_get_disassembled_cache(const GLoadedBinary *binary /* ---------------------------------------------------------------------------------- */ +/* SAUVEGARDE ET RESTAURATION DE PARAMETRES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : binary = élément binaire à traiter. * +* context = contexte pour les recherches XPath. * +* path = chemin d'accès au noeud XML à lire. * +* * +* Description : Charge en mémoire les anciennes destinations visitées. * +* * +* Retour : true si l'opération a bien tourné, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_loaded_binary_load_old_gotos(GLoadedBinary *binary, xmlXPathContext *context, const char *path) +{ + bool result; /* Bilan à faire remonter */ + char *top_access; /* Chemin d'accès principal */ + xmlXPathObjectPtr xobject; /* Cible d'une recherche */ + size_t count; /* Nombre de contenus premiers */ + size_t i; /* Boucle de parcours */ + char *access; /* Chemin d'accès à un élément */ + char *value; /* Valeur lue à partie du XML */ + bool is_virt; /* Détermination de l'utile */ + vmpa2t *new; /* Nouvelle destination */ + + result = true; + + asprintf(&top_access, "%s/OldGotos/Target", path); + + xobject = get_node_xpath_object(context, top_access); + + count = XPATH_OBJ_NODES_COUNT(xobject); + + for (i = 0; i < count; i++) + { + asprintf(&access, "%s/OldGotos/Target[position()=%zu]", path, i + 1); + + /* Type de destination */ + + value = get_node_prop_value(context, access, "type"); + if (value == NULL) + { + result = false; + break; + } + + is_virt = (strcmp(value, "virt") == 0); + + free(value); + + /* Adresse de destination */ + + value = get_node_prop_value(context, access, "location"); + if (value == NULL) + { + result = false; + break; + } + + if (is_virt) + new = string_to_vmpa_virt(value); + else + new = string_to_vmpa_phy(value); + + free(value); + + /* Intégration */ + + binary->old_gotos = realloc(binary->old_gotos, ++binary->goto_count * sizeof(vmpa2t)); + + copy_vmpa(&binary->old_gotos[binary->goto_count - 1], new); + + delete_vmpa(new); + + free(access); + + } + + if(xobject != NULL) + xmlXPathFreeObject(xobject); + + free(top_access); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : binary = élément binaire à traiter. * +* xdoc = structure XML en cours d'édition. * +* context = contexte à utiliser pour les recherches. * +* path = chemin d'accès réservé au binaire. * +* * +* Description : Ecrit les anciennes destinations visitées dans du XML. * +* * +* Retour : true si l'opération a bien tourné, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_loaded_binary_save_old_gotos(GLoadedBinary *binary, xmlDoc *xdoc, xmlXPathContext *context, const char *path) +{ + bool result; /* Bilan à faire remonter */ + size_t i; /* Boucle de parcours */ + char *access; /* Chemin d'accès à un élément */ + const vmpa2t *addr; /* Adresse de destination */ + bool is_virt; /* Détermination de l'utile */ + VMPA_BUFFER(loc); /* Version humaintement lisible*/ + + result = true; + + g_mutex_lock(&binary->goto_access); + + for (i = 0; i < binary->goto_count && result; i++) + { + asprintf(&access, "%s/OldGotos/Target[position()=%zu]", path, i + 1); + + result = (ensure_node_exist(xdoc, context, access) != NULL); + + addr = &binary->old_gotos[i]; + + is_virt = has_virt_addr(addr); + + if (result) + result = add_string_attribute_to_node(xdoc, context, access, "type", is_virt ? "virt" : "phys"); + + if (result) + { + if (is_virt) + vmpa2_virt_to_string(addr, MDS_UNDEFINED, loc, NULL); + else + vmpa2_phys_to_string(addr, MDS_UNDEFINED, loc, NULL); + + result = add_string_attribute_to_node(xdoc, context, access, "location", loc); + + } + + free(access); + + } + + g_mutex_unlock(&binary->goto_access); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : binary = élément binaire à consulter. * +* new = nouvelle destination à conserver en mémoire. * +* * +* Description : Complète la liste des destinations déjà visitées. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_loaded_binary_remember_new_goto(GLoadedBinary *binary, const vmpa2t *new) +{ + size_t previous_count; /* Sauvegarde de la taille */ + size_t i; /* Boucle de parcours */ + + g_mutex_lock(&binary->goto_access); + + /* Mise en avant de la nouvelle ancienne destination */ + + binary->old_gotos = realloc(binary->old_gotos, ++binary->goto_count * sizeof(vmpa2t)); + + if (binary->goto_count > 1) + memmove(&binary->old_gotos[1], &binary->old_gotos[0], (binary->goto_count - 1) * sizeof(vmpa2t)); + + copy_vmpa(&binary->old_gotos[0], new); + + /* Suppression de la même destination à une autre position */ + + previous_count = binary->goto_count; + + for (i = 1; i < binary->goto_count; i++) + if (cmp_vmpa(&binary->old_gotos[i], new) == 0) + { + if ((i + 1) < binary->goto_count) + memmove(&binary->old_gotos[i], &binary->old_gotos[i + 1], + (binary->goto_count - i - 1) * sizeof(vmpa2t)); + + binary->goto_count--; + i--; + + } + + if (previous_count != binary->goto_count) + binary->old_gotos = realloc(binary->old_gotos, binary->goto_count * sizeof(vmpa2t)); + + g_mutex_unlock(&binary->goto_access); + +} + + +/****************************************************************************** +* * +* Paramètres : binary = élément binaire à consulter. * +* count = nombre d'éléments dans la liste renvoyée. * +* * +* Description : Fournit la liste des anciennes destinations déjà visitées. * +* * +* Retour : Liste de destinations à libérer de la mémoire ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +vmpa2t *g_loaded_binary_get_old_gotos(GLoadedBinary *binary, size_t *count) +{ + vmpa2t *result; /* Liste à renvoyer */ + size_t i; /* Boucle de parcours */ + + g_mutex_lock(&binary->goto_access); + + *count = binary->goto_count; + + if (*count == 0) + result = NULL; + + else + { + result = malloc(*count * sizeof(vmpa2t)); + + for (i = 0; i < *count; i++) + copy_vmpa(&result[i], &binary->old_gotos[i]); + + } + + g_mutex_unlock(&binary->goto_access); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ /* GESTION SOUS FORME DE CONTENU CHARGE */ /* ---------------------------------------------------------------------------------- */ @@ -1315,6 +1586,9 @@ static bool g_loaded_binary_restore(GLoadedBinary *binary, xmlDoc *xdoc, xmlXPat result = g_loaded_binary_load_storage(binary, context, path); + if (result) + result = g_loaded_binary_load_old_gotos(binary, context, path); + return result; } @@ -1335,7 +1609,7 @@ static bool g_loaded_binary_restore(GLoadedBinary *binary, xmlDoc *xdoc, xmlXPat * * ******************************************************************************/ -static bool g_loaded_binary_save(const GLoadedBinary *binary, xmlDoc *xdoc, xmlXPathContext *context, const char *path) +static bool g_loaded_binary_save(GLoadedBinary *binary, xmlDoc *xdoc, xmlXPathContext *context, const char *path) { bool result; /* Bilan à faire remonter */ @@ -1348,6 +1622,9 @@ static bool g_loaded_binary_save(const GLoadedBinary *binary, xmlDoc *xdoc, xmlX if (result) result = g_loaded_binary_save_storage(binary, xdoc, context, path); + if (result) + result = g_loaded_binary_save_old_gotos(binary, xdoc, context, path); + /* Sauvegarde côté serveur */ if (result) diff --git a/src/analysis/binary.h b/src/analysis/binary.h index 831cade..ad4f568 100644 --- a/src/analysis/binary.h +++ b/src/analysis/binary.h @@ -153,6 +153,14 @@ GArchProcessor *g_loaded_binary_get_processor(const GLoadedBinary *); GBufferCache *g_loaded_binary_get_disassembled_cache(const GLoadedBinary *); +/* -------------------- SAUVEGARDE ET RESTAURATION DE PARAMETRES -------------------- */ + + +/* Complète la liste des destinations déjà visitées. */ +void g_loaded_binary_remember_new_goto(GLoadedBinary *, const vmpa2t *); + +/* Fournit la liste des anciennes destinations déjà visitées. */ +vmpa2t *g_loaded_binary_get_old_gotos(GLoadedBinary *, size_t *); diff --git a/src/analysis/loaded-int.h b/src/analysis/loaded-int.h index ed7d84a..face2bb 100644 --- a/src/analysis/loaded-int.h +++ b/src/analysis/loaded-int.h @@ -34,7 +34,7 @@ typedef bool (* restore_content_fc) (GLoadedContent *, xmlDoc *, xmlXPathContext *, const char *); /* Ecrit une sauvegarde de l'élément dans un fichier XML. */ -typedef bool (* save_content_fc) (const GLoadedContent *, xmlDoc *, xmlXPathContext *, const char *); +typedef bool (* save_content_fc) (GLoadedContent *, xmlDoc *, xmlXPathContext *, const char *); /* Fournit le contenu représenté de l'élément chargé. */ typedef GBinContent * (* get_content_fc) (const GLoadedContent *); diff --git a/src/analysis/loaded.c b/src/analysis/loaded.c index d148366..2343992 100644 --- a/src/analysis/loaded.c +++ b/src/analysis/loaded.c @@ -187,7 +187,7 @@ bool g_loaded_content_restore(GLoadedContent *content, xmlDocPtr xdoc, xmlXPathC * * ******************************************************************************/ -bool g_loaded_content_save(const GLoadedContent *content, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path) +bool g_loaded_content_save(GLoadedContent *content, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path) { bool result; /* Bilan à faire remonter */ GLoadedContentIface *iface; /* Interface utilisée */ diff --git a/src/analysis/loaded.h b/src/analysis/loaded.h index 60d1fce..284efae 100644 --- a/src/analysis/loaded.h +++ b/src/analysis/loaded.h @@ -62,7 +62,7 @@ GType g_loaded_content_get_type(void) G_GNUC_CONST; bool g_loaded_content_restore(GLoadedContent *, xmlDoc *, xmlXPathContext *, const char *); /* Ecrit une sauvegarde de l'élément dans un fichier XML. */ -bool g_loaded_content_save(const GLoadedContent *, xmlDoc *, xmlXPathContext *, const char *); +bool g_loaded_content_save(GLoadedContent *, xmlDoc *, xmlXPathContext *, const char *); /* Fournit le contenu représenté de l'élément chargé. */ GBinContent *g_loaded_content_get_content(const GLoadedContent *); diff --git a/src/gui/dialogs/goto.c b/src/gui/dialogs/goto.c index 1fe2bbd..1cb365f 100644 --- a/src/gui/dialogs/goto.c +++ b/src/gui/dialogs/goto.c @@ -30,6 +30,8 @@ #include +#include "../core/global.h" +#include "../../analysis/binary.h" #include "../../gtkext/easygtk.h" @@ -150,6 +152,12 @@ GtkWidget *create_goto_dialog(GtkWindow *parent) GtkWidget *entry; /* Zone de saisie principale */ GtkWidget *hbox; /* Support à construire #2 */ GtkWidget *radio; /* Définition de localisation */ + GLoadedBinary *binary; /* Binaire en cours d'édition */ + vmpa2t *old_gotos; /* Liste de destinations */ + size_t count; /* Taille de cette liste */ + size_t i; /* Boucle de parcours */ + bool is_virt; /* Détermination de l'utile */ + VMPA_BUFFER(loc); /* Version humaintement lisible*/ result = gtk_dialog_new(); gtk_window_set_title(GTK_WINDOW(result), _("Go to address")); @@ -181,11 +189,6 @@ GtkWidget *create_goto_dialog(GtkWindow *parent) g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(validate_addresses), GTK_DIALOG(result)); - - /* TODO */ - //gtk_combo_box_append_text(combobox, "test"); - - /* Propriétés de la localisation */ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); @@ -207,9 +210,36 @@ GtkWidget *create_goto_dialog(GtkWindow *parent) gtk_dialog_add_button(GTK_DIALOG(result), _("_Ok"), GTK_RESPONSE_OK); gtk_entry_set_text(GTK_ENTRY(entry), "0x"); - gtk_widget_grab_focus (entry); + gtk_widget_grab_focus(entry); gtk_editable_set_position(GTK_EDITABLE(entry), -1); + /* Restaurationd d'anciennes destinations */ + + binary = G_LOADED_BINARY(get_current_content()); + old_gotos = g_loaded_binary_get_old_gotos(binary, &count); + g_object_unref(G_OBJECT(binary)); + + if (old_gotos != NULL) + { + for (i = 0; i < count; i++) + { + is_virt = has_virt_addr(&old_gotos[i]); + + if (is_virt) + vmpa2_virt_to_string(&old_gotos[i], MDS_UNDEFINED, loc, NULL); + else + vmpa2_phys_to_string(&old_gotos[i], MDS_UNDEFINED, loc, NULL); + + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combobox), loc); + + } + + free(old_gotos); + + gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), 0); + + } + return result; } diff --git a/src/gui/menus/edition.c b/src/gui/menus/edition.c index b1ac0ad..be045b5 100644 --- a/src/gui/menus/edition.c +++ b/src/gui/menus/edition.c @@ -36,6 +36,7 @@ #include "../dialogs/bookmark.h" #include "../dialogs/goto.h" #include "../dialogs/gotox.h" +#include "../../analysis/binary.h" #include "../../analysis/db/items/switcher.h" #include "../../arch/targetableop.h" #include "../../glibext/gbinarycursor.h" @@ -422,6 +423,7 @@ static void mcb_edition_goto(GtkMenuItem *menuitem, GMenuBar *bar) GtkWidget *dialog; /* Boîte de dialogue à montrer */ vmpa2t *addr; /* Adresse de destination */ GLoadedPanel *panel; /* Afficheur effectif de code */ + GLoadedBinary *binary; /* Binaire en cours d'édition */ ref = g_editor_item_get_global_ref(G_EDITOR_ITEM(bar)); dialog = create_goto_dialog(GTK_WINDOW(ref)); @@ -433,6 +435,10 @@ static void mcb_edition_goto(GtkMenuItem *menuitem, GMenuBar *bar) panel = get_current_view(); assert(GTK_IS_BLOCK_DISPLAY(panel) || GTK_IS_GRAPH_DISPLAY(panel)); + binary = G_LOADED_BINARY(g_loaded_panel_get_content(panel)); + g_loaded_binary_remember_new_goto(binary, addr); + g_object_unref(G_OBJECT(binary)); + gtk_display_panel_request_move(GTK_DISPLAY_PANEL(panel), addr); g_object_unref(G_OBJECT(panel)); -- cgit v0.11.2-87-g4458