From 5dcd05f19ac62f6ff922176cd0ae6f8839910f2e Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 1 Jul 2012 11:52:52 +0000 Subject: 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 --- ChangeLog | 21 ++++++++++ src/analysis/binary.c | 20 ++-------- src/analysis/disass/disassembler.c | 5 ++- src/analysis/disass/disassembler.h | 4 +- src/format/dex/method.c | 2 +- src/glibext/gcodebuffer.c | 12 +++--- src/graph/node.c | 13 ++----- src/gtkext/gtkgraphview.c | 78 ++++++++++++++++++++++++++++++++++++-- src/gtkext/gtkviewpanel-int.h | 4 ++ src/gtkext/gtkviewpanel.c | 6 +-- 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 + + * 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 * 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)) { -- cgit v0.11.2-87-g4458