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/limit.c | |
| parent | 36a5b2577d67ab7c9f2c5817f6dba7a9601d1f20 (diff) | |
Reorganized the whole disassembling process and displayed the relative progression.
Diffstat (limited to 'src/analysis/disass/limit.c')
| -rw-r--r-- | src/analysis/disass/limit.c | 355 | 
1 files changed, 32 insertions, 323 deletions
| diff --git a/src/analysis/disass/limit.c b/src/analysis/disass/limit.c index 4fd931d..dba62cc 100644 --- a/src/analysis/disass/limit.c +++ b/src/analysis/disass/limit.c @@ -24,209 +24,10 @@  #include "limit.h" -#include <malloc.h> - - -#include "../../glibext/delayed-int.h" - - - -/* ------------------------- CALCULS DE LIMITES DE ROUTINES ------------------------- */ - - -#define G_TYPE_LIMIT_COMPUTING               g_limit_computing_get_type() -#define G_LIMIT_COMPUTING(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_limit_computing_get_type(), GLimitComputing)) -#define G_IS_LIMIT_COMPUTING(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_limit_computing_get_type())) -#define G_LIMIT_COMPUTING_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_LIMIT_COMPUTING, GLimitComputingClass)) -#define G_IS_LIMIT_COMPUTING_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_LIMIT_COMPUTING)) -#define G_LIMIT_COMPUTING_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_LIMIT_COMPUTING, GLimitComputingClass)) - - -/* Fraction de routines à limiter (instance) */ -typedef struct _GLimitComputing -{ -    GDelayedWork parent;                    /* A laisser en premier        */ - -    const GArchProcessor *proc;             /* Processeurs avec ses instr. */ - -    mrange_t *exe_ranges;                   /* Liste de zones exécutables  */ -    size_t exe_count;                       /* Nombre de ces zones         */ - -    GBinRoutine **routines;                 /* Liste de routines à traiter */ -    size_t count;                           /* Taille de cette liste       */ -    size_t begin;                           /* Point de départ du parcours */ -    size_t end;                             /* Point d'arrivée exclu       */ - -    bstatus_id_t id;                        /* Identifiant pour messages   */ - -} GLimitComputing; - -/* Fraction de routines à limiter (classe) */ -typedef struct _GLimitComputingClass -{ -    GDelayedWorkClass parent;               /* A laisser en premier        */ - -} GLimitComputingClass; - - -/* Indique le type défini pour les tâches de calculs de limites. */ -GType g_limit_computing_get_type(void); - -/* Initialise la classe des tâches de calculs de limites. */ -static void g_limit_computing_class_init(GLimitComputingClass *); - -/* Initialise une tâche de calculs de limites. */ -static void g_limit_computing_init(GLimitComputing *); - -/* Supprime toutes les références externes. */ -static void g_limit_computing_dispose(GLimitComputing *); - -/* Procède à la libération totale de la mémoire. */ -static void g_limit_computing_finalize(GLimitComputing *); - -/* Crée une tâche de calculs de limites différée. */ -static GLimitComputing *g_limit_computing_new(const GArchProcessor *, mrange_t *, size_t, GBinRoutine **, size_t, size_t, size_t, bstatus_id_t);  /* Recherche la zone correspond à une adresse donnée. */  static const mrange_t *find_x_range_for_addr(const mrange_t *, size_t, const vmpa2t *); -/* Assure le calcul de limites de routines en différé. */ -static void g_limit_computing_process(GLimitComputing *, GtkExtStatusBar *); - - - -/* ---------------------------------------------------------------------------------- */ -/*                           CALCULS DE LIMITES DE ROUTINES                           */ -/* ---------------------------------------------------------------------------------- */ - - -/* Indique le type défini pour les tâches de calculs de limites. */ -G_DEFINE_TYPE(GLimitComputing, g_limit_computing, G_TYPE_DELAYED_WORK); - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : klass = classe à initialiser.                                * -*                                                                             * -*  Description : Initialise la classe des tâches de calculs de limites.       * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_limit_computing_class_init(GLimitComputingClass *klass) -{ -    GObjectClass *object;                   /* Autre version de la classe  */ -    GDelayedWorkClass *work;                /* Version en classe parente   */ - -    object = G_OBJECT_CLASS(klass); - -    object->dispose = (GObjectFinalizeFunc/* ! */)g_limit_computing_dispose; -    object->finalize = (GObjectFinalizeFunc)g_limit_computing_finalize; - -    work = G_DELAYED_WORK_CLASS(klass); - -    work->run = (run_task_fc)g_limit_computing_process; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : computing = instance à initialiser.                          * -*                                                                             * -*  Description : Initialise une tâche de calculs de limites.                  * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_limit_computing_init(GLimitComputing *computing) -{ - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : computing = instance d'objet GLib à traiter.                 * -*                                                                             * -*  Description : Supprime toutes les références externes.                     * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_limit_computing_dispose(GLimitComputing *computing) -{ -    G_OBJECT_CLASS(g_limit_computing_parent_class)->dispose(G_OBJECT(computing)); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : computing = instance d'objet GLib à traiter.                 * -*                                                                             * -*  Description : Procède à la libération totale de la mémoire.                * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_limit_computing_finalize(GLimitComputing *computing) -{ -    G_OBJECT_CLASS(g_limit_computing_parent_class)->finalize(G_OBJECT(computing)); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : proc     = ensemble d'instructions désassemblées.            * -*                routines = prototypes existants à insérer.                   * -*                count    = quantité de ces prototypes.                       * -*                begin    = point de départ du parcours de liste.             * -*                end      = point d'arrivée exclu du parcours.                * -*                id       = identifiant du message affiché à l'utilisateur.   * -*                                                                             * -*  Description : Crée une tâche de calculs de limites différée.               * -*                                                                             * -*  Retour      : Tâche créée.                                                 * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static GLimitComputing *g_limit_computing_new(const GArchProcessor *proc, mrange_t *exe_ranges, size_t exe_count, GBinRoutine **routines, size_t count, size_t begin, size_t end, bstatus_id_t id) -{ -    GLimitComputing *result;                /* Tâche à retourner           */ - -    result = g_object_new(G_TYPE_LIMIT_COMPUTING, NULL); - -    result->proc = proc; - -    result->exe_ranges = exe_ranges; -    result->exe_count = exe_count; - -    result->routines = routines; -    result->count = count; -    result->begin = begin; -    result->end = end; - -    result->id = id; - -    return result; - -}  /****************************************************************************** @@ -260,163 +61,71 @@ static const mrange_t *find_x_range_for_addr(const mrange_t *ranges, size_t coun  /******************************************************************************  *                                                                             * -*  Paramètres  : computing  = récupération à mener.                           * -*                statusbar = barre de statut à tenir informée.                * +*  Paramètres  : proc     = ensemble d'instructions désassemblées.            * +*                routines = prototypes existants à insérer.                   * +*                count    = quantité de ces prototypes.                       * +*                begin    = point de départ du parcours de liste.             * +*                end      = point d'arrivée exclu du parcours.                * +*                id       = identifiant du message affiché à l'utilisateur.   *  *                                                                             * -*  Description : Assure le calcul de limites de routines en différé.          * +*  Description : S'assure qu'une routine est bien bornée.                     *  *                                                                             * -*  Retour      : -                                                            * +*  Retour      : Tâche créée.                                                 *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static void g_limit_computing_process(GLimitComputing *computing, GtkExtStatusBar *statusbar) +void compute_routine_limit(GBinRoutine *routine, GBinRoutine *prev, const GArchProcessor *proc, mrange_t *exe_ranges, size_t exe_count)  { -    size_t i;                               /* Boucle de parcours          */ -    GBinRoutine *routine;                   /* Routine en traitement       */      const mrange_t *range;                  /* Emplacement courant         */      vmpa2t addr;                            /* Adresse à conserver         */      GArchInstruction *start;                /* Première instruction        */      phys_t diff;                            /* Taille définie par déduction*/      mrange_t new;                           /* Nouvel emplacement taillé   */ -    for (i = computing->begin; i < computing->end; i++) -    { -        //gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / count); - -        routine = computing->routines[i]; - -        range = g_binary_routine_get_range(routine); -        if (get_mrange_length(range) > 0) continue; +    range = g_binary_routine_get_range(routine); +    if (get_mrange_length(range) > 0) goto crl_skip; -        copy_vmpa(&addr, get_mrange_addr(range)); +    copy_vmpa(&addr, get_mrange_addr(range)); -        /* Marquage de la première instruction */ +    /* Marquage de la première instruction */ -        start = g_arch_processor_find_instr_by_address(computing->proc, &addr); +    start = g_arch_processor_find_instr_by_address(proc, &addr); -        if (start == NULL) continue; +    /* FIXME ? */ +    if (start == NULL) goto crl_skip; -        g_arch_instruction_set_flag(start, AIF_ROUTINE_START); +    g_arch_instruction_set_flag(start, AIF_ROUTINE_START); -        /* Si on peut se raccrocher à la routine suivante... */ -        if ((i + 1) < computing->count) -        { -            range = g_binary_routine_get_range(computing->routines[i + 1]); - -            diff = compute_vmpa_diff(&addr, get_mrange_addr(range)); - -        } - -        /* Sinon on va jusqu'à la fin de la zone ! */ -        else -        { -            range = find_x_range_for_addr(computing->exe_ranges, computing->exe_count, &addr); -            if (range == NULL) continue; - -            diff = compute_vmpa_diff(&addr, get_mrange_addr(range)); -            diff = get_mrange_length(range) - diff; - -        } - -        init_mrange(&new, &addr, diff); - -        g_binary_routine_set_range(routine, &new); - -    } - -} - - - -/* ---------------------------------------------------------------------------------- */ -/*                            POINT D'ENTREE ET DECOUPAGES                            */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format   = format du binaire concerné par la procédure.      * -*                proc     = ensemble d'instructions désassemblées.            * -*                routines = prototypes existants à insérer.                   * -*                count    = quantité de ces prototypes.                       * -*                gid      = identifiant du groupe de travail à utiliser.      * -*                id       = identifiant du message affiché à l'utilisateur.   * -*                                                                             * -*  Description : S'assure que toutes les routines ont une taille définie.     * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void limit_all_routines(GExeFormat *format, const GArchProcessor *proc, GBinRoutine **routines, size_t count, wgroup_id_t gid, bstatus_id_t id) -{ -    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 */ -    GLimitComputing *computing;             /* Tâche de calcul à programmer*/ - -    exe_ranges = g_exe_format_get_x_ranges(format, &exe_count); - -    runs_count = g_get_num_processors(); - -    run_size = count / runs_count; - -    queue = get_work_queue(); - -    for (i = 0; i < runs_count; i++) +    /* Si on peut se raccrocher à la routine suivante... */ +    if (prev != NULL)      { -        begin = i * run_size; - -        if ((i + 1) < runs_count) -            end = count - begin; -        else -            end = begin + run_size; +        range = g_binary_routine_get_range(prev); -        computing = g_limit_computing_new(proc, exe_ranges, exe_count, routines, count, begin, end, id); - -        g_work_queue_schedule_work(queue, G_DELAYED_WORK(computing), gid); +        diff = compute_vmpa_diff(&addr, get_mrange_addr(range));      } -    g_work_queue_wait_for_completion(queue, gid); - -    if (exe_ranges != NULL) -        free(exe_ranges); - - - - -    do +    /* Sinon on va jusqu'à la fin de la zone ! */ +    else      { -        const mrange_t *_range; -        vmpa2t _end; +        range = find_x_range_for_addr(exe_ranges, exe_count, &addr); +        if (range == NULL) goto crl_skip; -        printf("LIMIT == %zu routines\n", count); +        diff = compute_vmpa_diff(&addr, get_mrange_addr(range)); +        diff = get_mrange_length(range) - diff; -        for (i = 0; i < count; i++) -        { -            _range = g_binary_routine_get_range(routines[i]); -            compute_mrange_end_addr(_range, &_end); +    } -            printf(" <LIMIT> 0x%08x <-> 0x%08x '%s'\n", -                   (unsigned int)((get_mrange_addr(_range))->virtual), -                   (unsigned int)_end.virtual, -                   g_binary_routine_to_string(routines[i])); +    init_mrange(&new, &addr, diff); -        } +    g_binary_routine_set_range(routine, &new); -    } while (0); + crl_skip: +    ;  } | 
