diff options
Diffstat (limited to 'src/analysis/disass/disassembler.c')
-rw-r--r-- | src/analysis/disass/disassembler.c | 421 |
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 /* ---------------------------------------------------------------------------------- */ |