summaryrefslogtreecommitdiff
path: root/src/analysis/disass
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-02-15 22:58:40 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-02-15 22:58:40 (GMT)
commit16242be5838a77690946cbb2f30b2e89f2df0b94 (patch)
treed3c2b2725f41f2a0d45ae7f32e2ab9cb1886b230 /src/analysis/disass
parent5ed40f0afbd58fbfdf05be7b2a10ab8d0819759f (diff)
Displayed tooltips for graph view edges.
Diffstat (limited to 'src/analysis/disass')
-rw-r--r--src/analysis/disass/block.c349
1 files changed, 349 insertions, 0 deletions
diff --git a/src/analysis/disass/block.c b/src/analysis/disass/block.c
index 9fce202..3077dc2 100644
--- a/src/analysis/disass/block.c
+++ b/src/analysis/disass/block.c
@@ -28,7 +28,13 @@
#include <malloc.h>
+#include <i18n.h>
+
+
#include "../block-int.h"
+#include "../../arch/raw.h"
+#include "../../common/extstr.h"
+#include "../../core/params.h"
#include "../../glibext/gbinarycursor.h"
@@ -84,6 +90,9 @@ static block_link_t *g_basic_block_get_destinations(const GBasicBlock *, const G
/* Fournit la représentation graphique d'un bloc de code. */
static GBufferView *g_basic_block_build_view(const GBasicBlock *, segcnt_list *);
+/* Construit un ensemble d'indications pour bloc. */
+static char *g_basic_block_build_tooltip(const GBasicBlock *);
+
/* ---------------------------------------------------------------------------------- */
@@ -124,6 +133,7 @@ static void g_basic_block_class_init(GBasicBlockClass *class)
block->get_src = (block_get_links_fc)g_basic_block_get_sources;
block->get_dest = (block_get_links_fc)g_basic_block_get_destinations;
block->build = (block_build_view_fc)g_basic_block_build_view;
+ block->build_tooltip = (block_build_tooltip_fc)g_basic_block_build_tooltip;
}
@@ -499,6 +509,345 @@ static GBufferView *g_basic_block_build_view(const GBasicBlock *block, segcnt_li
/******************************************************************************
* *
+* Paramètres : block = bloc de code à consulter. *
+* *
+* Description : Construit un ensemble d'indications pour bloc. *
+* *
+* Retour : Informations à présenter sous forme de bulle d'aide. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_basic_block_build_tooltip(const GBasicBlock *block)
+{
+ char *result; /* Description à retourner */
+ const mrange_t *brange[2]; /* Emplacements d'instruction */
+ phys_t diff; /* Espacement entre adresses */
+ mrange_t range; /* Couverture du bloc */
+ char *name; /* Désignation de l'entête */
+ GBinFormat *format; /* Format associé au binaire */
+ GBinSymbol *symbol; /* Symbole lié au bloc */
+ char *label; /* Etiquette à insérer */
+ GBufferCache *cache; /* Tampon d'impression colorée */
+ GBufferLine *line; /* Ligne au contenu coloré */
+ VMPA_BUFFER(loc); /* Indication de position */
+ GGenConfig *config; /* Configuration à consulter */
+ unsigned int max_calls; /* Quantité d'appels à afficher*/
+ unsigned int max_strings; /* Nbre de chaînes à afficher */
+ unsigned int ins_count; /* Quantité d'instructions */
+ unsigned int call_count; /* Quantité d'appels */
+ char *call_info; /* Détails des appels */
+ unsigned int string_count; /* Quantité de chaînes */
+ char *string_info; /* Détails des chaînes */
+ GArchProcessor *proc; /* Architecture utilisée */
+ instr_iter_t *iter; /* Parcours local d'adresses */
+ GArchInstruction *instr; /* Instruction correspondante */
+ size_t dcount; /* Nombre de liens de dest. */
+ size_t i; /* Boucle de parcours */
+ const instr_link_t *dest; /* Instr. visée par une autre */
+ const mrange_t *irange; /* Emplacement d'instruction */
+ GLineCursor *cursor; /* Emplacement dans un tampon */
+ size_t index; /* Indice de ligne à traiter */
+ char *info; /* Ligne d'information créée */
+
+ /* Définition de la couverture du bloc */
+
+ brange[0] = g_arch_instruction_get_range(block->first);
+ brange[1] = g_arch_instruction_get_range(block->last);
+
+ diff = compute_vmpa_diff(get_mrange_addr(brange[0]), get_mrange_addr(brange[1]));
+
+ init_mrange(&range, get_mrange_addr(brange[0]), diff + get_mrange_length(brange[1]));
+
+ /* Recherche d'un symbole de départ */
+
+ name = NULL;
+
+ format = G_BIN_FORMAT(g_loaded_binary_get_format(block->binary));
+
+ if (g_binary_format_find_symbol_at(format, get_mrange_addr(brange[0]), &symbol))
+ {
+ label = g_binary_symbol_get_label(symbol);
+
+ if (label != NULL)
+ {
+ cache = g_buffer_cache_new(NULL);
+ g_buffer_cache_append(cache, G_LINE_GENERATOR(symbol), BLF_NONE);
+
+ line = g_buffer_cache_find_line_by_index(cache, 0);
+ name = g_buffer_line_get_text(line, BLC_ASSEMBLY_LABEL, BLC_COUNT, true);
+ g_object_unref(G_OBJECT(line));
+
+ g_object_unref(G_OBJECT(cache));
+
+ /* Suppression de la fin de l'étiquette... */
+ name = strrpl(name, ":", "");
+
+ }
+
+ else
+ name = NULL;
+
+ free(label);
+
+ g_object_unref(G_OBJECT(symbol));
+
+ }
+
+ if (name == NULL)
+ {
+ proc = g_loaded_binary_get_processor(block->binary);
+
+ if (g_arch_processor_has_virtual_space(proc) && has_virt_addr(get_mrange_addr(&range)))
+ vmpa2_virt_to_string(get_mrange_addr(&range), MDS_UNDEFINED, loc, NULL);
+ else
+ vmpa2_phys_to_string(get_mrange_addr(&range), MDS_UNDEFINED, loc, NULL);
+
+ name = strdup(loc);
+
+ g_object_unref(G_OBJECT(proc));
+
+ }
+
+ result = name;
+
+ /* Lecture des paramètres de configuration */
+
+ config = get_main_configuration();
+
+ if (!g_generic_config_get_value(config, MPK_TOOLTIP_MAX_CALLS, &max_calls))
+ max_calls = 0;
+
+ max_calls++;
+
+ if (!g_generic_config_get_value(config, MPK_TOOLTIP_MAX_STRINGS, &max_strings))
+ max_strings = 0;
+
+ max_strings++;
+
+ /* Parcours des instructions */
+
+ ins_count = 0;
+
+ call_count = 0;
+ call_info = NULL;
+
+ string_count = 0;
+ string_info = NULL;
+
+ proc = g_loaded_binary_get_processor(block->binary);
+ cache = g_loaded_binary_get_disassembled_cache(block->binary);
+
+ iter = g_arch_processor_get_iter_from_address(proc, get_mrange_addr(&range));
+ if (iter == NULL) goto no_iter;
+
+ restrict_instruction_iterator(iter, &range);
+
+ for (instr = get_instruction_iterator_current(iter);
+ instr != NULL;
+ instr = get_instruction_iterator_next(iter))
+ {
+ ins_count ++;
+
+ /* Appels ou références ? */
+
+ g_arch_instruction_lock_dest(instr);
+ dcount = g_arch_instruction_count_destinations(instr);
+
+ for (i = 0; i < dcount; i++)
+ {
+ dest = g_arch_instruction_get_destination(instr, i);
+
+ switch (dest->type)
+ {
+ case ILT_CALL:
+
+ call_count++;
+
+ if (call_count > max_calls)
+ goto next_dest;
+
+ if (call_count == max_calls)
+ {
+ call_info = stradd(call_info, "\n ...");
+ goto next_dest;
+ }
+
+ irange = g_arch_instruction_get_range(instr);
+
+ cursor = g_binary_cursor_new();
+ g_binary_cursor_update(G_BINARY_CURSOR(cursor), get_mrange_addr(irange));
+
+ index = g_buffer_cache_find_index_by_cursor(cache, cursor, true);
+
+ g_object_unref(G_OBJECT(cursor));
+
+ index = g_buffer_cache_look_for_flag(cache, index, BLF_HAS_CODE);
+
+ line = g_buffer_cache_find_line_by_index(cache, index);
+
+ if (line != NULL)
+ {
+ info = g_buffer_line_get_text(line, BLC_ASSEMBLY_HEAD, BLC_COUNT, true);
+ g_object_unref(G_OBJECT(line));
+ }
+
+ else
+ info = NULL;
+
+ if (call_info != NULL)
+ call_info = stradd(call_info, "\n");
+
+ if (info != NULL)
+ {
+ call_info = stradd(call_info, " - ");
+ call_info = stradd(call_info, info);
+ free(info);
+ }
+
+ else
+ call_info = stradd(call_info, " - ???");
+
+ break;
+
+ case ILT_REF:
+
+ if (!G_IS_RAW_INSTRUCTION(dest->linked))
+ goto next_dest;
+
+ if (!g_raw_instruction_is_string(G_RAW_INSTRUCTION(dest->linked)))
+ goto next_dest;
+
+ string_count++;
+
+ if (string_count > max_strings)
+ goto next_dest;
+
+ if (string_count == max_strings)
+ {
+ string_info = stradd(string_info, "\n ...");
+ goto next_dest;
+ }
+
+ irange = g_arch_instruction_get_range(dest->linked);
+
+ cursor = g_binary_cursor_new();
+ g_binary_cursor_update(G_BINARY_CURSOR(cursor), get_mrange_addr(irange));
+
+ index = g_buffer_cache_find_index_by_cursor(cache, cursor, true);
+
+ g_object_unref(G_OBJECT(cursor));
+
+ index = g_buffer_cache_look_for_flag(cache, index, BLF_HAS_CODE);
+
+ line = g_buffer_cache_find_line_by_index(cache, index);
+
+ if (line != NULL)
+ {
+ info = g_buffer_line_get_text(line, BLC_ASSEMBLY, BLC_COUNT, true);
+ g_object_unref(G_OBJECT(line));
+ }
+
+ else
+ info = NULL;
+
+ if (string_info != NULL)
+ string_info = stradd(string_info, "\n");
+
+ if (info != NULL)
+ {
+ string_info = stradd(string_info, " - ");
+ string_info = stradd(string_info, info);
+ free(info);
+ }
+
+ else
+ string_info = stradd(string_info, " - ???");
+
+ break;
+
+ default:
+ break;
+
+ }
+
+ next_dest:
+
+ unref_instr_link(dest);
+
+ }
+
+ g_arch_instruction_unlock_dest(instr);
+
+ g_object_unref(G_OBJECT(instr));
+
+ }
+
+ delete_instruction_iterator(iter);
+
+ no_iter:
+
+ g_object_unref(G_OBJECT(cache));
+ g_object_unref(G_OBJECT(proc));
+
+ /* Construction du résumé */
+
+ result = stradd(result, "\n");
+
+ if (ins_count > 1)
+ asprintf(&info, " - %u %s", ins_count, _("instructions"));
+ else
+ asprintf(&info, " - %u %s", ins_count, _("instruction"));
+
+ result = stradd(result, info);
+ free(info);
+
+ result = stradd(result, "\n");
+
+ if (call_count > 1)
+ asprintf(&info, " - %u %s", call_count, _("calls:"));
+ else if (call_count == 1)
+ asprintf(&info, " - 1 %s", _("call:"));
+ else
+ asprintf(&info, " - 0 %s", _("call"));
+
+ if (call_count > 0)
+ {
+ info = stradd(info, "\n");
+ info = stradd(info, call_info);
+ free(call_info);
+ }
+
+ info = stradd(info, "\n");
+
+ result = stradd(result, info);
+ free(info);
+
+ if (string_count > 1)
+ asprintf(&info, " - %u %s", string_count, _("strings:"));
+ else if (string_count == 1)
+ asprintf(&info, " - 1 %s", _("string:"));
+ else
+ asprintf(&info, " - 0 %s", _("string"));
+
+ if (string_count > 0)
+ {
+ info = stradd(info, "\n");
+ info = stradd(info, call_info);
+ free(call_info);
+ }
+
+ result = stradd(result, info);
+ free(info);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : block = bloc d'instructions à consulter. *
* first = instruction de départ du bloc. [OUT] *
* last = dernière instruction du bloc. [OUT] *