summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-12-31 17:03:56 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-12-31 17:03:56 (GMT)
commit0846c211ca24bc4e88bbc517362e1e08deb837b5 (patch)
treef8467d2f3812142c688f4f2f30a7c23afadfe9d3 /src
parent4d9b68040b6147215947d5c5a0c67e9e478fba1c (diff)
Remembered the target locations used in the Goto dialog box.
Diffstat (limited to 'src')
-rw-r--r--src/analysis/binary.c281
-rw-r--r--src/analysis/binary.h8
-rw-r--r--src/analysis/loaded-int.h2
-rw-r--r--src/analysis/loaded.c2
-rw-r--r--src/analysis/loaded.h2
-rw-r--r--src/gui/dialogs/goto.c42
-rw-r--r--src/gui/menus/edition.c6
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 <i18n.h>
+#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));