From d246c98c515cb44c5bc4c742a674bae2e824872b Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 30 Jan 2015 23:37:39 +0000 Subject: Bound a symbol for each loaded value for 'ldr' instructions. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@462 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 32 +++ src/analysis/disass/area.c | 481 +++++++++++++++++++++++++++++++++++--------- src/analysis/disass/area.h | 15 +- src/analysis/disass/fetch.c | 60 +++++- src/arch/arm/v7/link.c | 86 +++++++- src/arch/context-int.h | 3 + src/arch/context.c | 55 +++++ src/arch/context.h | 6 + src/arch/raw.c | 70 +++++++ src/arch/raw.h | 3 + src/arch/vmpa.c | 28 ++- src/arch/vmpa.h | 5 +- src/format/format.c | 49 ++++- src/format/format.h | 3 + src/format/symbol.c | 77 +++++++ src/format/symbol.h | 6 + 16 files changed, 853 insertions(+), 126 deletions(-) diff --git a/ChangeLog b/ChangeLog index b358006..5f5714e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +15-01-31 Cyrille Bagard + + * src/analysis/disass/area.c: + * src/analysis/disass/area.h: + * src/analysis/disass/fetch.c: + Introduce new extra symbols into disassembled code areas. + + * src/arch/arm/v7/link.c: + Bind a symbol for each loaded value for 'ldr' instructions. + + * src/arch/context.c: + * src/arch/context.h: + * src/arch/context-int.h: + Memorize extra symbols created during the disassembling process. + + * src/arch/raw.c: + * src/arch/raw.h: + Provide a way to create raw instructions from given values. + + * src/arch/vmpa.c: + * src/arch/vmpa.h: + Fix a bug when computing the difference between addresses. Compute + the end of a memory range. + + * src/format/format.c: + * src/format/format.h: + Provide a way to look for a symbol located at a given address. + + * src/format/symbol.c: + * src/format/symbol.h: + Update the location of a symbol when incomplete. + 15-01-26 Cyrille Bagard * configure.ac: diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index 8340095..600818a 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -53,6 +53,9 @@ static void init_mem_area_from_addr(mem_area *, const vmpa2t *, phys_t); /* Initialise une aire de données à partir d'un espace donné. */ static void init_mem_area_from_range(mem_area *, const mrange_t *); +/* Initialise une aire de données à partir d'un morceau donné. */ +static void init_mem_area_from_bigger_area(mem_area *, const vmpa2t *, phys_t, const mem_area *); + /* Copie certaines propriétés d'une aire à une autre. */ static void copy_mem_area_properties(mem_area *, const mem_area *); @@ -72,9 +75,6 @@ static bool mark_range_in_mem_area_as_processed(mem_area *, phys_t, phys_t, GArc /* Procède au désassemblage d'un contenu binaire non exécutable. */ static void load_data_from_mem_area(mem_area *, mem_area *, size_t, const GLoadedBinary *, GProcContext *, const vmpa2t *, status_blob_info *); -/* S'assure qu'une aire contient toutes ses instructions. */ -static void fill_mem_area(mem_area *, mem_area *, size_t, const GLoadedBinary *, GProcContext *, status_blob_info *); - /* Rassemble les instructions conservées dans une zone donnée. */ @@ -87,6 +87,13 @@ 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 *); + + + + /* Manipule la cartographie des octets traités d'une zone. */ typedef bool (* visit_bytes_map_fc) (mem_area *, phys_t, phys_t, GArchInstruction *); @@ -140,10 +147,10 @@ static void init_mem_area_from_addr(mem_area *area, const vmpa2t *addr, phys_t l /****************************************************************************** * * -* Paramètres : dest = aire délimitée représentant des données. * -* src = aire délimitée contenant les informations à copier. * +* Paramètres : area = aire représentant à contenu à initialiser. * +* range = espace limitant à associer à l'aire de données. * * * -* Description : Copie certaines propriétés d'une aire à une autre. * +* Description : Initialise une aire de données à partir d'un espace donné. * * * * Retour : - * * * @@ -151,14 +158,20 @@ static void init_mem_area_from_addr(mem_area *area, const vmpa2t *addr, phys_t l * * ******************************************************************************/ -static void copy_mem_area_properties(mem_area *dest, const mem_area *src) +static void init_mem_area_from_range(mem_area *area, const mrange_t *range) { - dest->has_sym = src->has_sym; + phys_t len; /* Taille de la zone courante */ + size_t requested; /* Nombre de mots à allouer */ - if (src->has_sym) - dest->symbol = src->symbol; - else - dest->exec = src->exec; + copy_mrange(&area->range, range); + + len = get_mrange_length(range); + + requested = len / sizeof(unsigned long); + if (len % sizeof(unsigned long) != 0) requested++; + + area->processed = (unsigned long *)calloc(requested, sizeof(unsigned long)); + area->instructions = (GArchInstruction **)calloc(len, sizeof(GArchInstruction *)); } @@ -166,30 +179,81 @@ static void copy_mem_area_properties(mem_area *dest, const mem_area *src) /****************************************************************************** * * * Paramètres : area = aire représentant à contenu à initialiser. * -* range = espace limitant à associer à l'aire de données. * +* addr = adresse de départ de l'espace à mettre en place. * +* len = longueur de l'espace à créer. * +* ref = aire de référence avant découpage. * * * -* Description : Initialise une aire de données à partir d'un espace donné. * +* Description : Initialise une aire de données à partir d'un morceau donné. * * * * Retour : - * * * -* Remarques : - * +* Remarques : On considère que la zone de destination est inclue dans * +* celle de référence. * * * ******************************************************************************/ -static void init_mem_area_from_range(mem_area *area, const mrange_t *range) +static void init_mem_area_from_bigger_area(mem_area *area, const vmpa2t *addr, phys_t len, const mem_area *ref) { - phys_t len; /* Taille de la zone courante */ - size_t requested; /* Nombre de mots à allouer */ + phys_t start; /* Point de départ de la copie */ + phys_t i; /* Boucle de parcours */ + size_t index; /* Cellule de tableau visée #1 */ + unsigned int remaining; /* Nombre de bits restants #1 */ + size_t ref_index; /* Cellule de tableau visée #2 */ + unsigned int ref_remaining; /* Nombre de bits restants #2 */ - copy_mrange(&area->range, range); - len = get_mrange_length(range); + printf(" INIT_FROM (0x%08x / 0x%08x | 0x%x) : area (0x%08x / 0x%08x) len = 0x%x\n", + (unsigned int)ref->range.addr.physical, (unsigned int)ref->range.addr.virtual, + (unsigned int)ref->range.length, + (unsigned int)addr->physical, (unsigned int)addr->virtual, + (unsigned int)len); - requested = len / sizeof(unsigned long); - if (len % sizeof(unsigned long) != 0) requested++; - area->processed = (unsigned long *)calloc(requested, sizeof(unsigned long)); - area->instructions = (GArchInstruction **)calloc(len, sizeof(GArchInstruction *)); + init_mem_area_from_addr(area, addr, len); + + assert(mrange_contains_mrange(&ref->range, &area->range)); + + start = compute_vmpa_diff(get_mrange_addr(&ref->range), get_mrange_addr(&area->range)); + + for (i = 0; i < len; i++) + { + index = i / (sizeof(unsigned long) * 8); + remaining = i % (sizeof(unsigned long) * 8); + + ref_index = (start + i) / (sizeof(unsigned long) * 8); + ref_remaining = (start + i) % (sizeof(unsigned long) * 8); + + if (ref->processed[ref_index] & (1ul << ref_remaining)) + area->processed[index] |= (1ul << remaining); + + area->instructions[i] = ref->instructions[start + i]; + + } + +} + + +/****************************************************************************** +* * +* Paramètres : dest = aire délimitée représentant des données. * +* src = aire délimitée contenant les informations à copier. * +* * +* Description : Copie certaines propriétés d'une aire à une autre. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void copy_mem_area_properties(mem_area *dest, const mem_area *src) +{ + dest->has_sym = src->has_sym; + + if (src->has_sym) + dest->symbol = src->symbol; + else + dest->exec = src->exec; } @@ -210,8 +274,10 @@ static void fini_mem_area(mem_area *area) { free(area->processed); +#if 0 if (area->has_sym) - g_object_unref(area->symbol); + g_object_unref(area->symbol); /* FIXME ?! */ +#endif } @@ -239,6 +305,9 @@ static bool is_range_blank_in_mem_area(mem_area *area, phys_t start, phys_t len, size_t index; /* Cellule de tableau visée */ unsigned int remaining; /* Nombre de bits restants */ + if (area->has_sym) + return false; + max = start + len; assert(max <= get_mrange_length(&area->range)); @@ -304,13 +373,12 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, phys_t start, ph - - /****************************************************************************** * * * 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. * @@ -324,9 +392,12 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, phys_t start, ph * * ******************************************************************************/ -void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, const GLoadedBinary *binary, GProcContext *ctx, const vmpa2t *start, status_blob_info *info) +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) { + mem_area *area; /* Zone de désassemblage */ + + GBinFormat *format; /* Format du fichier binaire */ GArchProcessor *proc; /* Architecture du binaire */ @@ -349,12 +420,18 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, const mrange_t range; /* Couverture de l'instruction */ + vmpa2t sym_addr; /* Adresse de nouveau symbole */ + 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*/ + + /* 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)) printf("CODE OK!!\n");; - if (!is_range_blank_in_mem_areas(list, count, &range)) return; + if (!is_range_blank_in_mem_areas(*list, *count, &range)) return; /* Récupération des informations de base */ @@ -362,6 +439,8 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, const proc = get_arch_processor_from_format(G_EXE_FORMAT(format)); bin_data = g_loaded_binary_get_data(binary, &bin_length); + area = (*list) + *index; + diff = compute_vmpa_diff(get_mrange_addr(&area->range), start); alen = get_mrange_length(&area->range); @@ -397,9 +476,6 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, const if (instr == NULL) break; - - - /* Enregistrement des positions et adresses */ diff = compute_vmpa_diff(&prev, &pos); @@ -414,21 +490,73 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, const /* Progression dans les traitements */ - mark_range_in_mem_areas_as_processed(list, count, instr); + mark_range_in_mem_areas_as_processed(*list, *count, instr); inc_progessive_status(info, diff); - assert(!is_range_blank_in_mem_areas(list, count, &range)); + assert(!is_range_blank_in_mem_areas(*list, *count, &range)); + + /* Insertion des symboles découverts en parallèle */ + + for (has_new_sym = g_proc_context_pop_new_symbol_at(ctx, &sym_addr); + 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); + + + //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; + + /** + * 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. + */ + + /* On ne peut pas faire disparaître de régions */ + assert(new_index >= *index); + + /* Cas n°1 */ + if (new_index > *index) + { + *index = find_memory_area_by_addr(*list, *count, &pos); + + area = (*list) + *index; + diff = compute_vmpa_diff(get_mrange_addr(&area->range), &pos); + alen = get_mrange_length(&area->range); + i = 0; - printf(" --disass-- '%s' @ 0x%08x (break=%d)\n", - g_arch_instruction_get_keyword(instr, 0), - (unsigned int)get_virt_addr(&prev), - g_arch_instruction_is_return(instr)); + } + /* Cas n°2 */ + else /*if (new_index == *index)*/ + { + area = (*list) + *index; + alen = get_mrange_length(&area->range); + + } + + } if (g_arch_instruction_is_return(instr)) @@ -485,7 +613,7 @@ static void load_data_from_mem_area(mem_area *area, mem_area *list, size_t count /* 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)) printf("DATA OK!!\n");; + if (!is_range_blank_in_mem_areas(list, count, &range)) printf("DATA OK ! @ 0x%08x\n", (unsigned int)get_phy_addr(get_mrange_addr(&area->range))); if (!is_range_blank_in_mem_areas(list, count, &range)) return; /* Récupération des informations de base */ @@ -609,6 +737,7 @@ static void load_data_from_mem_area(mem_area *area, mem_area *list, size_t count * 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. * * info = indications quant à la progression à afficher. * @@ -621,21 +750,43 @@ static void load_data_from_mem_area(mem_area *area, mem_area *list, size_t count * * ******************************************************************************/ -static void fill_mem_area(mem_area *area, mem_area *list, size_t count, const GLoadedBinary *binary, GProcContext *ctx, status_blob_info *info) +void fill_mem_area(mem_area **list, size_t *count, size_t *index, const GLoadedBinary *binary, GProcContext *ctx, status_blob_info *info) { + mem_area *area; /* Zone de désassemblage */ + + 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 */ + + + + size_t k; - bool on = true; + for (k = 0; k < *count; k++) + { + printf(" (filled) AREA %zu :: 0x%08x + %u\n", + k, + (unsigned int)get_phy_addr(get_mrange_addr(&(*list)[k].range)), + (unsigned int)get_mrange_length(&(*list)[k].range)); - printf(" === FILLING | 0x%08x // 0x%08x <-> 0x%08x...\n", + } + + + area = (*list) + *index; + + + + printf(" === FILLING (%zu) | 0x%08x // 0x%08x <-> 0x%08x...\n", *index, (unsigned int)get_phy_addr(get_mrange_addr(&area->range)), (unsigned int)get_virt_addr(get_mrange_addr(&area->range)), (unsigned int)(get_virt_addr(get_mrange_addr(&area->range)) + get_mrange_length(&area->range))); + /* Les symboles se doivent d'être indépendants ! */ if (area->has_sym) return; @@ -650,29 +801,32 @@ static void fill_mem_area(mem_area *area, mem_area *list, size_t count, const GL if (area->exec && get_virt_addr(&start) % 2 == 0) { - load_code_from_mem_area(area, list, count, binary, ctx, &start, info); + old_list = *list; + old_index = *index; + + load_code_from_mem_area(list, count, index, binary, ctx, &start, info); - if (!is_range_blank_in_mem_area(area, i, 1, NULL)) + /* Rechargement si changement */ + if (*list != old_list || *index != old_index) { - printf(" --filled-- @ 0x%08x\n", (unsigned int)get_virt_addr(&start)); - on = false; - } - else - printf(" --fill failed-- @ 0x%08x\n", (unsigned int)get_virt_addr(&start)); + area = (*list) + *index; + len = get_mrange_length(&area->range); + + i = compute_vmpa_diff(get_mrange_addr(&area->range), &start); + } } if (is_range_blank_in_mem_area(area, i, 1, NULL)) - load_data_from_mem_area(area, list, count, binary, ctx, &start, info); + load_data_from_mem_area(area, *list, *count, binary, ctx, &start, info); } - else on = true; - if (is_range_blank_in_mem_area(area, i, 1, NULL)) - printf(" [%p] error with %u\n", area, (unsigned int)i); + 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)); @@ -1116,12 +1270,177 @@ 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. * +* * +* Description : Insère un symbole dans un découpage en aires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool insert_extra_symbol_into_mem_areas(mem_area **list, size_t *count, size_t *old_index, GBinSymbol *symbol) +{ + const mrange_t *sym_range; /* Emplacement du symbole */ + size_t index; /* Zone trouvée à scinder */ + mem_area *area; /* Aire en cours de traitement */ + mem_area saved; /* Aire aux données copiées */ + mrange_t area_range; /* Emplacement d'une aire */ + vmpa2t area_pos; /* Position relative à une aire*/ + vmpa2t sym_pos; /* Position pour un symbole */ + phys_t diff; /* Décalage entre localisation */ + phys_t new_length; /* Nouvelle taille de zone */ + + sym_range = g_binary_symbol_get_range(symbol); + + index = find_memory_area_by_addr(*list, *count, get_mrange_addr(sym_range)); + assert(index < *count); + + if (index <= *old_index) (*old_index)++; + + area = &(*list)[index]; + assert(!area->has_sym); + + saved = *area; + + copy_mrange(&area_range, &area->range); + + copy_vmpa(&area_pos, get_mrange_addr(&area_range)); + copy_vmpa(&sym_pos, get_mrange_addr(sym_range)); + + /* Si le symbole est construit avec une localisation partielle, on complète ! */ + if (get_phy_addr(&sym_pos) == VMPA_NO_PHYSICAL || get_virt_addr(&sym_pos) == VMPA_NO_VIRTUAL) + { + diff = compute_vmpa_diff(&area_pos, &sym_pos); + + copy_vmpa(&sym_pos, &area_pos); + advance_vmpa(&sym_pos, diff); + + g_binary_symbol_fix_range(symbol, &sym_pos); + + } + + /* Si le symbole se trouve en début de zone... */ + if (cmp_vmpa(&area_pos, &sym_pos) == 0) + { + *list = (mem_area *)realloc(*list, ++(*count) * sizeof(mem_area)); + + memmove(&(*list)[index + 1], &(*list)[index], (*count - index - 1) * sizeof(mem_area)); + + /* Aire du symbole */ + + area = &(*list)[index]; + + init_mem_area_from_range(area, sym_range); + + area->has_sym = true; + area->symbol = symbol; + + /* Aire raccourcie */ + + copy_vmpa(&area_pos, get_mrange_addr(&saved.range)); + advance_vmpa(&area_pos, get_mrange_length(sym_range)); + + //compute_mrange_end_addr(sym_range, &area_pos); + new_length = get_mrange_length(&area_range) - get_mrange_length(sym_range); + + area = &(*list)[index + 1]; + + init_mem_area_from_bigger_area(area, &area_pos, new_length, &saved); + + goto iesima_done; + + } + + compute_mrange_end_addr(&area->range, &area_pos); + compute_mrange_end_addr(sym_range, &sym_pos); + + /* Si le symbole se trouve en fin de zone... */ + if (cmp_vmpa(&area_pos, &sym_pos) == 0) + { + *list = (mem_area *)realloc(*list, ++(*count) * sizeof(mem_area)); + + memmove(&(*list)[index + 1], &(*list)[index], (*count - index - 1) * sizeof(mem_area)); + + /* Aire raccourcie */ + + copy_vmpa(&area_pos, get_mrange_addr(&area_range)); + new_length = get_mrange_length(&area_range) - get_mrange_length(sym_range); + + area = &(*list)[index]; + + init_mem_area_from_bigger_area(area, &area_pos, new_length, &saved); + + /* Aire du symbole */ + + area = &(*list)[index + 1]; + + init_mem_area_from_range(area, sym_range); + + area->has_sym = true; + area->symbol = symbol; + + } + + /* Sinon il se trouve au milieu et on découpe en trois... */ + else + { + *count += 2; + *list = (mem_area *)realloc(*list, *count * sizeof(mem_area)); + memmove(&(*list)[index + 2], &(*list)[index], (*count - index - 2) * sizeof(mem_area)); + /* Aire raccourcie #1 */ + copy_vmpa(&area_pos, get_mrange_addr(&area_range)); + new_length = compute_vmpa_diff(&area_pos, get_mrange_addr(sym_range)); + area = &(*list)[index]; + init_mem_area_from_bigger_area(area, &area_pos, new_length, &saved); + + /* Aire du symbole */ + + area = &(*list)[index + 1]; + + init_mem_area_from_range(area, sym_range); + + area->has_sym = true; + area->symbol = symbol; + + /* Aire raccourcie #2 */ + + copy_vmpa(&area_pos, get_mrange_addr(&saved.range)); + advance_vmpa(&area_pos, get_mrange_length(&(*list)[index].range)); + advance_vmpa(&area_pos, get_mrange_length(sym_range)); + + //compute_mrange_end_addr(sym_range, &area_pos); + new_length = get_mrange_length(&area_range) - get_mrange_length(sym_range) \ + - get_mrange_length(&(*list)[index].range); + + area = &(*list)[index + 2]; + + init_mem_area_from_bigger_area(area, &area_pos, new_length, &saved); + + } + + fini_mem_area(&saved); + + iesima_done: + + return true; +} @@ -1139,22 +1458,19 @@ mem_area *compute_memory_areas(GExeFormat *format, phys_t bin_length, size_t *co * * * Description : Détermine une liste de zones contigües à traiter. * * * -* Retour : Liste de zones mémoire à libérer après usage. * +* Retour : Indice de la zone trouvée, ou nombre d'aires en cas d'échec. * * * * Remarques : - * * * ******************************************************************************/ -mem_area *find_memory_area_by_addr(mem_area *list, size_t count, const vmpa2t *addr) +size_t find_memory_area_by_addr(mem_area *list, size_t count, const vmpa2t *addr) { - mem_area *result; /* Trouvaille à retourner */ - size_t i; /* Boucle de parcours */ - - result = NULL; + size_t result; /* Trouvaille à retourner */ - for (i = 0; i < count && result == NULL; i++) - if (mrange_contains_addr(&list[i].range, addr)) - result = &list[i]; + for (result = 0; result < count; result++) + if (mrange_contains_addr(&list[result].range, addr)) + break; return result; @@ -1179,6 +1495,7 @@ mem_area *find_memory_area_by_addr(mem_area *list, size_t count, const vmpa2t *a static bool handle_bytes_map_in_mem_area(mem_area *list, size_t count, const mrange_t *range, GArchInstruction *instr, visit_bytes_map_fc visitor) { bool result; /* Bilan à retourner */ + size_t found; /* Indice de la zone trouvée */ mem_area *area; /* Aire à traiter trouvée */ phys_t offset; /* Point de départ dans l'aire */ phys_t remaining; /* Quantité restant à traiter */ @@ -1187,8 +1504,10 @@ static bool handle_bytes_map_in_mem_area(mem_area *list, size_t count, const mra result = false; - area = find_memory_area_by_addr(list, count, get_mrange_addr(range)); - if (area == NULL) return false; + found = find_memory_area_by_addr(list, count, get_mrange_addr(range)); + if (found == count) return false; + + area = list + found; offset = compute_vmpa_diff(get_mrange_addr(&area->range), get_mrange_addr(range)); remaining = get_mrange_length(range); @@ -1228,13 +1547,15 @@ static bool handle_bytes_map_in_mem_area(mem_area *list, size_t count, const mra { advance_vmpa(&start, processed); - area = find_memory_area_by_addr(list, count, &start); - if (area == NULL) + found = find_memory_area_by_addr(list, count, &start); + if (found == count) { result = false; break; } + area = list + found; + processed = get_mrange_length(&area->range); if (remaining < processed) processed = remaining; @@ -1297,32 +1618,6 @@ static bool mark_range_in_mem_areas_as_processed(mem_area *list, size_t count, G /****************************************************************************** * * -* Paramètres : list = liste de zones délimitant des contenus à traiter. * -* count = nombre de zones à disposition. * -* binary = représentation de binaire chargé. * -* ctx = contexte offert en soutien à un désassemblage. * -* info = indications quant à la progression à afficher. * -* * -* Description : S'assure que l'ensemble des aires est entièrement décodé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void ensure_all_mem_areas_are_filled(mem_area *list, size_t count, const GLoadedBinary *binary, GProcContext *ctx, status_blob_info *info) -{ - size_t i; /* Boucle de parcours */ - - for (i = 0; i < count; i++) - fill_mem_area(&list[i], list, count, binary, ctx, info); - -} - - -/****************************************************************************** -* * * Paramètres : areas = série d'aires représentant à contenu à parcourir. * * count = nombre de ces zones présentes. * * * diff --git a/src/analysis/disass/area.h b/src/analysis/disass/area.h index 2e80b04..b517816 100644 --- a/src/analysis/disass/area.h +++ b/src/analysis/disass/area.h @@ -45,14 +45,19 @@ 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 *, mem_area *, size_t, const GLoadedBinary *, GProcContext *, const vmpa2t *, status_blob_info *); +void load_code_from_mem_area(mem_area **, size_t *, size_t *, const GLoadedBinary *, GProcContext *, const vmpa2t *, status_blob_info *); -/* Détermine une liste de zones contigües à traiter. */ -mem_area *compute_memory_areas(GExeFormat *, phys_t, size_t *); +/* S'assure qu'une aire qqcontient toutes ses instructions. */ +void fill_mem_area(mem_area **, size_t *, size_t *, const GLoadedBinary *, GProcContext *, status_blob_info *); + + + +/* Détermine une liste de zones contigües à traiter. */ +mem_area *compute_memory_areas(GExeFormat *, phys_t, size_t *); @@ -61,13 +66,11 @@ mem_area *compute_memory_areas(GExeFormat *, phys_t, size_t *); /* Détermine une liste de zones contigües à traiter. */ -mem_area *find_memory_area_by_addr(mem_area *, size_t, const vmpa2t *); +size_t find_memory_area_by_addr(mem_area *, size_t, const vmpa2t *); -/* S'assure que l'ensemble des aires est entièrement décodé. */ -void ensure_all_mem_areas_are_filled(mem_area *, size_t, const GLoadedBinary *, GProcContext *, status_blob_info *); /* Rassemble les instructions conservées dans des zones données. */ GArchInstruction *collect_instructions_from_mem_areas(mem_area *, size_t); diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c index 38ea8c0..c3ba2c2 100644 --- a/src/analysis/disass/fetch.c +++ b/src/analysis/disass/fetch.c @@ -24,6 +24,9 @@ #include "fetch.h" +#include + + #include @@ -32,7 +35,11 @@ /* Suit un flot d'exécution pour désassembler du code. */ -static void follow_execution_flow(const GLoadedBinary *, GProcContext *, mem_area *, size_t, status_blob_info *, virt_t); +static void follow_execution_flow(const GLoadedBinary *, GProcContext *, mem_area **, size_t *, status_blob_info *, virt_t); + +/* S'assure que l'ensemble des aires est entièrement décodé. */ +static void ensure_all_mem_areas_are_filled(mem_area **, size_t *, const GLoadedBinary *, GProcContext *, status_blob_info *); + @@ -53,10 +60,10 @@ static void follow_execution_flow(const GLoadedBinary *, GProcContext *, mem_are * * ******************************************************************************/ -static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx, mem_area *areas, size_t count, status_blob_info *info, virt_t virt) +static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx, mem_area **areas, size_t *count, status_blob_info *info, virt_t virt) { vmpa2t addr; /* Conversion en pleine adresse*/ - mem_area *area; /* Zone de désassemblage */ + size_t index; /* Zone trouvée à traiter */ printf("-- follow 0x%08x\n", (unsigned int)virt); @@ -72,9 +79,14 @@ static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx printf(" ++ point 0x%08x\n", (unsigned int)virt); - area = find_memory_area_by_addr(areas, count, &addr); + printf("looking area for 0x%08x\n", (unsigned int)virt); + + index = find_memory_area_by_addr(*areas, *count, &addr); + if (index == *count) continue; + + assert(index < *count); - load_code_from_mem_area(area, areas, count, binary, ctx, &addr, info); + load_code_from_mem_area(areas, count, &index, binary, ctx, &addr, info); @@ -88,6 +100,32 @@ static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx /****************************************************************************** * * +* Paramètres : list = liste de zones délimitant des contenus à traiter. * +* count = nombre de zones à disposition. * +* binary = représentation de binaire chargé. * +* ctx = contexte offert en soutien à un désassemblage. * +* info = indications quant à la progression à afficher. * +* * +* Description : S'assure que l'ensemble des aires est entièrement décodé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void ensure_all_mem_areas_are_filled(mem_area **list, size_t *count, const GLoadedBinary *binary, GProcContext *ctx, status_blob_info *info) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < *count; i++) + fill_mem_area(list, count, &i, binary, ctx, info); + +} + + +/****************************************************************************** +* * * Paramètres : binary = représentation de binaire chargé. * * statusbar = barre de statut avec progression à mettre à jour.* * id = identifiant du message affiché à l'utilisateur. * @@ -140,12 +178,12 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt virt = g_binary_format_get_entry_point(format); - follow_execution_flow(binary, ctx, areas, count, info, 0x84d0); + follow_execution_flow(binary, ctx, &areas, &count, info, 0x84d0); - follow_execution_flow(binary, ctx, areas, count, info, 0x84c5); - follow_execution_flow(binary, ctx, areas, count, info, 0x8a65); + follow_execution_flow(binary, ctx, &areas, &count, info, 0x84c5); + follow_execution_flow(binary, ctx, &areas, &count, info, 0x8a65); - follow_execution_flow(binary, ctx, areas, count, info, virt); + follow_execution_flow(binary, ctx, &areas, &count, info, virt); /* Symboles exécutables présents et passés à travers les mailles */ @@ -160,7 +198,7 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt addr = get_mrange_addr(range); virt = get_virt_addr(addr); - follow_execution_flow(binary, ctx, areas, count, info, virt); + follow_execution_flow(binary, ctx, &areas, &count, info, virt); } @@ -178,7 +216,7 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt _("Disassembling the remaining instructions..."), done, length); - ensure_all_mem_areas_are_filled(areas, count, binary, ctx, info); + ensure_all_mem_areas_are_filled(&areas, &count, binary, ctx, info); fini_progessive_status(info); diff --git a/src/arch/arm/v7/link.c b/src/arch/arm/v7/link.c index da5e30e..308d4e5 100644 --- a/src/arch/arm/v7/link.c +++ b/src/arch/arm/v7/link.c @@ -25,10 +25,15 @@ #include -#include +#include +#include + + +#include "operands/offset.h" #include "../register.h" +#include "../../raw.h" @@ -347,21 +352,20 @@ void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *instr phys_t phys_pc; /* Position dans l'exécution */ GArchOperand *op; /* Opérande de surcouche */ GArchOperand *sub_op; /* Opérande numérique en place */ - - uint32_t offset; /* Décallage encodé en dur */ bool ret; /* Bilan d'une récupération */ - - off_t val_offset; /* Position de valeur à lire */ - - - + vmpa2t sym_addr; /* Adresse de nouveau symbole */ off_t length; /* Taille des données à lire */ const bin_t *data; /* Données binaires à lire */ - - uint32_t target; /* Adresse virtuelle visée */ + mrange_t sym_range; /* Espace du nouveau symbole */ + VMPA_BUFFER(loc); /* Adresse au format texte */ + size_t name_len; /* Taille de nomination finale */ + char *name; /* Désignation humaine */ + GArchInstruction *sym_instr; /* Instruction de symbole */ + GBinSymbol *symbol; /* Nouveau symbole construit */ + GDbComment *comment; /* Définition de commentaire */ GArchOperand *new; /* Instruction de ciblage */ /* Récupération de l'adresse visée par le chargement */ @@ -401,13 +405,24 @@ void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *instr return; } - /* Lecture de la valeur vers laquelle renvoyer */ + /* Transformations et conservation d'une position de symbole */ if (g_armv7_offset_operand_is_positive(G_ARMV7_OFFSET_OPERAND(op))) val_offset = phys_pc + offset; else val_offset = phys_pc - offset; + init_vmpa(&sym_addr, val_offset, VMPA_NO_VIRTUAL); + init_mrange(&sym_range, &sym_addr, 4); + + + + + + + + + /* Lecture de la valeur vers laquelle renvoyer */ data = g_binary_format_get_content(format, &length); @@ -422,6 +437,55 @@ void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *instr printf(">>>>>>> @got target :: 0x%08x\n", (unsigned int)target); + + + + /* Réalise l'intégration du symbole associé */ + + sym_instr = g_raw_instruction_new_from_value(&sym_addr, MDS_32_BITS_UNSIGNED, target); + + name_len = strlen(_("Value used @ %s")) + VMPA_MAX_LEN + 1; + + name = (char *)calloc(name_len, sizeof(char)); + + vmpa2_virt_to_string(get_mrange_addr(range), MDS_32_BITS, loc, NULL); + snprintf(name, name_len, _("Value used @ %s"), loc); + + ADD_RAW_AS_SYM(format, symbol, &sym_addr, sym_instr, comment, name); + + free(name); + + + + g_proc_context_push_new_symbol_at(G_PROC_CONTEXT(context), &sym_addr); + printf("repush :: from 0x%x :: %x / %x\n", + (unsigned int)get_phy_addr(get_mrange_addr(range)), + (unsigned int)sym_addr.physical, (unsigned int)sym_addr.virtual); + + + printf("add sym %p\n", symbol); + + + + //g_proc_context_push_new_symbol_at(context, &sym_addr); + + + + + + + + + + + + + + + + + + //g_imm_operand_set_value(G_IMM_OPERAND(sub_op), MDS_32_BITS_UNSIGNED, target); diff --git a/src/arch/context-int.h b/src/arch/context-int.h index b181202..64465a2 100644 --- a/src/arch/context-int.h +++ b/src/arch/context-int.h @@ -41,6 +41,9 @@ struct _GProcContext virt_t *drop_points; /* Liste de points de départ */ size_t dp_count; /* Taille de cette liste */ + vmpa2t *extra_symbols; /* Adresses de symboles */ + size_t esyms_count; /* Nombres de nouveautés */ + }; diff --git a/src/arch/context.c b/src/arch/context.c index 794030a..5427e4a 100644 --- a/src/arch/context.c +++ b/src/arch/context.c @@ -85,6 +85,9 @@ static void g_proc_context_init(GProcContext *ctx) ctx->drop_points = NULL; ctx->dp_count = 0; + ctx->extra_symbols = NULL; + ctx->esyms_count = 0; + } @@ -205,3 +208,55 @@ virt_t g_proc_context_pop_drop_point(GProcContext *ctx) return result; } + + +/****************************************************************************** +* * +* Paramètres : ctx = contexte de désassemblage à compléter. * +* addr = adresse d'un nouveau symbole à traiter. * +* * +* Description : Empile une adresse de nouveau symbole à prendre en compte. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_proc_context_push_new_symbol_at(GProcContext *ctx, const vmpa2t *addr) +{ + ctx->extra_symbols = (vmpa2t *)realloc(ctx->extra_symbols, ++ctx->esyms_count * sizeof(vmpa2t)); + + copy_vmpa(&ctx->extra_symbols[ctx->esyms_count - 1], addr); + +} + + +/****************************************************************************** +* * +* Paramètres : ctx = contexte de désassemblage à compléter. * +* addr = adresse d'un nouveau symbole à traiter. * +* * +* Description : Dépile une adresse de nouveau symbole à prendre en compte. * +* * +* Retour : true si un symbole était bien encore en stock, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_proc_context_pop_new_symbol_at(GProcContext *ctx, vmpa2t *addr) +{ + bool result; /* Bilan à retourner */ + + result = (ctx->esyms_count > 0); + + if (result) + { + ctx->esyms_count--; + copy_vmpa(addr, &ctx->extra_symbols[ctx->esyms_count]); + } + + return result; + +} diff --git a/src/arch/context.h b/src/arch/context.h index 97b23b6..390d9f9 100644 --- a/src/arch/context.h +++ b/src/arch/context.h @@ -63,6 +63,12 @@ bool g_proc_context_has_addr_as_drop_points(const GProcContext *, virt_t); /* Fournit une adresse virtuelle comme point de départ de code. */ virt_t g_proc_context_pop_drop_point(GProcContext *); +/* Empile une adresse de nouveau symbole à prendre en compte. */ +void g_proc_context_push_new_symbol_at(GProcContext *, const vmpa2t *); + +/* Dépile une adresse de nouveau symbole à prendre en compte. */ +bool g_proc_context_pop_new_symbol_at(GProcContext *, vmpa2t *); + #endif /* _ARCH_CONTEXT_H */ diff --git a/src/arch/raw.c b/src/arch/raw.c index e76d75d..62c88c1 100644 --- a/src/arch/raw.c +++ b/src/arch/raw.c @@ -169,6 +169,76 @@ static void g_raw_instruction_finalize(GRawInstruction *instr) /****************************************************************************** * * +* Paramètres : addr = position à associer à l'instruction. * +* size = taille de l'opérande souhaitée. * +* value = valeur sur x bits à venir récupérer. * +* * +* Description : Crée une instruction de type 'db/dw/etc' simple. * +* * +* Retour : Instruction mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDataSize size, uint64_t value) +{ + GArchInstruction *result; /* Instruction à retourner */ + GArchOperand *operand; /* Octet non décodé à afficher */ + mrange_t range; /* Couverture de l'instruction */ + + result = g_object_new(G_TYPE_RAW_INSTRUCTION, NULL); + + operand = g_imm_operand_new_from_value(size, value); + if (operand == NULL) goto grinfv_error; + + g_imm_operand_pad(G_IMM_OPERAND(operand), true); + + g_arch_instruction_attach_extra_operand(result, operand); + + switch (size) + { + case MDS_8_BITS_UNSIGNED: + case MDS_8_BITS_SIGNED: + init_mrange(&range, addr, 1); + break; + + case MDS_16_BITS_UNSIGNED: + case MDS_16_BITS_SIGNED: + init_mrange(&range, addr, 2); + break; + + case MDS_32_BITS_UNSIGNED: + case MDS_32_BITS_SIGNED: + init_mrange(&range, addr, 4); + break; + + case MDS_64_BITS_UNSIGNED: + case MDS_64_BITS_SIGNED: + init_mrange(&range, addr, 8); + break; + + default: + goto grinfv_error; + break; + + } + + g_arch_instruction_set_range(result, &range); + + return result; + + grinfv_error: + + g_object_unref(G_OBJECT(result)); + + return NULL; + +} + + +/****************************************************************************** +* * * Paramètres : data = flux de données à analyser. * * size = taille de chacun des éléments à représenter. * * count = nombre de ces éléments. * diff --git a/src/arch/raw.h b/src/arch/raw.h index ce324f5..8ae9a74 100644 --- a/src/arch/raw.h +++ b/src/arch/raw.h @@ -52,6 +52,9 @@ typedef struct _GRawInstructionClass GRawInstructionClass; /* Indique le type défini pour une instruction inconnue d'architecture. */ GType g_raw_instruction_get_type(void); +/* Crée une instruction de type 'db/dw/etc' simple. */ +GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *, MemoryDataSize, uint64_t); + /* Crée une instruction de type 'db/dw/etc' étendue. */ GArchInstruction *g_raw_instruction_new_array(const bin_t *, MemoryDataSize, size_t, vmpa2t *, off_t, SourceEndian); diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c index b306f00..46d1a04 100644 --- a/src/arch/vmpa.c +++ b/src/arch/vmpa.c @@ -685,7 +685,12 @@ bool mrange_contains_addr(const mrange_t *range, const vmpa2t *addr) if (ret <= -1) { diff = compute_vmpa_diff(&range->addr, addr); - result = (diff < range->length); + + if (diff != VMPA_NO_PHYSICAL) + result = (diff < range->length); + else + result = false; + } else if (ret == 0) @@ -701,6 +706,27 @@ bool mrange_contains_addr(const mrange_t *range, const vmpa2t *addr) /****************************************************************************** * * +* Paramètres : range = zone mémoire à consulter. * +* addr = localisation mémoire à déterminer. * +* * +* Description : Calcule la position extérieure final d'une couverture. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void compute_mrange_end_addr(const mrange_t *range, vmpa2t *addr) +{ + copy_vmpa(addr, &range->addr); + advance_vmpa(addr, range->length); + +} + + +/****************************************************************************** +* * * Paramètres : rane = emplacement virtuel ou physique à traiter. * * msize = taille de cette adresse, réelle ou désirée. * * start = indique si le début ou la fin est à imprimer. * diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h index 6f8e809..97b2610 100644 --- a/src/arch/vmpa.h +++ b/src/arch/vmpa.h @@ -148,7 +148,7 @@ typedef struct _mrange_t /* Initialise une plage dans l'espace mémoire/physique. */ -void init_mrange(mrange_t *, const vmpa2t *, phys_t ); +void init_mrange(mrange_t *, const vmpa2t *, phys_t); /* Copie la définition d'une plage mémoire dans une autre. */ void copy_mrange(mrange_t *, const mrange_t *); @@ -162,6 +162,9 @@ bool mrange_contains_mrange(const mrange_t *, const mrange_t *); /* Indique si une localisation est incluse dans une zone ou non. */ bool mrange_contains_addr(const mrange_t *, const vmpa2t *); +/* Calcule la position extérieure final d'une couverture. */ +void compute_mrange_end_addr(const mrange_t *, vmpa2t *); + /* Transforme un emplacement physique en chaîne de caractères. */ char *mrange_phys_to_string(const mrange_t *, MemoryDataSize, bool, char [VMPA_MAX_LEN], size_t *); diff --git a/src/format/format.c b/src/format/format.c index e710668..ab5b372 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -253,7 +253,6 @@ GBinSymbol **g_binary_format_get_symbols(const GBinFormat *format, size_t *count * Paramètres : format = informations chargées à consulter. * * addr = adresse à cibler lors des recherches. * * symbol = éventuel symbole trouvé à déréfenrencer. [OUT] * -* diff = décallage entre l'adresse et le symbole. [OUT] * * * * Description : Recherche le symbole correspondant à une adresse. * * * @@ -263,7 +262,7 @@ GBinSymbol **g_binary_format_get_symbols(const GBinFormat *format, size_t *count * * ******************************************************************************/ -bool g_binary_format_resolve_symbol(const GBinFormat *format, const vmpa2t *addr, GBinSymbol **symbol, phys_t *diff) +bool g_binary_format_find_symbol_at(const GBinFormat *format, const vmpa2t *addr, GBinSymbol **symbol) { bool result; /* Bilan à retourner */ size_t i; /* Boucle de parcours */ @@ -275,11 +274,55 @@ bool g_binary_format_resolve_symbol(const GBinFormat *format, const vmpa2t *addr { range = g_binary_symbol_get_range(format->symbols[i]); - if (mrange_contains_addr(range, addr)) + if (cmp_vmpa(get_mrange_addr(range), addr) == 0) { *symbol = format->symbols[i]; g_object_ref(G_OBJECT(*symbol)); + result = true; + + } + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* addr = adresse à cibler lors des recherches. * +* symbol = éventuel symbole trouvé à déréfenrencer. [OUT] * +* diff = décallage entre l'adresse et le symbole. [OUT] * +* * +* Description : Recherche le symbole correspondant à une adresse. * +* * +* Retour : true si l'opération a été un succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_format_resolve_symbol(const GBinFormat *format, const vmpa2t *addr, GBinSymbol **symbol, phys_t *diff) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + const mrange_t *range; /* Espace mémoire parcouru */ + + result = false; + + //for (i = 0; i < format->symbols_count && !result; i++) + for (i = format->symbols_count; i > 0 && !result; i--) + { + range = g_binary_symbol_get_range(format->symbols[i - 1]); + + if (mrange_contains_addr(range, addr)) + { + *symbol = format->symbols[i - 1]; + g_object_ref(G_OBJECT(*symbol)); + *diff = compute_vmpa_diff(get_mrange_addr(range), addr); result = true; diff --git a/src/format/format.h b/src/format/format.h index 364f71a..9b2e0f6 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -68,6 +68,9 @@ void g_binary_format_add_symbol(GBinFormat *, GBinSymbol *); GBinSymbol **g_binary_format_get_symbols(const GBinFormat *, size_t *); /* Recherche le symbole correspondant à une adresse. */ +bool g_binary_format_find_symbol_at(const GBinFormat *, const vmpa2t *, GBinSymbol **); + +/* Recherche le symbole correspondant à une adresse. */ bool g_binary_format_resolve_symbol(const GBinFormat *, const vmpa2t *, GBinSymbol **, phys_t *); /* Ajoute une routine à la collection du format binaire. */ diff --git a/src/format/symbol.c b/src/format/symbol.c index 5e66c54..1e6063f 100644 --- a/src/format/symbol.c +++ b/src/format/symbol.c @@ -24,6 +24,7 @@ #include "symbol.h" +#include #include @@ -290,6 +291,63 @@ const char *g_binary_symbol_get_label(const GBinSymbol *symbol) /****************************************************************************** * * +* Paramètres : symbol = symbole à venir mettre à jour. * +* full = adresse dont la définition est complète. * +* * +* Description : Raffine la définition de l'emplacement d'un symbole. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_symbol_fix_range(GBinSymbol *symbol, const vmpa2t *full) +{ + GArchInstruction *instr; /* Instruction associée */ + mrange_t range; /* Plage à manipuler */ + GBinRoutine *routine; /* Routine associée */ + + switch (symbol->type) + { + case STP_DATA: + + instr = g_binary_symbol_get_instruction(symbol); + + copy_mrange(&range, g_arch_instruction_get_range(instr)); + + assert(cmp_vmpa(get_mrange_addr(&range), full) == 0); + + copy_vmpa(get_mrange_addr(&range), full); + + g_arch_instruction_set_range(instr, &range); + + break; + + case STP_ROUTINE: + + routine = g_binary_symbol_get_routine(symbol); + + copy_mrange(&range, g_binary_routine_get_range(routine)); + + assert(cmp_vmpa(get_mrange_addr(&range), full) == 0); + + copy_vmpa(get_mrange_addr(&range), full); + + g_binary_routine_set_range(routine, &range); + + break; + + default: + break; + + } + +} + + +/****************************************************************************** +* * * Paramètres : symbol = symbole à venir consulter. * * * * Description : Fournit l'emplacement où se situe un symbole. * @@ -393,6 +451,25 @@ void g_binary_symbol_attach_instruction(GBinSymbol *symbol, GArchInstruction *in * * * Paramètres : symbol = symbole à venir consulter. * * * +* Description : Fournit l'éventuelle routine associée au symbole. * +* * +* Retour : - * +* * +* Remarques : Il n'y a pas de transfert de propriété ici ! * +* * +******************************************************************************/ + +GBinRoutine *g_binary_symbol_get_routine(const GBinSymbol *symbol) +{ + return symbol->extra.routine; + +} + + +/****************************************************************************** +* * +* Paramètres : symbol = symbole à venir consulter. * +* * * Description : Fournit l'éventuelle instruction associée au symbole. * * * * Retour : - * diff --git a/src/format/symbol.h b/src/format/symbol.h index ac1ff0d..c5bf750 100644 --- a/src/format/symbol.h +++ b/src/format/symbol.h @@ -81,6 +81,9 @@ vmpa_t g_binary_symbol_get_address(const GBinSymbol *); /////////////////// /* Fournit un étiquette pour viser un symbole. */ const char *g_binary_symbol_get_label(const GBinSymbol *); +/* Raffine la définition de l'emplacement d'un symbole. */ +void g_binary_symbol_fix_range(GBinSymbol *, const vmpa2t *); + /* Fournit l'emplacement où se situe un symbole. */ const mrange_t *g_binary_symbol_get_range(const GBinSymbol *); @@ -93,6 +96,9 @@ void g_binary_symbol_attach_routine(GBinSymbol *, GBinRoutine *); /* Attache l'instruction associée au symbole. */ void g_binary_symbol_attach_instruction(GBinSymbol *, GArchInstruction *); +/* Fournit l'éventuelle routine associée au symbole. */ +GBinRoutine *g_binary_symbol_get_routine(const GBinSymbol *); + /* Fournit l'éventuelle instruction associée au symbole. */ GArchInstruction *g_binary_symbol_get_instruction(const GBinSymbol *); -- cgit v0.11.2-87-g4458