summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-10-29 14:27:36 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-10-29 14:27:36 (GMT)
commitdf579a2d535ce83ec4eab9ac05924f8c2dd0ffac (patch)
tree739604d628774f6f1794828bd3ffef321cdad607
parent1558bd267c6d0d5188bcb7fad2db342ba72a2b7c (diff)
Cleaned the code and fixed memory leaks.
-rw-r--r--ChangeLog7
-rw-r--r--src/analysis/disass/area.c1958
-rw-r--r--src/analysis/disass/area.h84
-rw-r--r--src/analysis/disass/fetch.c146
4 files changed, 196 insertions, 1999 deletions
diff --git a/ChangeLog b/ChangeLog
index 4450196..5660ec0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
16-10-29 Cyrille Bagard <nocbos@gmail.com>
+ * src/analysis/disass/area.c:
+ * src/analysis/disass/area.h:
+ * src/analysis/disass/fetch.c:
+ Clean the code and fix memory leaks.
+
+16-10-29 Cyrille Bagard <nocbos@gmail.com>
+
* src/arch/arm/v7/context.c:
Read GCC warning messages with more care.
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index 96de6f3..2786242 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -31,14 +31,14 @@
#include "../../analysis/contents/restricted.h"
+#include "../../arch/raw.h"
#include "../../common/bits.h"
#include "../../gui/panels/log.h"
-
/* Zone mémoire bien bornée */
-typedef struct _mem_area_v2
+typedef struct _mem_area
{
GBinFormat *format; /* Format du fichier binaire */
GBinContent *content; /* Données binaires à lire */
@@ -52,65 +52,37 @@ typedef struct _mem_area_v2
bitfield_t *processed; /* Octets traités dans la zone */
GArchInstruction **instructions; /* Instructions en place */
-
-
-
bool is_exec; /* Zone exécutable ? */
-} mem_area_v2;
-
+} mem_area;
/* Initialise une aire de données à partir d'une adresse donnée. */
-static void init_mem_area_from_addr_v2(mem_area_v2 *, const vmpa2t *, phys_t, const GLoadedBinary *);
+static void init_mem_area_from_addr(mem_area *, const vmpa2t *, phys_t, const GLoadedBinary *);
/* Libère d'une aire de données les ressources allouées. */
-static void fini_mem_area_v2(mem_area_v2 *);
+static void fini_mem_area(mem_area *);
/* Indique si une zone donnée est intégralement vierge ou non. */
-static bool is_range_blank_in_mem_area_v2(mem_area_v2 *, phys_t, phys_t);
+static bool is_range_blank_in_mem_area(mem_area *, phys_t, phys_t);
/* Marque une série d'octets comme ayant été traités. */
-static bool mark_range_in_mem_area_as_processed_v2(mem_area_v2 *, GArchInstruction *, bool);
-
-
+static bool mark_range_in_mem_area_as_processed(mem_area *, GArchInstruction *, bool);
/* Crée une instruction issue d'un désassemblage brut. */
-static GArchInstruction *load_raw_instruction_from_mem_area_v2(mem_area_v2 *, phys_t, vmpa2t *, phys_t *);
-
+static GArchInstruction *load_raw_instruction_from_mem_area(mem_area *, phys_t, vmpa2t *, phys_t *);
+/* S'assure de la présence d'un début de routine à un point. */
+static void update_address_as_routine(GBinFormat *, const vmpa2t *);
/* Procède au désassemblage d'un contenu binaire non exécutable. */
-static void load_data_from_mem_area_v2(mem_area_v2 *, GProcContext *, const vmpa2t *, GtkStatusStack *, activity_id_t);
+static void load_data_from_mem_area(mem_area *, GProcContext *, const vmpa2t *, GtkStatusStack *, activity_id_t);
/* S'assure qu'une aire contient toutes ses instructions. */
-static void fill_mem_area_v2(mem_area_v2 *, mem_area_v2 *, size_t, GProcContext *, GtkStatusStack *, activity_id_t);
+static void fill_mem_area(mem_area *, mem_area *, size_t, GProcContext *, GtkStatusStack *, activity_id_t);
/* Rassemble les instructions conservées dans une zone donnée. */
-static GArchInstruction *get_instructions_from_mem_area_v2(const mem_area_v2 *);
-
-
-
-
-
-
-/* S'assure de la présence d'un début de routine à un point. */
-static void update_address_as_routine(GBinFormat *, const vmpa2t *);
-
-
-/**
- * Content :: à passer en restricted.
-
- * Les sections croisées : pas de sens de les traiter ici, car au final une instruction sera à cheval
- * sur deux sections différentes -> incohérence au niveau de l'éditeur.
- * => régler le périmètres de segments règle donc tous les soucis.
-
- */
-
-
-
-
-
+static GArchInstruction *get_instructions_from_mem_area(const mem_area *);
@@ -129,7 +101,7 @@ static void update_address_as_routine(GBinFormat *, const vmpa2t *);
* *
******************************************************************************/
-static void init_mem_area_from_addr_v2(mem_area_v2 *area, const vmpa2t *addr, phys_t len, const GLoadedBinary *binary)
+static void init_mem_area_from_addr(mem_area *area, const vmpa2t *addr, phys_t len, const GLoadedBinary *binary)
{
GBinContent *content; /* Données binaires à lire */
@@ -166,7 +138,7 @@ static void init_mem_area_from_addr_v2(mem_area_v2 *area, const vmpa2t *addr, ph
* *
******************************************************************************/
-static void fini_mem_area_v2(mem_area_v2 *area)
+static void fini_mem_area(mem_area *area)
{
phys_t len; /* Etendue du parcours total */
phys_t i; /* Boucle de parcours */
@@ -202,7 +174,7 @@ static void fini_mem_area_v2(mem_area_v2 *area)
* *
******************************************************************************/
-static bool is_range_blank_in_mem_area_v2(mem_area_v2 *area, phys_t start, phys_t len)
+static bool is_range_blank_in_mem_area(mem_area *area, phys_t start, phys_t len)
{
bool result; /* Résultat à renvoyer */
@@ -229,7 +201,7 @@ static bool is_range_blank_in_mem_area_v2(mem_area_v2 *area, phys_t start, phys_
* *
******************************************************************************/
-static bool mark_range_in_mem_area_as_processed_v2(mem_area_v2 *area, GArchInstruction *instr, bool force)
+static bool mark_range_in_mem_area_as_processed(mem_area *area, GArchInstruction *instr, bool force)
{
bool result; /* Bilan d'action à renvoyer */
const vmpa2t *start; /* Adresse de départ de la zone*/
@@ -260,12 +232,6 @@ static bool mark_range_in_mem_area_as_processed_v2(mem_area_v2 *area, GArchInstr
}
-
-
-
-
-
-
/******************************************************************************
* *
* Paramètres : area = aire représentant à contenu à parcourir. *
@@ -281,7 +247,7 @@ static bool mark_range_in_mem_area_as_processed_v2(mem_area_v2 *area, GArchInstr
* *
******************************************************************************/
-static GArchInstruction *load_raw_instruction_from_mem_area_v2(mem_area_v2 *area, phys_t offset, vmpa2t *pos, phys_t *size)
+static GArchInstruction *load_raw_instruction_from_mem_area(mem_area *area, phys_t offset, vmpa2t *pos, phys_t *size)
{
GArchInstruction *result; /* Instruction à retourner */
GBinContent *content; /* Données binaires à lire */
@@ -296,7 +262,7 @@ static GArchInstruction *load_raw_instruction_from_mem_area_v2(mem_area_v2 *area
sz = area->packing_size;
- if (get_virt_addr(pos) % sz == 0 && is_range_blank_in_mem_area_v2(area, offset, sz))
+ if (get_virt_addr(pos) % sz == 0 && is_range_blank_in_mem_area(area, offset, sz))
{
*size = sz;
@@ -322,9 +288,61 @@ static GArchInstruction *load_raw_instruction_from_mem_area_v2(mem_area_v2 *area
}
+/******************************************************************************
+* *
+* Paramètres : format = format binaire en cours de traitement. *
+* addr = adresse d'une instruction présentée comme première. *
+* *
+* Description : S'assure de la présence d'un début de routine à un point. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void update_address_as_routine(GBinFormat *format, const vmpa2t *addr)
+{
+ GBinSymbol *symbol; /* Symbole présent ou créé */
+ bool found; /* Détection de symbole */
+ SymbolType sym_type; /* Type de symbole en place */
+ bool wrong_type; /* Analyse plus fine de ce type*/
+ mrange_t range; /* Etendue du symbole à créer */
+ VMPA_BUFFER(loc); /* Traduction de l'adresse */
+ char name[5 + VMPA_MAX_LEN]; /* Nom de symbole nouveau */
+ GBinRoutine *routine; /* Nouvelle routine trouvée */
+
+ found = g_binary_format_find_symbol_at(format, addr, &symbol);
+
+ if (found)
+ {
+ sym_type = g_binary_symbol_get_target_type(symbol);
+ wrong_type = (sym_type != STP_ROUTINE && sym_type != STP_ENTRY_POINT);
+ }
+
+ if (!found || (found && wrong_type))
+ {
+ init_mrange(&range, addr, 0);
+
+ vmpa2_virt_to_string(addr, MDS_UNDEFINED, loc, NULL);
+ snprintf(name, sizeof(name), "sub_%s", loc + 2);
+
+ routine = g_binary_routine_new();
+ g_binary_routine_set_name(routine, strdup(name));
+
+ g_binary_routine_set_range(routine, &range);
+ if (!found)
+ {
+ symbol = g_binary_symbol_new(STP_ROUTINE);
+ g_binary_symbol_attach_routine(symbol, routine);
+ g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
+ }
+ else _g_binary_symbol_attach_routine(symbol, routine, STP_ROUTINE);
+ }
+}
/******************************************************************************
@@ -348,7 +366,7 @@ static GArchInstruction *load_raw_instruction_from_mem_area_v2(mem_area_v2 *area
* *
******************************************************************************/
-void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t count, GProcContext *ctx, const vmpa2t *start, bool force, GtkStatusStack *status, activity_id_t id)
+void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, GProcContext *ctx, const vmpa2t *start, bool force, GtkStatusStack *status, activity_id_t id)
{
@@ -409,7 +427,7 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou
* inutile.
*/
- if (!is_range_blank_in_mem_area_v2(area, i, 1))
+ if (!is_range_blank_in_mem_area(area, i, 1))
break;
/* Décodage d'une nouvelle instruction */
@@ -425,7 +443,7 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou
{
if (i == init_diff && force)
{
- instr = load_raw_instruction_from_mem_area_v2(area, i, &pos, &diff);
+ instr = load_raw_instruction_from_mem_area(area, i, &pos, &diff);
forced_once = true;
}
@@ -442,7 +460,7 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou
/* Progression dans les traitements */
- done = mark_range_in_mem_area_as_processed_v2(area, instr, false);
+ done = mark_range_in_mem_area_as_processed(area, instr, false);
if (!done)
{
@@ -452,7 +470,7 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou
gtk_status_stack_update_activity_value(status, id, diff);
- assert(!is_range_blank_in_mem_area_v2(area, i, diff));
+ assert(!is_range_blank_in_mem_area(area, i, diff));
/* Enregistrement d'un éventuel début de routine */
@@ -472,7 +490,7 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou
has_new_sym = g_binary_format_find_symbol_at(format, &sym_addr, &symbol);
if (has_new_sym)
- insert_extra_symbol_into_mem_areas_v2(list, count, symbol);
+ insert_extra_symbol_into_mem_areas(list, count, symbol);
}
@@ -501,7 +519,7 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou
* *
******************************************************************************/
-static void load_data_from_mem_area_v2(mem_area_v2 *area, GProcContext *ctx, const vmpa2t *start, GtkStatusStack *status, activity_id_t id)
+static void load_data_from_mem_area(mem_area *area, GProcContext *ctx, const vmpa2t *start, GtkStatusStack *status, activity_id_t id)
{
phys_t diff; /* Volume de données traité */
phys_t alen; /* Taille de l'aire utilisée */
@@ -525,7 +543,7 @@ static void load_data_from_mem_area_v2(mem_area_v2 *area, GProcContext *ctx, con
{
/* On cherche à obtenir l'assurance que le traitement n'a jamais été fait */
- if (!is_range_blank_in_mem_area_v2(area, i, 1))
+ if (!is_range_blank_in_mem_area(area, i, 1))
break;
instr = NULL;
@@ -534,7 +552,7 @@ static void load_data_from_mem_area_v2(mem_area_v2 *area, GProcContext *ctx, con
/* Décodage d'une nouvelle instruction, sur mesure puis minimale */
- instr = load_raw_instruction_from_mem_area_v2(area, i, &pos, &diff);
+ instr = load_raw_instruction_from_mem_area(area, i, &pos, &diff);
/* On rencontre ici un morceau déjà traité. */
@@ -550,7 +568,7 @@ static void load_data_from_mem_area_v2(mem_area_v2 *area, GProcContext *ctx, con
/* Progression dans les traitements */
- done = mark_range_in_mem_area_as_processed_v2(area, instr, false);
+ done = mark_range_in_mem_area_as_processed(area, instr, false);
if (!done)
{
@@ -560,7 +578,7 @@ static void load_data_from_mem_area_v2(mem_area_v2 *area, GProcContext *ctx, con
gtk_status_stack_update_activity_value(status, id, diff);
- assert(!is_range_blank_in_mem_area_v2(area, i, diff));
+ assert(!is_range_blank_in_mem_area(area, i, diff));
/* On laisse une chance au code pour se reprendre... */
@@ -589,7 +607,7 @@ static void load_data_from_mem_area_v2(mem_area_v2 *area, GProcContext *ctx, con
* *
******************************************************************************/
-static void fill_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t count, GProcContext *ctx, GtkStatusStack *status, activity_id_t id)
+static void fill_mem_area(mem_area *area, mem_area *list, size_t count, GProcContext *ctx, GtkStatusStack *status, activity_id_t id)
{
const vmpa2t *addr; /* Début de la zone à traiter */
phys_t len; /* Taille de la zone à remplir */
@@ -601,20 +619,20 @@ static void fill_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t count,
for (i = 0; i < len; i++)
{
- if (is_range_blank_in_mem_area_v2(area, i, 1))
+ if (is_range_blank_in_mem_area(area, i, 1))
{
copy_vmpa(&start, addr);
advance_vmpa(&start, i);
if (area->is_exec && get_virt_addr(&start) % area->packing_size == 0)
- load_code_from_mem_area_v2(area, list, count, ctx, &start, false, status, id);
+ load_code_from_mem_area(area, list, count, ctx, &start, false, status, id);
- if (is_range_blank_in_mem_area_v2(area, i, 1))
- load_data_from_mem_area_v2(area, ctx, &start, status, id);
+ if (is_range_blank_in_mem_area(area, i, 1))
+ load_data_from_mem_area(area, ctx, &start, status, id);
}
- assert(!is_range_blank_in_mem_area_v2(area, i, 1));
+ assert(!is_range_blank_in_mem_area(area, i, 1));
}
@@ -633,7 +651,7 @@ static void fill_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t count,
* *
******************************************************************************/
-static GArchInstruction *get_instructions_from_mem_area_v2(const mem_area_v2 *area)
+static GArchInstruction *get_instructions_from_mem_area(const mem_area *area)
{
GArchInstruction *result; /* Liste d'instr. à renvoyer */
phys_t len; /* Nombre d'instructions au max*/
@@ -661,72 +679,6 @@ static GArchInstruction *get_instructions_from_mem_area_v2(const mem_area_v2 *ar
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/******************************************************************************
-* *
-* Paramètres : list = listes de zones utable à consulter. *
-* count = nombre de zones mises en place. *
-* addr = adresse à retrouver dans les aires présentes. *
-* *
-* Description : Détermine une liste de zones contigües à traiter. *
-* *
-* Retour : Indice de la zone trouvée, ou nombre d'aires en cas d'échec. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-mem_area_v2 *find_memory_area_by_addr_v2(mem_area_v2 *list, size_t count, const vmpa2t *addr)
-{
- mem_area_v2 *result; /* Elément trouvé à renvoyer */
-
- int find_mem_area(const vmpa2t *_addr, const mem_area_v2 *_area)
- {
- int status; /* Bilan à retourner */
-
- if (mrange_contains_addr(&_area->range, _addr))
- status = 0;
-
- else
- status = cmp_vmpa(_addr, get_mrange_addr(&_area->range));
-
- return status;
-
- }
-
- result = bsearch(addr, list, count, sizeof(mem_area_v2), (__compar_fn_t)find_mem_area);
-
- return result;
-
-}
-
-
-
-
-
-
-
-
/******************************************************************************
* *
* Paramètres : binary = binaire analysé contenant quantités d'infos. *
@@ -741,9 +693,9 @@ mem_area_v2 *find_memory_area_by_addr_v2(mem_area_v2 *list, size_t count, const
* *
******************************************************************************/
-mem_area_v2 *compute_memory_areas_v2(const GLoadedBinary *binary, phys_t bin_length, size_t *count)
+mem_area *compute_memory_areas(const GLoadedBinary *binary, phys_t bin_length, size_t *count)
{
- mem_area_v2 *result; /* Liste à renvoyer */
+ mem_area *result; /* Liste à renvoyer */
GExeFormat *format; /* Format de fichier associé */
mrange_t *exe_ranges; /* Liste de zones exécutables */
size_t exe_count; /* Nombre de ces zones */
@@ -753,7 +705,7 @@ mem_area_v2 *compute_memory_areas_v2(const GLoadedBinary *binary, phys_t bin_len
bool status; /* Bilan d'une conversion */
size_t i; /* Boucle de parcours #1 */
const vmpa2t *border; /* Nouvelle bordure rencontrée */
- mem_area_v2 *area; /* Zone avec valeurs à éditer */
+ mem_area *area; /* Zone avec valeurs à éditer */
vmpa2t tmp; /* Stockage temporaire */
GPortionLayer *layer; /* Couche première de portions */
GBinPortion **portions; /* Morceaux d'encadrement */
@@ -792,22 +744,22 @@ mem_area_v2 *compute_memory_areas_v2(const GLoadedBinary *binary, phys_t bin_len
if (cmp_vmpa(&last, border) < 0)
{
- result = (mem_area_v2 *)realloc(result, ++(*count) * sizeof(mem_area_v2));
+ result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area));
area = &result[*count - 1];
- init_mem_area_from_addr_v2(area, &last, compute_vmpa_diff(&last, border), binary);
+ init_mem_area_from_addr(area, &last, compute_vmpa_diff(&last, border), binary);
area->is_exec = false;
}
/* Insertion d'une zone exécutable déjà définie */
- result = (mem_area_v2 *)realloc(result, ++(*count) * sizeof(mem_area_v2));
+ result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area));
area = &result[*count - 1];
- init_mem_area_from_addr_v2(area, get_mrange_addr(&exe_ranges[i]),
+ init_mem_area_from_addr(area, get_mrange_addr(&exe_ranges[i]),
get_mrange_length(&exe_ranges[i]), binary);
area->is_exec = true;
@@ -826,11 +778,11 @@ mem_area_v2 *compute_memory_areas_v2(const GLoadedBinary *binary, phys_t bin_len
if (get_phy_addr(&tmp) < bin_length)
{
- result = (mem_area_v2 *)realloc(result, ++(*count) * sizeof(mem_area_v2));
+ result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area));
area = &result[*count - 1];
- init_mem_area_from_addr_v2(area, &tmp, bin_length - get_phy_addr(&tmp), binary);
+ init_mem_area_from_addr(area, &tmp, bin_length - get_phy_addr(&tmp), binary);
area->is_exec = false;
}
@@ -868,11 +820,11 @@ mem_area_v2 *compute_memory_areas_v2(const GLoadedBinary *binary, phys_t bin_len
/* Si le déccoupage actuel ne correspond pas au besoin des portions... */
if (cmp_vmpa(get_mrange_addr(&area->range), portion_start) != 0)
{
- fini_mem_area_v2(&result[j]);
+ fini_mem_area(&result[j]);
- result = (mem_area_v2 *)realloc(result, ++(*count) * sizeof(mem_area_v2));
+ result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area));
- memmove(&result[j + 2], &result[j + 1], (*count - j - 2) * sizeof(mem_area_v2));
+ memmove(&result[j + 2], &result[j + 1], (*count - j - 2) * sizeof(mem_area));
status = result[j].is_exec;
@@ -885,7 +837,7 @@ mem_area_v2 *compute_memory_areas_v2(const GLoadedBinary *binary, phys_t bin_len
new_length = compute_vmpa_diff(&tmp, portion_start);
- init_mem_area_from_addr_v2(area, &tmp, new_length, binary);
+ init_mem_area_from_addr(area, &tmp, new_length, binary);
area->is_exec = status;
/* Seconde moitié */
@@ -894,7 +846,7 @@ mem_area_v2 *compute_memory_areas_v2(const GLoadedBinary *binary, phys_t bin_len
area = &result[j + 1];
- init_mem_area_from_addr_v2(area, portion_start, length, binary);
+ init_mem_area_from_addr(area, portion_start, length, binary);
area->is_exec = status;
}
@@ -935,7 +887,7 @@ mem_area_v2 *compute_memory_areas_v2(const GLoadedBinary *binary, phys_t bin_len
if (length == 0)
continue;
- insert_extra_symbol_into_mem_areas_v2(result, *count, symbols[i]);
+ insert_extra_symbol_into_mem_areas(result, *count, symbols[i]);
}
@@ -953,6 +905,45 @@ mem_area_v2 *compute_memory_areas_v2(const GLoadedBinary *binary, phys_t bin_len
/******************************************************************************
* *
+* Paramètres : list = listes de zones utable à consulter. *
+* count = nombre de zones mises en place. *
+* addr = adresse à retrouver dans les aires présentes. *
+* *
+* Description : Détermine une liste de zones contigües à traiter. *
+* *
+* 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)
+{
+ mem_area *result; /* Elément trouvé à renvoyer */
+
+ int find_mem_area(const vmpa2t *_addr, const mem_area *_area)
+ {
+ int status; /* Bilan à retourner */
+
+ if (mrange_contains_addr(&_area->range, _addr))
+ status = 0;
+
+ else
+ status = cmp_vmpa(_addr, get_mrange_addr(&_area->range));
+
+ return status;
+
+ }
+
+ result = bsearch(addr, list, count, sizeof(mem_area), (__compar_fn_t)find_mem_area);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : areas = liste de zones délimitant des contenus à traiter. *
* count = nombre de zones à disposition. *
* symbol = élément nouveau à venir insérer dans les zones. *
@@ -965,14 +956,14 @@ mem_area_v2 *compute_memory_areas_v2(const GLoadedBinary *binary, phys_t bin_len
* *
******************************************************************************/
-void insert_extra_symbol_into_mem_areas_v2(mem_area_v2 *areas, size_t count, const GBinSymbol *symbol)
+void insert_extra_symbol_into_mem_areas(mem_area *areas, size_t count, const GBinSymbol *symbol)
{
SymbolType type; /* Type de symbole */
GArchInstruction *list; /* Ensemble à insérer */
GArchInstruction *iter; /* Boucle de parcours */
const mrange_t *range; /* Emplacement d'instruction */
const vmpa2t *addr; /* Départ de cet emplacement */
- mem_area_v2 *area; /* Zone d'accueil désignée */
+ mem_area *area; /* Zone d'accueil désignée */
VMPA_BUFFER(loc); /* Description d'un emplacement*/
phys_t start; /* Point de départ */
@@ -990,7 +981,7 @@ void insert_extra_symbol_into_mem_areas_v2(mem_area_v2 *areas, size_t count, con
/* Une aire d'accueil existe-t-elle ? */
- area = find_memory_area_by_addr_v2(areas, count, addr);
+ area = find_memory_area_by_addr(areas, count, addr);
if (area == NULL)
{
@@ -1016,7 +1007,7 @@ void insert_extra_symbol_into_mem_areas_v2(mem_area_v2 *areas, size_t count, con
/* Inscription d'une instruction de symbole (sans retour arrière possible :/ ) */
- mark_range_in_mem_area_as_processed_v2(area, iter, true);
+ mark_range_in_mem_area_as_processed(area, iter, true);
g_object_ref(G_OBJECT(iter));
@@ -1042,19 +1033,19 @@ void insert_extra_symbol_into_mem_areas_v2(mem_area_v2 *areas, size_t count, con
* *
******************************************************************************/
-void ensure_all_mem_areas_are_filled(mem_area_v2 *list, size_t count, GProcContext *ctx, GtkStatusStack *status, activity_id_t id)
+void ensure_all_mem_areas_are_filled(mem_area *list, size_t count, GProcContext *ctx, GtkStatusStack *status, activity_id_t id)
{
size_t i; /* Boucle de parcours */
for (i = 0; i < count; i++)
- fill_mem_area_v2(&list[i], list, count, ctx, status, id);
+ fill_mem_area(&list[i], list, count, ctx, status, id);
}
/******************************************************************************
* *
-* Paramètres : areas = série d'aires représentant à contenu à parcourir. *
+* Paramètres : list = série d'aires représentant du contenu à parcourir. *
* count = nombre de ces zones présentes. *
* *
* Description : Rassemble les instructions conservées dans des zones données.*
@@ -1065,7 +1056,7 @@ void ensure_all_mem_areas_are_filled(mem_area_v2 *list, size_t count, GProcConte
* *
******************************************************************************/
-GArchInstruction *collect_instructions_from_mem_areas_v2(const mem_area_v2 *list, size_t count)
+GArchInstruction *collect_instructions_from_mem_areas(const mem_area *list, size_t count)
{
GArchInstruction *result; /* Liste d'instr. à renvoyer */
size_t i; /* Boucle de parcours */
@@ -1075,7 +1066,7 @@ GArchInstruction *collect_instructions_from_mem_areas_v2(const mem_area_v2 *list
for (i = 0; i < count; i++)
{
- instr = get_instructions_from_mem_area_v2(&list[i]);
+ instr = get_instructions_from_mem_area(&list[i]);
g_arch_instruction_merge_lists(&result, &instr);
}
@@ -1084,1659 +1075,26 @@ GArchInstruction *collect_instructions_from_mem_areas_v2(const mem_area_v2 *list
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-//////////////////////////////////::://////////////////////////////////////////////////////////////////////
-
-
-
-
-/* Zone mémoire bien bornée */
-typedef struct _mem_area
-{
- mrange_t range; /* Couverture de la zone */
-
- unsigned long *processed; /* Octets traités dans la zone */
- GArchInstruction **instructions; /* Instructions en place */
-
- bool has_sym; /* Représentation via symbole ?*/
-
- union
- {
- bool exec; /* Zone exécutable ? */
- GBinSymbol *symbol; /* Symbole associé à la zone */
- };
-
-} mem_area;
-
-
-/* Initialise une aire de données à partir d'une adresse donnée. */
-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 *);
-
-/* Libère d'une aire de données les ressources allouées. */
-static void fini_mem_area(mem_area *);
-
-/* Indique si une zone donnée est intégralement vierge ou non. */
-static bool is_range_blank_in_mem_area(mem_area *, phys_t, phys_t, GArchInstruction *);
-
-/* Marque une série d'octets comme ayant été traités. */
-static bool mark_range_in_mem_area_as_processed(mem_area *, phys_t, phys_t, GArchInstruction *);
-
-
-
-
-/* S'assure de la présence d'un début de routine à un point. */
-//static void update_address_as_routine(GBinFormat *, const vmpa2t *);
-
-
-
-
-/* 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 *);
-
-
-
-/* Rassemble les instructions conservées dans une zone donnée. */
-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 *, GBinSymbol *, size_t);
-
-
-
-
-/* Manipule la cartographie des octets traités d'une zone. */
-typedef bool (* visit_bytes_map_fc) (mem_area *, phys_t, phys_t, GArchInstruction *);
-
-
-
-
-
-/* Manipule la cartographie des octets d'aires de données. */
-static bool handle_bytes_map_in_mem_area(mem_area *, size_t, const mrange_t *, GArchInstruction *, visit_bytes_map_fc);
-
-/* Indique si une zone donnée est intégralement vierge ou non. */
-static bool is_range_blank_in_mem_areas(mem_area *, size_t, const mrange_t *);
-
-/* Marque une série d'octets comme ayant été traités. */
-static bool mark_range_in_mem_areas_as_processed(mem_area *, size_t, GArchInstruction *);
-
-
-
-
-
-
-
-/******************************************************************************
-* *
-* Paramètres : area = aire représentant à contenu à initialiser. *
-* addr = adresse de départ de l'espace à mettre en place. *
-* len = longueur de l'espace à créer. *
-* *
-* Description : Initialise une aire de données à partir d'une adresse donnée.*
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void init_mem_area_from_addr(mem_area *area, const vmpa2t *addr, phys_t len)
-{
- size_t requested; /* Nombre de mots à allouer */
-
- init_mrange(&area->range, addr, 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 *));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : area = aire représentant à contenu à initialiser. *
-* range = espace limitant à associer à l'aire de données. *
-* *
-* Description : Initialise une aire de données à partir d'un espace donné. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void init_mem_area_from_range(mem_area *area, const mrange_t *range)
-{
- phys_t len; /* Taille de la zone courante */
- size_t requested; /* Nombre de mots à allouer */
-
- 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 *));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : area = aire représentant à contenu à initialiser. *
-* 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 morceau donné. *
-* *
-* Retour : - *
-* *
-* Remarques : On considère que la zone de destination est inclue dans *
-* celle de référence. *
-* *
-******************************************************************************/
-
-static void init_mem_area_from_bigger_area(mem_area *area, const vmpa2t *addr, phys_t len, const mem_area *ref)
-{
- 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 */
-
- 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;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : area = aire représentant à contenu à nettoyer en mémoire. *
-* *
-* Description : Libère d'une aire de données les ressources allouées. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void fini_mem_area(mem_area *area)
-{
- free(area->processed);
-
-#if 0
- if (area->has_sym)
- g_object_unref(area->symbol); /* FIXME ?! */
-#endif
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : area = aire représentant à contenu à parcourir. *
-* start = début de la zone à manipuler. *
-* len = taille de cette même aire de données. *
-* instr = instruction à mémoriser pour la suite. *
-* *
-* Description : Indique si une zone donnée est intégralement vierge ou non. *
-* *
-* Retour : true si l'aire visée n'a jamais été traitée, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool is_range_blank_in_mem_area(mem_area *area, phys_t start, phys_t len, GArchInstruction *instr)
-{
- bool result; /* Bilan à renvoyer */
- phys_t max; /* Point d'arrêt de la boucle */
- phys_t i; /* Boucle de parcours */
- 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));
-
- result = true;
-
- for (i = start; i < max && result; i++)
- {
- index = i / (sizeof(unsigned long) * 8);
- remaining = i % (sizeof(unsigned long) * 8);
-
- result &= ((area->processed[index] & (1ul << remaining)) == 0);
-
- }
-
- return result;
-
-}
-
-
/******************************************************************************
* *
-* Paramètres : area = aire représentant à contenu à parcourir. *
-* start = début de la zone à manipuler. *
-* len = taille de cette même aire de données. *
-* instr = instruction à mémoriser pour la suite. *
-* *
-* Description : Marque une série d'octets comme ayant été traités. *
-* *
-* Retour : true. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool mark_range_in_mem_area_as_processed(mem_area *area, phys_t start, phys_t len, GArchInstruction *instr)
-{
- phys_t max; /* Point d'arrêt de la boucle */
- phys_t i; /* Boucle de parcours */
- size_t index; /* Cellule de tableau visée */
- unsigned int remaining; /* Nombre de bits restants */
-
- max = start + len;
-
- assert(max <= get_mrange_length(&area->range));
-
- for (i = start; i < max; i++)
- {
- index = i / (sizeof(unsigned long) * 8);
- remaining = i % (sizeof(unsigned long) * 8);
-
- //assert((area->processed[index] & (1ul << remaining)) == 0);
-
- area->processed[index] |= (1ul << remaining);
-
- }
-
- //assert(area->instructions[start] == NULL);
-
- area->instructions[start] = instr;
-
- return true;
-
-}
-
-
-
-
-
-
-
-
-
-
-
-/******************************************************************************
-* *
-* Paramètres : format = format binaire en cours de traitement. *
-* addr = adresse d'une instruction présentée comme première. *
-* *
-* Description : S'assure de la présence d'un début de routine à un point. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void update_address_as_routine(GBinFormat *format, const vmpa2t *addr)
-{
- GBinSymbol *symbol; /* Symbole présent ou créé */
- bool found; /* Détection de symbole */
- SymbolType sym_type; /* Type de symbole en place */
- bool wrong_type; /* Analyse plus fine de ce type*/
- mrange_t range; /* Etendue du symbole à créer */
- VMPA_BUFFER(loc); /* Traduction de l'adresse */
- char name[5 + VMPA_MAX_LEN]; /* Nom de symbole nouveau */
- GBinRoutine *routine; /* Nouvelle routine trouvée */
-
- found = g_binary_format_find_symbol_at(format, addr, &symbol);
-
- if (found)
- {
- sym_type = g_binary_symbol_get_target_type(symbol);
- wrong_type = (sym_type != STP_ROUTINE && sym_type != STP_ENTRY_POINT);
- }
-
- if (!found || (found && wrong_type))
- {
- init_mrange(&range, addr, 0);
-
- vmpa2_virt_to_string(addr, MDS_UNDEFINED, loc, NULL);
- snprintf(name, sizeof(name), "sub_%s", loc + 2);
-
- routine = g_binary_routine_new();
- g_binary_routine_set_name(routine, strdup(name));
-
- g_binary_routine_set_range(routine, &range);
-
- if (!found)
- {
- symbol = g_binary_symbol_new(STP_ROUTINE);
- g_binary_symbol_attach_routine(symbol, routine);
- g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
- }
- else _g_binary_symbol_attach_routine(symbol, routine, STP_ROUTINE);
-
- }
-
-}
-
-
-/******************************************************************************
-* *
-* 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 : Procède au désassemblage d'un contenu binaire exécutable. *
-* *
-* Retour : Recalcul de rafraîchissement de l'aire de travail requis ? *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool load_code_from_mem_area(mem_area **list, size_t *count, size_t *index, const GLoadedBinary *binary, GProcContext *ctx, const vmpa2t *start, status_blob_info *info)
-{
- bool result; /* Besoin à retourner */
- mem_area *area; /* Zone de désassemblage */
-
-
-
- GBinFormat *format; /* Format du fichier binaire */
- GArchProcessor *proc; /* Architecture du binaire */
- GBinContent *content; /* Données binaires à lire */
-
- phys_t diff; /* Volume de données traité */
- phys_t alen; /* Taille de l'aire utilisée */
-
- phys_t i; /* Boucle de parcours */
-
-
- vmpa2t pos; /* Boucle de parcours */
- vmpa2t prev; /* Boucle de parcours */
-
- GArchInstruction *instr; /* Instruction décodée */
-
-
-
- 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 */
- bool refresh; /* Besoin de rafraîchissement */
-
- result = false;
-
- /* On cherche à obtenir l'assurance que le traitement n'a jamais été fait */
-
- init_mrange(&range, start, 1);
- if (!is_range_blank_in_mem_areas(*list, *count, &range)) return false;
-
- /* Récupération des informations de base */
-
- format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
- proc = g_loaded_binary_get_processor(binary);
- content = g_binary_format_get_content(format);
- /* TODO : unref */
-
- area = (*list) + *index;
-
- diff = compute_vmpa_diff(get_mrange_addr(&area->range), start);
- alen = get_mrange_length(&area->range);
-
- /**
- * On copie la position courante à partir de l'aire plutôt que du
- * point de départ car cette première est potentiellement plus complète.
- */
-
- copy_vmpa(&pos, get_mrange_addr(&area->range));
- advance_vmpa(&pos, diff);
-
- for (i = diff; i < alen; i += diff)
- {
- /* S'il y a eu un point d'entrée en milieu de zone, on s'arrête ! */
- if (!is_range_blank_in_mem_area(area, i, 1, NULL)) break;
-
- /* Décodage d'une nouvelle instruction */
-
- copy_vmpa(&prev, &pos);
-
- instr = g_arch_processor_disassemble(proc, ctx, content, &pos, G_EXE_FORMAT(format));
-
- /* TODO : valider que la taille de l'instruction obtenue ne dépasse pas la zone */
-
- if (instr == NULL) break;
-
- /* Enregistrement des positions et adresses */
-
- diff = compute_vmpa_diff(&prev, &pos);
-
- assert(diff == 4 || diff == 2); /* FIXME */
-
- init_mrange(&range, &prev, diff);
-
- g_arch_instruction_set_range(instr, &range);
-
- /* Enregistrement d'un éventuel début de routine */
-
- if (g_arch_instruction_get_flags(instr) & AIF_ROUTINE_START)
- update_address_as_routine(format, &prev);
-
- /* Eventuel renvoi vers d'autres adresses */
-
- g_arch_instruction_call_hook(instr, IPH_FETCH, proc, ctx, format);
-
- /* Progression dans les traitements */
-
- 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));
-
- /* 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))
- {
- has_new_sym = g_binary_format_find_symbol_at(format, &sym_addr, &symbol);
- assert(has_new_sym);
-
- refresh = insert_extra_symbol_into_mem_areas(list, count, symbol, *index);
-
- result |= refresh;
-
- /**
- * Si une insertion a été réalisée dans la même zone que celle courante ou avant,
- * en l'absence d'indication sur les localisations exactes, le plus simple
- * est de tout recharger.
- */
- if (refresh)
- {
- *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;
-
- }
-
- /**
- * Si la zone modifiée se trouve bien après la zone courante, l'emplacement de la liste
- * peut potentiellement avoir évolué. Donc on ne recharge ici que le minimum.
- */
- else area = (*list) + *index;
-
- }
-
- assert(!is_range_blank_in_mem_areas(*list, *count, &range));
-
- /* Rupture du flot d'exécution ? */
- if (g_arch_instruction_get_flags(instr) & AIF_RETURN_POINT)
- break;
-
- }
-
- g_object_unref(G_OBJECT(content));
-
- g_object_unref(G_OBJECT(proc));
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : area = aire représentant à contenu à parcourir. *
-* 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. *
-* start = démarrage de l'exécution au sein de la zone. *
-* info = indications quant à la progression à afficher. *
-* *
-* Description : Procède au désassemblage d'un contenu binaire non exécutable.*
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void load_data_from_mem_area(mem_area *area, mem_area *list, size_t count, const GLoadedBinary *binary, GProcContext *ctx, const vmpa2t *start, status_blob_info *info)
-{
- GBinFormat *format; /* Format du fichier binaire */
- GBinContent *content; /* Données binaires à lire */
- GArchProcessor *proc; /* Architecture du binaire */
- SourceEndian endianness; /* Boutisme de cette machine */
- phys_t diff; /* Volume de données traité */
- phys_t alen; /* Taille de l'aire utilisée */
- phys_t i; /* Boucle de parcours */
- vmpa2t pos; /* Boucle de parcours */
- vmpa2t prev; /* Boucle de parcours */
- GArchInstruction *instr; /* Instruction décodée */
- mrange_t range; /* Couverture de l'instruction */
-
- /* On cherche à obtenir l'assurance que le traitement n'a jamais été fait */
-
- init_mrange(&range, start, 1);
- if (!is_range_blank_in_mem_areas(list, count, &range)) return;
-
- /* Récupération des informations de base */
-
- format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
- content = g_binary_format_get_content(format);
- /* TODO g_object_unref(G_OBJECT(format)); */
-
- proc = g_loaded_binary_get_processor(binary);
- endianness = g_arch_processor_get_endianness(proc);
- g_object_unref(G_OBJECT(proc));
-
- diff = compute_vmpa_diff(get_mrange_addr(&area->range), start);
- alen = get_mrange_length(&area->range);
-
- /**
- * On copie la position courante à partir de l'aire plutôt que du
- * point de départ car cette première est potentiellement plus complète.
- */
-
- copy_vmpa(&pos, get_mrange_addr(&area->range));
- advance_vmpa(&pos, diff);
-
- for (i = diff; i < alen; i += diff)
- {
- /* Décodage d'une nouvelle instruction, sur mesure */
-
- copy_vmpa(&prev, &pos);
-
- instr = NULL;
- /*
- if (instr == NULL && (i + 4) <= alen)
- {
- init_mrange(&range, &pos, 4);
-
- if (is_range_blank_in_mem_areas(list, count, &range))
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endianness);
-
- }
- */
- if (instr == NULL && (i + 2) <= alen)
- {
- copy_vmpa(&pos, &prev);
- init_mrange(&range, &pos, 2);
-
- if (is_range_blank_in_mem_areas(list, count, &range))
- instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endianness);
-
- }
-
- if (instr == NULL/* && (i + 1) <= alen*/)
- {
- copy_vmpa(&pos, &prev);
- init_mrange(&range, &pos, 1);
-
- if (is_range_blank_in_mem_areas(list, count, &range))
- instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endianness);
- else
- {
- /**
- * On rencontre ici un morceau déjà traité.
- * On recherche donc la fin de cette partie à sauter, si elle existe.
- */
-
- //////////////
- return;
-
-
-
- for (i++; i < alen; i++)
- {
- advance_vmpa(&pos, 1);
- init_mrange(&range, &pos, 1);
-
- if (is_range_blank_in_mem_areas(list, count, &range))
- break;
-
- }
-
- diff = 0;
- continue;
-
- }
-
- }
-
- assert(instr != NULL);
-
- /* Enregistrement des positions et adresses */
-
- diff = compute_vmpa_diff(&prev, &pos);
-
- init_mrange(&range, &prev, diff);
-
- g_arch_instruction_set_range(instr, &range);
-
- /* Progression dans les traitements */
-
- 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));
-
-
-
- if (area->exec) break;
-
-
-
- }
-
- g_object_unref(G_OBJECT(content));
-
-}
-
-
-/******************************************************************************
-* *
-* 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. *
-* *
-* Description : S'assure qu'une aire contient toutes ses instructions. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-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*/
- bool refresh; /* Besoin de rafraîchissement */
-
- area = (*list) + *index;
-
- /* Les symboles se doivent d'être indépendants ! */
- if (area->has_sym) return;
-
- len = get_mrange_length(&area->range);
-
- for (i = 0; i < len; i++)
- {
- if (is_range_blank_in_mem_area(area, i, 1, NULL))
- {
- copy_vmpa(&start, get_mrange_addr(&area->range));
- advance_vmpa(&start, i);
-
- if (area->exec && get_virt_addr(&start) % 4/*2 - FIXME */ == 0)
- {
- refresh = load_code_from_mem_area(list, count, index, binary, ctx, &start, info);
-
- /**
- * Mêmes commentaires que dans load_code_from_mem_area() :
- * - en cas de décalage avéré, on recharge tout.
- * - sinon, la liste a potentiellement été déplacée, donc on recharge un minimum.
- */
- if (refresh)
- {
- area = (*list) + *index;
- len = get_mrange_length(&area->range);
-
- i = compute_vmpa_diff(get_mrange_addr(&area->range), &start);
-
- }
- else area = (*list) + *index;
-
- }
-
- if (is_range_blank_in_mem_area(area, i, 1, NULL))
- load_data_from_mem_area(area, *list, *count, binary, ctx, &start, info);
-
- }
-
- assert(!is_range_blank_in_mem_area(area, i, 1, NULL));
-
- }
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : area = aire représentant à contenu à parcourir. *
-* *
-* Description : Rassemble les instructions conservées dans une zone donnée. *
-* *
-* Retour : Liste d'instructions prêtes à emploi. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static GArchInstruction *get_instructions_from_mem_area(const mem_area *area)
-{
- GArchInstruction *result; /* Liste d'instr. à renvoyer */
- phys_t len; /* Nombre d'instructions au max*/
- phys_t i; /* Boucle de parcours */
- GArchInstruction *instr; /* Instruction décodée */
-
- result = NULL;
-
- if (area->has_sym)
- switch (g_binary_symbol_get_target_type(area->symbol))
- {
- case STP_DATA:
- case STP_RO_STRING:
- result = g_binary_symbol_get_instruction(area->symbol);
- g_object_ref(G_OBJECT(result));
- break;
-
- case STP_ROUTINE:
- assert(false);
- //instr = load_code_binary(binary, start, end, statusbar, id);
- // + fill
- break;
-
- default:
- assert(false);
- break;
-
- }
-
- else
- {
- len = get_mrange_length(&area->range);
-
- for (i = 0; i < len; i++)
- {
- instr = area->instructions[i];
-
- if (instr != NULL)
- {
- g_object_ref(G_OBJECT(instr));
- g_arch_instruction_add_to_list(&result, instr);
- }
-
- }
-
- }
-
- return result;
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/******************************************************************************
-* *
-* Paramètres : format = format d'un exécutable à consulter. *
-* bin_length = quantité d'octets à traiter au total. *
-* count = nombre de zones mises en place. [OUT] *
-* *
-* Description : Détermine une liste de zones contigües à traiter. *
-* *
-* Retour : Liste de zones mémoire à libérer après usage. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-mem_area *compute_memory_areas(GExeFormat *format, phys_t bin_length, size_t *count)
-{
- mem_area *result; /* Liste à renvoyer */
- mrange_t *exe_ranges; /* Liste de zones exécutables */
- size_t exe_count; /* Nombre de ces zones */
- GBinSymbol **symbols; /* Symboles à représenter */
- size_t sym_count; /* Qté de symboles présents */
- vmpa2t *last; /* Dernière bordure rencontrée */
- size_t i; /* Boucle de parcours #1 */
- vmpa2t *border; /* Nouvelle bordure rencontrée */
- mem_area *area; /* Zone avec valeurs à éditer */
- vmpa2t tmp; /* Stockage temporaire */
-
-
- GBinPortion **portions; /* Morceaux d'encadrement */
- size_t portions_count; /* Taille de cette liste */
- const vmpa2t *portion_start; /* Point de départ de portion */
-
- size_t j; /* Boucle de parcours #2 */
- SymbolType type; /* Nature d'un symbole */
- const mrange_t *range; /* Couverture d'un symbole */
- const vmpa2t *start; /* Point de départ du symbole */
- phys_t length; /* Taille de ce même symbole */
- bool included; /* Inclusion dans une zone ? */
- mem_area orig; /* Copie de la zone réduite */
- phys_t old_length; /* Taille de zone originelle */
- phys_t new_length; /* Nouvelle taille déterminée */
- size_t next; /* Indice de zone suivante */
-
- result = NULL;
- *count = 0;
-
- /**
- * Le parcours n'est valide que si les listes, symboles et zones exécutables,
- * sont triées !
- */
-
- exe_ranges = g_exe_format_get_x_ranges(format, &exe_count);
-
- symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &sym_count);
-
- /* Première étape : on comble les trous ! */
-
- last = make_vmpa(0, VMPA_NO_VIRTUAL);
-
- for (i = 0; i < exe_count; i++)
- {
- border = get_mrange_addr(&exe_ranges[i]);
-
- /* Zone tampon à constituer */
-
- if (cmp_vmpa_by_phy(last, border) < 0)
- {
- result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area));
-
- area = &result[*count - 1];
-
- init_mem_area_from_addr(area, last, compute_vmpa_diff(last, border));
- area->has_sym = false;
- area->exec = false;
-
- }
-
- /* Insertion d'une zone exécutable déjà définie */
-
- result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area));
-
- area = &result[*count - 1];
-
- init_mem_area_from_range(area, &exe_ranges[i]);
- area->has_sym = false;
- area->exec = true;
-
- /* Avancée du curseur */
-
- copy_vmpa(last, border);
-
- advance_vmpa(last, get_mrange_length(&exe_ranges[i]));
-
- }
-
- delete_vmpa(last);
-
- /* Extension finale complémentaire ? */
-
- area = &result[*count - 1];
-
- copy_vmpa(&tmp, get_mrange_addr(&area->range));
- advance_vmpa(&tmp, get_mrange_length(&area->range));
-
- if (get_phy_addr(&tmp) < bin_length)
- {
- result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area));
-
- area = &result[*count - 1];
-
- init_mem_area_from_addr(area, &tmp, bin_length - get_phy_addr(&tmp));
- area->has_sym = false;
- area->exec = false;
-
- }
-
- /* Seconde étape : on s'assure du découpage autour des portions pour respecter l'alignement */
-
- portions = NULL;//g_exe_format_get_portions_at_level(format, -1, &portions_count);
- portions_count = 0;
-
-
- for (i = 1; i < portions_count; i++)
- {
- portion_start = get_mrange_addr(g_binary_portion_get_range(portions[i]));
-
- for (j = 0; j < *count; j++)
- {
- area = &result[j];
-
- if (!mrange_contains_addr(&area->range, portion_start))
- continue;
-
- /* Si le déccoupage actuel ne correspond pas au besoin des portions... */
- if (cmp_vmpa(get_mrange_addr(&area->range), portion_start) != 0)
- {
- fini_mem_area(&result[j]);
-
- result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area));
-
- memmove(&result[j + 2], &result[j + 1], (*count - j - 2) * sizeof(mem_area));
-
- copy_mem_area_properties(&result[j + 1], &result[j]);
-
- /* Première moitié */
-
- area = &result[j];
-
- copy_vmpa(&tmp, get_mrange_addr(&area->range));
- length = get_mrange_length(&area->range);
-
- init_mem_area_from_addr(area, &tmp, compute_vmpa_diff(&tmp, portion_start));
-
- /* Seconde moitié */
-
- length -= get_mrange_length(&area->range);
-
- area = &result[j + 1];
-
- init_mem_area_from_addr(area, portion_start, length);
-
- }
-
- j = *count;
-
- }
-
- }
-
- /* Troisième étape : on insère les symboles existants */
-
- j = 0;
-
- for (i = 0; i < *count; i++)
- {
- /* Sélection et écartement des symboles */
-
- range = NULL; /* Pour GCC */
- length = 0; /* Pour GCC */
-
- for (; j < sym_count; j++)
- {
- type = g_binary_symbol_get_target_type(symbols[j]);
-
- /**
- * On ne garde que les symboles renvoyant directement une ou
- * plusieurs instructions, c'est à dire les symboles valides
- * pour un appel à g_binary_symbol_get_instruction().
- *
- * Les instructions des autres symboles sont obtenues et mises
- * en place durant la procédure de désassemblage.
- */
-
- if (type == STP_ROUTINE || type == STP_ENTRY_POINT || type == STP_CODE_LABEL)
- continue;
-
- range = g_binary_symbol_get_range(symbols[j]);
-
- length = get_mrange_length(range);
-
- if (length > 0)
- break;
-
- }
-
- if (j == sym_count)
- break;
-
- start = get_mrange_addr(range);
-
- /* Si un découpage s'impose... */
-
- if (mrange_contains_addr(&result[i].range, start))
- {
- copy_vmpa(&tmp, start);
- advance_vmpa(&tmp, length);
-
- included = mrange_contains_addr(&result[i].range, &tmp);
-
- memcpy(&orig, &result[i], sizeof(mem_area));
-
- fini_mem_area(&orig);
-
- /* Réduction de la zone de départ */
-
- copy_vmpa(&tmp, get_mrange_addr(&result[i].range));
- old_length = get_mrange_length(&result[i].range);
-
- new_length = compute_vmpa_diff(get_mrange_addr(&result[i].range), start);
-
- if (new_length == 0)
- {
- memmove(&result[i], &result[i + 1], (*count - i - 1) * sizeof(mem_area));
-
- (*count)--;
- next = i;
-
- }
- else
- {
- init_mem_area_from_addr(&result[i], &tmp, new_length);
- next = i + 1;
- }
-
- /* Insertion de la zone du symbole */
-
- result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area));
-
- memmove(&result[next + 1], &result[next], (*count - next - 1) * sizeof(mem_area));
-
- area = &result[next];
-
- init_mem_area_from_range(area, range);
-
- area->has_sym = true;
- area->symbol = symbols[j];
-
- /* Jointure finale... */
-
- if (included)
- {
- /* Simple extension pour rattraper la fin originelle */
-
- if ((old_length - new_length - length) > 0)
- {
- result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area));
-
- memmove(&result[next + 2], &result[next + 1], (*count - next - 2) * sizeof(mem_area));
-
- area = &result[next + 1];
-
- copy_vmpa(&tmp, start);
- advance_vmpa(&tmp, length);
-
- init_mem_area_from_addr(area, &tmp, old_length - new_length - length);
-
- copy_mem_area_properties(area, &orig);
-
- }
-
- i = next;
-
- }
- else
- {
- /* Suppression des éventuelles zones totalement recouvertes */
-
-
-
- /* Réduction de la zone d'arrivée */
-
-
- }
-
- j++;
-
- }
-
- }
-
- if (exe_ranges != NULL)
- free(exe_ranges);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : list = liste de zones délimitant des contenus à traiter. *
-* count = nombre de zones à disposition. *
-* symbol = élément nouveau à venir insérer dans les zones. *
-* working = indice de l'aire de travail courante. *
-* *
-* Description : Insère un symbole dans un découpage en aires. *
-* *
-* Retour : Recalcul de rafraîchissement de l'aire de travail requis ? *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool insert_extra_symbol_into_mem_areas(mem_area **list, size_t *count, GBinSymbol *symbol, size_t working)
-{
- bool result; /* Besoin à renvoyer */
- const mrange_t *sym_range; /* Emplacement du symbole */
- size_t index; /* Zone trouvée à scinder */
- mem_area *area; /* Aire en cours de traitement */
- 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);
-
- result = (working >= index);
-
- area = &(*list)[index];
-
- if (area->has_sym) return false;
-
- 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)
- {
- assert(false);
-
- 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 a une taille identique à la zone qui le contient, on remplace simplement... */
- if (get_mrange_length(&area_range) == get_mrange_length(sym_range))
- {
- assert((cmp_vmpa(&area_pos, &sym_pos) == 0));
-
- init_mem_area_from_range(area, sym_range);
-
- area->has_sym = true;
- area->symbol = symbol;
-
- goto iesima_done;
-
- }
-
- /* Si le symbole se trouve en début de zone... */
- if (cmp_vmpa(&area_pos, &sym_pos) == 0)
- {
- *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));
-
- 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));
-
- assert(new_length != 0); /* Symbole non présent au début */
-
- area = &(*list)[index];
-
- init_mem_area_from_bigger_area(area, &area_pos, new_length, &saved);
-
- /* 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);
-
- assert(new_length != 0); /* Symbole non présent à la fin */
-
- area = &(*list)[index + 2];
-
- init_mem_area_from_bigger_area(area, &area_pos, new_length, &saved);
-
- }
-
- fini_mem_area(&saved);
-
- iesima_done:
-
- return result;
-
-}
-
-
-
-
-
-
-
-
-
-/******************************************************************************
-* *
-* Paramètres : list = listes de zones utable à consulter. *
-* count = nombre de zones mises en place. *
-* addr = adresse à retrouver dans les aires présentes. *
-* *
-* Description : Détermine une liste de zones contigües à traiter. *
-* *
-* Retour : Indice de la zone trouvée, ou nombre d'aires en cas d'échec. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-size_t find_memory_area_by_addr(mem_area *list, size_t count, const vmpa2t *addr)
-{
- size_t result; /* Trouvaille à retourner */
- mem_area *found; /* Elément trouvé éventuel */
-
- int find_mem_area(const vmpa2t *addr, const mem_area *area)
- {
- int status; /* Bilan à retourner */
-
- if (mrange_contains_addr(&area->range, addr))
- status = 0;
-
- else
- status = cmp_vmpa(addr, get_mrange_addr(&area->range));
-
- return status;
-
- }
-
- found = bsearch(addr, list, count, sizeof(mem_area), (__compar_fn_t)find_mem_area);
-
- result = (found != NULL ? found - list : count);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : list = liste de zones délimitant des contenus à traiter. *
-* count = nombre de zones à disposition. *
-* range = aire des octets à manipuler. *
-* visitor = fonction opérationnelle finale à appeler. *
-* *
-* Description : Manipule la cartographie des octets d'aires de données. *
-* *
-* Retour : valeur retournée par le visiteur, voire false si erreur. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-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 */
- phys_t processed; /* Quantité traitée */
- vmpa2t start; /* Point de départ suivant */
-
- result = 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);
-
- /* Traitement intégral dans la zone trouvée */
-
- if ((offset + remaining) <= get_mrange_length(&area->range))
- result = visitor(area, offset, remaining, instr);
-
- else
- {
-
- printf("BUG_ON | off=%u remaining=%u length=%u\n",
- (unsigned int)offset,
- (unsigned int)remaining,
- (unsigned int)get_mrange_length(&area->range));
-
- printf("BUG_ON @ 0x%08x + %d\n",
- (unsigned int)get_virt_addr(get_mrange_addr(range)),
- (int)get_mrange_length(range)
- );
-
-
- assert(0);
-
- /* Traitement de la fin de la première aire */
-
- processed = get_mrange_length(&area->range) - offset;
-
- result = visitor(area, offset, processed, instr);
-
- /* Traitement des zones adjacentes suivantes */
-
- copy_vmpa(&start, get_mrange_addr(range));
-
- for (remaining -= processed; remaining > 0 && result; remaining -= processed)
- {
- advance_vmpa(&start, processed);
-
- 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;
-
- result = visitor(area, 0, processed, instr);
-
- }
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : list = liste de zones délimitant des contenus à traiter. *
-* count = nombre de zones à disposition. *
-* range = aire des octets à manipuler. *
-* *
-* Description : Indique si une zone donnée est intégralement vierge ou non. *
-* *
-* Retour : true si l'aire visée n'a jamais été traitée, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool is_range_blank_in_mem_areas(mem_area *list, size_t count, const mrange_t *range)
-{
- return handle_bytes_map_in_mem_area(list, count,
- range, NULL,
- is_range_blank_in_mem_area);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : list = liste de zones délimitant des contenus à traiter. *
-* count = nombre de zones à disposition. *
-* instr = instruction désassemblée à conserver en mémoire. *
-* *
-* Description : Marque une série d'octets comme ayant été traités. *
-* *
-* Retour : true. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool mark_range_in_mem_areas_as_processed(mem_area *list, size_t count, GArchInstruction *instr)
-{
- return handle_bytes_map_in_mem_area(list, count,
- g_arch_instruction_get_range(instr), instr,
- mark_range_in_mem_area_as_processed);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : areas = série d'aires représentant à contenu à parcourir. *
+* Paramètres : list = série d'aires représentant du contenu à libérer. *
* count = nombre de ces zones présentes. *
* *
-* Description : Rassemble les instructions conservées dans des zones données.*
+* Description : Libère la mémoire occupée par des zones de données. *
* *
-* Retour : Liste d'instructions prêtes à emploi. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchInstruction *collect_instructions_from_mem_areas(mem_area *list, size_t count)
+void release_mem_areas(mem_area *list, size_t count)
{
- GArchInstruction *result; /* Liste d'instr. à renvoyer */
size_t i; /* Boucle de parcours */
- GArchInstruction *instr; /* Instruction(s) à insérer */
-
- result = NULL;
for (i = 0; i < count; i++)
- {
- instr = get_instructions_from_mem_area(&list[i]);
- g_arch_instruction_merge_lists(&result, &instr);
- }
+ fini_mem_area(&list[i]);
- return result;
+ free(list);
}
diff --git a/src/analysis/disass/area.h b/src/analysis/disass/area.h
index abfa509..99113f6 100644
--- a/src/analysis/disass/area.h
+++ b/src/analysis/disass/area.h
@@ -31,96 +31,30 @@
-
/* Zone mémoire bien bornée */
-typedef struct _mem_area_v2 mem_area_v2;
-
-
-
+typedef struct _mem_area mem_area;
/* Procède au désassemblage d'un contenu binaire exécutable. */
-void load_code_from_mem_area_v2(mem_area_v2 *, mem_area_v2 *, size_t, GProcContext *, const vmpa2t *, bool, GtkStatusStack *, activity_id_t);
-
-
-
+void load_code_from_mem_area(mem_area *, mem_area *, size_t, GProcContext *, const vmpa2t *, bool, GtkStatusStack *, activity_id_t);
/* Détermine une liste de zones contigües à traiter. */
-mem_area_v2 *find_memory_area_by_addr_v2(mem_area_v2 *, size_t, const vmpa2t *);
-
-
+mem_area *compute_memory_areas(const GLoadedBinary *, phys_t, size_t *);
/* Détermine une liste de zones contigües à traiter. */
-mem_area_v2 *compute_memory_areas_v2(const GLoadedBinary *, phys_t, size_t *);
+mem_area *find_memory_area_by_addr(mem_area *, size_t, const vmpa2t *);
/* Insère un symbole dans un découpage en aires. */
-void insert_extra_symbol_into_mem_areas_v2(mem_area_v2 *, size_t, const GBinSymbol *);
+void insert_extra_symbol_into_mem_areas(mem_area *, size_t, const GBinSymbol *);
/* S'assure que l'ensemble des aires est entièrement décodé. */
-void ensure_all_mem_areas_are_filled(mem_area_v2 *, size_t, GProcContext *, GtkStatusStack *, activity_id_t);
+void ensure_all_mem_areas_are_filled(mem_area *, size_t, GProcContext *, GtkStatusStack *, activity_id_t);
/* Rassemble les instructions conservées dans des zones données. */
-GArchInstruction *collect_instructions_from_mem_areas_v2(const mem_area_v2 *, size_t);
-
-
-
-
-
-#include <stdbool.h>
-
-
-
-
-#include "../binary.h"
-#include "../../format/executable.h"
-#include "../../gtkext/gtkextstatusbar.h"
-
-
-//////
-#include "../../arch/raw.h"
-#include "../../arch/instruction.h"
-
-
-
-/* Zone mémoire bien bornée */
-typedef struct _mem_area mem_area;
-
+GArchInstruction *collect_instructions_from_mem_areas(const mem_area *, size_t);
-
-
-
-
-
-/* Procède au désassemblage d'un contenu binaire exécutable. */
-bool load_code_from_mem_area(mem_area **, size_t *, size_t *, const GLoadedBinary *, GProcContext *, const vmpa2t *, status_blob_info *);
-
-
-
-
-
-/* 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 *);
-
-
-
-
-
-
-
-/* Détermine une liste de zones contigües à traiter. */
-size_t find_memory_area_by_addr(mem_area *, size_t, const vmpa2t *);
-
-
-
-
-
-/* Rassemble les instructions conservées dans des zones données. */
-GArchInstruction *collect_instructions_from_mem_areas(mem_area *, size_t);
+/* Libère la mémoire occupée par des zones de données. */
+void release_mem_areas(mem_area *, size_t);
diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c
index ab3f3c7..9df9248 100644
--- a/src/analysis/disass/fetch.c
+++ b/src/analysis/disass/fetch.c
@@ -35,13 +35,7 @@
-
-
-
-
-
/* ------------------------- RECUPERATIONS EN TOILE DE FOND ------------------------- */
-/* ------------------------ DESASSEMBLAGE DE BINAIRE DIFFERE ------------------------ */
#define G_TYPE_DELAYED_FETCHING g_delayed_fetching_get_type()
@@ -62,7 +56,7 @@ typedef struct _GDelayedFetching
GExeFormat *format; /* Format du fichier binaire */
GProcContext *ctx; /* Contexte de désassemblage */
- mem_area_v2 *areas; /* Zone de productions */
+ mem_area *areas; /* Zone de productions */
size_t count; /* Nombre de ces zones */
GtkStatusStack *status; /* Barre de statut */
@@ -100,29 +94,18 @@ static void g_delayed_fetching_finalize(GDelayedFetching *);
static GDelayedFetching *g_delayed_fetching_new(const GDelayedFetching *, DisassPriorityLevel, virt_t);
/* Assure la récupération d'instructions en différé. */
-static void g_delayed_fetching_process(GDelayedFetching *, GtkExtStatusBar *);
-
-
-
-
-
-
+static void g_delayed_fetching_process(GDelayedFetching *, GtkStatusStack *);
-
-/* ------------------------ DESASSEMBLAGE DE BINAIRE DIFFERE ------------------------ */
/* ------------------------ DESASSEMBLAGE DE BINAIRE DIFFERE ------------------------ */
+/* Poursuit l'analyse à partir des points d'entrée découverts. */
+static void follow_execution_flow(GProcContext *, const GDelayedFetching *);
-
-/* 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 *);
-
-
-
-
+/* Etudie le besoin d'attendre d'avantage de prochaines tâches. */
+static bool check_if_extra_wait_is_needed(GWorkQueue *, wgroup_id_t, GProcContext *);
@@ -131,12 +114,6 @@ static void follow_execution_flow(const GLoadedBinary *, GProcContext *, mem_are
/* ---------------------------------------------------------------------------------- */
-
-
-
-
-
-
/* Indique le type défini pour les tâches de récupération différée. */
G_DEFINE_TYPE(GDelayedFetching, g_delayed_fetching, G_TYPE_DELAYED_WORK);
@@ -280,8 +257,8 @@ static GDelayedFetching *g_delayed_fetching_new(const GDelayedFetching *template
/******************************************************************************
* *
-* Paramètres : fetching = récupération à mener. *
-* statusbar = barre de statut à tenir informée. *
+* Paramètres : fetching = récupération à mener. *
+* status = barre de statut à tenir informée. *
* *
* Description : Assure la récupération d'instructions en différé. *
* *
@@ -291,18 +268,18 @@ static GDelayedFetching *g_delayed_fetching_new(const GDelayedFetching *template
* *
******************************************************************************/
-static void g_delayed_fetching_process(GDelayedFetching *fetching, GtkExtStatusBar *statusbar)
+static void g_delayed_fetching_process(GDelayedFetching *fetching, GtkStatusStack *status)
{
vmpa2t addr; /* Conversion en pleine adresse*/
- mem_area_v2 *area; /* Zone trouvée à traiter */
+ mem_area *area; /* Zone trouvée à traiter */
if (!g_exe_format_translate_address_into_vmpa(fetching->format, fetching->virt, &addr))
- return/*init_vmpa(&addr, VMPA_NO_PHYSICAL, fetching->virt)*/;
+ return;
- area = find_memory_area_by_addr_v2(fetching->areas, fetching->count, &addr);
+ area = find_memory_area_by_addr(fetching->areas, fetching->count, &addr);
if (area != NULL)
- load_code_from_mem_area_v2(area, fetching->areas, fetching->count,
+ load_code_from_mem_area(area, fetching->areas, fetching->count,
fetching->ctx, &addr, fetching->level < 2,
fetching->status, fetching->id);
@@ -310,21 +287,9 @@ static void g_delayed_fetching_process(GDelayedFetching *fetching, GtkExtStatusB
-
-
-
-
-
-
-
-/* Poursuit l'analyse à partir des points d'entrée découverts. */
-static void follow_execution_flow_v2(GProcContext *, const GDelayedFetching *);
-
-/* Etudie le besoin d'attendre d'avantage de prochaines tâches. */
-static bool check_if_extra_wait_is_needed(GWorkQueue *, wgroup_id_t, GProcContext *);
-
-
-
+/* ---------------------------------------------------------------------------------- */
+/* DESASSEMBLAGE DE BINAIRE DIFFERE */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
@@ -340,7 +305,7 @@ static bool check_if_extra_wait_is_needed(GWorkQueue *, wgroup_id_t, GProcContex
* *
******************************************************************************/
-static void follow_execution_flow_v2(GProcContext *ctx, const GDelayedFetching *template)
+static void follow_execution_flow(GProcContext *ctx, const GDelayedFetching *template)
{
GWorkQueue *queue; /* Gestionnaire de différés */
gint *remaining_counter; /* Compteur à considérer */
@@ -410,73 +375,6 @@ static bool check_if_extra_wait_is_needed(GWorkQueue *queue, wgroup_id_t id, GPr
}
-
-
-
-
-
-
-
-
-
-
-
-/******************************************************************************
-* *
-* Paramètres : binary = représentation de binaire chargé. *
-* ctx = contexte offert en soutien à un désassemblage. *
-* areas = liste de zones contenant des données à traiter. *
-* count = nombre de ces aires à disposition. *
-* info = informations liées à l'affichage de la progression. *
-* *
-* Description : Suit un flot d'exécution pour désassembler du code. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx, mem_area **areas, size_t *count, status_blob_info *info)
-{
-#if 0
- virt_t virt; /* Adresse de départ dépilée */
- vmpa2t addr; /* Conversion en pleine adresse*/
- GExeFormat *format; /* Format du fichier binaire */
- size_t index; /* Zone trouvée à traiter */
-
- while (g_proc_context_has_drop_points(ctx))
- {
- g_proc_context_pop_drop_point(ctx, &virt);
-
- format = g_loaded_binary_get_format(binary);
-
- if (!g_exe_format_translate_address_into_vmpa(format, virt, &addr))
- init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
-
- printf(" ++ point 0x%08x\n", (unsigned int)virt);
-
-
- 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(areas, count, &index, binary, ctx, &addr, info);
-
-
-
- printf(" ++\n");
-
-
- }
-#endif
-}
-
-static GDelayedFetching template; /* Patron des tâches à venir */
-
/******************************************************************************
* *
* Paramètres : binary = représentation de binaire chargé. *
@@ -495,7 +393,7 @@ static GDelayedFetching template; /* Patron des tâches à venir
GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GProcContext *ctx, wgroup_id_t gid, GtkStatusStack *status)
{
GArchInstruction *result; /* Instruction désassemblées */
- //GDelayedFetching template; /* Patron des tâches à venir */
+ GDelayedFetching template; /* Patron des tâches à venir */
GBinFormat *format; /* Format du fichier binaire */
GBinContent *content; /* Contenu binaire à manipuler */
phys_t length; /* Taille des données à lire */
@@ -515,7 +413,7 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GProcC
length = g_binary_content_compute_size(content);
g_object_unref(G_OBJECT(content));
- template.areas = compute_memory_areas_v2(binary, length, &template.count);
+ template.areas = compute_memory_areas(binary, length, &template.count);
template.status = status;
@@ -537,7 +435,7 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GProcC
(wait_for_incoming_works_cb)check_if_extra_wait_is_needed,
template.ctx);
- g_signal_connect(template.ctx, "drop-point-pushed", G_CALLBACK(follow_execution_flow_v2), &template);
+ g_signal_connect(template.ctx, "drop-point-pushed", G_CALLBACK(follow_execution_flow), &template);
template.id = gtk_status_stack_add_activity(status,
_("Disassembling following the execution flow..."),
@@ -567,7 +465,7 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GProcC
gtk_status_stack_update_activity(status, template.id, _("Collecting disassembled instructions..."));
- result = collect_instructions_from_mem_areas_v2(template.areas, template.count);
+ result = collect_instructions_from_mem_areas(template.areas, template.count);
gtk_status_stack_remove_activity(status, template.id);
@@ -575,7 +473,7 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GProcC
//g_object_unref(G_OBJECT(template.format));
- /* TODO / del(areas); */
+ release_mem_areas(template.areas, template.count);
return result;