diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/analysis/disass/area.c | 1958 | ||||
-rw-r--r-- | src/analysis/disass/area.h | 84 | ||||
-rw-r--r-- | src/analysis/disass/fetch.c | 146 |
3 files changed, 189 insertions, 1999 deletions
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; |