summaryrefslogtreecommitdiff
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
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
-rw-r--r--ChangeLog32
-rw-r--r--src/analysis/disass/area.c481
-rw-r--r--src/analysis/disass/area.h15
-rw-r--r--src/analysis/disass/fetch.c60
-rw-r--r--src/arch/arm/v7/link.c86
-rw-r--r--src/arch/context-int.h3
-rw-r--r--src/arch/context.c55
-rw-r--r--src/arch/context.h6
-rw-r--r--src/arch/raw.c70
-rw-r--r--src/arch/raw.h3
-rw-r--r--src/arch/vmpa.c28
-rw-r--r--src/arch/vmpa.h5
-rw-r--r--src/format/format.c49
-rw-r--r--src/format/format.h3
-rw-r--r--src/format/symbol.c77
-rw-r--r--src/format/symbol.h6
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 <nocbos@gmail.com>
+
+ * 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 <nocbos@gmail.com>
* 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 <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);
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 <assert.h>
-#include <operands/offset.h>
+#include <malloc.h>
+#include <i18n.h>
+
+
+#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 <assert.h>
#include <string.h>
@@ -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 *);