diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2015-01-30 23:37:39 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2015-01-30 23:37:39 (GMT) |
commit | d246c98c515cb44c5bc4c742a674bae2e824872b (patch) | |
tree | 2ea1ec27ae5fba761ee778ba4ddb85c7752ebbf5 /src/analysis/disass | |
parent | 262c95e0b088a56e9fd919edc57ad19f85e2e40e (diff) |
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
Diffstat (limited to 'src/analysis/disass')
-rw-r--r-- | src/analysis/disass/area.c | 481 | ||||
-rw-r--r-- | src/analysis/disass/area.h | 15 | ||||
-rw-r--r-- | src/analysis/disass/fetch.c | 60 |
3 files changed, 446 insertions, 110 deletions
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 <assert.h> + + #include <i18n.h> @@ -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); |