diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2015-01-30 23:37:39 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2015-01-30 23:37:39 (GMT) | 
| commit | d246c98c515cb44c5bc4c742a674bae2e824872b (patch) | |
| tree | 2ea1ec27ae5fba761ee778ba4ddb85c7752ebbf5 | |
| parent | 262c95e0b088a56e9fd919edc57ad19f85e2e40e (diff) | |
Bound a symbol for each loaded value for 'ldr' instructions.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@462 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
| -rw-r--r-- | ChangeLog | 32 | ||||
| -rw-r--r-- | src/analysis/disass/area.c | 481 | ||||
| -rw-r--r-- | src/analysis/disass/area.h | 15 | ||||
| -rw-r--r-- | src/analysis/disass/fetch.c | 60 | ||||
| -rw-r--r-- | src/arch/arm/v7/link.c | 86 | ||||
| -rw-r--r-- | src/arch/context-int.h | 3 | ||||
| -rw-r--r-- | src/arch/context.c | 55 | ||||
| -rw-r--r-- | src/arch/context.h | 6 | ||||
| -rw-r--r-- | src/arch/raw.c | 70 | ||||
| -rw-r--r-- | src/arch/raw.h | 3 | ||||
| -rw-r--r-- | src/arch/vmpa.c | 28 | ||||
| -rw-r--r-- | src/arch/vmpa.h | 5 | ||||
| -rw-r--r-- | src/format/format.c | 49 | ||||
| -rw-r--r-- | src/format/format.h | 3 | ||||
| -rw-r--r-- | src/format/symbol.c | 77 | ||||
| -rw-r--r-- | src/format/symbol.h | 6 | 
16 files changed, 853 insertions, 126 deletions
@@ -1,3 +1,35 @@ +15-01-31  Cyrille Bagard <nocbos@gmail.com> + +	* src/analysis/disass/area.c: +	* src/analysis/disass/area.h: +	* src/analysis/disass/fetch.c: +	Introduce new extra symbols into disassembled code areas. + +	* src/arch/arm/v7/link.c: +	Bind a symbol for each loaded value for 'ldr' instructions. + +	* src/arch/context.c: +	* src/arch/context.h: +	* src/arch/context-int.h: +	Memorize extra symbols created during the disassembling process. + +	* src/arch/raw.c: +	* src/arch/raw.h: +	Provide a way to create raw instructions from given values. + +	* src/arch/vmpa.c: +	* src/arch/vmpa.h: +	Fix a bug when computing the difference between addresses. Compute +	the end of a memory range. + +	* src/format/format.c: +	* src/format/format.h: +	Provide a way to look for a symbol located at a given address. + +	* src/format/symbol.c: +	* src/format/symbol.h: +	Update the location of a symbol when incomplete. +  15-01-26  Cyrille Bagard <nocbos@gmail.com>  	* configure.ac: diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index 8340095..600818a 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -53,6 +53,9 @@ static void init_mem_area_from_addr(mem_area *, const vmpa2t *, phys_t);  /* Initialise une aire de données à partir d'un espace donné. */  static void init_mem_area_from_range(mem_area *, const mrange_t *); +/* Initialise une aire de données à partir d'un morceau donné. */ +static void init_mem_area_from_bigger_area(mem_area *, const vmpa2t *, phys_t, const mem_area *); +  /* Copie certaines propriétés d'une aire à une autre. */  static void copy_mem_area_properties(mem_area *, const mem_area *); @@ -72,9 +75,6 @@ static bool mark_range_in_mem_area_as_processed(mem_area *, phys_t, phys_t, GArc  /* Procède au désassemblage d'un contenu binaire non exécutable. */  static void load_data_from_mem_area(mem_area *, mem_area *, size_t, const GLoadedBinary *, GProcContext *, const vmpa2t *, status_blob_info *); -/* S'assure qu'une aire contient toutes ses instructions. */ -static void fill_mem_area(mem_area *, mem_area *, size_t, const GLoadedBinary *, GProcContext *, status_blob_info *); -  /* Rassemble les instructions conservées dans une zone donnée. */ @@ -87,6 +87,13 @@ static GArchInstruction *get_instructions_from_mem_area(const mem_area *); + +/* Insère un symbole dans un découpage en aires. */ +static bool insert_extra_symbol_into_mem_areas(mem_area **, size_t *, size_t *, GBinSymbol *); + + + +  /* Manipule la cartographie des octets traités d'une zone. */  typedef bool (* visit_bytes_map_fc) (mem_area *, phys_t, phys_t, GArchInstruction *); @@ -140,10 +147,10 @@ static void init_mem_area_from_addr(mem_area *area, const vmpa2t *addr, phys_t l  /******************************************************************************  *                                                                             * -*  Paramètres  : dest = aire délimitée représentant des données.              * -*                src  = aire délimitée contenant les informations à copier.   * +*  Paramètres  : area  = aire représentant à contenu à initialiser.           * +*                range = espace limitant à associer à l'aire de données.      *  *                                                                             * -*  Description : Copie certaines propriétés d'une aire à une autre.           * +*  Description : Initialise une aire de données à partir d'un espace donné.   *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -151,14 +158,20 @@ static void init_mem_area_from_addr(mem_area *area, const vmpa2t *addr, phys_t l  *                                                                             *  ******************************************************************************/ -static void copy_mem_area_properties(mem_area *dest, const mem_area *src) +static void init_mem_area_from_range(mem_area *area, const mrange_t *range)  { -    dest->has_sym = src->has_sym; +    phys_t len;                             /* Taille de la zone courante  */ +    size_t requested;                       /* Nombre de mots à allouer    */ -    if (src->has_sym) -        dest->symbol = src->symbol; -    else -        dest->exec = src->exec; +    copy_mrange(&area->range, range); + +    len = get_mrange_length(range); + +    requested = len / sizeof(unsigned long); +    if (len % sizeof(unsigned long) != 0) requested++; + +    area->processed = (unsigned long *)calloc(requested, sizeof(unsigned long)); +    area->instructions = (GArchInstruction **)calloc(len, sizeof(GArchInstruction *));  } @@ -166,30 +179,81 @@ static void copy_mem_area_properties(mem_area *dest, const mem_area *src)  /******************************************************************************  *                                                                             *  *  Paramètres  : area  = aire représentant à contenu à initialiser.           * -*                range = espace limitant à associer à l'aire de données.      * +*                addr = adresse de départ de l'espace à mettre en place.      * +*                len  = longueur de l'espace à créer.                         * +*                ref   = aire de référence avant découpage.                   *  *                                                                             * -*  Description : Initialise une aire de données à partir d'un espace donné.   * +*  Description : Initialise une aire de données à partir d'un morceau donné.  *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * -*  Remarques   : -                                                            * +*  Remarques   : On considère que la zone de destination est inclue dans      * +*                celle de référence.                                          *  *                                                                             *  ******************************************************************************/ -static void init_mem_area_from_range(mem_area *area, const mrange_t *range) +static void init_mem_area_from_bigger_area(mem_area *area, const vmpa2t *addr, phys_t len, const mem_area *ref)  { -    phys_t len;                             /* Taille de la zone courante  */ -    size_t requested;                       /* Nombre de mots à allouer    */ +    phys_t start;                           /* Point de départ de la copie */ +    phys_t i;                               /* Boucle de parcours          */ +    size_t index;                           /* Cellule de tableau visée #1 */ +    unsigned int remaining;                 /* Nombre de bits restants #1  */ +    size_t ref_index;                       /* Cellule de tableau visée #2 */ +    unsigned int ref_remaining;             /* Nombre de bits restants #2  */ -    copy_mrange(&area->range, range); -    len = get_mrange_length(range); +    printf(" INIT_FROM (0x%08x / 0x%08x | 0x%x) : area (0x%08x / 0x%08x) len = 0x%x\n", +           (unsigned int)ref->range.addr.physical, (unsigned int)ref->range.addr.virtual, +           (unsigned int)ref->range.length, +           (unsigned int)addr->physical, (unsigned int)addr->virtual, +           (unsigned int)len); -    requested = len / sizeof(unsigned long); -    if (len % sizeof(unsigned long) != 0) requested++; -    area->processed = (unsigned long *)calloc(requested, sizeof(unsigned long)); -    area->instructions = (GArchInstruction **)calloc(len, sizeof(GArchInstruction *)); +    init_mem_area_from_addr(area, addr, len); + +    assert(mrange_contains_mrange(&ref->range, &area->range)); + +    start = compute_vmpa_diff(get_mrange_addr(&ref->range), get_mrange_addr(&area->range)); + +    for (i = 0; i < len; i++) +    { +        index = i / (sizeof(unsigned long) * 8); +        remaining = i % (sizeof(unsigned long) * 8); + +        ref_index = (start + i) / (sizeof(unsigned long) * 8); +        ref_remaining = (start + i) % (sizeof(unsigned long) * 8); + +        if (ref->processed[ref_index] & (1ul << ref_remaining)) +            area->processed[index] |= (1ul << remaining); + +        area->instructions[i] = ref->instructions[start + i]; + +    } + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : dest = aire délimitée représentant des données.              * +*                src  = aire délimitée contenant les informations à copier.   * +*                                                                             * +*  Description : Copie certaines propriétés d'une aire à une autre.           * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void copy_mem_area_properties(mem_area *dest, const mem_area *src) +{ +    dest->has_sym = src->has_sym; + +    if (src->has_sym) +        dest->symbol = src->symbol; +    else +        dest->exec = src->exec;  } @@ -210,8 +274,10 @@ static void fini_mem_area(mem_area *area)  {      free(area->processed); +#if 0      if (area->has_sym) -        g_object_unref(area->symbol); +        g_object_unref(area->symbol);   /* FIXME ?! */ +#endif  } @@ -239,6 +305,9 @@ static bool is_range_blank_in_mem_area(mem_area *area, phys_t start, phys_t len,      size_t index;                           /* Cellule de tableau visée    */      unsigned int remaining;                 /* Nombre de bits restants     */ +    if (area->has_sym) +        return false; +      max = start + len;      assert(max <= get_mrange_length(&area->range)); @@ -304,13 +373,12 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, phys_t start, ph - -  /******************************************************************************  *                                                                             *  *  Paramètres  : area   = aire représentant à contenu à parcourir.            *  *                list   = liste de zones délimitant des contenus à traiter.   *  *                count  = nombre de zones à disposition.                      * +*                index  = indice de l'aire à considérer pendant l'opération.  *  *                binary = représentation de binaire chargé.                   *  *                ctx    = contexte offert en soutien à un désassemblage.      *  *                start  = démarrage de l'exécution au sein de la zone.        * @@ -324,9 +392,12 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, phys_t start, ph  *                                                                             *  ******************************************************************************/ -void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, const GLoadedBinary *binary, GProcContext *ctx, const vmpa2t *start, status_blob_info *info) +void load_code_from_mem_area(mem_area **list, size_t *count, size_t *index, const GLoadedBinary *binary, GProcContext *ctx, const vmpa2t *start, status_blob_info *info)  { +    mem_area *area;                         /* Zone de désassemblage       */ + +      GBinFormat *format;                     /* Format du fichier binaire   */      GArchProcessor *proc;                   /* Architecture du binaire     */ @@ -349,12 +420,18 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, const      mrange_t range;                             /* Couverture de l'instruction */ +    vmpa2t sym_addr;                        /* Adresse de nouveau symbole  */ +    bool has_new_sym;                       /* Statut d'un dépilement      */ + +    GBinSymbol *symbol;                     /* Symbole créé en parallèle   */ +    size_t new_index;                       /* Nouvelle position déterminée*/ + +      /* On cherche à obtenir l'assurance que le traitement n'a jamais été fait */      init_mrange(&range, start, 1); -    if (!is_range_blank_in_mem_areas(list, count, &range)) printf("CODE OK!!\n");; -    if (!is_range_blank_in_mem_areas(list, count, &range)) return; +    if (!is_range_blank_in_mem_areas(*list, *count, &range)) return;      /* Récupération des informations de base */ @@ -362,6 +439,8 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, const      proc = get_arch_processor_from_format(G_EXE_FORMAT(format));      bin_data = g_loaded_binary_get_data(binary, &bin_length); +    area = (*list) + *index; +      diff = compute_vmpa_diff(get_mrange_addr(&area->range), start);      alen = get_mrange_length(&area->range); @@ -397,9 +476,6 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, const          if (instr == NULL) break; - - -          /* Enregistrement des positions et adresses */          diff = compute_vmpa_diff(&prev, &pos); @@ -414,21 +490,73 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, const          /* Progression dans les traitements */ -        mark_range_in_mem_areas_as_processed(list, count, instr); +        mark_range_in_mem_areas_as_processed(*list, *count, instr);          inc_progessive_status(info, diff); -        assert(!is_range_blank_in_mem_areas(list, count, &range)); +        assert(!is_range_blank_in_mem_areas(*list, *count, &range)); + +        /* Insertion des symboles découverts en parallèle */ + +        for (has_new_sym = g_proc_context_pop_new_symbol_at(ctx, &sym_addr); +             has_new_sym; +             has_new_sym = g_proc_context_pop_new_symbol_at(ctx, &sym_addr)) +        { +            printf("depop :: %x / %x\n", (unsigned int)sym_addr.physical, (unsigned int)sym_addr.virtual); + + +            //if (sym_addr.physical != 0x5bc && sym_addr.physical != 0x5c0) continue; +            //if (sym_addr.physical != 0x5bc) continue; +            //if (sym_addr.physical != 0x5bc && sym_addr.physical != 0x5c0 && sym_addr.physical != 0x5c4) continue; + + +            has_new_sym = g_binary_format_find_symbol_at(format, &sym_addr, &symbol); +            assert(has_new_sym); +            new_index = *index; +            if (!insert_extra_symbol_into_mem_areas(list, count, &new_index, symbol)) +                continue; + +            /** +             * Seulement deux cas de figure peuvent intervenir : +             * +             *  - le symbole a été inséré avant la position courante, +             *    dans une autre aire ou en amont dans l'espace de celle courante. +             *    La position courante est alors à recalculer entièrement, +             *    et la boucle de parcours à relancer. +             * +             *  - le symbole a été inséré après la position courante. +             *    Dans le pire des cas, l'aire courante a été diminuée, +             *    et il est juste nécessaire de recalculer la borne de fin. +             */ + +            /* On ne peut pas faire disparaître de régions */ +            assert(new_index >= *index); + +            /* Cas n°1 */ +            if (new_index > *index) +            { +                *index = find_memory_area_by_addr(*list, *count, &pos); + +                area = (*list) + *index; +                diff = compute_vmpa_diff(get_mrange_addr(&area->range), &pos); +                alen = get_mrange_length(&area->range); +                i = 0; -        printf(" --disass-- '%s' @ 0x%08x (break=%d)\n", -               g_arch_instruction_get_keyword(instr, 0), -               (unsigned int)get_virt_addr(&prev), -               g_arch_instruction_is_return(instr)); +            } +            /* Cas n°2 */ +            else /*if (new_index == *index)*/ +            { +                area = (*list) + *index; +                alen = get_mrange_length(&area->range); + +            } + +        }          if (g_arch_instruction_is_return(instr)) @@ -485,7 +613,7 @@ static void load_data_from_mem_area(mem_area *area, mem_area *list, size_t count      /* On cherche à obtenir l'assurance que le traitement n'a jamais été fait */      init_mrange(&range, start, 1); -    if (!is_range_blank_in_mem_areas(list, count, &range)) printf("DATA OK!!\n");; +    if (!is_range_blank_in_mem_areas(list, count, &range)) printf("DATA OK ! @ 0x%08x\n", (unsigned int)get_phy_addr(get_mrange_addr(&area->range)));      if (!is_range_blank_in_mem_areas(list, count, &range)) return;      /* Récupération des informations de base */ @@ -609,6 +737,7 @@ static void load_data_from_mem_area(mem_area *area, mem_area *list, size_t count  *  Paramètres  : area   = aire représentant à contenu à parcourir.            *  *                list   = liste de zones délimitant des contenus à traiter.   *  *                count  = nombre de zones à disposition.                      * +*                index  = indice de l'aire à considérer pendant l'opération.  *  *                binary = représentation de binaire chargé.                   *  *                ctx    = contexte offert en soutien à un désassemblage.      *  *                info   = indications quant à la progression à afficher.      * @@ -621,21 +750,43 @@ static void load_data_from_mem_area(mem_area *area, mem_area *list, size_t count  *                                                                             *  ******************************************************************************/ -static void fill_mem_area(mem_area *area, mem_area *list, size_t count, const GLoadedBinary *binary, GProcContext *ctx, status_blob_info *info) +void fill_mem_area(mem_area **list, size_t *count, size_t *index, const GLoadedBinary *binary, GProcContext *ctx, status_blob_info *info)  { +    mem_area *area;                         /* Zone de désassemblage       */ + +      phys_t len;                             /* Taille de la zone à remplir */      phys_t i;                               /* Boucle de parcours          */      vmpa2t start;                           /* Adresse de départ de combles*/ +    mem_area *old_list;                     /* Sauvegarde pour comparaison */ +    size_t old_index;                       /* Sauvegarde pour comparaison */ + + + +    size_t k; -    bool on = true; +    for (k = 0; k < *count; k++)  +   { +        printf(" (filled) AREA %zu :: 0x%08x + %u\n", +               k, +               (unsigned int)get_phy_addr(get_mrange_addr(&(*list)[k].range)), +               (unsigned int)get_mrange_length(&(*list)[k].range)); -    printf(" === FILLING | 0x%08x // 0x%08x <-> 0x%08x...\n", +    } + + +    area = (*list) + *index; + + + +    printf(" === FILLING (%zu) | 0x%08x // 0x%08x <-> 0x%08x...\n", *index,             (unsigned int)get_phy_addr(get_mrange_addr(&area->range)),             (unsigned int)get_virt_addr(get_mrange_addr(&area->range)),             (unsigned int)(get_virt_addr(get_mrange_addr(&area->range)) + get_mrange_length(&area->range))); +      /* Les symboles se doivent d'être indépendants ! */      if (area->has_sym) return; @@ -650,29 +801,32 @@ static void fill_mem_area(mem_area *area, mem_area *list, size_t count, const GL              if (area->exec && get_virt_addr(&start) % 2 == 0)              { -                load_code_from_mem_area(area, list, count, binary, ctx, &start, info); +                old_list = *list; +                old_index = *index; + +                load_code_from_mem_area(list, count, index, binary, ctx, &start, info); -                if (!is_range_blank_in_mem_area(area, i, 1, NULL)) +                /* Rechargement si changement */ +                if (*list != old_list || *index != old_index)                  { -                    printf(" --filled-- @ 0x%08x\n", (unsigned int)get_virt_addr(&start)); -                    on = false; -                } -                else -                    printf(" --fill failed-- @ 0x%08x\n", (unsigned int)get_virt_addr(&start)); +                    area = (*list) + *index; +                    len = get_mrange_length(&area->range); + +                    i = compute_vmpa_diff(get_mrange_addr(&area->range), &start); +                }              }              if (is_range_blank_in_mem_area(area, i, 1, NULL)) -                load_data_from_mem_area(area, list, count, binary, ctx, &start, info); +                load_data_from_mem_area(area, *list, *count, binary, ctx, &start, info);          } -        else on = true; -          if (is_range_blank_in_mem_area(area, i, 1, NULL)) -            printf(" [%p] error with %u\n", area, (unsigned int)i); +            printf(" [%p] error with %u @ 0x%08x\n", area, (unsigned int)i, +                   (unsigned int)get_phy_addr(get_mrange_addr(&area->range)));          assert(!is_range_blank_in_mem_area(area, i, 1, NULL)); @@ -1116,12 +1270,177 @@ mem_area *compute_memory_areas(GExeFormat *format, phys_t bin_length, size_t *co  } +/****************************************************************************** +*                                                                             * +*  Paramètres  : area   = aire représentant à contenu à parcourir.            * +*                list   = liste de zones délimitant des contenus à traiter.   * +*                count  = nombre de zones à disposition.                      * +*                index  = indice de l'aire à considérer pendant l'opération.  * +*                binary = représentation de binaire chargé.                   * +*                ctx    = contexte offert en soutien à un désassemblage.      * +*                start  = démarrage de l'exécution au sein de la zone.        * +*                info   = indications quant à la progression à afficher.      * +*                                                                             * +*  Description : Insère un symbole dans un découpage en aires.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool insert_extra_symbol_into_mem_areas(mem_area **list, size_t *count, size_t *old_index, GBinSymbol *symbol) +{ +    const mrange_t *sym_range;              /* Emplacement du symbole      */ +    size_t index;                           /* Zone trouvée à scinder      */ +    mem_area *area;                         /* Aire en cours de traitement */ +    mem_area saved;                         /* Aire aux données copiées    */ +    mrange_t area_range;                    /* Emplacement d'une aire      */ +    vmpa2t area_pos;                        /* Position relative à une aire*/ +    vmpa2t sym_pos;                         /* Position pour un symbole    */ +    phys_t diff;                            /* Décalage entre localisation */ +    phys_t new_length;                      /* Nouvelle taille de zone     */ + +    sym_range = g_binary_symbol_get_range(symbol); + +    index = find_memory_area_by_addr(*list, *count, get_mrange_addr(sym_range)); +    assert(index < *count); + +    if (index <= *old_index) (*old_index)++; + +    area = &(*list)[index]; +    assert(!area->has_sym); + +    saved = *area; + +    copy_mrange(&area_range, &area->range); + +    copy_vmpa(&area_pos, get_mrange_addr(&area_range)); +    copy_vmpa(&sym_pos, get_mrange_addr(sym_range)); + +    /* Si le symbole est construit avec une localisation partielle, on complète ! */ +    if (get_phy_addr(&sym_pos) == VMPA_NO_PHYSICAL || get_virt_addr(&sym_pos) == VMPA_NO_VIRTUAL) +    { +        diff = compute_vmpa_diff(&area_pos, &sym_pos); + +        copy_vmpa(&sym_pos, &area_pos); +        advance_vmpa(&sym_pos, diff); + +        g_binary_symbol_fix_range(symbol, &sym_pos); + +    } + +    /* Si le symbole se trouve en début de zone... */ +    if (cmp_vmpa(&area_pos, &sym_pos) == 0) +    { +        *list = (mem_area *)realloc(*list, ++(*count) * sizeof(mem_area)); + +        memmove(&(*list)[index + 1], &(*list)[index], (*count - index - 1) * sizeof(mem_area)); + +        /* Aire du symbole */ + +        area = &(*list)[index]; + +        init_mem_area_from_range(area, sym_range); + +        area->has_sym = true; +        area->symbol = symbol; + +        /* Aire raccourcie */ + +        copy_vmpa(&area_pos, get_mrange_addr(&saved.range)); +        advance_vmpa(&area_pos, get_mrange_length(sym_range)); + +        //compute_mrange_end_addr(sym_range, &area_pos); +        new_length = get_mrange_length(&area_range) - get_mrange_length(sym_range); + +        area = &(*list)[index + 1]; + +        init_mem_area_from_bigger_area(area, &area_pos, new_length, &saved); + +        goto iesima_done; + +    } + +    compute_mrange_end_addr(&area->range, &area_pos); +    compute_mrange_end_addr(sym_range, &sym_pos); + +    /* Si le symbole se trouve en fin de zone... */ +    if (cmp_vmpa(&area_pos, &sym_pos) == 0) +    { +        *list = (mem_area *)realloc(*list, ++(*count) * sizeof(mem_area)); + +        memmove(&(*list)[index + 1], &(*list)[index], (*count - index - 1) * sizeof(mem_area)); + +        /* Aire raccourcie */ + +        copy_vmpa(&area_pos, get_mrange_addr(&area_range)); +        new_length = get_mrange_length(&area_range) - get_mrange_length(sym_range); + +        area = &(*list)[index]; + +        init_mem_area_from_bigger_area(area, &area_pos, new_length, &saved); + +        /* Aire du symbole */ + +        area = &(*list)[index + 1]; + +        init_mem_area_from_range(area, sym_range); + +        area->has_sym = true; +        area->symbol = symbol; + +    } + +    /* Sinon il se trouve au milieu et on découpe en trois... */ +    else +    { +        *count += 2; +        *list = (mem_area *)realloc(*list, *count * sizeof(mem_area)); +        memmove(&(*list)[index + 2], &(*list)[index], (*count - index - 2) * sizeof(mem_area)); +        /* Aire raccourcie #1 */ +        copy_vmpa(&area_pos, get_mrange_addr(&area_range)); +        new_length = compute_vmpa_diff(&area_pos, get_mrange_addr(sym_range)); +        area = &(*list)[index]; +        init_mem_area_from_bigger_area(area, &area_pos, new_length, &saved); + +        /* Aire du symbole */ + +        area = &(*list)[index + 1]; + +        init_mem_area_from_range(area, sym_range); + +        area->has_sym = true; +        area->symbol = symbol; + +        /* Aire raccourcie #2 */ + +        copy_vmpa(&area_pos, get_mrange_addr(&saved.range)); +        advance_vmpa(&area_pos, get_mrange_length(&(*list)[index].range)); +        advance_vmpa(&area_pos, get_mrange_length(sym_range)); + +        //compute_mrange_end_addr(sym_range, &area_pos); +        new_length = get_mrange_length(&area_range) - get_mrange_length(sym_range) \ +            - get_mrange_length(&(*list)[index].range); + +        area = &(*list)[index + 2]; + +        init_mem_area_from_bigger_area(area, &area_pos, new_length, &saved); + +    } + +    fini_mem_area(&saved); + + iesima_done: + +    return true; +} @@ -1139,22 +1458,19 @@ mem_area *compute_memory_areas(GExeFormat *format, phys_t bin_length, size_t *co  *                                                                             *  *  Description : Détermine une liste de zones contigües à traiter.            *  *                                                                             * -*  Retour      : Liste de zones mémoire à libérer après usage.                * +*  Retour      : Indice de la zone trouvée, ou nombre d'aires en cas d'échec. *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -mem_area *find_memory_area_by_addr(mem_area *list, size_t count, const vmpa2t *addr) +size_t find_memory_area_by_addr(mem_area *list, size_t count, const vmpa2t *addr)  { -    mem_area *result;                       /* Trouvaille à retourner      */ -    size_t i;                               /* Boucle de parcours          */ - -    result = NULL; +    size_t result;                          /* Trouvaille à retourner      */ -    for (i = 0; i < count && result == NULL; i++) -        if (mrange_contains_addr(&list[i].range, addr)) -            result = &list[i]; +    for (result = 0; result < count; result++) +        if (mrange_contains_addr(&list[result].range, addr)) +            break;      return result; @@ -1179,6 +1495,7 @@ mem_area *find_memory_area_by_addr(mem_area *list, size_t count, const vmpa2t *a  static bool handle_bytes_map_in_mem_area(mem_area *list, size_t count, const mrange_t *range, GArchInstruction *instr, visit_bytes_map_fc visitor)  {      bool result;                            /* Bilan à retourner           */ +    size_t found;                           /* Indice de la zone trouvée   */      mem_area *area;                         /* Aire à traiter trouvée      */      phys_t offset;                          /* Point de départ dans l'aire */      phys_t remaining;                       /* Quantité restant à traiter  */ @@ -1187,8 +1504,10 @@ static bool handle_bytes_map_in_mem_area(mem_area *list, size_t count, const mra      result = false; -    area = find_memory_area_by_addr(list, count, get_mrange_addr(range)); -    if (area == NULL) return false; +    found = find_memory_area_by_addr(list, count, get_mrange_addr(range)); +    if (found == count) return false; + +    area = list + found;      offset = compute_vmpa_diff(get_mrange_addr(&area->range), get_mrange_addr(range));      remaining = get_mrange_length(range); @@ -1228,13 +1547,15 @@ static bool handle_bytes_map_in_mem_area(mem_area *list, size_t count, const mra          {              advance_vmpa(&start, processed); -            area = find_memory_area_by_addr(list, count, &start); -            if (area == NULL) +            found = find_memory_area_by_addr(list, count, &start); +            if (found == count)              {                  result = false;                  break;              } +            area = list + found; +              processed = get_mrange_length(&area->range);              if (remaining < processed) processed = remaining; @@ -1297,32 +1618,6 @@ static bool mark_range_in_mem_areas_as_processed(mem_area *list, size_t count, G  /******************************************************************************  *                                                                             * -*  Paramètres  : list   = liste de zones délimitant des contenus à traiter.   * -*                count  = nombre de zones à disposition.                      * -*                binary = représentation de binaire chargé.                   * -*                ctx    = contexte offert en soutien à un désassemblage.      * -*                info   = indications quant à la progression à afficher.      * -*                                                                             * -*  Description : S'assure que l'ensemble des aires est entièrement décodé.    * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void ensure_all_mem_areas_are_filled(mem_area *list, size_t count, const GLoadedBinary *binary, GProcContext *ctx, status_blob_info *info) -{ -    size_t i;                               /* Boucle de parcours          */ - -    for (i = 0; i < count; i++) -        fill_mem_area(&list[i], list, count, binary, ctx, info); - -} - - -/****************************************************************************** -*                                                                             *  *  Paramètres  : areas = série d'aires représentant à contenu à parcourir.    *  *                count = nombre de ces zones présentes.                       *  *                                                                             * diff --git a/src/analysis/disass/area.h b/src/analysis/disass/area.h index 2e80b04..b517816 100644 --- a/src/analysis/disass/area.h +++ b/src/analysis/disass/area.h @@ -45,14 +45,19 @@ typedef struct _mem_area mem_area;  /* Procède au désassemblage d'un contenu binaire exécutable. */ -void load_code_from_mem_area(mem_area *, mem_area *, size_t, const GLoadedBinary *, GProcContext *, const vmpa2t *, status_blob_info *); +void load_code_from_mem_area(mem_area **, size_t *, size_t *, const GLoadedBinary *, GProcContext *, const vmpa2t *, status_blob_info *); -/* Détermine une liste de zones contigües à traiter. */ -mem_area *compute_memory_areas(GExeFormat *, phys_t, size_t *); +/* S'assure qu'une aire qqcontient toutes ses instructions. */ +void fill_mem_area(mem_area **, size_t *, size_t *, const GLoadedBinary *, GProcContext *, status_blob_info *); + + + +/* Détermine une liste de zones contigües à traiter. */ +mem_area *compute_memory_areas(GExeFormat *, phys_t, size_t *); @@ -61,13 +66,11 @@ mem_area *compute_memory_areas(GExeFormat *, 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 *); +size_t find_memory_area_by_addr(mem_area *, size_t, const vmpa2t *); -/* S'assure que l'ensemble des aires est entièrement décodé. */ -void ensure_all_mem_areas_are_filled(mem_area *, size_t, const GLoadedBinary *, GProcContext *, status_blob_info *);  /* Rassemble les instructions conservées dans des zones données. */  GArchInstruction *collect_instructions_from_mem_areas(mem_area *, size_t); diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c index 38ea8c0..c3ba2c2 100644 --- a/src/analysis/disass/fetch.c +++ b/src/analysis/disass/fetch.c @@ -24,6 +24,9 @@  #include "fetch.h" +#include <assert.h> + +  #include <i18n.h> @@ -32,7 +35,11 @@  /* Suit un flot d'exécution pour désassembler du code. */ -static void follow_execution_flow(const GLoadedBinary *, GProcContext *, mem_area *, size_t, status_blob_info *, virt_t); +static void follow_execution_flow(const GLoadedBinary *, GProcContext *, mem_area **, size_t *, status_blob_info *, virt_t); + +/* S'assure que l'ensemble des aires est entièrement décodé. */ +static void ensure_all_mem_areas_are_filled(mem_area **, size_t *, const GLoadedBinary *, GProcContext *, status_blob_info *); + @@ -53,10 +60,10 @@ static void follow_execution_flow(const GLoadedBinary *, GProcContext *, mem_are  *                                                                             *  ******************************************************************************/ -static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx, mem_area *areas, size_t count, status_blob_info *info, virt_t virt) +static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx, mem_area **areas, size_t *count, status_blob_info *info, virt_t virt)  {      vmpa2t addr;                            /* Conversion en pleine adresse*/ -    mem_area *area;                         /* Zone de désassemblage       */ +    size_t index;                           /* Zone trouvée à traiter      */      printf("-- follow 0x%08x\n", (unsigned int)virt); @@ -72,9 +79,14 @@ static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx          printf("  ++ point 0x%08x\n", (unsigned int)virt); -        area = find_memory_area_by_addr(areas, count, &addr); +        printf("looking area for 0x%08x\n", (unsigned int)virt); + +        index = find_memory_area_by_addr(*areas, *count, &addr); +        if (index ==  *count) continue; + +        assert(index < *count); -        load_code_from_mem_area(area, areas, count, binary, ctx, &addr, info); +        load_code_from_mem_area(areas, count, &index, binary, ctx, &addr, info); @@ -88,6 +100,32 @@ static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx  /******************************************************************************  *                                                                             * +*  Paramètres  : list   = liste de zones délimitant des contenus à traiter.   * +*                count  = nombre de zones à disposition.                      * +*                binary = représentation de binaire chargé.                   * +*                ctx    = contexte offert en soutien à un désassemblage.      * +*                info   = indications quant à la progression à afficher.      * +*                                                                             * +*  Description : S'assure que l'ensemble des aires est entièrement décodé.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void ensure_all_mem_areas_are_filled(mem_area **list, size_t *count, const GLoadedBinary *binary, GProcContext *ctx, status_blob_info *info) +{ +    size_t i;                               /* Boucle de parcours          */ + +    for (i = 0; i < *count; i++) +        fill_mem_area(list, count, &i, binary, ctx, info); + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : binary    = représentation de binaire chargé.                *  *                statusbar = barre de statut avec progression à mettre à jour.*  *                id        = identifiant du message affiché à l'utilisateur.  * @@ -140,12 +178,12 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt      virt = g_binary_format_get_entry_point(format); -    follow_execution_flow(binary, ctx, areas, count, info, 0x84d0); +    follow_execution_flow(binary, ctx, &areas, &count, info, 0x84d0); -    follow_execution_flow(binary, ctx, areas, count, info, 0x84c5); -    follow_execution_flow(binary, ctx, areas, count, info, 0x8a65); +    follow_execution_flow(binary, ctx, &areas, &count, info, 0x84c5); +    follow_execution_flow(binary, ctx, &areas, &count, info, 0x8a65); -    follow_execution_flow(binary, ctx, areas, count, info, virt); +    follow_execution_flow(binary, ctx, &areas, &count, info, virt);      /* Symboles exécutables présents et passés à travers les mailles */ @@ -160,7 +198,7 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt          addr = get_mrange_addr(range);          virt = get_virt_addr(addr); -        follow_execution_flow(binary, ctx, areas, count, info, virt); +        follow_execution_flow(binary, ctx, &areas, &count, info, virt);      } @@ -178,7 +216,7 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt                                    _("Disassembling the remaining instructions..."),                                    done, length); -    ensure_all_mem_areas_are_filled(areas, count, binary, ctx, info); +    ensure_all_mem_areas_are_filled(&areas, &count, binary, ctx, info);      fini_progessive_status(info); diff --git a/src/arch/arm/v7/link.c b/src/arch/arm/v7/link.c index da5e30e..308d4e5 100644 --- a/src/arch/arm/v7/link.c +++ b/src/arch/arm/v7/link.c @@ -25,10 +25,15 @@  #include <assert.h> -#include <operands/offset.h> +#include <malloc.h> +#include <i18n.h> + + +#include "operands/offset.h"  #include "../register.h" +#include "../../raw.h" @@ -347,21 +352,20 @@ void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *instr      phys_t phys_pc;                         /* Position dans l'exécution   */      GArchOperand *op;                       /* Opérande de surcouche       */      GArchOperand *sub_op;                   /* Opérande numérique en place */ - -      uint32_t offset;                        /* Décallage encodé en dur     */      bool ret;                               /* Bilan d'une récupération    */ - -      off_t val_offset;                       /* Position de valeur à lire   */ - - - +    vmpa2t sym_addr;                        /* Adresse de nouveau symbole  */      off_t length;                           /* Taille des données à lire   */      const bin_t *data;                      /* Données binaires à lire     */ - -      uint32_t target;                        /* Adresse virtuelle visée     */ +    mrange_t sym_range;                     /* Espace du nouveau symbole   */ +    VMPA_BUFFER(loc);                       /* Adresse au format texte     */ +    size_t name_len;                        /* Taille de nomination finale */ +    char *name;                             /* Désignation humaine         */ +    GArchInstruction *sym_instr;            /* Instruction de symbole      */ +    GBinSymbol *symbol;                     /* Nouveau symbole construit   */ +    GDbComment *comment;                    /* Définition de commentaire   */      GArchOperand *new;                      /* Instruction de ciblage      */      /* Récupération de l'adresse visée par le chargement */ @@ -401,13 +405,24 @@ void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *instr          return;      } -    /* Lecture de la valeur vers laquelle renvoyer */ +    /* Transformations et conservation d'une position de symbole */      if (g_armv7_offset_operand_is_positive(G_ARMV7_OFFSET_OPERAND(op)))          val_offset = phys_pc + offset;      else          val_offset = phys_pc - offset; +    init_vmpa(&sym_addr, val_offset, VMPA_NO_VIRTUAL); +    init_mrange(&sym_range, &sym_addr, 4); + + + + + + + + +    /* Lecture de la valeur vers laquelle renvoyer */      data = g_binary_format_get_content(format, &length); @@ -422,6 +437,55 @@ void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *instr      printf(">>>>>>> @got target :: 0x%08x\n", (unsigned int)target); + + + +    /* Réalise l'intégration du symbole associé */ + +    sym_instr = g_raw_instruction_new_from_value(&sym_addr, MDS_32_BITS_UNSIGNED, target); + +    name_len = strlen(_("Value used @ %s")) + VMPA_MAX_LEN + 1; + +    name = (char *)calloc(name_len, sizeof(char)); + +    vmpa2_virt_to_string(get_mrange_addr(range), MDS_32_BITS, loc, NULL); +    snprintf(name, name_len, _("Value used @ %s"), loc); + +    ADD_RAW_AS_SYM(format, symbol, &sym_addr, sym_instr, comment, name); + +    free(name); + + + +    g_proc_context_push_new_symbol_at(G_PROC_CONTEXT(context), &sym_addr); +    printf("repush :: from 0x%x :: %x / %x\n", +           (unsigned int)get_phy_addr(get_mrange_addr(range)), +           (unsigned int)sym_addr.physical, (unsigned int)sym_addr.virtual); + + +    printf("add sym %p\n", symbol); + + + +    //g_proc_context_push_new_symbol_at(context, &sym_addr); + + + + + + + + + + + + + + + + + +      //g_imm_operand_set_value(G_IMM_OPERAND(sub_op), MDS_32_BITS_UNSIGNED, target); diff --git a/src/arch/context-int.h b/src/arch/context-int.h index b181202..64465a2 100644 --- a/src/arch/context-int.h +++ b/src/arch/context-int.h @@ -41,6 +41,9 @@ struct _GProcContext      virt_t *drop_points;                    /* Liste de points de départ   */      size_t dp_count;                        /* Taille de cette liste       */ +    vmpa2t *extra_symbols;                  /* Adresses de symboles        */ +    size_t esyms_count;                     /* Nombres de nouveautés       */ +  }; diff --git a/src/arch/context.c b/src/arch/context.c index 794030a..5427e4a 100644 --- a/src/arch/context.c +++ b/src/arch/context.c @@ -85,6 +85,9 @@ static void g_proc_context_init(GProcContext *ctx)      ctx->drop_points = NULL;      ctx->dp_count = 0; +    ctx->extra_symbols = NULL; +    ctx->esyms_count = 0; +  } @@ -205,3 +208,55 @@ virt_t g_proc_context_pop_drop_point(GProcContext *ctx)      return result;  } + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ctx  = contexte de désassemblage à compléter.                * +*                addr = adresse d'un nouveau symbole à traiter.               * +*                                                                             * +*  Description : Empile une adresse de nouveau symbole à prendre en compte.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_proc_context_push_new_symbol_at(GProcContext *ctx, const vmpa2t *addr) +{ +    ctx->extra_symbols = (vmpa2t *)realloc(ctx->extra_symbols, ++ctx->esyms_count * sizeof(vmpa2t)); + +    copy_vmpa(&ctx->extra_symbols[ctx->esyms_count - 1], addr); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ctx  = contexte de désassemblage à compléter.                * +*                addr = adresse d'un nouveau symbole à traiter.               * +*                                                                             * +*  Description : Dépile une adresse de nouveau symbole à prendre en compte.   * +*                                                                             * +*  Retour      : true si un symbole était bien encore en stock, false sinon.  * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_proc_context_pop_new_symbol_at(GProcContext *ctx, vmpa2t *addr) +{ +    bool result;                            /* Bilan à retourner           */ + +    result = (ctx->esyms_count > 0); + +    if (result) +    { +        ctx->esyms_count--; +        copy_vmpa(addr, &ctx->extra_symbols[ctx->esyms_count]); +    } + +    return result; + +} diff --git a/src/arch/context.h b/src/arch/context.h index 97b23b6..390d9f9 100644 --- a/src/arch/context.h +++ b/src/arch/context.h @@ -63,6 +63,12 @@ bool g_proc_context_has_addr_as_drop_points(const GProcContext *, virt_t);  /* Fournit une adresse virtuelle comme point de départ de code. */  virt_t g_proc_context_pop_drop_point(GProcContext *); +/* Empile une adresse de nouveau symbole à prendre en compte. */ +void g_proc_context_push_new_symbol_at(GProcContext *, const vmpa2t *); + +/* Dépile une adresse de nouveau symbole à prendre en compte. */ +bool g_proc_context_pop_new_symbol_at(GProcContext *, vmpa2t *); +  #endif  /* _ARCH_CONTEXT_H */ diff --git a/src/arch/raw.c b/src/arch/raw.c index e76d75d..62c88c1 100644 --- a/src/arch/raw.c +++ b/src/arch/raw.c @@ -169,6 +169,76 @@ static void g_raw_instruction_finalize(GRawInstruction *instr)  /******************************************************************************  *                                                                             * +*  Paramètres  : addr  = position à associer à l'instruction.                 * +*                size  = taille de l'opérande souhaitée.                      * +*                value = valeur sur x bits à venir récupérer.                 * +*                                                                             * +*  Description : Crée une instruction de type 'db/dw/etc' simple.             * +*                                                                             * +*  Retour      : Instruction mise en place.                                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDataSize size, uint64_t value) +{ +    GArchInstruction *result;               /* Instruction à retourner     */ +    GArchOperand *operand;                  /* Octet non décodé à afficher */ +    mrange_t range;                         /* Couverture de l'instruction */ + +    result = g_object_new(G_TYPE_RAW_INSTRUCTION, NULL); + +    operand = g_imm_operand_new_from_value(size, value); +    if (operand == NULL) goto grinfv_error; + +    g_imm_operand_pad(G_IMM_OPERAND(operand), true); + +    g_arch_instruction_attach_extra_operand(result, operand); + +    switch (size) +    { +        case MDS_8_BITS_UNSIGNED: +        case MDS_8_BITS_SIGNED: +            init_mrange(&range, addr, 1); +            break; + +        case MDS_16_BITS_UNSIGNED: +        case MDS_16_BITS_SIGNED: +            init_mrange(&range, addr, 2); +            break; + +        case MDS_32_BITS_UNSIGNED: +        case MDS_32_BITS_SIGNED: +            init_mrange(&range, addr, 4); +            break; + +        case MDS_64_BITS_UNSIGNED: +        case MDS_64_BITS_SIGNED: +            init_mrange(&range, addr, 8); +            break; + +        default: +            goto grinfv_error; +            break; + +    } + +    g_arch_instruction_set_range(result, &range); + +    return result; + + grinfv_error: + +    g_object_unref(G_OBJECT(result)); + +    return NULL; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : data   = flux de données à analyser.                         *  *                size   = taille de chacun des éléments à représenter.        *  *                count  = nombre de ces éléments.                             * diff --git a/src/arch/raw.h b/src/arch/raw.h index ce324f5..8ae9a74 100644 --- a/src/arch/raw.h +++ b/src/arch/raw.h @@ -52,6 +52,9 @@ typedef struct _GRawInstructionClass GRawInstructionClass;  /* Indique le type défini pour une instruction inconnue d'architecture. */  GType g_raw_instruction_get_type(void); +/* Crée une instruction de type 'db/dw/etc' simple. */ +GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *, MemoryDataSize, uint64_t); +  /* Crée une instruction de type 'db/dw/etc' étendue. */  GArchInstruction *g_raw_instruction_new_array(const bin_t *, MemoryDataSize, size_t, vmpa2t *, off_t, SourceEndian); diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c index b306f00..46d1a04 100644 --- a/src/arch/vmpa.c +++ b/src/arch/vmpa.c @@ -685,7 +685,12 @@ bool mrange_contains_addr(const mrange_t *range, const vmpa2t *addr)      if (ret <= -1)      {          diff = compute_vmpa_diff(&range->addr, addr); -        result = (diff < range->length); + +        if (diff != VMPA_NO_PHYSICAL) +            result = (diff < range->length); +        else +            result = false; +      }      else if (ret == 0) @@ -701,6 +706,27 @@ bool mrange_contains_addr(const mrange_t *range, const vmpa2t *addr)  /******************************************************************************  *                                                                             * +*  Paramètres  : range = zone mémoire à consulter.                            * +*                addr  = localisation mémoire à déterminer.                   * +*                                                                             * +*  Description : Calcule la position extérieure final d'une couverture.       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void compute_mrange_end_addr(const mrange_t *range, vmpa2t *addr) +{ +    copy_vmpa(addr, &range->addr); +    advance_vmpa(addr, range->length); + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : rane   = emplacement virtuel ou physique à traiter.          *  *                msize  = taille de cette adresse, réelle ou désirée.         *  *                start  = indique si le début ou la fin est à imprimer.       * diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h index 6f8e809..97b2610 100644 --- a/src/arch/vmpa.h +++ b/src/arch/vmpa.h @@ -148,7 +148,7 @@ typedef struct _mrange_t  /* Initialise une plage dans l'espace mémoire/physique. */ -void init_mrange(mrange_t *, const vmpa2t *, phys_t ); +void init_mrange(mrange_t *, const vmpa2t *, phys_t);  /* Copie la définition d'une plage mémoire dans une autre. */  void copy_mrange(mrange_t *, const mrange_t *); @@ -162,6 +162,9 @@ bool mrange_contains_mrange(const mrange_t *, const mrange_t *);  /* Indique si une localisation est incluse dans une zone ou non. */  bool mrange_contains_addr(const mrange_t *, const vmpa2t *); +/* Calcule la position extérieure final d'une couverture. */ +void compute_mrange_end_addr(const mrange_t *, vmpa2t *); +  /* Transforme un emplacement physique en chaîne de caractères. */  char *mrange_phys_to_string(const mrange_t *, MemoryDataSize, bool, char [VMPA_MAX_LEN], size_t *); diff --git a/src/format/format.c b/src/format/format.c index e710668..ab5b372 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -253,7 +253,6 @@ GBinSymbol **g_binary_format_get_symbols(const GBinFormat *format, size_t *count  *  Paramètres  : format = informations chargées à consulter.                  *  *                addr   = adresse à cibler lors des recherches.               *  *                symbol = éventuel symbole trouvé à déréfenrencer. [OUT]      * -*                diff   = décallage entre l'adresse et le symbole. [OUT]      *  *                                                                             *  *  Description : Recherche le symbole correspondant à une adresse.            *  *                                                                             * @@ -263,7 +262,7 @@ GBinSymbol **g_binary_format_get_symbols(const GBinFormat *format, size_t *count  *                                                                             *  ******************************************************************************/ -bool g_binary_format_resolve_symbol(const GBinFormat *format, const vmpa2t *addr, GBinSymbol **symbol, phys_t *diff) +bool g_binary_format_find_symbol_at(const GBinFormat *format, const vmpa2t *addr, GBinSymbol **symbol)  {      bool result;                            /* Bilan à retourner           */      size_t i;                               /* Boucle de parcours          */ @@ -275,11 +274,55 @@ bool g_binary_format_resolve_symbol(const GBinFormat *format, const vmpa2t *addr      {          range = g_binary_symbol_get_range(format->symbols[i]); -        if (mrange_contains_addr(range, addr)) +        if (cmp_vmpa(get_mrange_addr(range), addr) == 0)          {              *symbol = format->symbols[i];              g_object_ref(G_OBJECT(*symbol)); +            result = true; + +        } + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = informations chargées à consulter.                  * +*                addr   = adresse à cibler lors des recherches.               * +*                symbol = éventuel symbole trouvé à déréfenrencer. [OUT]      * +*                diff   = décallage entre l'adresse et le symbole. [OUT]      * +*                                                                             * +*  Description : Recherche le symbole correspondant à une adresse.            * +*                                                                             * +*  Retour      : true si l'opération a été un succès, false sinon.            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_binary_format_resolve_symbol(const GBinFormat *format, const vmpa2t *addr, GBinSymbol **symbol, phys_t *diff) +{ +    bool result;                            /* Bilan à retourner           */ +    size_t i;                               /* Boucle de parcours          */ +    const mrange_t *range;                  /* Espace mémoire parcouru     */ + +    result = false; + +    //for (i = 0; i < format->symbols_count && !result; i++) +    for (i = format->symbols_count; i > 0 && !result; i--) +    { +        range = g_binary_symbol_get_range(format->symbols[i - 1]); + +        if (mrange_contains_addr(range, addr)) +        { +            *symbol = format->symbols[i - 1]; +            g_object_ref(G_OBJECT(*symbol)); +              *diff = compute_vmpa_diff(get_mrange_addr(range), addr);              result = true; diff --git a/src/format/format.h b/src/format/format.h index 364f71a..9b2e0f6 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -68,6 +68,9 @@ void g_binary_format_add_symbol(GBinFormat *, GBinSymbol *);  GBinSymbol **g_binary_format_get_symbols(const GBinFormat *, size_t *);  /* Recherche le symbole correspondant à une adresse. */ +bool g_binary_format_find_symbol_at(const GBinFormat *, const vmpa2t *, GBinSymbol **); + +/* Recherche le symbole correspondant à une adresse. */  bool g_binary_format_resolve_symbol(const GBinFormat *, const vmpa2t *, GBinSymbol **, phys_t *);  /* Ajoute une routine à la collection du format binaire. */ diff --git a/src/format/symbol.c b/src/format/symbol.c index 5e66c54..1e6063f 100644 --- a/src/format/symbol.c +++ b/src/format/symbol.c @@ -24,6 +24,7 @@  #include "symbol.h" +#include <assert.h>  #include <string.h> @@ -290,6 +291,63 @@ const char *g_binary_symbol_get_label(const GBinSymbol *symbol)  /******************************************************************************  *                                                                             * +*  Paramètres  : symbol = symbole à venir mettre à jour.                      * +*                full   = adresse dont la définition est complète.            * +*                                                                             * +*  Description : Raffine la définition de l'emplacement d'un symbole.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_binary_symbol_fix_range(GBinSymbol *symbol, const vmpa2t *full) +{ +    GArchInstruction *instr;                /* Instruction associée        */ +    mrange_t range;                         /* Plage à manipuler           */ +    GBinRoutine *routine;                   /* Routine associée            */ + +    switch (symbol->type) +    { +        case STP_DATA: + +            instr = g_binary_symbol_get_instruction(symbol); + +            copy_mrange(&range, g_arch_instruction_get_range(instr)); + +            assert(cmp_vmpa(get_mrange_addr(&range), full) == 0); + +            copy_vmpa(get_mrange_addr(&range), full); + +            g_arch_instruction_set_range(instr, &range); + +            break; + +        case STP_ROUTINE: + +            routine = g_binary_symbol_get_routine(symbol); + +            copy_mrange(&range, g_binary_routine_get_range(routine)); + +            assert(cmp_vmpa(get_mrange_addr(&range), full) == 0); + +            copy_vmpa(get_mrange_addr(&range), full); + +            g_binary_routine_set_range(routine, &range); + +            break; + +        default: +            break; + +    } + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : symbol = symbole à venir consulter.                          *  *                                                                             *  *  Description : Fournit l'emplacement où se situe un symbole.                * @@ -393,6 +451,25 @@ void g_binary_symbol_attach_instruction(GBinSymbol *symbol, GArchInstruction *in  *                                                                             *  *  Paramètres  : symbol = symbole à venir consulter.                          *  *                                                                             * +*  Description : Fournit l'éventuelle routine associée au symbole.            * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : Il n'y a pas de transfert de propriété ici !                 * +*                                                                             * +******************************************************************************/ + +GBinRoutine *g_binary_symbol_get_routine(const GBinSymbol *symbol) +{ +    return symbol->extra.routine; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : symbol = symbole à venir consulter.                          * +*                                                                             *  *  Description : Fournit l'éventuelle instruction associée au symbole.        *  *                                                                             *  *  Retour      : -                                                            * diff --git a/src/format/symbol.h b/src/format/symbol.h index ac1ff0d..c5bf750 100644 --- a/src/format/symbol.h +++ b/src/format/symbol.h @@ -81,6 +81,9 @@ vmpa_t g_binary_symbol_get_address(const GBinSymbol *); ///////////////////  /* Fournit un étiquette pour viser un symbole. */  const char *g_binary_symbol_get_label(const GBinSymbol *); +/* Raffine la définition de l'emplacement d'un symbole. */ +void g_binary_symbol_fix_range(GBinSymbol *, const vmpa2t *); +  /* Fournit l'emplacement où se situe un symbole. */  const mrange_t *g_binary_symbol_get_range(const GBinSymbol *); @@ -93,6 +96,9 @@ void g_binary_symbol_attach_routine(GBinSymbol *, GBinRoutine *);  /* Attache l'instruction associée au symbole. */  void g_binary_symbol_attach_instruction(GBinSymbol *, GArchInstruction *); +/* Fournit l'éventuelle routine associée au symbole. */ +GBinRoutine *g_binary_symbol_get_routine(const GBinSymbol *); +  /* Fournit l'éventuelle instruction associée au symbole. */  GArchInstruction *g_binary_symbol_get_instruction(const GBinSymbol *);  | 
