summaryrefslogtreecommitdiff
path: root/src/analysis/disass/disassembler.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-04-03 12:48:41 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-04-03 12:48:41 (GMT)
commitf80c4c6ee0479070f7319a5ce7e30e05406cdb8f (patch)
tree94bc363a6d1aeac29c1985a9627ceda962d1c38a /src/analysis/disass/disassembler.c
parent36a5b2577d67ab7c9f2c5817f6dba7a9601d1f20 (diff)
Reorganized the whole disassembling process and displayed the relative progression.
Diffstat (limited to 'src/analysis/disass/disassembler.c')
-rw-r--r--src/analysis/disass/disassembler.c421
1 files changed, 155 insertions, 266 deletions
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index 4e6a13c..5bd9d43 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -33,12 +33,9 @@
#include "fetch.h"
-#include "limit.h"
-#include "links.h"
-#include "loop.h"
-#include "macro.h"
#include "output.h"
-#include "rank.h"
+
+#include "instructions.h"
#include "routines.h"
#include "../../decomp/lang/asm.h"
#include "../../format/format.h"
@@ -81,8 +78,14 @@ static void g_delayed_disassembly_init(GDelayedDisassembly *);
/* Crée une tâche de désassemblage différé. */
static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *, GArchInstruction **, GCodeBuffer *);
+/* Opère sur toutes les instructions. */
+static void process_all_instructions(wgroup_id_t, GtkStatusStack *, const char *, ins_fallback_cb, GArchProcessor *, GExeFormat *);
+
+/* Opère sur toutes les routines. */
+static void process_all_routines(wgroup_id_t, GtkStatusStack *, const char *, rtn_fallback_cb, GArchProcessor *, GExeFormat *);
+
/* Assure le désassemblage en différé. */
-static void g_delayed_disassembly_process(GDelayedDisassembly *, GtkExtStatusBar *);
+static void g_delayed_disassembly_process(GDelayedDisassembly *, GtkStatusStack *);
@@ -178,10 +181,14 @@ static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GAr
/******************************************************************************
* *
-* Paramètres : disass = analyse à mener. *
-* statusbar = barre de statut à tenir informée. *
+* Paramètres : gid = groupe de travail impliqué. *
+ status = barre de statut à tenir informée. *
+* msg = message à faire paraître pour la patience. *
+* fallback = routine de traitements particuliers. *
+* proc = ensemble d'instructions désassemblées. *
+* format = accès aux données du binaire d'origine. *
* *
-* Description : Assure le désassemblage en différé. *
+* Description : Opère sur toutes les instructions. *
* *
* Retour : - *
* *
@@ -189,129 +196,204 @@ static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GAr
* *
******************************************************************************/
-static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtStatusBar *statusbar)
+static void process_all_instructions(wgroup_id_t gid, GtkStatusStack *status, const char *msg, ins_fallback_cb fallback, GArchProcessor *proc, GExeFormat *format)
{
- wgroup_id_t gid; /* Identifiant pour les tâches */
+ guint runs_count; /* Qté d'exécutions parallèles */
+ size_t ins_count; /* Quantité d'instructions */
+ size_t run_size; /* Volume réparti par exécution*/
+ GWorkQueue *queue; /* Gestionnaire de différés */
+ activity_id_t id; /* Identifiant de progression */
+ guint i; /* Boucle de parcours */
+ size_t begin; /* Début de bloc de traitement */
+ size_t end; /* Fin d'un bloc de traitement */
+ GInstructionsStudy *study; /* Tâche d'étude à programmer */
- //GBinFormat *format; /* Format du fichier binaire */
- GArchProcessor *proc; /* Architecture du binaire */
+ runs_count = g_get_num_processors();
+ ins_count = g_arch_processor_count_disassembled_instructions(proc);
- //size_t i; /* Boucle de parcours */
+ run_size = ins_count / runs_count;
- GBinRoutine **routines; /* Liste des routines trouvées */
- size_t routines_count; /* Nombre de ces routines */
- activity_id_t id; /* Identifiant de statut */
+ queue = get_work_queue();
+ id = gtk_status_stack_add_activity(status, msg, ins_count);
- //GArchProcessor *proc; /* Architecture du binaire */
+ for (i = 0; i < runs_count; i++)
+ {
+ begin = i * run_size;
+ if ((i + 1) == runs_count)
+ end = ins_count;
+ else
+ end = begin + run_size;
+ study = g_instructions_study_new(proc, G_BIN_FORMAT(format), begin, end, id, fallback);
- gid = g_work_queue_define_work_group(get_work_queue());
+ g_work_queue_schedule_work(queue, G_DELAYED_WORK(study), gid);
+ }
+ g_work_queue_wait_for_completion(queue, gid);
+ gtk_status_stack_remove_activity(status, id);
+}
- //format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
- proc = g_loaded_binary_get_processor(disass->binary);
+/******************************************************************************
+* *
+* Paramètres : gid = groupe de travail impliqué. *
+ status = barre de statut à tenir informée. *
+* msg = message à faire paraître pour la patience. *
+* fallback = routine de traitements particuliers. *
+* proc = ensemble d'instructions désassemblées. *
+* format = accès aux données du binaire d'origine. *
+* *
+* Description : Opère sur toutes les routines. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- routines = g_binary_format_get_routines(G_BIN_FORMAT(disass->format), &routines_count);
+static void process_all_routines(wgroup_id_t gid, GtkStatusStack *status, const char *msg, rtn_fallback_cb fallback, GArchProcessor *proc, GExeFormat *format)
+{
+ mrange_t *exe_ranges; /* Liste de zones exécutables */
+ size_t exe_count; /* Nombre de ces zones */
+ GBinRoutine **routines; /* Liste des routines trouvées */
+ size_t routines_count; /* Nombre de ces routines */
+ guint runs_count; /* Qté d'exécutions parallèles */
+ size_t run_size; /* Volume réparti par exécution*/
+ GWorkQueue *queue; /* Gestionnaire de différés */
+ activity_id_t id; /* Identifiant de progression */
+ guint i; /* Boucle de parcours */
+ size_t begin; /* Début de bloc de traitement */
+ size_t end; /* Fin d'un bloc de traitement */
+ GRoutinesStudy *study; /* Tâche d'étude à programmer */
+ exe_ranges = g_exe_format_get_x_ranges(format, &exe_count);
- /* Première étape */
+ routines = g_binary_format_get_routines(G_BIN_FORMAT(format), &routines_count);
- //id = gtk_extended_status_bar_push(statusbar, _("Disassembling..."), true);
+ runs_count = g_get_num_processors();
+ run_size = routines_count / runs_count;
+ queue = get_work_queue();
- process_disassembly_event(PGA_DISASSEMBLY_STARTED, disass->binary);
+ id = gtk_status_stack_add_activity(status, msg, routines_count);
+ for (i = 0; i < runs_count; i++)
+ {
+ begin = i * run_size;
+ if ((i + 1) == runs_count)
+ end = routines_count;
+ else
+ end = begin + run_size;
- *disass->instrs = disassemble_binary_content(disass->binary, gid, statusbar);
+ study = g_routines_study_new(proc, exe_ranges, exe_count, routines, routines_count,
+ begin, end, id, fallback);
+ g_work_queue_schedule_work(queue, G_DELAYED_WORK(study), gid);
- g_arch_processor_set_disassembled_instructions(proc, *disass->instrs);
+ }
+ g_work_queue_wait_for_completion(queue, gid);
- // plugins //////////////////////////
- process_disassembly_event(PGA_DISASSEMBLY_RAW, disass->binary);
+ gtk_status_stack_remove_activity(status, id);
+ if (exe_ranges != NULL)
+ free(exe_ranges);
+}
- /*
- *disass->instrs = disassemble_binary_parts(disass->binary, disass->parts, disass->count,
- statusbar, id);
- */
+/******************************************************************************
+* *
+* Paramètres : disass = analyse à mener. *
+* status = barre de statut à tenir informée. *
+* *
+* Description : Assure le désassemblage en différé. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatusStack *status)
+{
+ wgroup_id_t gid; /* Identifiant pour les tâches */
+ //GBinFormat *format; /* Format du fichier binaire */
+ GArchProcessor *proc; /* Architecture du binaire */
- do
- {
- GBinFormat *format; /* Format du fichier binaire */
- GArchInstruction *iter; /* Boucle de parcours */
+ //size_t i; /* Boucle de parcours */
+
+ GBinRoutine **routines; /* Liste des routines trouvées */
+ size_t routines_count; /* Nombre de ces routines */
+
- format = G_BIN_FORMAT(g_loaded_binary_get_format(disass->binary));
- for (iter = *disass->instrs;
- iter != NULL;
- iter = g_arch_instruction_get_next_iter(*disass->instrs, iter, 0))
- {
- g_arch_instruction_call_hook(iter, IPH_LINK, proc, /*ctx*/NULL, format);
+ gid = g_work_queue_define_work_group(get_work_queue());
- }
+ //format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
+ proc = g_loaded_binary_get_processor(disass->binary);
- } while (0);
+ routines = g_binary_format_get_routines(G_BIN_FORMAT(disass->format), &routines_count);
- // plugins //////////////////////////
- process_disassembly_event(PGA_DISASSEMBLY_HOOKED_LINK, disass->binary);
+ /* Première étape */
+ //id = gtk_extended_status_bar_push(statusbar, _("Disassembling..."), true);
- //gtk_extended_status_bar_remove(statusbar, id);
+ process_disassembly_event(PGA_DISASSEMBLY_STARTED, disass->binary);
- //run_plugins_on_binary(disass->binary, PGA_BINARY_DISASSEMBLED, true);
- do
- {
- GBinFormat *format; /* Format du fichier binaire */
- GArchInstruction *iter; /* Boucle de parcours */
+ *disass->instrs = disassemble_binary_content(disass->binary, gid, status);
+ g_arch_processor_set_disassembled_instructions(proc, *disass->instrs);
- format = G_BIN_FORMAT(g_loaded_binary_get_format(disass->binary));
- for (iter = *disass->instrs;
- iter != NULL;
- iter = g_arch_instruction_get_next_iter(*disass->instrs, iter, 0))
- {
+ // plugins //////////////////////////
+ process_disassembly_event(PGA_DISASSEMBLY_RAW, disass->binary);
- g_arch_instruction_call_hook(iter, IPH_POST, proc, /*ctx*/NULL, format);
+ process_all_instructions(gid, status, _("Calling 'link' hook on all instructions..."),
+ g_instructions_study_do_link_operation,
+ proc, disass->format);
- }
+
+ // plugins //////////////////////////
+ process_disassembly_event(PGA_DISASSEMBLY_HOOKED_LINK, disass->binary);
+
+
+
+ //gtk_extended_status_bar_remove(statusbar, id);
+ //run_plugins_on_binary(disass->binary, PGA_BINARY_DISASSEMBLED, true);
- } while (0);
+ process_all_instructions(gid, status, _("Calling 'post' hook on all instructions..."),
+ g_instructions_study_do_post_operation,
+ proc, disass->format);
@@ -332,17 +414,13 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
routines = g_binary_format_get_routines(G_BIN_FORMAT(disass->format), &routines_count);
-
-
- id = gtk_extended_status_bar_push(statusbar, _("Finding remaining limits..."), true);
-
//qsort(routines, routines_count, sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_rcompare);
- limit_all_routines(disass->format, proc, routines, routines_count, gid, 0/*id*/);
- gtk_extended_status_bar_remove(statusbar, 0/*id*/);
- //run_plugins_on_binary(disass->binary, PGA_BINARY_BOUNDED, true);
+ process_all_routines(gid, status,
+ _("Finding remaining limits..."),
+ g_routines_study_compute_limits, proc, disass->format);
@@ -353,24 +431,9 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
/* Troisième étape */
- id = gtk_extended_status_bar_push(statusbar, _("Establishing links..."), true);
-
-
- /**
- *
- * Lequel choisir ???
-
-G_BIN_FORMAT(disass->format)
-G_BIN_FORMAT(g_loaded_binary_get_format(disass->binary)
-
- */
-
-
- establish_links_between_instructions(*disass->instrs, G_BIN_FORMAT(disass->format), statusbar, 0/*id*/);
-
- gtk_extended_status_bar_remove(statusbar, 0/*id*/);
-
- //run_plugins_on_binary(disass->binary, PGA_BINARY_LINKED, true);
+ process_all_instructions(gid, status, _("Establishing links betweek all instructions..."),
+ g_instructions_study_do_link_operation,
+ proc, disass->format);
@@ -408,58 +471,11 @@ G_BIN_FORMAT(g_loaded_binary_get_format(disass->binary)
// Control-flow analysis...
-
-
-
-
-
-
-
- mrange_t *exe_ranges; /* Liste de zones exécutables */
- size_t exe_count; /* Nombre de ces zones */
- guint runs_count; /* Qté d'exécutions parallèles */
- size_t run_size; /* Volume réparti par exécution*/
- GWorkQueue *queue; /* Gestionnaire de différés */
- guint i; /* Boucle de parcours */
- size_t begin; /* Début de bloc de traitement */
- size_t end; /* Fin d'un bloc de traitement */
- GRoutinesStudy *study; /* Tâche d'étude à programmer */
-
- exe_ranges = g_exe_format_get_x_ranges(disass->format, &exe_count);
-
- runs_count = g_get_num_processors();
-
- run_size = routines_count / runs_count;
-
- queue = get_work_queue();
-
- for (i = 0; i < runs_count; i++)
- {
- begin = i * run_size;
-
- if ((i + 1) < runs_count)
- end = routines_count - begin;
- else
- end = begin + run_size;
-
- study = g_routines_study_new(proc, exe_ranges, exe_count, routines, routines_count, begin, end, id);
-
- g_work_queue_schedule_work(queue, G_DELAYED_WORK(study), gid);
-
- }
-
- g_work_queue_wait_for_completion(queue, gid);
-
- if (exe_ranges != NULL)
- free(exe_ranges);
-
-
-
-
-
-
-
-
+ /*
+ process_all_routines(gid, status,
+ _("Control-flow analysis for routines..."),
+ g_routines_study_handle_blocks, proc, disass->format);
+ */
@@ -510,7 +526,7 @@ G_BIN_FORMAT(g_loaded_binary_get_format(disass->binary)
proc = g_loaded_binary_get_processor(disass->binary);
print_disassembled_instructions(disass->buffer, disass->format, proc, *disass->instrs,
- routines, routines_count, statusbar, 0/*id*/);
+ routines, routines_count, status, 0/*id*/);
g_object_unref(G_OBJECT(proc));
@@ -532,133 +548,6 @@ G_BIN_FORMAT(g_loaded_binary_get_format(disass->binary)
}
-#if 0
-/******************************************************************************
-* *
-* Paramètres : disass = analyse à mener. *
-* statusbar = barre de statut à tenir informée. *
-* *
-* Description : Assure le désassemblage en différé. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_delayed_disassembly_process_old(GDelayedDisassembly *disass, GtkExtStatusBar *statusbar)
-{
-#ifdef DEBUG
- unsigned int valid; /* Instructions traduites */
- unsigned int db; /* Instructions non décodées */
- unsigned int valid_sum; /* Instructions traduites */
- unsigned int instr_sum; /* Instructions totales */
- size_t i; /* Boucle de parcours */
-#endif
- GBinRoutine **routines; /* Liste des routines trouvées */
- size_t routines_count; /* Nombre de ces routines */
- bstatus_id_t id; /* Identifiant de statut */
-
- routines = g_binary_format_get_routines(G_BIN_FORMAT(disass->format), &routines_count);
-
- /* Première étape */
-
- id = gtk_extended_status_bar_push(statusbar, _("Disassembling..."), true);
-
- *disass->instrs = disassemble_binary_parts(disass->binary, disass->parts, disass->count,
- statusbar, id);
-
- gtk_extended_status_bar_remove(statusbar, id);
-
-#ifdef DEBUG
-
- valid_sum = 0;
- instr_sum = 0;
-
- for (i = 0; i < disass->count; i++)
- {
- g_binary_part_get_checkup(disass->parts[i], &valid, &db);
- valid_sum += valid;
- instr_sum += (valid + db);
- }
-
- log_variadic_message(LMT_WARNING, _("Disassembled instructions : %u %% (%u / %d)"),
- (valid_sum * 100) / instr_sum,
- valid_sum, instr_sum);
-
-#endif
-
- run_plugins_on_binary(disass->binary, PGA_BINARY_DISASSEMBLED, true);
-
- /* Seconde étape */
-
- id = gtk_extended_status_bar_push(statusbar, _("Establishing links..."), true);
-
- establish_links_between_lines(*disass->instrs, routines, routines_count, statusbar, id);
-
- gtk_extended_status_bar_remove(statusbar, id);
-
- run_plugins_on_binary(disass->binary, PGA_BINARY_LINKED, true);
-
- /* Troisième étape */
-
- id = gtk_extended_status_bar_push(statusbar, _("Finding remaining limits..."), true);
-
- qsort(routines, routines_count, sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_rcompare);
-
- limit_all_routines(*disass->instrs, routines, routines_count, statusbar, id);
-
- gtk_extended_status_bar_remove(statusbar, id);
-
- run_plugins_on_binary(disass->binary, PGA_BINARY_BOUNDED, true);
-
- /* Quatrième étape */
-
- id = gtk_extended_status_bar_push(statusbar, _("Detecting loops..."), true);
-
- detect_loops_in_code(*disass->instrs, routines, routines_count, statusbar, id);
-
- gtk_extended_status_bar_remove(statusbar, id);
-
- /* Cinquième étape */
-
- id = gtk_extended_status_bar_push(statusbar, _("Grouping routines instructions..."), true);
-
- qsort(routines, routines_count, sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_rcompare);
-
- group_routines_instructions(*disass->instrs, routines, routines_count, statusbar, id);
-
- gtk_extended_status_bar_remove(statusbar, id);
-
- run_plugins_on_binary(disass->binary, PGA_BINARY_GROUPED, true);
-
- /* Sixième étape */
-
- id = gtk_extended_status_bar_push(statusbar, _("Ranking each instructions block..."), true);
-
- qsort(routines, routines_count, sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_rcompare);
-
- rank_routines_blocks(routines, routines_count, statusbar, id);
-
- gtk_extended_status_bar_remove(statusbar, id);
-
- run_plugins_on_binary(disass->binary, PGA_BINARY_GROUPED, true);
-
- /* Septième étape */
-
- id = gtk_extended_status_bar_push(statusbar, _("Printing disassembled code..."), true);
-
- qsort(routines, routines_count, sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_compare);
-
- print_disassembled_instructions(disass->buffer, disass->format, *disass->instrs,
- routines, routines_count, statusbar, id);
-
- gtk_extended_status_bar_remove(statusbar, id);
-
- run_plugins_on_binary(disass->binary, PGA_BINARY_PRINTED, true);
-
-}
-#endif
/* ---------------------------------------------------------------------------------- */