diff options
Diffstat (limited to 'src/analysis/disass/area.c')
-rw-r--r-- | src/analysis/disass/area.c | 122 |
1 files changed, 87 insertions, 35 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); |