summaryrefslogtreecommitdiff
path: root/src/analysis/disass
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-01-30 23:37:39 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-01-30 23:37:39 (GMT)
commitd246c98c515cb44c5bc4c742a674bae2e824872b (patch)
tree2ea1ec27ae5fba761ee778ba4ddb85c7752ebbf5 /src/analysis/disass
parent262c95e0b088a56e9fd919edc57ad19f85e2e40e (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.c481
-rw-r--r--src/analysis/disass/area.h15
-rw-r--r--src/analysis/disass/fetch.c60
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);