From d450f573d94f795d83d09526546d63c81fde2e1d Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 18 Feb 2015 19:31:36 +0000 Subject: Fixed a bug by properly reloading a reallocated list of binary areas. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@475 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 9 +++ src/analysis/disass/area.c | 137 ++++++++++++++++++++++----------------------- src/analysis/disass/area.h | 6 +- src/arch/target.c | 2 +- 4 files changed, 81 insertions(+), 73 deletions(-) diff --git a/ChangeLog b/ChangeLog index ad647ec..5949c37 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +15-02-18 Cyrille Bagard + + * src/analysis/disass/area.c: + * src/analysis/disass/area.h: + Fix a bug by properly reloading a reallocated list of binary areas. + + * src/arch/target.c: + Avoid to crash when there is no label linked to a symbol. + 15-02-17 Cyrille Bagard * src/analysis/binary.c: diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index 974a223..f47e74c 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -89,7 +89,7 @@ static GArchInstruction *get_instructions_from_mem_area(const mem_area *); /* Insère un symbole dans un découpage en aires. */ -static bool insert_extra_symbol_into_mem_areas(mem_area **, size_t *, size_t *, GBinSymbol *); +static bool insert_extra_symbol_into_mem_areas(mem_area **, size_t *, GBinSymbol *, size_t); @@ -390,15 +390,15 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, phys_t start, ph * * * Description : Procède au désassemblage d'un contenu binaire exécutable. * * * -* Retour : - * +* Retour : Recalcul de rafraîchissement de l'aire de travail requis ? * * * * Remarques : - * * * ******************************************************************************/ -void load_code_from_mem_area(mem_area **list, size_t *count, size_t *index, const GLoadedBinary *binary, GProcContext *ctx, const vmpa2t *start, status_blob_info *info) +bool load_code_from_mem_area(mem_area **list, size_t *count, size_t *index, const GLoadedBinary *binary, GProcContext *ctx, const vmpa2t *start, status_blob_info *info) { - + bool result; /* Besoin à retourner */ mem_area *area; /* Zone de désassemblage */ @@ -428,14 +428,14 @@ void load_code_from_mem_area(mem_area **list, size_t *count, size_t *index, cons bool has_new_sym; /* Statut d'un dépilement */ GBinSymbol *symbol; /* Symbole créé en parallèle */ - size_t new_index; /* Nouvelle position déterminée*/ - + bool refresh; /* Besoin de rafraîchissement */ + result = false; /* On cherche à obtenir l'assurance que le traitement n'a jamais été fait */ init_mrange(&range, start, 1); - if (!is_range_blank_in_mem_areas(*list, *count, &range)) return; + if (!is_range_blank_in_mem_areas(*list, *count, &range)) return false; /* Récupération des informations de base */ @@ -507,39 +507,19 @@ void load_code_from_mem_area(mem_area **list, size_t *count, size_t *index, cons has_new_sym; has_new_sym = g_proc_context_pop_new_symbol_at(ctx, &sym_addr)) { - printf("depop :: %x / %x\n", (unsigned int)sym_addr.physical, (unsigned int)sym_addr.virtual); - //continue; - - //if (sym_addr.physical != 0x5bc && sym_addr.physical != 0x5c0) continue; - //if (sym_addr.physical != 0x5bc) continue; - //if (sym_addr.physical != 0x5bc && sym_addr.physical != 0x5c0 && sym_addr.physical != 0x5c4) continue; - - has_new_sym = g_binary_format_find_symbol_at(format, &sym_addr, &symbol); assert(has_new_sym); - new_index = *index; - if (!insert_extra_symbol_into_mem_areas(list, count, &new_index, symbol)) - continue; + refresh = insert_extra_symbol_into_mem_areas(list, count, symbol, *index); + + result |= refresh; /** - * Seulement deux cas de figure peuvent intervenir : - * - * - le symbole a été inséré avant la position courante, - * dans une autre aire ou en amont dans l'espace de celle courante. - * La position courante est alors à recalculer entièrement, - * et la boucle de parcours à relancer. - * - * - le symbole a été inséré après la position courante. - * Dans le pire des cas, l'aire courante a été diminuée, - * et il est juste nécessaire de recalculer la borne de fin. + * Si une insertion a été réalisée dans la même zone que celle courante ou avant, + * en l'absence d'indication sur les localisations exactes, le plus simple + * est de tout recharger. */ - - /* On ne peut pas faire disparaître de régions */ - assert(new_index >= *index); - - /* Cas n°1 */ - if (new_index > *index) + if (refresh) { *index = find_memory_area_by_addr(*list, *count, &pos); @@ -552,14 +532,11 @@ void load_code_from_mem_area(mem_area **list, size_t *count, size_t *index, cons } - /* Cas n°2 */ - else /*if (new_index == *index)*/ - { - area = (*list) + *index; - - alen = get_mrange_length(&area->range); - - } + /** + * Si la zone modifiée se trouve bien après la zone courante, l'emplacement de la liste + * peut potentiellement avoir évolué. Donc on ne recharge ici que le minimum. + */ + else area = (*list) + *index; } @@ -583,6 +560,7 @@ void load_code_from_mem_area(mem_area **list, size_t *count, size_t *index, cons g_object_unref(G_OBJECT(proc)); + return result; } @@ -771,9 +749,8 @@ void fill_mem_area(mem_area **list, size_t *count, size_t *index, const GLoadedB phys_t len; /* Taille de la zone à remplir */ phys_t i; /* Boucle de parcours */ vmpa2t start; /* Adresse de départ de combles*/ - mem_area *old_list; /* Sauvegarde pour comparaison */ - size_t old_index; /* Sauvegarde pour comparaison */ + bool refresh; /* Besoin de rafraîchissement */ size_t k; @@ -814,13 +791,14 @@ void fill_mem_area(mem_area **list, size_t *count, size_t *index, const GLoadedB if (area->exec && get_virt_addr(&start) % 2 == 0) { - old_list = *list; - old_index = *index; + refresh = load_code_from_mem_area(list, count, index, binary, ctx, &start, info); - load_code_from_mem_area(list, count, index, binary, ctx, &start, info); - - /* Rechargement si changement */ - if (*list != old_list || *index != old_index) + /** + * Mêmes commentaires que dans load_code_from_mem_area() : + * - en cas de décalage avéré, on recharge tout. + * - sinon, la liste a potentiellement été déplacée, donc on recharge un minimum. + */ + if (refresh) { area = (*list) + *index; len = get_mrange_length(&area->range); @@ -828,6 +806,7 @@ void fill_mem_area(mem_area **list, size_t *count, size_t *index, const GLoadedB i = compute_vmpa_diff(get_mrange_addr(&area->range), &start); } + else area = (*list) + *index; } @@ -836,11 +815,6 @@ void fill_mem_area(mem_area **list, size_t *count, size_t *index, const GLoadedB } - - if (is_range_blank_in_mem_area(area, i, 1, NULL)) - printf(" [%p] error with %u @ 0x%08x\n", area, (unsigned int)i, - (unsigned int)get_phy_addr(get_mrange_addr(&area->range))); - assert(!is_range_blank_in_mem_area(area, i, 1, NULL)); } @@ -1285,25 +1259,22 @@ mem_area *compute_memory_areas(GExeFormat *format, phys_t bin_length, size_t *co /****************************************************************************** * * -* Paramètres : area = aire représentant à contenu à parcourir. * -* list = liste de zones délimitant des contenus à traiter. * -* count = nombre de zones à disposition. * -* index = indice de l'aire à considérer pendant l'opération. * -* binary = représentation de binaire chargé. * -* ctx = contexte offert en soutien à un désassemblage. * -* start = démarrage de l'exécution au sein de la zone. * -* info = indications quant à la progression à afficher. * +* Paramètres : list = liste de zones délimitant des contenus à traiter. * +* count = nombre de zones à disposition. * +* symbol = élément nouveau à venir insérer dans les zones. * +* working = indice de l'aire de travail courante. * * * * Description : Insère un symbole dans un découpage en aires. * * * -* Retour : - * +* Retour : Recalcul de rafraîchissement de l'aire de travail requis ? * * * * Remarques : - * * * ******************************************************************************/ -static bool insert_extra_symbol_into_mem_areas(mem_area **list, size_t *count, size_t *old_index, GBinSymbol *symbol) +static bool insert_extra_symbol_into_mem_areas(mem_area **list, size_t *count, GBinSymbol *symbol, size_t working) { + bool result; /* Besoin à renvoyer */ const mrange_t *sym_range; /* Emplacement du symbole */ size_t index; /* Zone trouvée à scinder */ mem_area *area; /* Aire en cours de traitement */ @@ -1319,19 +1290,18 @@ static bool insert_extra_symbol_into_mem_areas(mem_area **list, size_t *count, s index = find_memory_area_by_addr(*list, *count, get_mrange_addr(sym_range)); assert(index < *count); - //if (index <= *old_index) (*old_index)++; + result = (working >= index); area = &(*list)[index]; - if (strcmp("Value used @ 0x00008a26", g_db_comment_get_text(g_binary_symbol_get_comment(symbol))) == 0) - printf("break\n"); - do { size_t i; + printf("--- INDEX = %zu OLD_INDEX = %zu\n", index, working); + printf("--- comment '%s'...\n", g_db_comment_get_text(g_binary_symbol_get_comment(symbol))); @@ -1348,10 +1318,17 @@ static bool insert_extra_symbol_into_mem_areas(mem_area **list, size_t *count, s } while (0); - if (area->has_sym) return true; + + + + if (area->has_sym) return false; assert(!area->has_sym); + + + + saved = *area; copy_mrange(&area_range, &area->range); @@ -1371,6 +1348,20 @@ static bool insert_extra_symbol_into_mem_areas(mem_area **list, size_t *count, s } + /* Si le symbole a une taille identique à la zone qui le contient, on remplace simplement... */ + if (get_mrange_length(&area_range) == get_mrange_length(sym_range)) + { + assert((cmp_vmpa(&area_pos, &sym_pos) == 0)); + + init_mem_area_from_range(area, sym_range); + + area->has_sym = true; + area->symbol = symbol; + + goto iesima_done; + + } + /* Si le symbole se trouve en début de zone... */ if (cmp_vmpa(&area_pos, &sym_pos) == 0) { @@ -1446,6 +1437,8 @@ static bool insert_extra_symbol_into_mem_areas(mem_area **list, size_t *count, s copy_vmpa(&area_pos, get_mrange_addr(&area_range)); new_length = compute_vmpa_diff(&area_pos, get_mrange_addr(sym_range)); + assert(new_length != 0); /* Symbole non présent au début */ + area = &(*list)[index]; init_mem_area_from_bigger_area(area, &area_pos, new_length, &saved); @@ -1469,6 +1462,8 @@ static bool insert_extra_symbol_into_mem_areas(mem_area **list, size_t *count, s new_length = get_mrange_length(&area_range) - get_mrange_length(sym_range) \ - get_mrange_length(&(*list)[index].range); + assert(new_length != 0); /* Symbole non présent à la fin */ + area = &(*list)[index + 2]; init_mem_area_from_bigger_area(area, &area_pos, new_length, &saved); @@ -1479,7 +1474,7 @@ static bool insert_extra_symbol_into_mem_areas(mem_area **list, size_t *count, s iesima_done: - return true; + return result; } diff --git a/src/analysis/disass/area.h b/src/analysis/disass/area.h index b517816..35a3533 100644 --- a/src/analysis/disass/area.h +++ b/src/analysis/disass/area.h @@ -25,6 +25,10 @@ #define _ANALYSIS_DISASS_AREA_H +#include + + + #include "../binary.h" #include "../../format/executable.h" #include "../../gtkext/gtkextstatusbar.h" @@ -45,7 +49,7 @@ typedef struct _mem_area mem_area; /* Procède au désassemblage d'un contenu binaire exécutable. */ -void load_code_from_mem_area(mem_area **, size_t *, size_t *, const GLoadedBinary *, GProcContext *, const vmpa2t *, status_blob_info *); +bool load_code_from_mem_area(mem_area **, size_t *, size_t *, const GLoadedBinary *, GProcContext *, const vmpa2t *, status_blob_info *); diff --git a/src/arch/target.c b/src/arch/target.c index 93ccbe4..40e9598 100644 --- a/src/arch/target.c +++ b/src/arch/target.c @@ -216,7 +216,7 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l VMPA_BUFFER(value); /* Adresse brute à imprimer */ size_t len; /* Taille de l'élément inséré */ - if (operand->symbol != NULL) + if (operand->symbol != NULL /* FIXME */ && g_binary_symbol_get_label(operand->symbol) != NULL /* FIXME */) { if (operand->diff > 0) g_buffer_line_insert_text(line, BLC_MAIN, "<", 1, RTT_LTGT); -- cgit v0.11.2-87-g4458