diff options
Diffstat (limited to 'src/analysis/disass')
| -rw-r--r-- | src/analysis/disass/area.c | 637 | ||||
| -rw-r--r-- | src/analysis/disass/area.h | 6 | ||||
| -rw-r--r-- | src/analysis/disass/disassembler.c | 10 | ||||
| -rw-r--r-- | src/analysis/disass/fetch.c | 4 | ||||
| -rw-r--r-- | src/analysis/disass/fetch.h | 2 | ||||
| -rw-r--r-- | src/analysis/disass/limit.c | 55 | ||||
| -rw-r--r-- | src/analysis/disass/limit.h | 2 | ||||
| -rw-r--r-- | src/analysis/disass/output.c | 26 | ||||
| -rw-r--r-- | src/analysis/disass/routines.c | 14 | ||||
| -rw-r--r-- | src/analysis/disass/routines.h | 2 | 
10 files changed, 454 insertions, 304 deletions
| diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index 71e2784..2bc7a53 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -35,6 +35,7 @@  #include "../../analysis/contents/restricted.h"  #include "../../arch/raw.h"  #include "../../common/bits.h" +#include "../../common/sort.h"  #include "../../format/format.h"  #include "../../glibext/delayed-int.h"  #include "../../gui/panels/log.h" @@ -115,11 +116,32 @@ typedef struct _GAreaCollector      mem_area *areas;                        /* Zone de productions         */ -    size_t begin;                           /* Début du parcours à mener   */ -    size_t end;                             /* Fin de ce même parcours     */ +    union +    { +        struct +        { +            size_t acount;                  /* Nombre de zones créées      */ + +            GLoadedBinary *binary;          /* Binaire à associer aux zones*/ -    GArchInstruction **collected;           /* Instructions collectées     */ -    size_t count;                           /* Quantité de ces instructions*/ +            phys_t first;                   /* Début de traitement         */ +            phys_t last;                    /* Fin de traitement           */ + +            bool closing;                   /* Tâche clôturant le parcours */ + +        }; + +        struct +        { +            size_t begin;                   /* Début du parcours à mener   */ +            size_t end;                     /* Fin de ce même parcours     */ + +            GArchInstruction **collected;   /* Instructions collectées     */ +            size_t ccount;                  /* Quantité de ces instructions*/ + +        }; + +    };  } GAreaCollector; @@ -149,6 +171,12 @@ static void g_area_collector_finalize(GAreaCollector *);  /* Assure un traitement particulier concernant les zones. */  static void g_area_collector_process(GAreaCollector *, GtkStatusStack *); +/* Crée une tâche de calcul des zones binaires à désassembler. */ +static GAreaCollector *g_area_collector_new_intro(activity_id_t, GLoadedBinary *, phys_t, phys_t, bool); + +/* Construit une liste bornée de zones contigües. */ +static void g_area_collector_do_compute(GAreaCollector *, GtkStatusStack *); +  /* Crée une tâche de récupération d'instructions différée. */  static GAreaCollector *g_area_collector_new_outro(activity_id_t, mem_area *, size_t, size_t); @@ -779,230 +807,6 @@ static GArchInstruction **get_instructions_from_mem_area(const mem_area *area, G  /******************************************************************************  *                                                                             * -*  Paramètres  : binary     = binaire analysé contenant quantités d'infos.    * -*                bin_length = quantité d'octets à traiter au total.           * -*                count      = nombre de zones mises en place. [OUT]           * -*                                                                             * -*  Description : Détermine une liste de zones contigües à traiter.            * -*                                                                             * -*  Retour      : Liste de zones mémoire à libérer après usage.                * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -mem_area *compute_memory_areas(const GLoadedBinary *binary, phys_t bin_length, size_t *count) -{ -    mem_area *result;                       /* Liste à renvoyer            */ -    GExeFormat *format;                     /* Format de fichier associé   */ -    mrange_t *exe_ranges;                   /* Liste de zones exécutables  */ -    size_t exe_count;                       /* Nombre de ces zones         */ -    GBinSymbol **symbols;                   /* Symboles à représenter      */ -    size_t sym_count;                       /* Qté de symboles présents    */ -    vmpa2t last;                            /* Dernière bordure rencontrée */ -    bool status;                            /* Bilan d'une conversion      */ -    size_t i;                               /* Boucle de parcours #1       */ -    const vmpa2t *border;                   /* Nouvelle bordure rencontrée */ -    mem_area *area;                         /* Zone avec valeurs à éditer  */ -    vmpa2t tmp;                             /* Stockage temporaire         */ -    GPortionLayer *layer;                   /* Couche première de portions */ -    GBinPortion **portions;                 /* Morceaux d'encadrement      */ -    size_t portions_count;                  /* Taille de cette liste       */ -    const vmpa2t *portion_start;            /* Point de départ de portion  */ -    const vmpa2t *portion_next;             /* Départ de portion suivante  */ -    size_t j;                               /* Boucle de parcours #2       */ -    SymbolType type;                        /* Nature d'un symbole         */ -    const mrange_t *range;                  /* Couverture d'un symbole     */ -    phys_t length;                          /* Taille de ce même symbole   */ -    phys_t new_length;                      /* Nouvelle taille déterminée  */ - -    result = NULL; -    *count = 0; - -    /** -     * Le parcours n'est valide que si les zones exécutables sont triées ! -     */ - -    format = g_loaded_binary_get_format(binary); - -    exe_ranges = g_exe_format_get_x_ranges(format, &exe_count); - -    symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &sym_count); - -    /* Première étape : on comble les trous ! */ - -    status = g_exe_format_translate_offset_into_vmpa(format, 0, &last); -    assert(status); - -    for (i = 0; i < exe_count; i++) -    { -        border = get_mrange_addr(&exe_ranges[i]); - -        /* Zone tampon à constituer */ - -        if (cmp_vmpa(&last, border) < 0) -        { -            result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area)); - -            area = &result[*count - 1]; - -            init_mem_area_from_addr(area, &last, compute_vmpa_diff(&last, border), binary); -            area->is_exec = false; - -        } - -        /* Insertion d'une zone exécutable déjà définie */ - -        result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area)); - -        area = &result[*count - 1]; - -        init_mem_area_from_addr(area, get_mrange_addr(&exe_ranges[i]), -                                   get_mrange_length(&exe_ranges[i]), binary); -        area->is_exec = true; - -        /* Avancée du curseur */ - -        compute_mrange_end_addr(&exe_ranges[i], &last); - -    } - -    /* Extension finale complémentaire ? */ - -    area = &result[*count - 1]; - -    copy_vmpa(&tmp, get_mrange_addr(&area->range)); -    advance_vmpa(&tmp, get_mrange_length(&area->range)); - -    if (get_phy_addr(&tmp) < bin_length) -    { -        result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area)); - -        area = &result[*count - 1]; - -        init_mem_area_from_addr(area, &tmp, bin_length - get_phy_addr(&tmp), binary); -        area->is_exec = false; - -    } - -    /* Seconde étape : on s'assure du découpage autour des portions pour respecter l'alignement */ - -    layer = g_exe_format_get_main_layer(format); - -    portions = g_portion_layer_collect_all_portions(layer, &portions_count); - -    for (i = 1; i < portions_count; i++) -    { -        portion_start = get_mrange_addr(g_binary_portion_get_range(portions[i])); - -        /** -         * Si plusieurs portions débutent au même endroit, il ne sert -         * à rien de découper plusieurs fois. -         */ -        if ((i + 1) < portions_count) -        { -            portion_next = get_mrange_addr(g_binary_portion_get_range(portions[i + 1])); - -            if (cmp_vmpa(portion_start, portion_next) == 0) -                continue; - -        } - -        for (j = 0; j < *count; j++) -        { -            area = &result[j]; - -            if (!mrange_contains_addr(&area->range, portion_start)) -                continue; - -            /* Si le déccoupage actuel ne correspond pas au besoin des portions... */ -            if (cmp_vmpa(get_mrange_addr(&area->range), portion_start) != 0) -            { -                fini_mem_area(&result[j]); - -                result = (mem_area *)realloc(result, ++(*count) * sizeof(mem_area)); - -                memmove(&result[j + 2], &result[j + 1], (*count - j - 2) * sizeof(mem_area)); - -                status = result[j].is_exec; - -                /* Première moitié */ - -                area = &result[j]; - -                copy_vmpa(&tmp, get_mrange_addr(&area->range)); -                length = get_mrange_length(&area->range); - -                new_length = compute_vmpa_diff(&tmp, portion_start); - -                init_mem_area_from_addr(area, &tmp, new_length, binary); -                area->is_exec = status; - -                /* Seconde moitié */ - -                length -= get_mrange_length(&area->range); - -                area = &result[j + 1]; - -                init_mem_area_from_addr(area, portion_start, length, binary); -                area->is_exec = status; - -            } - -            j = *count; - -        } - -    } - -    if (portions != NULL) -        free(portions); - -    g_object_unref(G_OBJECT(layer)); - -    /* Troisième étape : on insère les symboles existants */ - -    for (i = 0; i < sym_count; i++) -    { -        type = g_binary_symbol_get_target_type(symbols[i]); - -        /** -         * On ne garde que les symboles renvoyant directement une ou -         * plusieurs instructions, c'est à dire les symboles valides -         * pour un appel à g_binary_symbol_get_instruction(). -         * -         * Les instructions des autres symboles sont obtenues et mises -         * en place durant la procédure de désassemblage. -         */ - -        if (type == STP_ROUTINE || type == STP_ENTRY_POINT || type == STP_CODE_LABEL) -            continue; - -        range = g_binary_symbol_get_range(symbols[i]); - -        length = get_mrange_length(range); - -        if (length == 0) -            continue; - -        insert_extra_symbol_into_mem_areas(result, *count, symbols[i]); - -    } - -    /* Nettoyage final */ - -    if (exe_ranges != NULL) -        free(exe_ranges); - -    g_object_unref(G_OBJECT(format)); - -    return result; - -} - - -/****************************************************************************** -*                                                                             *  *  Paramètres  : list  = listes de zones utable à consulter.                  *  *                count = nombre de zones mises en place.                      *  *                addr  = adresse à retrouver dans les aires présentes.        * @@ -1212,6 +1016,9 @@ static void g_area_collector_init(GAreaCollector *collector)  static void g_area_collector_dispose(GAreaCollector *collector)  { +    if (collector->run == (run_task_fc)g_area_collector_do_compute) +        g_object_unref(G_OBJECT(collector->binary)); +      G_OBJECT_CLASS(g_area_collector_parent_class)->dispose(G_OBJECT(collector));  } @@ -1258,6 +1065,366 @@ static void g_area_collector_process(GAreaCollector *collector, GtkStatusStack *  /******************************************************************************  *                                                                             * +*  Paramètres  : id      = identifiant pour signaler la progression courante. * +*                binary  = binaire chargé à conserver dans les zones définies.* +*                first   = localisation du début de la portion à traiter.     * +*                last    = localisation de la fin de la portion à traiter.    * +*                closing = indique si la tâche doit terminer l'analyse.       * +*                                                                             * +*  Description : Crée une tâche de calcul des zones binaires à désassembler.  * +*                                                                             * +*  Retour      : Tâche créée.                                                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GAreaCollector *g_area_collector_new_intro(activity_id_t id, GLoadedBinary *binary, phys_t first, phys_t last, bool closing) +{ +    GAreaCollector *result;            /* Tâche à retourner           */ + +    result = g_object_new(G_TYPE_AREA_COLLECTOR, NULL); + +    result->id = id; +    result->run = (run_task_fc)g_area_collector_do_compute; + +    result->areas = NULL; + +    result->acount = 0; + +    result->binary = binary; +    g_object_ref(G_OBJECT(binary)); + +    result->first = first; +    result->last = last; + +    result->closing = closing; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : fetching = récupération à mener.                             * +*                status   = barre de statut à tenir informée.                 * +*                                                                             * +*  Description : Construit une liste bornée de zones contigües.               * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_area_collector_do_compute(GAreaCollector *collector, GtkStatusStack *status) +{ +    mem_area **list;                        /* Liste de zones à constituer */ +    size_t *count;                          /* Nombre d'éléments intégrés  */ +    vmpa2t first;                           /* Point de départ             */ +    vmpa2t last;                            /* Point d'arrivée             */ +    GExeFormat *format;                     /* Format du binaire           */ +    vmpa2t prev;                            /* Dernière bordure rencontrée */ +    bool state;                             /* Bilan d'une conversion      */ +    GBinSymbol **symbols;                   /* Symboles à représenter      */ +    size_t sym_count;                       /* Qté de symboles présents    */ +    bool has_sym_index;                     /* Détermine une validité      */ +    size_t sym_index;                       /* Prochain symbole non traité */ +    GBinPortion *portions;                  /* Couche première de portions */ + +    void populate_with_symbols(const vmpa2t *limit) +    { +        GBinSymbol *symbol;                 /* Symbole en cours d'analyse  */ +        SymbolType type;                    /* Nature d'un symbole         */ +        const mrange_t *range;              /* Couverture d'un symbole     */ +        vmpa2t end;                         /* Adresse de fin du symbole   */ + +        for (; sym_index < sym_count; sym_index++) +        { +            symbol = symbols[sym_index]; + +            type = g_binary_symbol_get_target_type(symbol); + +            /** +             * On ne garde que les symboles renvoyant directement une ou +             * plusieurs instructions, c'est à dire les symboles valides +             * pour un appel à g_binary_symbol_get_instruction(). +             * +             * Les instructions des autres symboles sont obtenues et mises +             * en place durant la procédure de désassemblage. +             */ + +            if (type == STP_ROUTINE || type == STP_ENTRY_POINT || type == STP_CODE_LABEL) +                continue; + +            range = g_binary_symbol_get_range(symbol); + +            if (get_mrange_length(range) == 0) +                continue; + +            if (cmp_vmpa(get_mrange_addr(range), limit) >= 0) +                break; + +            compute_mrange_end_addr(range, &end); + +            /** +             * Si un symbole est à cheval entre deux zones, tant pis pour lui ! +             */ + +            if (cmp_vmpa(&end, limit) > 0) +                break; + +            insert_extra_symbol_into_mem_areas(*list, *count, symbol); + +        } + +    } + +    void fill_gap(vmpa2t *old, vmpa2t *new, bool exec) +    { +        phys_t diff;                        /* Espace entre bordures       */ +        mem_area *area;                     /* Zone avec valeurs à éditer  */ + +        diff = compute_vmpa_diff(old, new); + +        /** +         * S'il existe un écart entre la dernière bordure ajoutée et +         * l'extréminité de la portion courante, on le comble ! +         */ + +        if (diff > 0) +        { +            /* Zone tampon à constituer */ + +            *list = (mem_area *)realloc(*list, ++(*count) * sizeof(mem_area)); + +            area = &(*list)[*count - 1]; + +            init_mem_area_from_addr(area, old, diff, collector->binary); +            area->is_exec = exec; + +            /* Insertion des symboles existants */ + +            if (!has_sym_index) +            { +                int cmp_vmpa_with_symbol(const vmpa2t *a, const GBinSymbol **s) +                { +                    return g_binary_symbol_cmp_with_vmpa(*s, a); +                } + +                bsearch_index(old, symbols, sym_count, sizeof(GBinSymbol *), +                              (__compar_fn_t)cmp_vmpa_with_symbol, &sym_index); + +                has_sym_index = true; + +            } + +            populate_with_symbols(new); + +            /* Avancée du curseur */ + +            copy_vmpa(old, new); + +            gtk_status_stack_update_activity_value(status, collector->id, diff); + +        } + +    } + +    bool build_area_from_portion(GBinPortion *portion, GBinPortion *parent, BinaryPortionVisit visit, void *unused) +    { +        const mrange_t *range;              /* Espace de portion à traiter */ +        vmpa2t border;                      /* Nouvelle bordure rencontrée */ +        bool on_track;                      /* Le tronçon courant est bon ?*/ +        PortionAccessRights rights;         /* Droits d'accès à analyser   */ + +        range = g_binary_portion_get_range(portion); + +        if (visit == BPV_ENTER) +        { +            copy_vmpa(&border, get_mrange_addr(range)); + +            on_track = cmp_vmpa(&first, &border) <= 0 && cmp_vmpa(&border, &last) < 0; + +            if (on_track) +            { +                rights = (parent != NULL ? g_binary_portion_get_rights(parent) : PAC_NONE); +                fill_gap(&prev, &border, rights & PAC_EXEC); +            } +            else +                copy_vmpa(&prev, &border); + +        } + +        else if (visit == BPV_SHOW) +        { +            copy_vmpa(&border, get_mrange_addr(range)); + +            on_track = cmp_vmpa(&first, &border) <= 0 && cmp_vmpa(&border, &last) < 0; + +            if (on_track) +            { +                rights = (parent != NULL ? g_binary_portion_get_rights(parent) : PAC_NONE); +                fill_gap(&prev, &border, rights & PAC_EXEC); + +                compute_mrange_end_addr(range, &border); + +                rights = g_binary_portion_get_rights(portion); +                fill_gap(&prev, &border, rights & PAC_EXEC); + +            } +            else +                compute_mrange_end_addr(range, &prev); + +        } + +        else if (visit == BPV_EXIT) +        { +            compute_mrange_end_addr(range, &border); + +            if (collector->closing) +                on_track = cmp_vmpa(&first, &border) <= 0 && cmp_vmpa(&border, &last) <= 0; +            else +                on_track = cmp_vmpa(&first, &border) <= 0 && cmp_vmpa(&border, &last) < 0; + +            if (on_track) +            { +                rights = (parent != NULL ? g_binary_portion_get_rights(parent) : PAC_NONE); +                fill_gap(&prev, &border, rights & PAC_EXEC); +            } +            else +                copy_vmpa(&prev, &border); + +        } + +#ifndef NDEBUG +        else +            assert(false); +#endif + +        return (cmp_vmpa(&prev, &last) < 0); + +    } + +    list = &collector->areas; +    count = &collector->acount; + +    init_vmpa(&first, collector->first, VMPA_NO_VIRTUAL); +    init_vmpa(&last, collector->last, VMPA_NO_VIRTUAL); + +    format = g_loaded_binary_get_format(collector->binary); + +#ifndef NDEBUG +    state = g_exe_format_translate_offset_into_vmpa(format, 0, &prev); +    assert(state); +#else +    g_exe_format_translate_offset_into_vmpa(format, 0, &prev); +#endif + +    symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &sym_count); + +    has_sym_index = false; + +    portions = g_exe_format_get_portions(format); + +    g_binary_portion_visit(portions, (visit_portion_fc)build_area_from_portion, NULL); + +    g_object_unref(G_OBJECT(portions)); + +    g_object_unref(G_OBJECT(format)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : gid    = groupe de travail impliqué.                         * +*                status = barre de statut à tenir informée.                   * +*                binary = binaire analysé contenant quantités d'infos.        * +*                length = quantité d'octets à traiter au total.               * +*                count  = nombre de zones mises en place. [OUT]               * +*                                                                             * +*  Description : Détermine une liste de zones contigües à traiter.            * +*                                                                             * +*  Retour      : Liste de zones mémoire à libérer après usage.                * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +mem_area *collect_memory_areas(wgroup_id_t gid, GtkStatusStack *status, GLoadedBinary *binary, phys_t length, size_t *count) +{ +    mem_area *result;                       /* Liste finale à retourner    */ +    guint runs_count;                       /* Qté d'exécutions parallèles */ +    GAreaCollector **collectors;            /* Collecteurs à suivre        */ +    phys_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          */ +    phys_t first;                           /* Début de zone de traitement */ +    bool closing;                           /* Détection de fin en amont   */ +    phys_t last;                            /* Fin de zone de traitement   */ + +    runs_count = g_get_num_processors(); + +    collectors = (GAreaCollector **)calloc(runs_count, sizeof(GAreaCollector *)); + +    run_size = length / runs_count; + +    queue = get_work_queue(); + +    id = gtk_status_stack_add_activity(status, _("Computing memory areas to disassemble"), length); + +    for (i = 0; i < runs_count; i++) +    { +        first = i * run_size; + +        closing = ((i + 1) == runs_count); + +        if (closing) +            last = length; +        else +            last = first + run_size; + +        collectors[i] = g_area_collector_new_intro(id, binary, first, last, closing); + +        g_object_ref(G_OBJECT(collectors[i])); +        g_work_queue_schedule_work(queue, G_DELAYED_WORK(collectors[i]), gid); + +    } + +    g_work_queue_wait_for_completion(queue, gid); + +    /* Récupération des aires */ + +    result = NULL; +    *count = 0; + +    for (i = 0; i < runs_count; i++) +    { +        result = (mem_area *)realloc(result, (*count + collectors[i]->acount) * sizeof(mem_area)); + +        memcpy(&result[*count], collectors[i]->areas, collectors[i]->acount * sizeof(mem_area)); +        *count += collectors[i]->acount; + +        g_object_unref(G_OBJECT(collectors[i])); + +    } + +    /* Fin */ + +    free(collectors); + +    gtk_status_stack_remove_activity(status, id); + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : id    = identifiant pour signaler la progression courante.   *  *                list  = liste des zones en place à parcourir.                *  *                begin = indice de la première zone à traiter.                * @@ -1286,7 +1453,7 @@ static GAreaCollector *g_area_collector_new_outro(activity_id_t id, mem_area *li      result->end = end;      result->collected = NULL; -    result->count = 0; +    result->ccount = 0;      return result; @@ -1313,7 +1480,7 @@ static void g_area_collector_do_collect(GAreaCollector *collector, GtkStatusStac      for (i = collector->begin; i < collector->end; i++)      {          collector->collected = get_instructions_from_mem_area(&collector->areas[i], -                                                              collector->collected, &collector->count); +                                                              collector->collected, &collector->ccount);          fini_mem_area(&collector->areas[i]); @@ -1326,8 +1493,8 @@ static void g_area_collector_do_collect(GAreaCollector *collector, GtkStatusStac  /******************************************************************************  *                                                                             * -*  Paramètres  : gid      = groupe de travail impliqué.                       * -*                status   = barre de statut à tenir informée.                 * +*  Paramètres  : gid    = groupe de travail impliqué.                         * +*                status = barre de statut à tenir informée.                   *  *                list   = liste des zones de données à relire puis libérer.   *  *                acount = taille de cette liste de zones.                     *  *                icount = nombre d'instructions récupérées. [OUT]             * @@ -1388,10 +1555,10 @@ GArchInstruction **collect_disassembled_instructions(wgroup_id_t gid, GtkStatusS      for (i = 0; i < runs_count; i++)      {          result = (GArchInstruction **)realloc(result, -                                              (*icount + collectors[i]->count) * sizeof(GArchInstruction *)); +                                              (*icount + collectors[i]->ccount) * sizeof(GArchInstruction *)); -        memcpy(&result[*icount], collectors[i]->collected, collectors[i]->count * sizeof(GArchInstruction *)); -        *icount += collectors[i]->count; +        memcpy(&result[*icount], collectors[i]->collected, collectors[i]->ccount * sizeof(GArchInstruction *)); +        *icount += collectors[i]->ccount;          g_object_unref(G_OBJECT(collectors[i])); diff --git a/src/analysis/disass/area.h b/src/analysis/disass/area.h index 725b9a8..d5f910b 100644 --- a/src/analysis/disass/area.h +++ b/src/analysis/disass/area.h @@ -43,9 +43,6 @@ typedef struct _mem_area mem_area;  void load_code_from_mem_area(mem_area *, mem_area *, size_t, GProcContext *, const vmpa2t *, bool, GtkStatusStack *, activity_id_t);  /* Détermine une liste de zones contigües à traiter. */ -mem_area *compute_memory_areas(const GLoadedBinary *, phys_t, size_t *); - -/* Détermine une liste de zones contigües à traiter. */  mem_area *find_memory_area_by_addr(mem_area *, size_t, const vmpa2t *);  /* Insère un symbole dans un découpage en aires. */ @@ -58,6 +55,9 @@ void ensure_all_mem_areas_are_filled(mem_area *, size_t, GProcContext *, GtkStat  /* ----------------------- MANIPULATIONS PARALLELES DES ZONES ----------------------- */ +/* Détermine une liste de zones contigües à traiter. */ +mem_area *collect_memory_areas(wgroup_id_t, GtkStatusStack *, GLoadedBinary *, phys_t, size_t *); +  /* Rassemble les instructions conservées dans des zones données. */  GArchInstruction **collect_disassembled_instructions(wgroup_id_t, GtkStatusStack *, mem_area *, size_t, size_t *); diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c index 172ee1c..5326c36 100644 --- a/src/analysis/disass/disassembler.c +++ b/src/analysis/disass/disassembler.c @@ -312,8 +312,7 @@ static void process_all_instructions(wgroup_id_t gid, GtkStatusStack *status, co  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         */ +    GBinPortion *portions;                  /* Couche première de portions */      GBinRoutine **routines;                 /* Liste des routines trouvées */      size_t routines_count;                  /* Nombre de ces routines      */      guint runs_count;                       /* Qté d'exécutions parallèles */ @@ -325,7 +324,7 @@ static void process_all_routines(wgroup_id_t gid, GtkStatusStack *status, const      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); +    portions = g_exe_format_get_portions(format);      routines = g_binary_format_get_routines(G_BIN_FORMAT(format), &routines_count); @@ -346,7 +345,7 @@ static void process_all_routines(wgroup_id_t gid, GtkStatusStack *status, const          else              end = begin + run_size; -        study = g_routines_study_new(proc, exe_ranges, exe_count, routines, routines_count, +        study = g_routines_study_new(proc, portions, routines, routines_count,                                       begin, end, id, fallback);          g_work_queue_schedule_work(queue, G_DELAYED_WORK(study), gid); @@ -357,8 +356,7 @@ static void process_all_routines(wgroup_id_t gid, GtkStatusStack *status, const      gtk_status_stack_remove_activity(status, id); -    if (exe_ranges != NULL) -        free(exe_ranges); +    g_object_unref(G_OBJECT(portions));  } diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c index 784e103..ee0916b 100644 --- a/src/analysis/disass/fetch.c +++ b/src/analysis/disass/fetch.c @@ -392,7 +392,7 @@ static bool check_if_extra_wait_is_needed(GWorkQueue *queue, wgroup_id_t id, GPr  *                                                                             *  ******************************************************************************/ -GArchInstruction **disassemble_binary_content(const GLoadedBinary *binary, GProcContext *ctx, wgroup_id_t gid, GtkStatusStack *status, size_t *count) +GArchInstruction **disassemble_binary_content(GLoadedBinary *binary, GProcContext *ctx, wgroup_id_t gid, GtkStatusStack *status, size_t *count)  {      GArchInstruction **result;               /* Instruction désassemblées   */      GDelayedFetching template;              /* Patron des tâches à venir   */ @@ -415,7 +415,7 @@ GArchInstruction **disassemble_binary_content(const GLoadedBinary *binary, GProc      length = g_binary_content_compute_size(content);      g_object_unref(G_OBJECT(content)); -    template.areas = compute_memory_areas(binary, length, &template.count); +    template.areas = collect_memory_areas(gid, status, binary, length, &template.count);      template.status = status; diff --git a/src/analysis/disass/fetch.h b/src/analysis/disass/fetch.h index bf2b52f..b36a999 100644 --- a/src/analysis/disass/fetch.h +++ b/src/analysis/disass/fetch.h @@ -32,7 +32,7 @@  /* Procède au désassemblage basique d'un contenu binaire. */ -GArchInstruction **disassemble_binary_content(const GLoadedBinary *, GProcContext *, wgroup_id_t, GtkStatusStack *, size_t *); +GArchInstruction **disassemble_binary_content(GLoadedBinary *, GProcContext *, wgroup_id_t, GtkStatusStack *, size_t *); diff --git a/src/analysis/disass/limit.c b/src/analysis/disass/limit.c index 28a8264..18d089a 100644 --- a/src/analysis/disass/limit.c +++ b/src/analysis/disass/limit.c @@ -25,48 +25,12 @@ -/* Recherche la zone correspond à une adresse donnée. */ -static const mrange_t *find_x_range_for_addr(const mrange_t *, size_t, const vmpa2t *); - - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : ranges = liste de zones offrant une exécution et disponibles.* -*                count  = taille de cette liste.                              * -*                                                                             * -*  Description : Recherche la zone correspond à une adresse donnée.           * -*                                                                             * -*  Retour      : Zone trouvée ou NULL si aucune ne correspond.                * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static const mrange_t *find_x_range_for_addr(const mrange_t *ranges, size_t count, const vmpa2t *addr) -{ -    const mrange_t *result;                 /* Zone à retourner            */ -    size_t i;                               /* Boucle de parcours          */ - -    result = NULL; - -    for (i = 0; i < count && result == NULL; i++) -        if (mrange_contains_addr(&ranges[i], addr)) -            result = &ranges[i]; - -    return result; - -} - -  /******************************************************************************  *                                                                             * -*  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.   * +*  Paramètres  : routine  = routine dont les frontières sont à fixer.         * +*                prev     = routine précédente dans les traitements.          * +*                proc     = ensemble d'instructions désassemblées.            * +*                portions = ensemble de couches binaires bornées.             *  *                                                                             *  *  Description : S'assure qu'une routine est bien bornée.                     *  *                                                                             * @@ -76,12 +40,13 @@ static const mrange_t *find_x_range_for_addr(const mrange_t *ranges, size_t coun  *                                                                             *  ******************************************************************************/ -void compute_routine_limit(GBinRoutine *routine, GBinRoutine *prev, GArchProcessor *proc, mrange_t *exe_ranges, size_t exe_count) +void compute_routine_limit(GBinRoutine *routine, GBinRoutine *prev, GArchProcessor *proc, GBinPortion *portions)  {      const mrange_t *range;                  /* Emplacement courant         */      vmpa2t addr;                            /* Adresse à conserver         */      GArchInstruction *start;                /* Première instruction        */      phys_t diff;                            /* Taille définie par déduction*/ +    GBinPortion *portion;                   /* Conteneur avec limites      */      mrange_t new;                           /* Nouvel emplacement taillé   */      range = g_binary_routine_get_range(routine); @@ -114,12 +79,16 @@ void compute_routine_limit(GBinRoutine *routine, GBinRoutine *prev, GArchProcess      /* Sinon on va jusqu'à la fin de la zone ! */      else      { -        range = find_x_range_for_addr(exe_ranges, exe_count, &addr); -        if (range == NULL) goto crl_skip; +        portion = g_binary_portion_find_at_addr(portions, &addr, (GdkRectangle []) { }); +        if (portion == NULL) goto crl_skip; + +        range = g_binary_portion_get_range(portion);          diff = compute_vmpa_diff(&addr, get_mrange_addr(range));          diff = get_mrange_length(range) - diff; +        g_object_unref(G_OBJECT(portion)); +      }      init_mrange(&new, &addr, diff); diff --git a/src/analysis/disass/limit.h b/src/analysis/disass/limit.h index 7aba8a6..ed53325 100644 --- a/src/analysis/disass/limit.h +++ b/src/analysis/disass/limit.h @@ -32,7 +32,7 @@  /* S'assure qu'une routine est bien bornée. */ -void compute_routine_limit(GBinRoutine *, GBinRoutine *, GArchProcessor *, mrange_t *, size_t); +void compute_routine_limit(GBinRoutine *, GBinRoutine *, GArchProcessor *, GBinPortion *); diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c index 0d85870..fe4d705 100644 --- a/src/analysis/disass/output.c +++ b/src/analysis/disass/output.c @@ -59,7 +59,7 @@  void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GArchProcessor *proc, GtkStatusStack *status)  { -    GPortionLayer *layer;                   /* Couche première de portions */ +    GBinPortion *root;                      /* Couche première de portions */      GBinPortion **portions;                 /* Morceaux d'encadrement      */      size_t portions_count;                  /* Taille de cette liste       */      size_t portion_index;                   /* Prochaine portion à traiter */ @@ -99,12 +99,29 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA +    bool collect_all_portions(GBinPortion *portion, GBinPortion *parent, BinaryPortionVisit visit, void *unused) +    { +        if (visit == BPV_ENTER || visit == BPV_SHOW) +        { +            portions = (GBinPortion **)realloc(portions, ++portions_count * sizeof(GBinPortion *)); +            portions[portions_count - 1] = portion; +        } + +        return true; + +    } -    layer = g_exe_format_get_main_layer(format); +    portions = NULL; +    portions_count = 0; -    portions = g_portion_layer_collect_all_portions(layer, &portions_count);      portion_index = 0; +    root = g_exe_format_get_portions(format); + +    g_binary_portion_visit(root, (visit_portion_fc)collect_all_portions, NULL); + +    g_object_unref(G_OBJECT(root)); +      symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &sym_count);      sym_index = 0; @@ -339,9 +356,6 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA      if (portions != NULL)          free(portions); -    g_object_unref(G_OBJECT(layer)); - -      fprintf(stderr, "MISSING :: %u symbols\n", _missing); diff --git a/src/analysis/disass/routines.c b/src/analysis/disass/routines.c index a9414fc..6fd9279 100644 --- a/src/analysis/disass/routines.c +++ b/src/analysis/disass/routines.c @@ -40,8 +40,7 @@ struct _GRoutinesStudy      GArchProcessor *proc;                   /* Processeurs avec ses instr. */ -    mrange_t *exe_ranges;                   /* Liste de zones exécutables  */ -    size_t exe_count;                       /* Nombre de ces zones         */ +    GBinPortion *portions;                  /* Couches de binaire bornées  */      GBinRoutine **routines;                 /* Liste de routines à traiter */      size_t count;                           /* Taille de cette liste       */ @@ -147,6 +146,8 @@ static void g_routines_study_init(GRoutinesStudy *study)  static void g_routines_study_dispose(GRoutinesStudy *study)  { +    g_object_unref(G_OBJECT(study->portions)); +      G_OBJECT_CLASS(g_routines_study_parent_class)->dispose(G_OBJECT(study));  } @@ -174,6 +175,7 @@ static void g_routines_study_finalize(GRoutinesStudy *study)  /******************************************************************************  *                                                                             *  *  Paramètres  : proc     = ensemble d'instructions désassemblées.            * +*                portions = ensemble de couches binaires bornées.             *  *                routines = prototypes existants à insérer.                   *  *                count    = quantité de ces prototypes.                       *  *                begin    = point de départ du parcours de liste.             * @@ -189,7 +191,7 @@ static void g_routines_study_finalize(GRoutinesStudy *study)  *                                                                             *  ******************************************************************************/ -GRoutinesStudy *g_routines_study_new(GArchProcessor *proc, mrange_t *exe_ranges, size_t exe_count, GBinRoutine **routines, size_t count, size_t begin, size_t end, activity_id_t id, rtn_fallback_cb fallback) +GRoutinesStudy *g_routines_study_new(GArchProcessor *proc, GBinPortion *portions, GBinRoutine **routines, size_t count, size_t begin, size_t end, activity_id_t id, rtn_fallback_cb fallback)  {      GRoutinesStudy *result;                /* Tâche à retourner           */ @@ -197,8 +199,8 @@ GRoutinesStudy *g_routines_study_new(GArchProcessor *proc, mrange_t *exe_ranges,      result->proc = proc; -    result->exe_ranges = exe_ranges; -    result->exe_count = exe_count; +    result->portions = portions; +    g_object_ref(G_OBJECT(portions));      result->routines = routines;      result->count = count; @@ -267,7 +269,7 @@ void g_routines_study_compute_limits(GRoutinesStudy *study, size_t index)      else          next = NULL; -    compute_routine_limit(routine, next, study->proc, study->exe_ranges, study->exe_count); +    compute_routine_limit(routine, next, study->proc, study->portions);  } diff --git a/src/analysis/disass/routines.h b/src/analysis/disass/routines.h index 72df309..b89f69a 100644 --- a/src/analysis/disass/routines.h +++ b/src/analysis/disass/routines.h @@ -52,7 +52,7 @@ typedef void (* rtn_fallback_cb) (GRoutinesStudy *, size_t);  /* Crée une tâche d'étude de routines différée. */ -GRoutinesStudy *g_routines_study_new(GArchProcessor *, mrange_t *, size_t, GBinRoutine **, size_t, size_t, size_t, activity_id_t, rtn_fallback_cb); +GRoutinesStudy *g_routines_study_new(GArchProcessor *, GBinPortion *, GBinRoutine **, size_t, size_t, size_t, activity_id_t, rtn_fallback_cb);  /* Détermine si besoin est les bornes des routines. */  void g_routines_study_compute_limits(GRoutinesStudy *, size_t); | 
