summaryrefslogtreecommitdiff
path: root/src/analysis/disass
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/disass')
-rw-r--r--src/analysis/disass/area.c122
-rw-r--r--src/analysis/disass/area.h2
-rw-r--r--src/analysis/disass/fetch.c16
-rw-r--r--src/analysis/disass/output.c12
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);
+
+
}