summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2012-07-01 11:52:52 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2012-07-01 11:52:52 (GMT)
commit5dcd05f19ac62f6ff922176cd0ae6f8839910f2e (patch)
tree6fbf5798a57ab6874b68b6ea523619481013c814
parent51dff92af8ca82ac1cce3f74be70c3705ca88683 (diff)
Built the graph view when defining a target address.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@247 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog21
-rw-r--r--src/analysis/binary.c20
-rw-r--r--src/analysis/disass/disassembler.c5
-rw-r--r--src/analysis/disass/disassembler.h4
-rw-r--r--src/format/dex/method.c2
-rw-r--r--src/glibext/gcodebuffer.c12
-rw-r--r--src/graph/node.c13
-rw-r--r--src/gtkext/gtkgraphview.c78
-rw-r--r--src/gtkext/gtkviewpanel-int.h4
-rw-r--r--src/gtkext/gtkviewpanel.c6
10 files changed, 122 insertions, 43 deletions
diff --git a/ChangeLog b/ChangeLog
index 6968d8a..09f90ee 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+12-07-01 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/analysis/binary.c:
+ * src/analysis/disass/disassembler.c:
+ * src/analysis/disass/disassembler.h:
+ Provide disassembled instructions when done with disassembling.
+
+ * src/format/dex/method.c:
+ Set the method size.
+
+ * src/glibext/gcodebuffer.c:
+ Draw the restricted part of the buffer correctly.
+
+ * src/graph/node.c:
+ Typo.
+
+ * src/gtkext/gtkgraphview.c:
+ * src/gtkext/gtkviewpanel.c:
+ * src/gtkext/gtkviewpanel-int.h:
+ Build the graph view when defining a target address.
+
12-06-30 Cyrille Bagard <nocbos@gmail.com>
* src/glibext/gcodebuffer.c:
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 53da917..45e6d31 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -96,6 +96,7 @@ struct _GOpenidaBinary
GRenderingLine *lines; /* Lignes de rendu en place */
GRenderingOptions *options; /* Options de désassemblage */
+ GArchInstruction *instrs; /* Instructions d'assemblage */
GCodeBuffer *disass_buffer; /* Instructions lisibles */
GCodeBuffer **dec_buffers; /* Sources sous forme de texte */
size_t decbuf_count; /* Taille des tableaux */
@@ -834,7 +835,7 @@ void g_openida_binary_analyse(GOpenidaBinary *binary)
}
}
- binary->disass_buffer = disassemble_binary(binary, parts, parts_count);
+ binary->disass_buffer = disassemble_binary(binary, parts, parts_count, &binary->instrs);
/* TODO : remme ! */
ack_completed_disassembly(NULL, binary);
@@ -993,22 +994,7 @@ GRenderingLine *g_openida_binary_get_lines(const GOpenidaBinary *binary)
GArchInstruction *g_openida_binary_get_instructions(const GOpenidaBinary *binary)
{
- GArchInstruction *result; /* Liste à renvoyer */
- GRenderingLine *iter; /* Boucle de parcours */
-
- result = NULL;
-
- for (iter = binary->lines;
- iter != NULL;
- iter = g_rendering_line_get_next_iter(binary->lines, iter, NULL))
- {
- if (G_IS_CODE_LINE(iter)) break;
- }
-
- if (iter != NULL)
- result = g_code_line_get_instruction(G_CODE_LINE(iter));
-
- return result;
+ return binary->instrs;
}
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index c270389..5a866c0 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -368,6 +368,7 @@ static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, con
* Paramètres : binary = représentation de binaire chargé. *
* parts = parties binaires à désassembler. *
* count = nombre de parties à traiter. *
+* instrs = liste des instructions chargées. [OUT] *
* *
* Description : Procède au désassemblage d'un contenu binaire donné. *
* *
@@ -377,7 +378,7 @@ static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, con
* *
******************************************************************************/
-GCodeBuffer *disassemble_binary(const GOpenidaBinary *binary, GBinPart **parts, size_t parts_count)
+GCodeBuffer *disassemble_binary(const GOpenidaBinary *binary, GBinPart **parts, size_t parts_count, GArchInstruction **instrs)
{
GCodeBuffer *result; /* Tampon constitué à renvoyer */
const uint8_t *data; /* Données binaires brutes */
@@ -397,6 +398,8 @@ GCodeBuffer *disassemble_binary(const GOpenidaBinary *binary, GBinPart **parts,
g_delayed_work_wait_for_completion(G_DELAYED_WORK(disass));
+ *instrs = disass->instrs;
+
g_object_unref(G_OBJECT(disass));
return result;
diff --git a/src/analysis/disass/disassembler.h b/src/analysis/disass/disassembler.h
index 7cfdcc5..2a0f72a 100644
--- a/src/analysis/disass/disassembler.h
+++ b/src/analysis/disass/disassembler.h
@@ -2,7 +2,7 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
* disassembler.h - prototypes pour l'encadrement des phases de désassemblage
*
- * Copyright (C) 2010 Cyrille Bagard
+ * Copyright (C) 2010-2012 Cyrille Bagard
*
* This file is part of OpenIDA.
*
@@ -31,7 +31,7 @@
/* Procède à la décompilation des routines d'un fichier donné. */
-GCodeBuffer *disassemble_binary(const GOpenidaBinary *, GBinPart **parts, size_t parts_count);
+GCodeBuffer *disassemble_binary(const GOpenidaBinary *, GBinPart **parts, size_t parts_count, GArchInstruction **);
diff --git a/src/format/dex/method.c b/src/format/dex/method.c
index 95f121a..cca03a7 100644
--- a/src/format/dex/method.c
+++ b/src/format/dex/method.c
@@ -161,7 +161,7 @@ GDexMethod *g_dex_method_new(const GDexFormat *format, const encoded_method *see
g_binary_routine_set_address(routine, result->offset);
-
+ g_binary_routine_set_size(routine, item.insns_size * sizeof(uint16_t));
result->routine = routine;
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
index d5dbc8c..97d6505 100644
--- a/src/glibext/gcodebuffer.c
+++ b/src/glibext/gcodebuffer.c
@@ -731,7 +731,7 @@ void g_buffer_view_get_size(GBufferView *view, gint *width, gint *height, bool a
first = g_code_buffer_get_index_from_address(view->buffer, view->start);
last = g_code_buffer_get_index_from_address(view->buffer, view->end);
- *height *= (last - first);
+ *height *= (last - first + 1);
}
@@ -783,6 +783,7 @@ void g_buffer_view_draw(const GBufferView *view, const GdkEventExpose *event, Gd
gint real_y; /* Ordonnée réelle pour tampon */
size_t first; /* Première ligne visée */
+ size_t end; /* Dernière ligne avant limite */
size_t last; /* Dernière ligne visée + 1 */
gint y; /* Point de départ + décallage */
@@ -799,16 +800,17 @@ void g_buffer_view_draw(const GBufferView *view, const GdkEventExpose *event, Gd
- first = (real_y / view->line_height);
+ first = g_code_buffer_get_index_from_address(view->buffer, view->start);
+ first += (real_y / view->line_height);
+
last = first + (event->area.height / view->line_height);
if (event->area.height % view->line_height > 0) last++;
- last = MIN(last, view->buffer->used > 0 ? view->buffer->used - 1 : 0);
+ end = g_code_buffer_get_index_from_address(view->buffer, view->end);
+ last = MIN(last, end);
y = event->area.y - (real_y % view->line_height);
-
-
lines = view->buffer->lines;
if (view->buffer->used > 0)
diff --git a/src/graph/node.c b/src/graph/node.c
index 3e6cc14..0d278f3 100644
--- a/src/graph/node.c
+++ b/src/graph/node.c
@@ -203,17 +203,12 @@ char *g_graph_node_register_for_dot(const GGraphNode *node, char *cmds)
cmds = stradd(cmds, node->name);
cmds = stradd(cmds, " [shape=box, fixedsize ");
-
- printf(" req=(%d ; %d) -->> (%g ; %g)\n",
- requisition.width,
- requisition.height,
- requisition.width / G_GRAPH_NODE_GET_CLASS(node)->dpi_x,
- requisition.height / G_GRAPH_NODE_GET_CLASS(node)->dpi_y);
-
- snprintf(buffer, 128, ", width=\"%g\"", requisition.width / G_GRAPH_NODE_GET_CLASS(node)->dpi_x);
+ snprintf(buffer, 128, ", width=\"%g\"",
+ requisition.width / G_GRAPH_NODE_GET_CLASS(node)->dpi_x);
cmds = stradd(cmds, buffer);
- snprintf(buffer, 128, ", height=\"%g\"", requisition.height / G_GRAPH_NODE_GET_CLASS(node)->dpi_y);
+ snprintf(buffer, 128, ", height=\"%g\"",
+ requisition.height / G_GRAPH_NODE_GET_CLASS(node)->dpi_y);
cmds = stradd(cmds, buffer);
cmds = stradd(cmds, "];\n");
diff --git a/src/gtkext/gtkgraphview.c b/src/gtkext/gtkgraphview.c
index 263ab7d..8366c1f 100644
--- a/src/gtkext/gtkgraphview.c
+++ b/src/gtkext/gtkgraphview.c
@@ -27,6 +27,7 @@
#include "gtkblockview.h"
#include "gtkbufferview.h"
#include "gtkviewpanel-int.h"
+#include "../graph/layout.h"
@@ -41,7 +42,7 @@ struct _GtkGraphView
vmpa_t start; /* Début de la portion vue */
vmpa_t end; /* Fin de la portion affichée */
- GtkBlockView **childs; /* Liste des sous-blocs */
+ GtkViewPanel **childs; /* Liste des sous-blocs */
size_t childs_count; /* Taille de cette liste */
GtkLinkRenderer **links; /* Liste des liens graphiques */
@@ -73,6 +74,9 @@ static void gtk_graph_view_size_allocate(GtkWidget *, GtkAllocation *);
/* Met à jour l'affichage de la vue sous forme graphique. */
static gboolean gtk_graph_view_expose(GtkWidget *, GdkEventExpose *, GtkGraphView *);
+/* Réagit à la sélection externe d'une adresse. */
+static void gtk_graph_view_define_main_address(GtkGraphView *, vmpa_t);
+
/* Indique la position d'affichage d'une adresse donnée. */
static bool gtk_graph_view_get_address_coordinates(const GtkGraphView *, vmpa_t, gint *, gint *);
@@ -82,6 +86,9 @@ static void gtk_graph_view_scroll(GtkGraphView *);
/* Supprime tout contenu de l'afficheur de code en graphique. */
static void gtk_graph_view_reset(GtkGraphView *);
+/* Liste d'éléments du graphique à placer. */
+static GtkViewPanel **gtk_graph_view_load_nodes(GtkGraphView *, GOpenidaBinary *, vmpa_t, vmpa_t);
+
/* Détermine le type du composant d'affichage en graphique. */
@@ -132,6 +139,7 @@ static void gtk_graph_view_init(GtkGraphView *view)
viewpanel = GTK_VIEW_PANEL(view);
+ viewpanel->define = (define_address_fc)gtk_graph_view_define_main_address;
viewpanel->get_coordinates = (get_addr_coordinates_fc)gtk_graph_view_get_address_coordinates;
viewpanel->scroll = (scroll_fc)gtk_graph_view_scroll;
@@ -287,6 +295,61 @@ static gboolean gtk_graph_view_expose(GtkWidget *widget, GdkEventExpose *event,
/******************************************************************************
* *
+* Paramètres : view = composant GTK à mettre à jour. *
+* addr = adresse sélectionnée de manière externe. *
+* *
+* Description : Réagit à la sélection externe d'une adresse. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_graph_view_define_main_address(GtkGraphView *view, vmpa_t addr)
+{
+ GExeFormat *format; /* Type de fichier chargé */
+ GBinRoutine **routines; /* Liste des routines trouvées */
+ size_t routines_count; /* Nombre de ces routines */
+ size_t i; /* Boucle de parcours */
+ vmpa_t start; /* Début d'une routine */
+ vmpa_t end; /* Fin d'une routine */
+
+ if (!(view->start <= addr && addr < view->end))
+ {
+ gtk_graph_view_reset(view);
+
+ format = g_openida_binary_get_format(GTK_VIEW_PANEL(view)->binary);
+ routines = g_binary_format_get_routines(G_BIN_FORMAT(format), &routines_count);
+
+ for (i = 0; i < routines_count; i++)
+ {
+ start = g_binary_routine_get_address(routines[i]);
+ end = start + g_binary_routine_get_size(routines[i]);
+
+ if (start <= addr && addr < end)
+ {
+ view->start = start;
+ view->end = end;
+
+ view->childs = gtk_graph_view_load_nodes(view, GTK_VIEW_PANEL(view)->binary,
+ start, end);
+
+ build_graph_view(view, view->childs, view->childs_count);
+
+ break;
+
+ }
+
+ }
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : view = composant GTK à consulter. *
* addr = adresse à présenter à l'écran. *
* x = position horizontale au sein du composant. [OUT] *
@@ -495,6 +558,7 @@ static GtkViewPanel **gtk_graph_view_load_nodes(GtkGraphView *view, GOpenidaBina
code = g_openida_binary_display_code_in_text(binary);
first = start;
+ last = first;
for (iter = g_arch_instruction_find_by_address(list, start, true);
iter != NULL;
@@ -505,11 +569,13 @@ static GtkViewPanel **gtk_graph_view_load_nodes(GtkGraphView *view, GOpenidaBina
result = (GtkViewPanel **)realloc(result, ++(*count) * sizeof(GtkViewPanel *));
result[*count - 1] = GTK_VIEW_PANEL(gtk_block_view_new());
+ gtk_widget_show(result[*count - 1]);
+ gtk_view_panel_attach_binary(result[*count - 1], binary, addr, code);
gtk_view_panel_show_border(result[*count - 1], true);
subview = g_buffer_view_new(buffer);
- //g_buffer_view_restrict(subview, size_t first, size_t last);
+ g_buffer_view_restrict(subview, first, last);
gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(result[*count - 1]),
subview, addr, code);
@@ -525,11 +591,13 @@ static GtkViewPanel **gtk_graph_view_load_nodes(GtkGraphView *view, GOpenidaBina
result = (GtkViewPanel **)realloc(result, ++(*count) * sizeof(GtkViewPanel *));
result[*count - 1] = GTK_VIEW_PANEL(gtk_block_view_new());
+ gtk_widget_show(result[*count - 1]);
+ gtk_view_panel_attach_binary(result[*count - 1], binary, addr, code);
gtk_view_panel_show_border(result[*count - 1], true);
subview = g_buffer_view_new(buffer);
- //g_buffer_view_restrict(subview, size_t first, size_t last);
+ g_buffer_view_restrict(subview, first, last);
gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(result[*count - 1]),
subview, addr, code);
@@ -544,11 +612,13 @@ static GtkViewPanel **gtk_graph_view_load_nodes(GtkGraphView *view, GOpenidaBina
result = (GtkViewPanel **)realloc(result, ++(*count) * sizeof(GtkViewPanel *));
result[*count - 1] = GTK_VIEW_PANEL(gtk_block_view_new());
+ gtk_widget_show(result[*count - 1]);
+ gtk_view_panel_attach_binary(result[*count - 1], binary, addr, code);
gtk_view_panel_show_border(result[*count - 1], true);
subview = g_buffer_view_new(buffer);
- //g_buffer_view_restrict(subview, size_t first, size_t last);
+ g_buffer_view_restrict(subview, first, last);
gtk_buffer_view_attach_buffer(GTK_BUFFER_VIEW(result[*count - 1]),
subview, addr, code);
diff --git a/src/gtkext/gtkviewpanel-int.h b/src/gtkext/gtkviewpanel-int.h
index 446d182..a4edd06 100644
--- a/src/gtkext/gtkviewpanel-int.h
+++ b/src/gtkext/gtkviewpanel-int.h
@@ -36,6 +36,9 @@
/* Prend acte de l'association d'un binaire chargé. */
typedef void (* attach_binary_fc) (GtkViewPanel *, GOpenidaBinary *, bool *, bool *);
+/* Réagit à la sélection externe d'une adresse. */
+typedef void (* define_address_fc) (GtkViewPanel *, vmpa_t);
+
/* Indique la position d'affichage d'une adresse donnée. */
typedef bool (* get_addr_coordinates_fc) (const GtkViewPanel *, vmpa_t, gint *, gint *);
@@ -57,6 +60,7 @@ struct _GtkViewPanel
GOpenidaBinary *binary; /* Binaire à visualiser */
attach_binary_fc attach; /* Association avec un binaire */
+ define_address_fc define; /* Centrage sur une partie */
get_addr_coordinates_fc get_coordinates;/* Conversion adresse <-> pos. */
scroll_fc scroll; /* Défilement du contenu */
diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c
index 2dac981..326e4d8 100644
--- a/src/gtkext/gtkviewpanel.c
+++ b/src/gtkext/gtkviewpanel.c
@@ -517,10 +517,8 @@ void gtk_view_panel_scroll_to_address(const GtkViewPanel *panel, vmpa_t addr)
gint y; /* Ordonnée à garantir */
GtkAdjustment *adj; /* Défilement à mettre à jour */
- /* TODO
- if (panel->define_address != NULL)
- panel->define_address(panel, addr);
- */
+ if (panel->define != NULL)
+ panel->define(panel, addr);
if (panel->get_coordinates(panel, addr, &x, &y))
{