diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2015-01-09 22:30:16 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2015-01-09 22:30:16 (GMT) | 
| commit | cc3e31eecd90766ae4f0bb391428c5c59567ef4c (patch) | |
| tree | e442bbaf401855f7bac411ac45e3545aa96ba661 /src/arch/arm/context.c | |
| parent | 50a4c165df49b04fe55278d5dcfa6b56d3cc1125 (diff) | |
Chosen the right encoding to use when disassembling ARM binary.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@452 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch/arm/context.c')
| -rw-r--r-- | src/arch/arm/context.c | 216 | 
1 files changed, 180 insertions, 36 deletions
diff --git a/src/arch/arm/context.c b/src/arch/arm/context.c index 7f41b92..24546c0 100644 --- a/src/arch/arm/context.c +++ b/src/arch/arm/context.c @@ -24,28 +24,17 @@  #include "context.h" -#include "../context-int.h" -#include "../../decomp/context-int.h" - - - -/* ------------------------ MANIPULATION GLOBALE DU CONTEXTE ------------------------ */ - +#include <assert.h> +#include <malloc.h> +#include <string.h> -/* Définition d'un contexte pour processeur ARM (instance) */ -struct _GArmContext -{ -    GProcContext parent;                    /* A laisser en premier        */ -}; +#include "context-int.h" +#include "../../decomp/context-int.h" -/* Définition d'un contexte pour processeur ARM (classe) */ -struct _GArmContextClass -{ -    GProcContextClass parent;               /* A laisser en premier        */ -}; +/* ------------------------ MANIPULATION GLOBALE DU CONTEXTE ------------------------ */  /* Initialise la classe des contextes de processeur ARM. */ @@ -60,8 +49,8 @@ static void g_arm_context_dispose(GArmContext *);  /* Procède à la libération totale de la mémoire. */  static void g_arm_context_finalize(GArmContext *); -/* Ajoute une adresse virtuelle comme point de départ de code. */ -static void g_arm_context_push_drop_point(GArmContext *, virt_t ); +/* Indique l'encodage (générique) utilisé à une adresse donnée. */ +static size_t find_disass_arm_area(disass_arm_area *, virt_t, size_t, size_t); @@ -127,17 +116,12 @@ G_DEFINE_TYPE(GArmContext, g_arm_context, G_TYPE_PROC_CONTEXT);  static void g_arm_context_class_init(GArmContextClass *klass)  {      GObjectClass *object;                   /* Autre version de la classe  */ -    GProcContextClass *proc;                /* Version parente de la classe*/      object = G_OBJECT_CLASS(klass);      object->dispose = (GObjectFinalizeFunc/* ! */)g_arm_context_dispose;      object->finalize = (GObjectFinalizeFunc)g_arm_context_finalize; -	proc = G_PROC_CONTEXT_CLASS(klass); - -	proc->push_point = (push_drop_point_fc)g_arm_context_push_drop_point; -  } @@ -222,10 +206,61 @@ GArmContext *g_arm_context_new(void)  /******************************************************************************  *                                                                             * -*  Paramètres  : ctx  = contexte de désassemblage à compléter.                * -*                addr = adresse d'un nouveau point de départ à traiter.       * +*  Paramètres  : areas = ensemble des découpages du désassemblage.            * +*                addr = adresse d'un nouveau point de départ à retrouver.     * +*                first = indice de la première zone à considérer.             * +*                last  = indice de la dernière zone à considérer.             * +*                                                                             * +*  Description : Indique l'encodage (générique) utilisé à une adresse donnée. *  *                                                                             * -*  Description : Ajoute une adresse virtuelle comme point de départ de code.  * +*  Retour      : Marqueur à priori toujours valide.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static size_t find_disass_arm_area(disass_arm_area *areas, virt_t addr, size_t first, size_t last) +{ +    size_t index;                           /* Indice de cellule idéale    */ +    size_t mid;                             /* Division de l'espace        */ + +    printf(" < 0x%08x > %zu / %zu...\n", addr, first, last); + +    if (first == last) +        index = first; + +    else +    { +        mid = first + (last - first + 1) / 2; + +        printf(" --looking-- %zu / %zu -> %zu\n", first, last, mid); + +        if (areas[mid].start <= addr) +            index = find_disass_arm_area(areas, addr, mid, last); +        else +            index = find_disass_arm_area(areas, addr, first, mid - 1); + +    } + +    printf(" !! FOUND !! (for 0x%08x) --  [%zu] [%zu/%zu] 0x%08x <-> 0x%08x\n", +           (unsigned int)addr, index, first, last, +           (unsigned int)areas[index].start, +           (unsigned int)areas[index].end); + +    assert(areas[index].start <= addr && addr < areas[index].end); + +    return index; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ctx    = contexte de désassemblage à compléter.              * +*                addr   = adresse d'un nouveau point de départ à créer.       * +*                marker = forme générique d'un encodage à mémoriser.          * +*                                                                             * +*  Description : Enregistre l'encodage (générique) utilisé à une adresse.     *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -233,29 +268,138 @@ GArmContext *g_arm_context_new(void)  *                                                                             *  ******************************************************************************/ -static void g_arm_context_push_drop_point(GArmContext *ctx, virt_t addr) +void _g_arm_context_define_encoding(GArmContext *ctx, virt_t addr, unsigned int marker)  { +    size_t selected;                        /* Zone associée à une adresse */ + +    /* TODO : pose de verroux ? */ + +    selected = find_disass_arm_area(ctx->areas, addr, 0, ctx->acount - 1); + +    /* S'agit-il d'une redéfinition ? */ +    if (ctx->areas[selected].start == addr) +        ctx->areas[selected].marker = marker; + +    /* Sinon on redivise... */ +    else +    { + + + + + +    do +    { +        unsigned int i; + +        printf(" --sel-- %u for 0x%08x\n", (unsigned int)selected, (unsigned int)addr); +        for (i = 0; i < ctx->acount; i++) +            printf(" --def before-- [%u] 0x%08x <-> 0x%08x\n", +                   i, +                   (unsigned int)ctx->areas[i].start, +                   (unsigned int)ctx->areas[i].end); -	printf("PUSH !!\n"); +    } +    while (0); -	if (addr & 0x1) -	{ -		addr -= 0x1; -	} -	else ; -	// ARM / Thumb -	G_PROC_CONTEXT_CLASS(g_arm_context_parent_class)->push_point(G_PROC_CONTEXT(ctx), addr); +        ctx->areas = (disass_arm_area *)realloc(ctx->areas, ++ctx->acount * sizeof(disass_arm_area)); + +        memmove(&ctx->areas[selected + 1], &ctx->areas[selected], +                (ctx->acount - selected - 1) * sizeof(disass_arm_area)); + +        ctx->areas[selected].start = ctx->areas[selected + 1].start; +        ctx->areas[selected].end = addr - 1; +        ctx->areas[selected].marker = ctx->areas[selected + 1].marker; + +        ctx->areas[selected + 1].start = addr; +        ctx->areas[selected + 1].marker = marker; + + + +    do +    { +        unsigned int i; + +        for (i = 0; i < ctx->acount; i++) +            printf(" --def after-- [%u] 0x%08x <-> 0x%08x\n", +                   i, +                   (unsigned int)ctx->areas[i].start, +                   (unsigned int)ctx->areas[i].end); + +    } +    while (0); + + + + + + +    } + + + + +    /* +    do +    { +        unsigned int i; + +        printf(" --sel-- %u for 0x%08x\n", (unsigned int)selected, (unsigned int)addr); + +        for (i = 0; i < ctx->acount; i++) +            printf(" --def-- [%u] 0x%08x <-> 0x%08x\n", +                   i, +                   (unsigned int)ctx->areas[i].start, +                   (unsigned int)ctx->areas[i].end); + +    } +    while (0); +    */ + + + +  } +/****************************************************************************** +*                                                                             * +*  Paramètres  : ctx  = contexte de désassemblage à consulter.                * +*                addr = adresse d'un nouveau point de départ à retrouver.     * +*                                                                             * +*  Description : Indique l'encodage (générique) utilisé à une adresse donnée. * +*                                                                             * +*  Retour      : Marqueur à priori toujours valide.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +unsigned int _g_arm_context_find_encoding(GArmContext *ctx, virt_t addr) +{ +    size_t selected;                        /* Zone associée à une adresse */ + +    /* TODO : pose de verroux ? */ + +    selected = find_disass_arm_area(ctx->areas, addr, 0, ctx->acount - 1); + +    return ctx->areas[selected].marker; + +} + + + + + +  /* ---------------------------------------------------------------------------------- */  /*                           CONTEXTE POUR LA DECOMPILATION                           */  | 
