summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2012-10-28 15:59:12 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2012-10-28 15:59:12 (GMT)
commitc3aba0893c29cc098c029306fd7a4c8c1fa2eee2 (patch)
tree49432db1af3115758a216ac5bfd92d5935929858
parent55866b34f5cff022a465d58f808450f25f354218 (diff)
Updated the code of the old panel and displayed found strings again.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@276 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog33
-rw-r--r--src/arch/archbase.c9
-rwxr-xr-xsrc/format/dex/dex.c8
-rw-r--r--src/format/dex/pool.c38
-rw-r--r--src/format/dex/pool.h3
-rw-r--r--src/format/symbol.c2
-rw-r--r--src/gtkext/easygtk.c38
-rw-r--r--src/gtkext/easygtk.h3
-rw-r--r--src/gui/panels/Makefile.am1
-rw-r--r--src/gui/panels/panel-int.h2
-rw-r--r--src/gui/panels/panel.c206
-rw-r--r--src/gui/panels/strings.c392
-rw-r--r--src/gui/panels/strings.h65
-rw-r--r--src/gui/panels/symbols.c6
-rw-r--r--src/gui/panels/symbols.h2
15 files changed, 753 insertions, 55 deletions
diff --git a/ChangeLog b/ChangeLog
index f4f1c1d..af9d3e2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+12-10-28 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/arch/archbase.c:
+ Remove GCC warnings about print format.
+
+ * src/format/dex/dex.c:
+ * src/format/dex/pool.c:
+ * src/format/dex/pool.h:
+ Register all strings found in the Dex pool.
+
+ * src/format/symbol.c:
+ Remove a GCC warning by fixing a typo.
+
+ * src/gtkext/easygtk.c:
+ * src/gtkext/easygtk.h:
+ Provide a function to create menus with image.
+
+ * src/gui/panels/Makefile.am:
+ Add the strings.[ch] files to libguipanels_la_SOURCES.
+
+ * src/gui/panels/panel.c:
+ * src/gui/panels/panel-int.h:
+ Rewrite some parts of the code to improve panel docking.
+
+ * src/gui/panels/strings.c:
+ * src/gui/panels/strings.h:
+ Move entries: update the code of the old panel and display found
+ strings again.
+
+ * src/gui/panels/symbols.c:
+ * src/gui/panels/symbols.h:
+ Typo and clean the code.
+
12-10-22 Cyrille Bagard <nocbos@gmail.com>
* src/panel/log.c:
diff --git a/src/arch/archbase.c b/src/arch/archbase.c
index 61e2396..6241164 100644
--- a/src/arch/archbase.c
+++ b/src/arch/archbase.c
@@ -24,6 +24,7 @@
#include "archbase.h"
+#include <inttypes.h>
#include <stdio.h>
@@ -49,22 +50,22 @@ size_t vmpa_to_string(vmpa_t addr, MemoryDataSize msize, char buffer[VMPA_MAX_SI
switch (msize)
{
case MDS_8_BITS:
- snprintf(buffer, VMPA_MAX_SIZE,"0x%02llx", addr);
+ snprintf(buffer, VMPA_MAX_SIZE,"0x%02" PRIx64, addr);
result = 4;
break;
case MDS_16_BITS:
- snprintf(buffer, VMPA_MAX_SIZE, "0x%04llx", addr);
+ snprintf(buffer, VMPA_MAX_SIZE, "0x%04" PRIx64, addr);
result = 6;
break;
case MDS_32_BITS:
- snprintf(buffer, VMPA_MAX_SIZE, "0x%08llx", addr);
+ snprintf(buffer, VMPA_MAX_SIZE, "0x%08" PRIx64, addr);
result = 10;
break;
case MDS_64_BITS:
- snprintf(buffer, VMPA_MAX_SIZE, "0x%016llx", addr);
+ snprintf(buffer, VMPA_MAX_SIZE, "0x%016" PRIx64, addr);
result = 18;
break;
diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c
index b286f7c..f0fb421 100755
--- a/src/format/dex/dex.c
+++ b/src/format/dex/dex.c
@@ -197,6 +197,14 @@ GBinFormat *g_dex_format_new(const bin_t *content, off_t length)
g_dex_format_find_all_sources(result);
+
+ if (!find_all_dex_strings(result))
+ {
+ g_object_unref(G_OBJECT(result));
+ return NULL;
+ }
+
+
return G_BIN_FORMAT(result);
}
diff --git a/src/format/dex/pool.c b/src/format/dex/pool.c
index 9237839..f8c5a4a 100644
--- a/src/format/dex/pool.c
+++ b/src/format/dex/pool.c
@@ -24,6 +24,9 @@
#include "pool.h"
+#include <string.h>
+
+
#include "dex-int.h"
#include "../mangling/demangler.h"
@@ -31,6 +34,41 @@
/******************************************************************************
* *
+* Paramètres : format = description de l'exécutable à analyser. *
+* *
+* Description : Charge en mémoire toutes les chaînes trouvées. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool find_all_dex_strings(GDexFormat *format)
+{
+ uint32_t i; /* Boucle de parcours */
+ const char *text; /* Texte issu du binaire */
+ GBinSymbol *symbol; /* Nouveau symbole construit */
+
+ for (i = 0; i < format->header.string_ids_size; i++)
+ {
+ text = get_string_from_dex_pool(format, i);
+ if (text == NULL) continue;
+
+ symbol = g_binary_symbol_new(STP_STRING, NULL, i);
+ g_binary_symbol_set_alt_name(symbol, strdup(text));
+
+ g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
+
+ }
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : format = représentation interne du format DEX à consulter. *
* index = index du type recherchée. *
* *
diff --git a/src/format/dex/pool.h b/src/format/dex/pool.h
index 6894da1..62c3aef 100644
--- a/src/format/dex/pool.h
+++ b/src/format/dex/pool.h
@@ -30,6 +30,9 @@
+/* Charge en mémoire toutes les chaînes trouvées. */
+bool find_all_dex_strings(GDexFormat *);
+
/* Extrait une chaîne de caractères d'une table DEX. */
const char *get_string_from_dex_pool(const GDexFormat *, uint32_t);
diff --git a/src/format/symbol.c b/src/format/symbol.c
index 3ac2d6d..986586c 100644
--- a/src/format/symbol.c
+++ b/src/format/symbol.c
@@ -247,7 +247,7 @@ off_t g_binary_symbol_get_size(const GBinSymbol *symbol)
void g_binary_symbol_set_alt_name(GBinSymbol *symbol, char *alt)
{
- return symbol->alt = alt;
+ symbol->alt = alt;
}
diff --git a/src/gtkext/easygtk.c b/src/gtkext/easygtk.c
index cdf3689..8aea549 100644
--- a/src/gtkext/easygtk.c
+++ b/src/gtkext/easygtk.c
@@ -557,6 +557,44 @@ GtkWidget *qck_create_menu_item(GObject *object, const char *name, const char *c
* *
* Paramètres : object = espace dédié à l'inscription de références. *
* name = nom à donner au nouveau composant. *
+* id = identifiant du menu prédéfini. *
+* handler = éventuelle fonction de sélection associée. *
+* data = données à transmettre avec l'événement si besoin. *
+* *
+* Description : Crée et enregistre un composant 'GtkImageMenuItem'. *
+* *
+* Retour : Simple élément de menu mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GtkWidget *qck_create_menu_item_with_stock_img(GObject *object, const char *name, const char *id, GCallback handler, gpointer data)
+{
+ GtkWidget *result; /* Résultat à renvoyer */
+
+ result = gtk_image_menu_item_new_from_stock(id, NULL);
+
+ if (G_IS_OBJECT(object) && name != NULL)
+ {
+ g_object_ref(G_OBJECT(result));
+ g_object_set_data_full(object, name, result, (GDestroyNotify)g_object_unref);
+ }
+
+ gtk_widget_show(result);
+
+ if (handler != NULL)
+ g_signal_connect(result, "activate", handler, data);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : object = espace dédié à l'inscription de références. *
+* name = nom à donner au nouveau composant. *
* caption = intitulé du menu à créer. *
* handler = éventuelle fonction de sélection associée. *
* data = données à transmettre avec l'événement si besoin. *
diff --git a/src/gtkext/easygtk.h b/src/gtkext/easygtk.h
index e46efee..ea234e0 100644
--- a/src/gtkext/easygtk.h
+++ b/src/gtkext/easygtk.h
@@ -77,6 +77,9 @@ GtkWidget *qck_create_combobox(GObject *, const char *, GCallback, gpointer);
/* Crée et enregistre un composant 'GtkMenuItem'. */
GtkWidget *qck_create_menu_item(GObject *, const char *, const char *, GCallback, gpointer);
+/* Crée et enregistre un composant 'GtkImageMenuItem'. */
+GtkWidget *qck_create_menu_item_with_stock_img(GObject *, const char *, const char *, GCallback, gpointer);
+
/* Crée et enregistre un composant 'GtkCheckMenuItem'. */
GtkWidget *qck_create_check_menu_item(GObject *, const char *, const char *, GCallback, gpointer);
diff --git a/src/gui/panels/Makefile.am b/src/gui/panels/Makefile.am
index 2678d54..f2ea661 100644
--- a/src/gui/panels/Makefile.am
+++ b/src/gui/panels/Makefile.am
@@ -4,6 +4,7 @@ noinst_LTLIBRARIES = libguipanels.la
libguipanels_la_SOURCES = \
log.h log.c \
panel.h panel.c \
+ strings.h strings.c \
symbols.h symbols.c \
welcome.h welcome.c
diff --git a/src/gui/panels/panel-int.h b/src/gui/panels/panel-int.h
index e1c8932..def1934 100644
--- a/src/gui/panels/panel-int.h
+++ b/src/gui/panels/panel-int.h
@@ -56,7 +56,7 @@ typedef struct _panel_node
{
struct _panel_node *parent; /* Noeud parent */
- char path; /* Chemin du nom courant */
+ char *path; /* Chemin du nom courant */
size_t depth; /* Profondeur utilisée */
bool simple; /* Noeud sans division */
diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c
index cf4423d..3ad60b6 100644
--- a/src/gui/panels/panel.c
+++ b/src/gui/panels/panel.c
@@ -32,6 +32,7 @@
#include "log.h"
#include "panel-int.h"
+#include "strings.h"
#include "symbols.h"
#include "welcome.h"
#include "../../gtkext/easygtk.h"
@@ -71,8 +72,14 @@ static void switch_panel_node_into_paned(panel_node *, bool, bool);
/* Met en place un nouveau noeud dans une division. */
static void attach_panel_node_to_paned(panel_node *, panel_node *, bool);
-/* Indique si un noeud correspond à la branche recherchée. */
-static bool is_panel_node_matching(const panel_node *, char);
+/* Valorise la correspondance entre un noeud et un chemin. */
+static int compute_panel_node_matching_score(const panel_node *, const char *);
+
+/* Calcule la longueur du plus court chemin vers un 'M'. */
+static size_t _compute_panel_node_main_level(const panel_node *);
+
+/* Recherche le noeud constituant la branche principale. */
+static panel_node *find_main_panel_node_branch(panel_node *, panel_node *);
/* Place au bon endroit un panneau donné. */
static void insert_item_as_panel_node(GPanelItem *, panel_node *, const char *, size_t);
@@ -350,6 +357,9 @@ void load_main_panels(GObject *ref)
item = create_symbols_panel(ref);
g_panel_item_dock(item);
+ item = create_strings_panel(ref);
+ g_panel_item_dock(item);
+
}
@@ -380,7 +390,7 @@ static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const cha
result = (panel_node *)calloc(1, sizeof(panel_node));
- result->path = path[depth];
+ result->path = strdup(path);
result->depth = depth;
result->simple = true;
@@ -438,7 +448,7 @@ static void switch_panel_node_into_paned(panel_node *current, bool horiz, bool f
/* Achève la transformation */
- current->path = '\0';
+ current->path = NULL;
current->simple = false;
@@ -507,7 +517,51 @@ static void attach_panel_node_to_paned(panel_node *parent, panel_node *node, boo
* Paramètres : node = noeud d'où lancer les recherches. *
* target = identifiant de la position visée. *
* *
-* Description : Indique si un noeud correspond à la branche recherchée. *
+* Description : Valorise la correspondance entre un noeud et un chemin. *
+* *
+* Retour : Bilan de l'évaluation. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int compute_panel_node_matching_score(const panel_node *node, const char *target)
+{
+ int result; /* Bilan à retourner */
+ size_t len; /* Longueur de comparaison */
+ size_t i; /* Boucle de parcours */
+
+ if (node->simple)
+ {
+ result = 0;
+
+ len = strlen(node->path);
+ len = MIN(len, strlen(target));
+
+ for (i = 0; i < len; i++)
+ {
+ if (node->path[i] != target[i]) break;
+ else result++;
+ }
+
+ }
+
+ else
+ {
+ result = compute_panel_node_matching_score(node->first, target);
+ result = MAX(result, compute_panel_node_matching_score(node->second, target));
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : node = noeud d'où lancer les recherches. *
+* *
+* Description : Calcule la longueur du plus court chemin vers un 'M'. *
* *
* Retour : Bilan de l'évaluation. *
* *
@@ -515,16 +569,59 @@ static void attach_panel_node_to_paned(panel_node *parent, panel_node *node, boo
* *
******************************************************************************/
-static bool is_panel_node_matching(const panel_node *node, char target)
+static size_t _compute_panel_node_main_level(const panel_node *node)
{
- if (node->path == target)
- return true;
+ size_t result; /* Plus petit chemin à renvoyer*/
if (node->simple)
- return false;
+ {
+ result = strcspn(&node->path[node->depth], "M");
+
+ if (node->path[node->depth + result] == '\0')
+ result = SIZE_MAX;
- return is_panel_node_matching(node->first, target)
- || is_panel_node_matching(node->second, target);
+ }
+
+ else
+ {
+ result = _compute_panel_node_main_level(node->first);
+ result = MIN(result, _compute_panel_node_main_level(node->second));
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : a = première branche à analyser. *
+* b = seconde branche à analyser. *
+* *
+* Description : Recherche le noeud constituant la branche principale. *
+* *
+* Retour : Branche principale ou NULL si aucune n'est idéale. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static panel_node *find_main_panel_node_branch(panel_node *a, panel_node *b)
+{
+ panel_node *result; /* Trouvaille à remonter */
+ size_t main_a; /* Proximité du 'M' côté a */
+ size_t main_b; /* Proximité du 'M' côté b */
+
+ main_a = _compute_panel_node_main_level(a);
+ main_b = _compute_panel_node_main_level(b);
+
+ if (main_a == SIZE_MAX && main_b == SIZE_MAX)
+ result = NULL;
+
+ else
+ result = (main_a < main_b ? a : b);
+
+ return result;
}
@@ -550,15 +647,17 @@ static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const
bool horiz; /* Traduction en composant */
bool first; /* Point d'insertion */
panel_node *new; /* Nouveau noeud créé */
+ int score1; /* Score de la 1ère branche */
+ int score2; /* Score de la 2nde branche */
panel_node *support; /* Noeud d'accueil désigné */
if (node->simple)
{
/* Si on est sur la bonne voie... */
- if (path[depth] == '\0' || path[depth] == node->path)
+ if (compute_panel_node_matching_score(node, path) > 0)
{
/* Le parcours s'arrête ici ! */
- if (path[depth] == '\0' || path[depth + 1] == '\0')
+ if (strcmp(node->path, path) == 0)
gtk_dock_panel_add_widget(GTK_DOCK_STATION(node->station),
G_EDITOR_ITEM(item)->widget,
G_EDITOR_ITEM(item)->name);
@@ -566,13 +665,13 @@ static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const
/* On ne peut aller plus loin, on doit diviser... */
else
{
- div = toupper(path[depth + 1]);
+ div = toupper(path[depth]);
first = (div == 'E' || div == 'S');
horiz = (div == 'W' || div == 'E');
switch_panel_node_into_paned(node, horiz, first);
- new = create_simple_panel_node_for_item(item, path, depth + 1);
+ new = create_simple_panel_node_for_item(item, path, depth);
attach_panel_node_to_paned(node, new, !first);
@@ -603,50 +702,64 @@ static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const
/* On regarde des autres côtés... */
- else if (is_panel_node_matching(node->first, path[depth]))
- insert_item_as_panel_node(item, node->first, path, depth + (node->first->simple ? 1 : 0));
-
- else if (is_panel_node_matching(node->second, path[depth]))
- insert_item_as_panel_node(item, node->second, path, depth + (node->second->simple ? 1 : 0));
-
- /* On doit diviser qqch... */
else
{
- /* Si l'élément doit passer en force */
- if (isupper(path[depth]))
- {
- div = path[depth];
- first = (div == 'E' || div == 'S');
- horiz = (div == 'W' || div == 'E');
+ score1 = compute_panel_node_matching_score(node->first, path);
+ score2 = compute_panel_node_matching_score(node->second, path);
- switch_panel_node_into_paned(node, horiz, first);
-
- new = create_simple_panel_node_for_item(item, path, depth);
+ /* Si une descente est possible... */
+ if (score1 > 0 || score2 > 0)
+ {
+ if (node->first->simple || node->second->simple)
+ depth++;
- attach_panel_node_to_paned(node, new, !first);
+ if (score1 > score2)
+ insert_item_as_panel_node(item, node->first, path, depth);
- rebuild_panels_interface(node);
+ else
+ insert_item_as_panel_node(item, node->second, path, depth);
}
+ /* Sinon, on doit diviser qqch... */
else
{
- if (is_panel_node_matching(node->second, 'M'))
- support = node->second;
+ /* Si l'élément doit passer en force */
+ if (isupper(path[depth]))
+ {
+ div = path[depth];
+ first = (div == 'E' || div == 'S');
+ horiz = (div == 'W' || div == 'E');
+
+ switch_panel_node_into_paned(node, horiz, first);
+
+ new = create_simple_panel_node_for_item(item, path, depth);
+
+ attach_panel_node_to_paned(node, new, !first);
+
+ rebuild_panels_interface(node);
+
+ }
+
else
- support = node->first;
+ {
+ support = find_main_panel_node_branch(node->first, node->second);
+ if (support == NULL)
+ support = node->first;
- div = toupper(path[depth]);
- first = (div == 'E' || div == 'S');
- horiz = (div == 'W' || div == 'E');
+ div = toupper(path[depth]);
+ first = (div == 'E' || div == 'S');
+ horiz = (div == 'W' || div == 'E');
- switch_panel_node_into_paned(support, horiz, first);
+ switch_panel_node_into_paned(support, horiz, first);
- new = create_simple_panel_node_for_item(item, path, depth);
+ new = create_simple_panel_node_for_item(item, path, depth);
- attach_panel_node_to_paned(support, new, !first);
+ attach_panel_node_to_paned(support, new, !first);
- rebuild_panels_interface(support);
+ rebuild_panels_interface(support);
+
+ }
}
@@ -796,6 +909,7 @@ static void set_panel_node_size_request(const panel_node *node, const GtkRequisi
GtkRequisition first_req; /* Taille demandée par n°1 */
GtkRequisition second_req; /* Taille demandée par n°2 */
gint handle_size; /* Taille de la séparation */
+ panel_node *main_node; /* Branche principale */
gint position; /* Position de la séparation */
bool can_lower; /* Diminution possible ? */
bool can_upper; /* Augmentation possible ? */
@@ -813,8 +927,10 @@ static void set_panel_node_size_request(const panel_node *node, const GtkRequisi
* Définitions des bornes dans chacun des cas.
*/
+ main_node = find_main_panel_node_branch(node->first, node->second);
+
/* Le premier noeud est le principal... */
- if (is_panel_node_matching(node->first, 'M'))
+ if (node->first == main_node)
{
if (GTK_IS_HPANED(node->paned))
position = (space->width * MAIN_PART_PERCENT) / 100;
@@ -827,7 +943,7 @@ static void set_panel_node_size_request(const panel_node *node, const GtkRequisi
}
/* Le second noeud est le principal... */
- else if (is_panel_node_matching(node->second, 'M'))
+ else if (node->second == main_node)
{
if (GTK_IS_HPANED(node->paned))
position = space->width - (space->width * MAIN_PART_PERCENT) / 100;
diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c
new file mode 100644
index 0000000..605a700
--- /dev/null
+++ b/src/gui/panels/strings.c
@@ -0,0 +1,392 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * strings.c - panneau d'affichage des chaînes de caractères
+ *
+ * Copyright (C) 2008-2012 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * 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 "strings.h"
+
+
+#include <inttypes.h>
+
+
+#include "panel-int.h"
+#include "../../common/extstr.h"
+#include "../../gtkext/easygtk.h"
+
+
+
+/* -------------------------- PARTIE PRINCIPALE DU PANNEAU -------------------------- */
+
+
+/* Panneau d'aperçu de graphiques (instance) */
+struct _GStringsPanel
+{
+ GPanelItem parent; /* A laisser en premier */
+
+ GtkTreeView *treeview; /* Composant d'affichage */
+ GtkTreeStore *store; /* Modèle de gestion */
+
+ GLoadedBinary *binary; /* Binaire à prendre en compte */
+
+ GtkWidget *menubar; /* Support pour l'édition */
+
+};
+
+
+/* Panneau d'aperçu de graphiques (classe) */
+struct _GStringsPanelClass
+{
+ GPanelItemClass parent; /* A laisser en premier */
+
+};
+
+
+/* Colonnes de la liste des symboles */
+typedef enum _StringsColumn
+{
+ STC_ADDRESS, /* Adresse mémoire du symbole */
+ STC_STRING, /* Désignation humaine */
+ STC_RAW, /* Données non retouchées */
+
+ STC_COUNT /* Nombre de colonnes */
+
+} StringsColumn;
+
+
+/* Réagit à un changement d'affichage principal de contenu. */
+static void change_strings_panel_current_binary(GStringsPanel *, GLoadedBinary *);
+
+
+
+/* ------------------------- GESTIONS DES MENUS CONTEXTUELS ------------------------- */
+
+
+/* Affiche le menu d'édition propre aux chaînes trouvées. */
+static gboolean on_strings_button_press_event(GtkTreeView *, GdkEventButton *, GStringsPanel *);
+
+/* Réagit avec le menu "--- -> Copier". */
+static void mcb_strings_copy(GtkMenuItem *, GtkTreeView *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* PARTIE PRINCIPALE DU PANNEAU */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type définit pour un panneau d'aperçu de graphiques. */
+G_DEFINE_TYPE(GStringsPanel, g_strings_panel, G_TYPE_PANEL_ITEM);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des panneaux d'aperçu de graphiques. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_strings_panel_class_init(GStringsPanelClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : panel = instance à initialiser. *
+* *
+* Description : Initialise une instance de panneau d'aperçu de graphiques. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_strings_panel_init(GStringsPanel *panel)
+{
+ GEditorItem *base; /* Version basique d'instance */
+ GObject *ref; /* Espace de référencement */
+ GtkWidget *scrollwnd; /* Support défilant */
+ 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 */
+ GtkWidget *submenuitem; /* Sous-élément de menu */
+
+ base = G_EDITOR_ITEM(panel);
+
+ base->widget = gtk_vbox_new(FALSE, 0);
+ gtk_widget_show(base->widget);
+
+ ref = G_OBJECT(base->widget);
+ g_object_set_data(ref, "panel", panel);
+
+ /* Liste des chaînes */
+
+ scrollwnd = gtk_scrolled_window_new(NULL, NULL);
+ gtk_widget_show(scrollwnd);
+ gtk_box_pack_start(GTK_BOX(base->widget), 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(STC_COUNT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+ g_object_set_data(G_OBJECT(panel), "store", store);
+
+ treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
+ gtk_widget_show(treeview);
+ gtk_container_add(GTK_CONTAINER(scrollwnd), treeview);
+
+ g_object_unref(G_OBJECT(store));
+
+ column = gtk_tree_view_column_new();
+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+ gtk_tree_view_set_expander_column(GTK_TREE_VIEW(treeview), column);
+
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(_("Address"), renderer,
+ "text", STC_ADDRESS, 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(_("String"), renderer,
+ "markup", STC_STRING, NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+
+ /* Menu contextuel */
+
+ panel->menubar = gtk_menu_new();
+
+ submenuitem = qck_create_menu_item_with_stock_img(NULL, NULL, GTK_STOCK_COPY,
+ G_CALLBACK(mcb_strings_copy), treeview);
+ gtk_container_add(GTK_CONTAINER(panel->menubar), submenuitem);
+
+ submenuitem = qck_create_menu_item(NULL, NULL, _("Find references..."), NULL, NULL);
+ gtk_container_add(GTK_CONTAINER(panel->menubar), submenuitem);
+
+ g_signal_connect(G_OBJECT(treeview), "button_release_event",
+ G_CALLBACK(on_strings_button_press_event), panel);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ref = espace de référencement global. *
+* *
+* Description : Crée un panneau d'affichage des symboles. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GEditorItem *g_strings_panel_new(GObject *ref)
+{
+ GEditorItem *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_STRINGS_PANEL, NULL);
+
+ g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_STRINGS_ID,
+ _("Strings"), G_EDITOR_ITEM(result)->widget, "SE");
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ref = espace de référencement global. *
+* *
+* Description : Construit et intègre un panneau d'affichage des symboles. *
+* *
+* Retour : Adresse du panneau mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GPanelItem *create_strings_panel(GObject *ref)
+{
+ GEditorItem *result; /* Elément réactif à renvoyer */
+
+ result = g_strings_panel_new(ref);
+
+ /* Enregistre correctement le tout */
+ result->update_binary = (update_item_binary_fc)change_strings_panel_current_binary;
+ register_editor_item(result);
+
+ return G_PANEL_ITEM(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : panel = panneau à mettre à jour. *
+* binary = nouvelle instance de binaire analysé. *
+* *
+* Description : Réagit à un changement d'affichage principal de contenu. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void change_strings_panel_current_binary(GStringsPanel *panel, GLoadedBinary *binary)
+{
+ GtkTreeStore *store; /* Modèle de gestion */
+ GExeFormat *format; /* Format de travail */
+ size_t count; /* Nombre des chaînes */
+ GBinSymbol **symbols; /* Liste des chaînes trouvées */
+ size_t i; /* Boucle de parcours */
+ char address[VMPA_MAX_SIZE]; /* Conversion de l'adresse */
+ const char *raw; /* Texte brut trouvé */
+ char *text; /* Version imprimable du texte */
+ GtkTreeIter iter; /* Point d'insertion */
+
+ store = g_object_get_data(G_OBJECT(panel), "store");
+
+ format = g_loaded_binary_get_format(binary);
+ symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &count);
+
+ for (i = 0; i < count; i++)
+ {
+ if (g_binary_symbol_get_target_type(symbols[i]) != STP_STRING) continue;
+
+ /* FIXME : adresses autres que 32 bits */
+ snprintf(address, VMPA_MAX_SIZE, "0x%08" PRIx64, g_binary_symbol_get_address(symbols[i]));
+
+ raw = g_binary_symbol_to_string(symbols[i]);
+
+ text = strdup(raw);
+ text = strrpl(text, "&", "&amp;");
+ text = strrpl(text, "<", "&lt;");
+ text = strrpl(text, ">", "&gt;");
+ text = strrpl(text, "\r", "<b>\\r</b>");
+ text = strrpl(text, "\n", "<b>\\n</b>");
+
+ gtk_tree_store_append(store, &iter, NULL);
+ gtk_tree_store_set(store, &iter,
+ STC_ADDRESS, address,
+ STC_STRING, text,
+ STC_RAW, raw,
+ -1);
+
+ free(text);
+
+ }
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* GESTIONS DES MENUS CONTEXTUELS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : treeview = composant GTK visé par l'opération. *
+* event = informations liées à l'événement. *
+* data = référence vers le panneau contenant le menu. *
+* *
+* Description : Affiche le menu d'édition propre aux chaînes trouvées. *
+* *
+* Retour : FALSE pour poursuivre la propagation de l'événement. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gboolean on_strings_button_press_event(GtkTreeView *treeview, GdkEventButton *event, GStringsPanel *panel)
+{
+ gboolean result; /* Bilan d'action à renvoyer */
+
+ result = FALSE;
+
+ if (event->type == GDK_BUTTON_RELEASE && event->button == 3)
+ {
+ gtk_menu_popup(GTK_MENU(panel->menubar),
+ NULL, NULL, NULL, NULL,
+ event->button, event->time);
+
+ result = TRUE;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : menuitem = élément de menu sélectionné. *
+* treeview = arbre contenant la sélection à exporter. *
+* *
+* Description : Réagit avec le menu "--- -> Copier". *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void mcb_strings_copy(GtkMenuItem *menuitem, GtkTreeView *treeview)
+{
+ GtkTreeSelection *selection; /* Sélection de l'arbre */
+ GtkTreeIter iter; /* Point de sélection */
+ GtkTreeModel *model; /* Modèle de gestion */
+ gchar *string; /* Chaîne sélectionnée */
+ GtkClipboard *clipboard; /* Presse-papiers d'arrivée */
+
+ selection = gtk_tree_view_get_selection(treeview);
+
+ if (gtk_tree_selection_get_selected(selection, &model, &iter))
+ {
+ gtk_tree_model_get(model, &iter, STC_RAW, &string, -1);
+
+ if (string != NULL)
+ {
+ clipboard = gtk_clipboard_get_for_display(gdk_display_get_default(),
+ GDK_SELECTION_PRIMARY);
+
+ gtk_clipboard_set_text(clipboard, string, strlen(string));
+ g_free(string);
+
+ }
+
+ }
+
+}
diff --git a/src/gui/panels/strings.h b/src/gui/panels/strings.h
new file mode 100644
index 0000000..2ac2fbf
--- /dev/null
+++ b/src/gui/panels/strings.h
@@ -0,0 +1,65 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * strings.h - prototypes pour le panneau d'affichage des chaînes de caractères
+ *
+ * Copyright (C) 2008-2012 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * 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_STRINGS_H
+#define _GUI_PANELS_STRINGS_H
+
+
+#include <i18n.h>
+
+
+#include "panel.h"
+
+
+
+#define PANEL_STRINGS_ID _("Strings")
+
+
+#define G_TYPE_STRINGS_PANEL g_strings_panel_get_type()
+#define G_STRINGS_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_strings_panel_get_type(), GStringsPanel))
+#define G_IS_STRINGS_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_strings_panel_get_type()))
+#define G_STRINGS_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_STRINGS_PANEL, GStringsPanelClass))
+#define G_IS_STRINGS_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_STRINGS_PANEL))
+#define G_STRINGS_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_STRINGS_PANEL, GStringsPanelClass))
+
+
+/* Panneau d'affichage des symboles (instance) */
+typedef struct _GStringsPanel GStringsPanel;
+
+/* Panneau d'affichage des symboles (classe) */
+typedef struct _GStringsPanelClass GStringsPanelClass;
+
+
+/* Indique le type définit pour un panneau d'affichage des symboles. */
+GType g_strings_panel_get_type(void);
+
+/* Crée un panneau d'affichage des symboles. */
+GEditorItem *g_strings_panel_new(GObject *);
+
+/* Construit et intègre un panneau d'affichage des symboles. */
+GPanelItem *create_strings_panel(GObject *);
+
+
+
+#endif /* _GUI_PANELS_STRINGS_H */
diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c
index c51b2d1..87cdfa4 100644
--- a/src/gui/panels/symbols.c
+++ b/src/gui/panels/symbols.c
@@ -84,7 +84,7 @@ static void g_symbols_panel_init(GSymbolsPanel *);
static void on_symbols_selection_change(GtkTreeSelection *, GSymbolsPanel *);
/* Réagit à un changement d'affichage principal de contenu. */
-void change_symbols_panel_current_binary(GSymbolsPanel *, GLoadedBinary *);
+static void change_symbols_panel_current_binary(GSymbolsPanel *, GLoadedBinary *);
@@ -296,7 +296,7 @@ GEditorItem *g_symbols_panel_new(GObject *ref)
result = g_object_new(G_TYPE_SYMBOLS_PANEL, NULL);
- g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_SYMBOL_ID,
+ g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_SYMBOLS_ID,
_("Binary symbols"), G_EDITOR_ITEM(result)->widget, "e");
return result;
@@ -383,7 +383,7 @@ static void on_symbols_selection_change(GtkTreeSelection *selection, GSymbolsPan
* *
******************************************************************************/
-void change_symbols_panel_current_binary(GSymbolsPanel *panel, GLoadedBinary *binary)
+static void change_symbols_panel_current_binary(GSymbolsPanel *panel, GLoadedBinary *binary)
{
GtkToggleToolButton *button; /* Mode de représentation */
GtkRequisition req; /* Nouvelle taille idéale */
diff --git a/src/gui/panels/symbols.h b/src/gui/panels/symbols.h
index 182238a..1a9316d 100644
--- a/src/gui/panels/symbols.h
+++ b/src/gui/panels/symbols.h
@@ -33,7 +33,7 @@
-#define PANEL_SYMBOL_ID _("Symbols")
+#define PANEL_SYMBOLS_ID _("Symbols")
#define G_TYPE_SYMBOLS_PANEL g_symbols_panel_get_type()