diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2016-04-03 12:48:41 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2016-04-03 12:48:41 (GMT) | 
| commit | f80c4c6ee0479070f7319a5ce7e30e05406cdb8f (patch) | |
| tree | 94bc363a6d1aeac29c1985a9627ceda962d1c38a /src/analysis/disass/disassembler.c | |
| parent | 36a5b2577d67ab7c9f2c5817f6dba7a9601d1f20 (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.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  /* ---------------------------------------------------------------------------------- */ | 
