From a2f149e5d151dcd937351f6e54229e508123c3ad Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 24 Mar 2017 19:47:25 +0100 Subject: Built tooltips from all kinds of operands. --- ChangeLog | 19 +++++++ src/analysis/routine.c | 2 +- src/arch/immediate.c | 130 +++++++++++++++++++++++++++++++++++++++---- src/arch/operand-int.h | 4 ++ src/arch/operand.c | 30 ++++++++++ src/arch/operand.h | 7 +++ src/arch/target.c | 81 +++++++++++++++++++++++++++ src/gtkext/gtkblockdisplay.c | 50 +++-------------- 8 files changed, 270 insertions(+), 53 deletions(-) diff --git a/ChangeLog b/ChangeLog index 086aab9..af5e121 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,24 @@ 17-03-24 Cyrille Bagard + * src/analysis/routine.c: + Typo. + + * src/arch/immediate.c: + Build tooltips for immediate operands. + + * src/arch/operand-int.h: + * src/arch/operand.c: + * src/arch/operand.h: + Build tooltips from all kinds of operands. + + * src/arch/target.c: + Build tooltips for routines and strings. + + * src/gtkext/gtkblockdisplay.c: + Clean code. + +17-03-24 Cyrille Bagard + * src/analysis/db/collection.c: * src/analysis/db/items/comment.c: * src/analysis/db/items/move.c: diff --git a/src/analysis/routine.c b/src/analysis/routine.c index 089d287..9ec17c1 100644 --- a/src/analysis/routine.c +++ b/src/analysis/routine.c @@ -1142,7 +1142,7 @@ void g_binary_routine_print_code(const GBinRoutine *routine, GLangOutput *lang, /****************************************************************************** * * -* Paramètres : routine = routine à mettre à jour. * +* Paramètres : routine = routine à consulter. * * binary = informations relatives au binaire chargé. * * * * Description : Construit un petit résumé concis de la routine. * diff --git a/src/arch/immediate.c b/src/arch/immediate.c index 5df1f42..5970f06 100644 --- a/src/arch/immediate.c +++ b/src/arch/immediate.c @@ -25,6 +25,7 @@ #include +#include #include #include #include @@ -32,6 +33,9 @@ #include +#include + + #include "operand-int.h" #include "../common/asm.h" #include "../common/extstr.h" @@ -79,9 +83,15 @@ static void g_imm_operand_dispose(GImmOperand *); /* Procède à la libération totale de la mémoire. */ static void g_imm_operand_finalize(GImmOperand *); +/* Construit la chaîne de caractères correspondant à l'opérande. */ +static size_t _g_imm_operand_to_string(const GImmOperand *, AsmSyntax, ImmOperandDisplay, char [IMM_MAX_SIZE]); + /* Traduit un opérande en version humainement lisible. */ static void g_imm_operand_print(const GImmOperand *, GBufferLine *, AsmSyntax); +/* Construit un petit résumé concis de l'opérande. */ +static char *g_imm_operand_build_tooltip(const GImmOperand *, const GLoadedBinary *); + /* Indique le type défini pour un opérande de valeur numérique. */ @@ -113,6 +123,7 @@ static void g_imm_operand_class_init(GImmOperandClass *klass) object->finalize = (GObjectFinalizeFunc)g_imm_operand_finalize; operand->print = (operand_print_fc)g_imm_operand_print; + operand->build_tooltip = (operand_build_tooltip_fc)g_imm_operand_build_tooltip; g_signal_new("value-changed", G_TYPE_IMM_OPERAND, @@ -662,6 +673,7 @@ bool g_imm_operand_is_null(const GImmOperand *operand) * * * Paramètres : operand = opérande à transcrire. * * syntax = type de représentation demandée. * +* display = type d'affichage demandé. * * value = valeur portée par l'opérande transcrite. [OUT] * * * * Description : Construit la chaîne de caractères correspondant à l'opérande.* @@ -672,7 +684,7 @@ bool g_imm_operand_is_null(const GImmOperand *operand) * * ******************************************************************************/ -size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax, char value[IMM_MAX_SIZE]) +static size_t _g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax, ImmOperandDisplay display, char value[IMM_MAX_SIZE]) { size_t result; /* Longueur à retourner */ unsigned int range; /* Catégorie de la taille */ @@ -685,7 +697,7 @@ size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax, cha const char *conv; /* Opérateur de conversion */ char binval[65]; /* Conversion intégrée */ unsigned int max; /* Indice du plus fort bit */ - unsigned int i; /* Boucle de parcours #1 */ + unsigned int i; /* Boucle de parcours */ char format[16 + 65]; /* Format d'impression final */ static const char *zpad_defs[] = { "", "02", "04", "08", "016" }; @@ -698,7 +710,7 @@ size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax, cha range = MDS_RANGE(operand->size); /* Encadrement pour les caractères */ - if (operand->display == IOD_CHAR) + if (display == IOD_CHAR) { prefix = (syntax == ASX_ATT ? "$'" : "'"); suffix = "'"; @@ -710,7 +722,7 @@ size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax, cha } /* Préfix de forme '0x', 'b' ou '0' */ - switch (operand->display) + switch (display) { case IOD_BIN: alternate = "b"; @@ -727,13 +739,13 @@ size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax, cha } /* Va-t-on réellement avoir besoin d'un formatage ? */ - if (operand->display != IOD_BIN) + if (display != IOD_BIN) intro = "%"; else intro = ""; /* Drapeau de remplissage ? */ - switch (operand->display) + switch (display) { case IOD_BIN: case IOD_CHAR: @@ -751,12 +763,12 @@ size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax, cha /* Spécification de la conversion */ - if (operand->display != IOD_BIN) + if (display != IOD_BIN) { if (MDS_IS_SIGNED(operand->size)) - conv = conv_si_defs[operand->display]; + conv = conv_si_defs[display]; else - conv = conv_us_defs[operand->display]; + conv = conv_us_defs[display]; } else @@ -779,7 +791,7 @@ size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax, cha conv = binval; for (i = max; i > 0; i--) - binval[max - i] = (operand->raw & (1 << (i - 1)) ? '1' : '0'); + binval[max - i] = (operand->raw & (1llu << (i - 1)) ? '1' : '0'); binval[max] = '\0'; @@ -852,6 +864,31 @@ size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax, cha /****************************************************************************** * * +* Paramètres : operand = opérande à transcrire. * +* syntax = type de représentation demandée. * +* value = valeur portée par l'opérande transcrite. [OUT] * +* * +* Description : Construit la chaîne de caractères correspondant à l'opérande.* +* * +* Retour : Nombre de caractères utilisés. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax, char value[IMM_MAX_SIZE]) +{ + size_t result; /* Longueur à retourner */ + + result = _g_imm_operand_to_string(operand, syntax, operand->display, value); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : operand = opérande à traiter. * * line = ligne tampon où imprimer l'opérande donné. * * syntax = type de représentation demandée. * @@ -878,6 +915,79 @@ static void g_imm_operand_print(const GImmOperand *operand, GBufferLine *line, A /****************************************************************************** * * +* Paramètres : operand = opérande à consulter. * +* binary = informations relatives au binaire chargé. * +* * +* Description : Construit un petit résumé concis de l'opérande. * +* * +* Retour : Chaîne de caractères à libérer après usage ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_imm_operand_build_tooltip(const GImmOperand *operand, const GLoadedBinary *binary) +{ + char *result; /* Description à retourner */ + char value[IMM_MAX_SIZE]; /* Conversion artificielle */ + char *conv; /* Affichage de la Conversion */ + + if (isprint(operand->raw)) + asprintf(&result, _("Character: '%c'"), (char)operand->raw); + else + asprintf(&result, _("Character: <not printable>")); + + /* Binaire */ + + _g_imm_operand_to_string(operand, ASX_INTEL, IOD_BIN, value); + + asprintf(&conv, _("Binary: %s"), value); + + result = stradd(result, "\n"); + result = stradd(result, conv); + + free(conv); + + /* Octal */ + + _g_imm_operand_to_string(operand, ASX_INTEL, IOD_OCT, value); + + asprintf(&conv, _("Octal: %s"), value); + + result = stradd(result, "\n"); + result = stradd(result, conv); + + free(conv); + + /* Décimal */ + + _g_imm_operand_to_string(operand, ASX_INTEL, IOD_DEC, value); + + asprintf(&conv, _("Decimal: %s"), value); + + result = stradd(result, "\n"); + result = stradd(result, conv); + + free(conv); + + /* Hexadécimal */ + + _g_imm_operand_to_string(operand, ASX_INTEL, IOD_HEX, value); + + asprintf(&conv, _("Hexadecimal: %s"), value); + + result = stradd(result, "\n"); + result = stradd(result, conv); + + free(conv); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : operand = opérande à traiter. * * pos = valeur résultante. [OUT] * * * diff --git a/src/arch/operand-int.h b/src/arch/operand-int.h index eb1a1d7..8335614 100644 --- a/src/arch/operand-int.h +++ b/src/arch/operand-int.h @@ -36,6 +36,9 @@ typedef int (* operand_compare_fc) (const GArchOperand * const *, const GArchOpe /* Traduit un opérande en version humainement lisible. */ typedef void (* operand_print_fc) (const GArchOperand *, GBufferLine *, AsmSyntax); +/* Construit un petit résumé concis de l'opérande. */ +typedef char * (* operand_build_tooltip_fc) (const GArchOperand *, const GLoadedBinary *); + /* Adjonction de rendu alternatif */ typedef struct _alt_rendering @@ -67,6 +70,7 @@ struct _GArchOperandClass operand_compare_fc compare; /* Comparaison d'opérandes */ operand_print_fc print; /* Texte humain équivalent */ + operand_build_tooltip_fc build_tooltip; /* Construction de description */ }; diff --git a/src/arch/operand.c b/src/arch/operand.c index 731c757..dd28238 100644 --- a/src/arch/operand.c +++ b/src/arch/operand.c @@ -388,3 +388,33 @@ void g_arch_operand_print(const GArchOperand *operand, GBufferLine *line, AsmSyn G_ARCH_OPERAND_GET_CLASS(operand)->print(operand, line, syntax); } + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* binary = informations relatives au binaire chargé. * +* * +* Description : Construit un petit résumé concis de l'opérande. * +* * +* Retour : Chaîne de caractères à libérer après usage ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *g_arch_operand_build_tooltip(const GArchOperand *operand, const GLoadedBinary *binary) +{ + char *result; /* Description à retourner */ + GArchOperandClass *class; /* Classe associée à l'objet */ + + class = G_ARCH_OPERAND_GET_CLASS(operand); + + if (class->build_tooltip != NULL) + result = class->build_tooltip(operand, binary); + else + result = NULL; + + return result; + +} diff --git a/src/arch/operand.h b/src/arch/operand.h index ca9f3c8..36fc231 100644 --- a/src/arch/operand.h +++ b/src/arch/operand.h @@ -32,6 +32,10 @@ +/* Depuis "../analysis/binary.h" : description de fichier binaire */ +typedef struct _GLoadedBinary GLoadedBinary; + + #define G_TYPE_ARCH_OPERAND g_arch_operand_get_type() #define G_ARCH_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_arch_operand_get_type(), GArchOperand)) #define G_IS_ARCH_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_arch_operand_get_type())) @@ -59,6 +63,9 @@ void g_arch_operand_set_alt_text(GArchOperand *, const char *, RenderingTagType) /* Traduit un opérande en version humainement lisible. */ void g_arch_operand_print(const GArchOperand *, GBufferLine *, AsmSyntax); +/* Construit un petit résumé concis de l'opérande. */ +char *g_arch_operand_build_tooltip(const GArchOperand *, const GLoadedBinary *); + #endif /* _ARCH_OPERAND_H */ diff --git a/src/arch/target.c b/src/arch/target.c index 3632b76..bce00a7 100644 --- a/src/arch/target.c +++ b/src/arch/target.c @@ -75,6 +75,9 @@ static void g_target_operand_finalize(GTargetOperand *); /* Traduit un opérande en version humainement lisible. */ static void g_target_operand_print(const GTargetOperand *, GBufferLine *, AsmSyntax); +/* Construit un petit résumé concis de l'opérande. */ +static char *g_target_operand_build_tooltip(const GTargetOperand *, const GLoadedBinary *); + /* Indique le type défini pour un opérande de valeur numérique. */ @@ -106,6 +109,7 @@ static void g_target_operand_class_init(GTargetOperandClass *klass) object->finalize = (GObjectFinalizeFunc)g_target_operand_finalize; operand->print = (operand_print_fc)g_target_operand_print; + operand->build_tooltip = (operand_build_tooltip_fc)g_target_operand_build_tooltip; } @@ -252,6 +256,83 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l /****************************************************************************** * * +* Paramètres : operand = opérande à consulter. * +* binary = informations relatives au binaire chargé. * +* * +* Description : Construit un petit résumé concis de l'opérande. * +* * +* Retour : Chaîne de caractères à libérer après usage ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_target_operand_build_tooltip(const GTargetOperand *operand, const GLoadedBinary *binary) +{ + char *result; /* Description à retourner */ + SymbolType stype; /* Type de symbole identifié */ + GBinRoutine *routine; /* Routine à manipuler */ + const mrange_t *srange; /* Emplacement du symbole */ + GBufferCache *cache; /* Tampon de désassemblage */ + size_t index; /* Indice de ligne à traiter */ + GBufferLine *line; /* Ligne présente à l'adresse */ + + result = NULL; + + if (operand->symbol != NULL && operand->diff == 0) + { + stype = g_binary_symbol_get_target_type(operand->symbol); + + switch (stype) + { + case STP_ROUTINE: + case STP_ENTRY_POINT: + + routine = g_binary_symbol_get_routine(operand->symbol); + + result = g_binary_routine_build_tooltip(routine, binary); + + //g_object_unref(G_OBJECT(routine)); // TODO + + break; + + case STP_STRING: + case STP_RO_STRING: + + srange = g_binary_symbol_get_range(operand->symbol); + + cache = g_loaded_binary_get_disassembled_cache(binary); + + index = g_buffer_cache_find_index_by_addr(cache, get_mrange_addr(srange), true); + + 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) + { + result = g_buffer_line_get_text(line, BLC_ASSEMBLY, BLC_COUNT, true); + g_object_unref(G_OBJECT(line)); + } + + g_object_unref(G_OBJECT(cache)); + + break; + + default: + break; + + } + + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : operand = structure dont le contenu est à consulter. * * * * Description : Renseigne la taille de la valeur indiquée à la construction. * diff --git a/src/gtkext/gtkblockdisplay.c b/src/gtkext/gtkblockdisplay.c index 9698ee5..b39b561 100644 --- a/src/gtkext/gtkblockdisplay.c +++ b/src/gtkext/gtkblockdisplay.c @@ -25,7 +25,7 @@ #include "gtkbufferdisplay-int.h" -#include "../arch/target.h" +#include "../arch/operand.h" @@ -287,11 +287,6 @@ static gboolean gtk_block_display_query_tooltip(GtkWidget *widget, gint x, gint gint real_x; /* Abscisse absolue réelle */ gint real_y; /* Ordonnée absolue réelle */ GObject *creator; /* Origine du segment pointé */ - GBinSymbol *symbol; /* Eventuel symbole survolé */ - GTargetOperand *operand; /* Operande associé */ - phys_t diff; /* Différence avec la base */ - SymbolType stype; /* Type de symbole identifié */ - GBinRoutine *routine; /* Routine à manipuler */ char *info; /* Information à faire paraître*/ if (keyboard) return FALSE; @@ -309,49 +304,20 @@ static gboolean gtk_block_display_query_tooltip(GtkWidget *widget, gint x, gint if (creator != NULL) { - symbol = NULL; + if (G_IS_ARCH_OPERAND(creator)) + info = g_arch_operand_build_tooltip(G_ARCH_OPERAND(creator), panel->binary); - if (!G_IS_TARGET_OPERAND(creator)) - goto gbdqt_done; + else + info = NULL; - operand = G_TARGET_OPERAND(creator); - - symbol = g_target_operand_get_symbol(operand, &diff); - - if (symbol == NULL || diff != 0) - goto gbdqt_done; - - stype = g_binary_symbol_get_target_type(symbol); - - switch (stype) - { - case STP_ROUTINE: - case STP_ENTRY_POINT: - - routine = g_binary_symbol_get_routine(symbol); - - info = g_binary_routine_build_tooltip(routine, panel->binary); - - //g_object_unref(G_OBJECT(routine)); - - result = (info != NULL); - break; - - default: - break; - - } - - if (result) + if (info != NULL) { gtk_tooltip_set_markup(tooltip, info); free(info); - } - gbdqt_done: + result = TRUE; - if (symbol != NULL) - g_object_unref(G_OBJECT(symbol)); + } g_object_unref(creator); -- cgit v0.11.2-87-g4458