From 97d1cc10210cf4ec237e1d9a8b23b120ddef47c5 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 29 Nov 2014 09:33:00 +0000 Subject: Displayed segments in the disassembly view. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@429 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 23 +++++++ src/analysis/disass/output.c | 31 ++++++++- src/arch/instruction.c | 2 + src/format/elf/elf.c | 4 +- src/format/executable.c | 56 +++++++++++++++ src/format/executable.h | 3 + src/glibext/gbinportion.c | 161 ++++++++++++++++++++++++++++++++++++++++++- src/glibext/gbinportion.h | 10 +++ src/glibext/gbufferline.c | 38 ++++++++-- src/glibext/gbufferline.h | 3 + 10 files changed, 317 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index d4d129a..41501e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +14-11-29 Cyrille Bagard + + * src/analysis/disass/output.c: + Display segments in the disassembly view. + + * src/arch/instruction.c: + Typo. + + * src/format/elf/elf.c: + Quote segments names. + + * src/format/executable.c: + * src/format/executable.h: + Find all binary portions and sort them. + + * src/glibext/gbinportion.c: + * src/glibext/gbinportion.h: + Add a depth level to portions and allow to sort them. + + * src/glibext/gbufferline.c: + * src/glibext/gbufferline.h: + Provide a way to fill the addresses columns quickly. + 14-11-25 Cyrille Bagard * src/dialogs/binparts.c: diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c index a6d7845..2007f48 100644 --- a/src/analysis/disass/output.c +++ b/src/analysis/disass/output.c @@ -70,13 +70,15 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form GBufferLine *line; + GBinPortion **portions; /* Morceaux d'encadrement */ + size_t portions_count; /* Taille de cette liste */ + size_t portion_index; /* Prochaine portion à traiter */ GBinSymbol **symbols; /* Symboles à représenter */ size_t sym_count; /* Qté de symboles présents */ - - size_t sym_index; /* Prochain symbole non traité */ + const vmpa2t *paddr; /* Adresse de portion */ GDbComment *comment; /* Commentaire à ajouter */ @@ -91,11 +93,15 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form output = g_asm_output_new(); - symbols = g_binary_format_get_symbols(format, &sym_count); + + portions = g_exe_format_get_portions_at_level(format, -1, &portions_count); + portion_index = 0; + symbols = g_binary_format_get_symbols(format, &sym_count); sym_index = 0; + //GDbCollection *g_loaded_binary_find_collection(GLoadedBinary *, DBFeatures); @@ -133,6 +139,22 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form #endif + iaddr = get_mrange_addr(g_arch_instruction_get_range(iter)); + + while (portion_index < portions_count) + { + paddr = get_mrange_addr(g_binary_portion_get_range(portions[portion_index])); + + if (cmp_vmpa_by_phy(iaddr, paddr) != 0) + break; + + g_binary_portion_print(portions[portion_index], buffer, msize); + + portion_index++; + + } + + line = g_arch_instruction_print(iter, buffer, msize, content, ASX_INTEL); @@ -178,6 +200,9 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form } + + /* free portions... */ + g_object_unref(G_OBJECT(output)); } diff --git a/src/arch/instruction.c b/src/arch/instruction.c index f649150..d91e110 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -671,6 +671,7 @@ const char *g_arch_instruction_get_keyword(const GArchInstruction *instr, AsmSyn * * * Paramètres : instr = instruction d'assemblage à représenter. * * buffer = espace où placer ledit contenu. * +* msize = taille idéale des positions et adresses; * * syntax = type de représentation demandée. * * * * Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * @@ -724,6 +725,7 @@ static GBufferLine *_g_arch_instruction_print(const GArchInstruction *instr, GCo * * * Paramètres : instr = instruction d'assemblage à représenter. * * buffer = espace où placer ledit contenu. * +* msize = taille idéale des positions et adresses; * * syntax = type de représentation demandée. * * * * Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c index 64708ee..6d2138a 100644 --- a/src/format/elf/elf.c +++ b/src/format/elf/elf.c @@ -345,7 +345,7 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GBinPortion * new = g_binary_portion_new(background); - sprintf(desc, "%s %s", + sprintf(desc, "%s \"%s\"", _("Segment"), get_elf_program_type_desc(ELF_PHDR(format, phdr, p_type))); @@ -391,7 +391,7 @@ static void g_elf_format_refine_portions(const GElfFormat *format, GBinPortion * else name = NULL; if (name != NULL) - sprintf(desc, "%s %s", _("Section"), name); + sprintf(desc, "%s \"%s\"", _("Section"), name); else sprintf(desc, "%s ???", _("Section")); diff --git a/src/format/executable.c b/src/format/executable.c index ea1b398..0ae6934 100644 --- a/src/format/executable.c +++ b/src/format/executable.c @@ -162,6 +162,62 @@ GBinPortion *g_exe_format_get_portions(GExeFormat *format) /****************************************************************************** * * +* Paramètres : format = description de l'exécutable à consulter. * +* level = étage des portions à considérer ou -1 pour tous. * +* count = nombre de portions trouvées et renvoyées. [OUT] * +* * +* Description : Fournit une liste choisie de portions d'un binaire. * +* * +* Retour : Liste de définitins de zones à libérer après usage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinPortion **g_exe_format_get_portions_at_level(GExeFormat *format, unsigned int level, size_t *count) +{ + GBinPortion **result; /* Liste à retourner */ + + typedef struct _portions_list + { + unsigned int required; + GBinPortion **portions; + size_t length; + + } portions_list; + + portions_list list; /* Sauvegarde de la liste */ + + bool visit_for_level(GBinPortion *portion, portions_list *list) + { + if (list->required == -1 || g_binary_portion_get_level(portion) == list->required) + { + list->portions = (GBinPortion **)realloc(list->portions, ++list->length * sizeof(GBinPortion *)); + list->portions[list->length - 1] = portion; + } + + return true; + + } + + list.required = level; + list.portions = NULL; + list.length = 0; + + g_binary_portion_visit(g_exe_format_get_portions(format), (visit_portion_fc)visit_for_level, &list); + + result = list.portions; + *count = list.length; + + qsort(result, *count, sizeof(GBinPortion *), (__compar_fn_t)g_binary_portion_compare); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : format = informations chargées à consulter. * * count = quantité de zones listées. [OUT] * * * diff --git a/src/format/executable.h b/src/format/executable.h index 10bff42..28ac201 100644 --- a/src/format/executable.h +++ b/src/format/executable.h @@ -78,6 +78,9 @@ vmpa_t g_exe_format_get_entry_point(const GExeFormat *); /* Décrit les différentes portions qui composent le binaire. */ GBinPortion *g_exe_format_get_portions(GExeFormat *); +/* Fournit une liste choisie de portions d'un binaire. */ +GBinPortion **g_exe_format_get_portions_at_level(GExeFormat *, unsigned int, size_t *); + /* Fournit les espaces mémoires des portions exécutables. */ mrange_t *g_exe_format_get_x_ranges(GExeFormat *format, size_t *count); diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c index 94a04cc..1fbb460 100644 --- a/src/glibext/gbinportion.c +++ b/src/glibext/gbinportion.c @@ -44,6 +44,7 @@ struct _GBinPortion { GObject parent; /* A laisser en premier */ + unsigned int level; /* Profondeur de la portion */ GBinPortion *container; /* Portion parente ou racine */ char *code; /* Code de la couleur de fond */ @@ -51,8 +52,8 @@ struct _GBinPortion char *desc; /* Désignation humaine */ mrange_t range; /* Emplacement dans le code */ - vmpa2t addr; /* Emplacement dans le code */ - off_t size; /* Taille de la partie */ + vmpa2t addr; /* Emplacement dans le code */ /* TODO : clean */ + off_t size; /* Taille de la partie */ /* TODO : clean */ PortionAccessRights rights; /* Droits d'accès */ @@ -86,6 +87,9 @@ static void g_binary_portion_dispose(GBinPortion *); /* Procède à la libération totale de la mémoire. */ static void g_binary_portion_finalize(GBinPortion *); +/* Définit le niveau de profondeur pour une branche de portions. */ +static void g_binary_portion_set_level(GBinPortion *, unsigned int); + /* Détermine l'aire d'une sous-portion. */ static bool g_binary_portion_compute_sub_area(GBinPortion *, GBinPortion *, const GdkRectangle *, GdkRectangle *); @@ -139,6 +143,7 @@ static void g_binary_portion_class_init(GBinPortionClass *klass) static void g_binary_portion_init(GBinPortion *portion) { + portion->level = 0; } @@ -221,6 +226,37 @@ GBinPortion *g_binary_portion_new(const char *code) /****************************************************************************** * * +* Paramètres : a = premières informations à consulter. * +* b = secondes informations à consulter. * +* * +* Description : Etablit la comparaison ascendante entre deux portions. * +* * +* Retour : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b). * +* * +* Remarques : - * +* * +******************************************************************************/ + +int g_binary_portion_compare(const GBinPortion **a, const GBinPortion **b) +{ + int result; /* Bilan à retourner */ + + if ((*a)->level < (*b)->level) + result = -1; + + else if ((*a)->level > (*b)->level) + result = 1; + + else + result = cmp_mrange(&(*a)->range, &(*b)->range); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : portion = description de partie à mettre à jour. * * desc = nom à donner à la partie. * * * @@ -362,6 +398,52 @@ void g_binary_portion_include(GBinPortion *portion, GBinPortion *sub) portion->sub_portions[portion->sub_count - 1] = sub; + g_binary_portion_set_level(sub, portion->level + 1); + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à mettre à jour. * +* level = niveau de profondeur à associer. * +* * +* Description : Définit le niveau de profondeur pour une branche de portions.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_portion_set_level(GBinPortion *portion, unsigned int level) +{ + size_t i; /* Boucle de parcours */ + + portion->level = level; + + for (i = 0; i < portion->sub_count; i++) + g_binary_portion_set_level(portion->sub_portions[i], level + 1); + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à mettre à jour. * +* * +* Description : Indique le niveau de profondeur d'une portion donnée. * +* * +* Retour : Niveau de profondeur positif ou nul. * +* * +* Remarques : - * +* * +******************************************************************************/ + +unsigned int g_binary_portion_get_level(GBinPortion *portion) +{ + return portion->level; + } @@ -603,6 +685,81 @@ bool g_binary_portion_get_pos_from_addr(GBinPortion *portion, const vmpa2t *addr /****************************************************************************** * * +* Paramètres : portion = description de partie à consulter. * +* buffer = espace où placer ledit contenu. * +* msize = taille idéale des positions et adresses; * +* * +* Description : Insère dans un tampon une description de portion. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_portion_print(const GBinPortion *portion, GCodeBuffer *buffer, MemoryDataSize msize) +{ + GBufferLine *line; /* Nouvelle ligne à éditer */ + char rights[64]; /* Traduction en texte */ + + /* On ne traite pas les portions anonymes ! */ + if (portion->desc == NULL) return; + + line = g_code_buffer_append_new_line(buffer, &portion->range); + g_buffer_line_fill_mrange(line, msize, msize); + + /* Séparation */ + + line = g_code_buffer_append_new_line(buffer, &portion->range); + g_buffer_line_fill_mrange(line, msize, msize); + + g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); + g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, + "; ======================================================", 56, RTT_COMMENT); + + /* Retour à la ligne */ + + line = g_code_buffer_append_new_line(buffer, &portion->range); + g_buffer_line_fill_mrange(line, msize, msize); + + g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); + g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT); + + /* Description */ + + line = g_code_buffer_append_new_line(buffer, &portion->range); + g_buffer_line_fill_mrange(line, msize, msize); + + g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); + + g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT); + + g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, portion->desc, strlen(portion->desc), RTT_COMMENT); + + snprintf(rights, sizeof(rights), " (%s%s%s%s)", + _("rights: "), + portion->rights & PAC_READ ? "r" : "-", + portion->rights & PAC_WRITE ? "w" : "-", + portion->rights & PAC_EXEC ? "x" : "-"); + + g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, rights, strlen(rights), RTT_COMMENT); + + /* Retour à la ligne */ + + line = g_code_buffer_append_new_line(buffer, &portion->range); + g_buffer_line_fill_mrange(line, msize, msize); + + g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); + g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, "; ", 2, RTT_COMMENT); + + line = g_code_buffer_append_new_line(buffer, &portion->range); + g_buffer_line_fill_mrange(line, msize, msize); + +} + + +/****************************************************************************** +* * * Paramètres : portion = description de partie à mettre à jour. * * x = abscisse du point de recherche. * * y = ordonnée du point de recherche. * diff --git a/src/glibext/gbinportion.h b/src/glibext/gbinportion.h index ac6b4fd..f92b87e 100644 --- a/src/glibext/gbinportion.h +++ b/src/glibext/gbinportion.h @@ -30,6 +30,7 @@ #include +#include "gcodebuffer.h" #include "../arch/vmpa.h" #include "../common/fnv1a.h" @@ -82,6 +83,9 @@ GType g_binary_portion_get_type(void); /* Crée une description de partie de code vierge. */ GBinPortion *g_binary_portion_new(const char *); +/* Etablit la comparaison ascendante entre deux portions. */ +int g_binary_portion_compare(const GBinPortion **, const GBinPortion **); + /* Attribue une description humaine à une partie de code. */ void g_binary_portion_set_desc(GBinPortion *, const char *); @@ -103,6 +107,9 @@ PortionAccessRights g_binary_portion_get_rights(const GBinPortion *); /* Procède à l'inclusion d'une portion dans une autre. */ void g_binary_portion_include(GBinPortion *, GBinPortion *); +/* Indique le niveau de profondeur d'une portion donnée. */ +unsigned int g_binary_portion_get_level(GBinPortion *); + /* Parcours un ensemble de portions binaires. */ bool g_binary_portion_visit(GBinPortion *, visit_portion_fc, void *); @@ -118,6 +125,9 @@ bool g_binary_portion_get_addr_from_pos(GBinPortion *, gint, const GdkRectangle /* Fournit l'adresse correspondant à une position donnée. */ bool g_binary_portion_get_pos_from_addr(GBinPortion *, const vmpa2t *, const GdkRectangle *, gint *); +/* Insère dans un tampon une description de portion. */ +void g_binary_portion_print(const GBinPortion *, GCodeBuffer *, MemoryDataSize); + /* Prépare une astuce concernant une portion pour son affichage. */ gboolean g_binary_portion_query_tooltip(GBinPortion *, gint, gint, const GdkRectangle *, GtkTooltip *); diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c index 6970dac..a71ef9d 100644 --- a/src/glibext/gbufferline.c +++ b/src/glibext/gbufferline.c @@ -468,6 +468,36 @@ const mrange_t *g_buffer_line_get_range(const GBufferLine *line) /****************************************************************************** * * +* Paramètres : line = ligne à venir compléter. * +* psize = taille souhaitée de l'impression des positions. * +* vsize = taille souhaitée de l'impression des adresses. * +* * +* Description : Construit le tronc commun d'une ligne autour de sa position. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_buffer_line_fill_mrange(GBufferLine *line, MemoryDataSize psize, MemoryDataSize vsize) +{ + size_t len; /* Taille de l'élément inséré */ + VMPA_BUFFER(address); /* Adresse au format texte */ + + /* Adresse physique puis virtuelle */ + + mrange_phys_to_string(&line->range, psize, true, address, &len); + g_buffer_line_insert_text(line, BLC_PHYSICAL, address, len, RTT_RAW); + + mrange_virt_to_string(&line->range, vsize, true, address, &len); + g_buffer_line_insert_text(line, BLC_VIRTUAL, address, len, RTT_RAW); + +} + + +/****************************************************************************** +* * * Paramètres : line = ligne à venir compléter. * * psize = taille souhaitée de l'impression des positions. * * vsize = taille souhaitée de l'impression des adresses. * @@ -485,8 +515,6 @@ const mrange_t *g_buffer_line_get_range(const GBufferLine *line) void g_buffer_line_fill_for_instr(GBufferLine *line, MemoryDataSize psize, MemoryDataSize vsize, const bin_t *content, off_t length, bool full) { - size_t len; /* Taille de l'élément inséré */ - VMPA_BUFFER(address); /* Adresse au format texte */ size_t required; /* Taille de traitement requise*/ char static_buffer[64]; /* Petit tampon local rapide */ char *bin_code; /* Tampon utilisé pour le code */ @@ -501,11 +529,7 @@ void g_buffer_line_fill_for_instr(GBufferLine *line, MemoryDataSize psize, Memor /* Adresse physique puis virtuelle */ - mrange_phys_to_string(&line->range, psize, true, address, &len); - g_buffer_line_insert_text(line, BLC_PHYSICAL, address, len, RTT_RAW); - - mrange_virt_to_string(&line->range, vsize, true, address, &len); - g_buffer_line_insert_text(line, BLC_VIRTUAL, address, len, RTT_RAW); + g_buffer_line_fill_mrange(line, psize, vsize); /* Détermination du réceptacle */ diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h index 5a45fe2..f6ee171 100644 --- a/src/glibext/gbufferline.h +++ b/src/glibext/gbufferline.h @@ -93,6 +93,9 @@ GBufferLine *g_buffer_line_new(const mrange_t *, BufferLineColumn); /* Indique la zone mémoire où se situe la ligne. */ const mrange_t *g_buffer_line_get_range(const GBufferLine *); +/* Construit le tronc commun d'une ligne autour de sa position. */ +void g_buffer_line_fill_mrange(GBufferLine *, MemoryDataSize, MemoryDataSize); + /* Construit le tronc commun d'une ligne d'instruction. */ void g_buffer_line_fill_for_instr(GBufferLine *, MemoryDataSize, MemoryDataSize, const bin_t *, off_t, bool); -- cgit v0.11.2-87-g4458