diff options
Diffstat (limited to 'src/analysis')
-rw-r--r-- | src/analysis/disass/area.c | 122 | ||||
-rw-r--r-- | src/analysis/disass/area.h | 2 | ||||
-rw-r--r-- | src/analysis/disass/fetch.c | 16 | ||||
-rw-r--r-- | src/analysis/disass/output.c | 12 |
4 files changed, 110 insertions, 42 deletions
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index 1abb402..b1d4bb1 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -75,6 +75,10 @@ static bool mark_range_in_mem_area_as_processed_v2(mem_area_v2 *, GArchInstructi +/* 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 *); + + /* 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); @@ -264,6 +268,60 @@ static bool mark_range_in_mem_area_as_processed_v2(mem_area_v2 *area, GArchInstr +/****************************************************************************** +* * +* Paramètres : area = aire représentant à contenu à parcourir. * +* offset = point de départ au sein de l'aire en question. * +* pos = tête de lecture dans l'espace global. * +* size = taille de l'instruction mise en place. [OUT] * +* * +* Description : Crée une instruction issue d'un désassemblage brut. * +* * +* Retour : Instruction mise en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GArchInstruction *load_raw_instruction_from_mem_area_v2(mem_area_v2 *area, phys_t offset, vmpa2t *pos, phys_t *size) +{ + GArchInstruction *result; /* Instruction à retourner */ + GBinContent *content; /* Données binaires à lire */ + SourceEndian endianness; /* Boutisme de cette machine */ + phys_t sz; /* Volume de données traité */ + vmpa2t prev; /* Boucle de parcours */ + + result = NULL; + + content = area->content; + endianness = area->endianness; + + sz = area->packing_size; + + if (get_virt_addr(pos) % sz == 0 && is_range_blank_in_mem_area_v2(area, offset, sz)) + { + *size = sz; + + copy_vmpa(&prev, pos); + + result = g_raw_instruction_new_array(content, MDS_FROM_BYTES(sz), 1, pos, endianness); + + if (result == NULL) + copy_vmpa(pos, &prev); + + } + + if (result == NULL) + { + *size = 1; + + result = g_raw_instruction_new_array(content, MDS_8_BITS, 1, pos, endianness); + + } + + return result; + +} @@ -280,6 +338,7 @@ static bool mark_range_in_mem_area_as_processed_v2(mem_area_v2 *area, GArchInstr * 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. * +* force = force la création d'au moins une instruction. * * status = barre de statut à actualiser. * * id = identifiant du groupe de progression à l'affichage. * * * @@ -291,7 +350,7 @@ static bool mark_range_in_mem_area_as_processed_v2(mem_area_v2 *area, GArchInstr * * ******************************************************************************/ -void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t count, GProcContext *ctx, const vmpa2t *start, GtkStatusStack *status, activity_id_t id) +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) { @@ -300,9 +359,11 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou GArchProcessor *proc; /* Architecture du binaire */ GBinContent *content; /* Données binaires à lire */ - phys_t diff; /* Volume de données traité */ + phys_t init_diff; /* Position initiale de lecture*/ phys_t alen; /* Taille de l'aire utilisée */ + bool forced_once; /* Préfigure une sortie rapide */ + phys_t i; /* Boucle de parcours */ @@ -310,6 +371,7 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou vmpa2t prev; /* Boucle de parcours */ GArchInstruction *instr; /* Instruction décodée */ + phys_t diff; /* Volume de données traité */ @@ -326,15 +388,13 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou - - /* Récupération des informations de base */ format = area->format; proc = area->proc; content = area->content; - diff = compute_vmpa_diff(get_mrange_addr(&area->range), start); + init_diff = compute_vmpa_diff(get_mrange_addr(&area->range), start); alen = get_mrange_length(&area->range); copy_vmpa(&pos, start); @@ -343,7 +403,9 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou printf("=== processing @ 0x%08x\n", (unsigned int)start->virtual); - for (i = diff; i < alen; i += diff) + forced_once = false; + + for (i = init_diff; i < alen; i += diff) { /** * On réalise un premier test informel (car non atomique) peu coûteux @@ -362,11 +424,24 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou copy_vmpa(&prev, &pos); instr = g_arch_processor_disassemble(proc, ctx, content, &pos, G_EXE_FORMAT(format)); - if (instr == NULL) break; - /* Enregistrement des positions et adresses */ + if (instr != NULL) + diff = compute_vmpa_diff(&prev, &pos); - diff = compute_vmpa_diff(&prev, &pos); + else + { + if (i == init_diff && force) + { + instr = load_raw_instruction_from_mem_area_v2(area, i, &pos, &diff); + forced_once = true; + } + + if (instr == NULL) + break; + + } + + /* Enregistrement des positions et adresses */ init_mrange(&range, &prev, diff); @@ -409,7 +484,7 @@ void load_code_from_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t cou } /* Rupture du flot d'exécution ? */ - if (g_arch_instruction_get_flags(instr) & AIF_RETURN_POINT) + if (forced_once || g_arch_instruction_get_flags(instr) & AIF_RETURN_POINT) break; } @@ -435,8 +510,6 @@ 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) { - GBinContent *content; /* Données binaires à lire */ - SourceEndian endianness; /* Boutisme de cette machine */ phys_t diff; /* Volume de données traité */ phys_t alen; /* Taille de l'aire utilisée */ vmpa2t pos; /* Boucle de parcours */ @@ -448,9 +521,6 @@ static void load_data_from_mem_area_v2(mem_area_v2 *area, GProcContext *ctx, con /* Récupération des informations de base */ - content = area->content; - endianness = area->endianness; - diff = compute_vmpa_diff(get_mrange_addr(&area->range), start); alen = get_mrange_length(&area->range); @@ -471,25 +541,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 */ - if (get_virt_addr(&pos) % area->packing_size == 0 - && is_range_blank_in_mem_area_v2(area, i, area->packing_size)) - { - diff = area->packing_size; - - instr = g_raw_instruction_new_array(content, MDS_FROM_BYTES(diff), 1, &pos, endianness); - - if (instr == NULL) - copy_vmpa(&pos, &prev); - - } - - if (instr == NULL) - { - diff = 1; - - instr = g_raw_instruction_new_array(content, MDS_8_BITS, 1, &pos, endianness); - - } + instr = load_raw_instruction_from_mem_area_v2(area, i, &pos, &diff); /* On rencontre ici un morceau déjà traité. */ @@ -562,7 +614,7 @@ static void fill_mem_area_v2(mem_area_v2 *area, mem_area_v2 *list, size_t count, 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, status, id); + load_code_from_mem_area_v2(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); diff --git a/src/analysis/disass/area.h b/src/analysis/disass/area.h index 3ffdbc5..abfa509 100644 --- a/src/analysis/disass/area.h +++ b/src/analysis/disass/area.h @@ -40,7 +40,7 @@ typedef struct _mem_area_v2 mem_area_v2; /* 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 *, GtkStatusStack *, activity_id_t); +void load_code_from_mem_area_v2(mem_area_v2 *, mem_area_v2 *, size_t, GProcContext *, const vmpa2t *, bool, GtkStatusStack *, activity_id_t); diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c index 373b8dc..4b162e8 100644 --- a/src/analysis/disass/fetch.c +++ b/src/analysis/disass/fetch.c @@ -68,6 +68,7 @@ typedef struct _GDelayedFetching GtkStatusStack *status; /* Barre de statut */ activity_id_t id; /* Groupe de progression */ + DisassPriorityLevel level; /* Niveau d'importance du point*/ virt_t virt; /* Adresse de départ dépilée */ } GDelayedFetching; @@ -96,7 +97,7 @@ static void g_delayed_fetching_dispose(GDelayedFetching *); static void g_delayed_fetching_finalize(GDelayedFetching *); /* Crée une tâche de récupération d'instructions différée. */ -static GDelayedFetching *g_delayed_fetching_new(const GDelayedFetching *, virt_t); +static GDelayedFetching *g_delayed_fetching_new(const GDelayedFetching *, unsigned int, virt_t); /* Assure la récupération d'instructions en différé. */ static void g_delayed_fetching_process(GDelayedFetching *, GtkExtStatusBar *); @@ -236,6 +237,7 @@ static void g_delayed_fetching_finalize(GDelayedFetching *fetching) /****************************************************************************** * * * Paramètres : template = modèle dont les informations sont à copier. * +* level = indication de priorité et d'origine de l'adresse. * * virt = point départ dépilé et personnalisant l'instance. * * * * Description : Crée une tâche de récupération d'instructions différée. * @@ -246,7 +248,7 @@ static void g_delayed_fetching_finalize(GDelayedFetching *fetching) * * ******************************************************************************/ -static GDelayedFetching *g_delayed_fetching_new(const GDelayedFetching *template, virt_t virt) +static GDelayedFetching *g_delayed_fetching_new(const GDelayedFetching *template, DisassPriorityLevel level, virt_t virt) { GDelayedFetching *result; /* Tâche à retourner */ @@ -268,9 +270,9 @@ static GDelayedFetching *g_delayed_fetching_new(const GDelayedFetching *template result->id = template->id; + result->level = level; result->virt = virt; - return result; } @@ -301,7 +303,8 @@ static void g_delayed_fetching_process(GDelayedFetching *fetching, GtkExtStatusB if (area != NULL) load_code_from_mem_area_v2(area, fetching->areas, fetching->count, - fetching->ctx, &addr, fetching->status, fetching->id); + fetching->ctx, &addr, fetching->level < 2, + fetching->status, fetching->id); } @@ -341,6 +344,7 @@ static void follow_execution_flow_v2(GProcContext *ctx, const GDelayedFetching * { GWorkQueue *queue; /* Gestionnaire de différés */ gint *remaining_counter; /* Compteur à considérer */ + DisassPriorityLevel level; /* Niveau d'importance du point*/ virt_t virt; /* Adresse de départ dépilée */ GDelayedFetching *fetching; /* Récupération à mener */ @@ -348,9 +352,9 @@ static void follow_execution_flow_v2(GProcContext *ctx, const GDelayedFetching * remaining_counter = (gint *)g_object_get_data(G_OBJECT(ctx), "remaining_counter"); - while (g_proc_context_pop_drop_point(ctx, &virt)) + while (g_proc_context_pop_drop_point(ctx, &level, &virt)) { - fetching = g_delayed_fetching_new(template, virt); + fetching = g_delayed_fetching_new(template, level, virt); /** * Pas très élégant : l'identifiant du groupe de travail ne sert qu'ici ; diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c index 0ff6148..78aba82 100644 --- a/src/analysis/disass/output.c +++ b/src/analysis/disass/output.c @@ -101,6 +101,12 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA char *prefixed; + + unsigned int _missing = 0; + + + + output = g_asm_output_new(); layer = g_exe_format_get_main_layer(format); @@ -202,6 +208,8 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA _("Unable to find a proper location for symbol '%s' @ 0x%08x"), g_binary_symbol_get_label(symbols[sym_index]), get_virt_addr(saddr)); + _missing++; + if (++sym_index == sym_count) goto no_more_symbol_finally; @@ -342,4 +350,8 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA g_object_unref(G_OBJECT(output)); + + fprintf(stderr, "MISSING :: %u symbols\n", _missing); + + } |