diff options
27 files changed, 878 insertions, 170 deletions
@@ -1,3 +1,66 @@ +15-04-01  Cyrille Bagard <nocbos@gmail.com> + +	* src/analysis/disass/area.c: +	Update code by changing IPH_LINK to IPH_FETCH. + +	* src/analysis/disass/disassembler.c: +	Register all disassembled instructions and run the new IPH_LINK methods. + +	* src/analysis/disass/links.c: +	Establish natural links in the execution flow. + +	* src/analysis/disass/macro.c: +	Save some progress in the definition of basic blocks. + +	* src/arch/arm/v7/fetch.c: +	* src/arch/arm/v7/fetch.h: +	New entries: redefine the old IPH_LINK methods into IPH_FETCH new ones. + +	* src/arch/arm/v7/link.c: +	* src/arch/arm/v7/link.h: +	Moved entries: see the 'fetch.[ch]' files. + +	* src/arch/arm/v7/Makefile.am: +	Replace the 'link.[ch]' files by the 'fetch.[ch]' ones +	in libarcharmv7_la_SOURCES. + +	* src/arch/arm/v7/opdefs/b_A8818.d: +	* src/arch/arm/v7/opdefs/bl_A8825.d: +	* src/arch/arm/v7/opdefs/bx_A8827.d: +	* src/arch/arm/v7/opdefs/cbnz_A8829.d: +	* src/arch/arm/v7/opdefs/ldr_A8864.d: +	Update definitions. + +	* src/arch/arm/v7/opdefs/Makefile.am: +	Update included headers list. + +	* src/arch/arm/v7/opdefs/pop_A88131.d: +	* src/arch/arm/v7/opdefs/pop_A88132.d: +	Update definitions. + +	* src/arch/arm/v7/post.c: +	* src/arch/arm/v7/post.h: +	Update prototypes. + +	* src/arch/instruction.c: +	Update code. + +	* src/arch/instruction.h: +	Update code. Redefine prototypes for hooks. Register a link type dedicated +	to cross refrences. + +	* src/arch/link.c: +	* src/arch/link.h: +	New entries: provide generic methods for some kinks of links. + +	* src/arch/Makefile.am: +	Add the 'link.[ch]' files to libarch_la_SOURCES. + +	* src/arch/processor.c: +	* src/arch/processor.h: +	* src/arch/processor-int.h: +	Begin to store all disassembled instructions in the processor structure. +  15-03-29  Cyrille Bagard <nocbos@gmail.com>  	* plugins/readelf/header.c: diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index 90738be..3a23993 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -565,7 +565,7 @@ bool load_code_from_mem_area(mem_area **list, size_t *count, size_t *index, cons          /* Eventuel renvoi vers d'autres adresses */ -        g_arch_instruction_call_hook(instr, IPH_LINK, ctx, format); +        g_arch_instruction_call_hook(instr, IPH_FETCH, proc, ctx, format);          /* Progression dans les traitements */ diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c index 95d95d0..fcc41cb 100644 --- a/src/analysis/disass/disassembler.c +++ b/src/analysis/disass/disassembler.c @@ -186,6 +186,8 @@ static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GAr  static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtStatusBar *statusbar)  { +    //GBinFormat *format;                     /* Format du fichier binaire   */ +    GArchProcessor *proc;                   /* Architecture du binaire     */      unsigned int valid;                     /* Instructions traduites      */ @@ -199,9 +201,12 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta      bstatus_id_t id;                        /* Identifiant de statut       */ -    GArchProcessor *proc;                   /* Architecture du binaire     */ +    //GArchProcessor *proc;                   /* Architecture du binaire     */ +    //format = G_BIN_FORMAT(g_loaded_binary_get_format(binary)); +    proc = g_loaded_binary_get_processor(disass->binary); +      routines = g_binary_format_get_routines(G_BIN_FORMAT(disass->format), &routines_count); @@ -219,6 +224,8 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta      *disass->instrs = disassemble_binary_content(disass->binary, statusbar); +    g_arch_processor_set_disassembled_instructions(proc, *disass->instrs); +      /*      *disass->instrs = disassemble_binary_parts(disass->binary, disass->parts, disass->count, @@ -229,6 +236,32 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta +    do +    { +        GBinFormat *format;                     /* Format du fichier binaire   */ +        GArchInstruction *iter;                 /* Boucle de parcours          */ + + + +        format = G_BIN_FORMAT(g_loaded_binary_get_format(disass->binary)); + +        for (iter = *disass->instrs; +             iter != NULL; +             iter = g_arch_instruction_get_next_iter(*disass->instrs, iter, 0)) +        { + +            g_arch_instruction_call_hook(iter, IPH_LINK, proc, /*ctx*/NULL, format); + + + +        } + + + +    } while (0); + + +      //gtk_extended_status_bar_remove(statusbar, id); @@ -250,7 +283,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta               iter = g_arch_instruction_get_next_iter(*disass->instrs, iter, 0))          { -            g_arch_instruction_call_hook(iter, IPH_POST, /*ctx*/NULL, format); +            g_arch_instruction_call_hook(iter, IPH_POST, proc, /*ctx*/NULL, format); diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c index 022ace3..06b6b03 100644 --- a/src/analysis/disass/links.c +++ b/src/analysis/disass/links.c @@ -33,10 +33,8 @@  /* Complète un désassemblage accompli pour une instruction. */  static void convert_immediate_into_target(GArchInstruction *, size_t, GBinFormat *); - - - - +/* Rétablit un lien naturel coupé par un autre lien. */ +static void establish_natural_link(GArchInstruction *, GArchInstruction *); @@ -118,10 +116,83 @@ static void establish_links_for_instruction(GArchInstruction *instr, GArchInstru          target = g_arch_instruction_find_by_address(list, &addr, true);          if (target != NULL) -            g_arch_instruction_link_with(instr, target, ILT_JUMP /* FIXME */); +            g_arch_instruction_link_with(instr, target, ILT_REF); + +    } + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr = instruction désassemblée à traiter.                  * +*                prev  = instruction précédente.                              * +*                                                                             * +*  Description : Rétablit un lien naturel coupé par un autre lien.            * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev) +{ +    GArchInstruction **others;              /* Instructions diverses liées */ +    InstructionLinkType *types;             /* Types de lien existants     */ +    size_t count;                           /* Nbre de sources affichées   */ +    size_t i;                               /* Boucle de parcours          */ + +    /** +     * Si rien ne vient séparer les deux instructions, +     * on ne peut pas créer de lien plus naturel que l'existant. +     */ + +    if (!g_arch_instruction_has_sources(instr)) +        return; + +    /** +     * Si on se trouve à une extrémité, on ne se lie pas +     * avec le voisin. +     */ + +    if (g_arch_instruction_is_return(prev)) +        return; + +    if (g_arch_instruction_get_flags(instr) & AIF_ROUTINE_START) +        return; + +    /** +     * On s'assure que le lien naturel est valide. +     */ + +    count = g_arch_instruction_get_destinations(prev, &others, &types, NULL); + +    for (i = 0; i < count; i++) +    { +        if (types[i] == ILT_EXEC_FLOW) break; +        if (types[i] == ILT_JUMP) break; +        if (types[i] == ILT_CASE_JUMP) break; +        if (types[i] == ILT_LOOP) break; +    } + +    if (i < count) return; + +    /** +     * On vérifie que le lien n'existe pas déjà avant d'en créer un... +     */ +    count = g_arch_instruction_get_sources(instr, &others, &types); + +    for (i = 0; i < count; i++) +    { +        if (others[i] == prev && types[i] == ILT_JUMP_IF_TRUE) break; +        if (others[i] == prev && types[i] == ILT_JUMP_IF_FALSE) break;      } +    if (i == count) +        g_arch_instruction_link_with(prev, instr, ILT_EXEC_FLOW); +  } @@ -142,13 +213,19 @@ static void establish_links_for_instruction(GArchInstruction *instr, GArchInstru  void establish_links_between_instructions(GArchInstruction *list, GBinFormat *format, GtkExtStatusBar *statusbar, bstatus_id_t id)  { +    GArchInstruction *prev;                 /* Itération précédente        */      GArchInstruction *iter;                 /* Boucle de parcours          */ +    prev = NULL; +      for (iter = list;           iter != NULL;           iter = g_arch_instruction_get_next_iter(list, iter, ~0/* FIXME */))      { +        if (prev != NULL) +            establish_natural_link(iter, prev); +        prev = iter;          establish_links_for_instruction(iter, list, format); diff --git a/src/analysis/disass/macro.c b/src/analysis/disass/macro.c index 218371b..087f1ae 100644 --- a/src/analysis/disass/macro.c +++ b/src/analysis/disass/macro.c @@ -297,6 +297,9 @@ static bool code_coverage_stop_here(const code_coverage *coverage, const vmpa2t  {      void *ptr;                              /* Résultat des recherches     */ +    if (!mrange_contains_addr(&coverage->range, addr)) +        return true; +      ptr = bsearch(addr, coverage->ends, coverage->ends_count,                    sizeof(vmpa2t), (__compar_fn_t)cmp_vmpa); @@ -532,10 +535,21 @@ static void find_next_hops(GArchInstruction *instrs, const vmpa2t *start, const      InstructionLinkType *types;             /* Type de lien entre lignes   */      size_t dcount;                          /* Nombre de liens de dest.    */      size_t i;                               /* Boucle de parcours #2       */ +    size_t not_handled;                     /* Nombre d'éléments écartés   */ + +    printf(" ---- FN [ %p ] ---------------------------\n", info); + + +    printf("CONTAINS ? %d\n", mrange_contains_addr(&coverage->range, start));      /* Si la position est déjà présente, on évite de boucler... */      if (!add_hop_into_branch(info, start)) +    { +        printf("  ++ !add 0x%08x\n", (unsigned int)start->virtual);          return; +    } +    else +        printf("  ++ add 0x%08x\n", (unsigned int)start->virtual);      /* On suit le flot jusqu'à la prochaine bifurcation */      for (iter = g_arch_instruction_find_by_address(instrs, start, true); @@ -544,20 +558,43 @@ static void find_next_hops(GArchInstruction *instrs, const vmpa2t *start, const      {          range = g_arch_instruction_get_range(iter); + +        if (code_coverage_stop_here(coverage, get_mrange_addr(range))) +            printf("  ++ stop here 0x%08x\n", (unsigned int)range->addr.virtual); +          if (code_coverage_stop_here(coverage, get_mrange_addr(range)))              break; + +        if (g_arch_instruction_has_sources(iter)) +            add_hop_into_branch(info, get_mrange_addr(range)); + + + +        if (g_arch_instruction_is_return(iter)) +            printf("  ++ return 0x%08x\n", (unsigned int)range->addr.virtual); +          if (g_arch_instruction_is_return(iter))          {              iter = NULL;              break;          } +        /* +        if (!g_arch_instruction_has_destinations(iter)) +            printf("  ++ no dest 0x%08x\n", (unsigned int)range->addr.virtual); +        */ +          if (!g_arch_instruction_has_destinations(iter))              continue; + +        printf("  ++ dcount 0x%08x\n", (unsigned int)range->addr.virtual); +          dcount = g_arch_instruction_get_destinations(iter, &dests, &types, NULL); +        not_handled = 0; +          for (i = 0; i < dcount; i++)          {              range = g_arch_instruction_get_range(dests[i]); @@ -577,19 +614,23 @@ static void find_next_hops(GArchInstruction *instrs, const vmpa2t *start, const                      break;                  default: +                    not_handled++;                      break;              }          } -        break; +        if (not_handled < dcount) +            break;      }      /* Si on termine... */      if (iter != NULL) add_hop_into_branch(info, get_mrange_addr(range)); +    printf(" ------- [ %p ] ---\n", info); +  } @@ -614,6 +655,20 @@ static bool compute_first_common_addr(const branch_info *a, const branch_info *b      result = false; + +    printf("....................\n"); + +    printf(" A :: "); +    for (i = 0; i < a->count; i++) +        printf("0x%08x ", a->hops[i].virtual); +    printf("\n"); + +    printf(" B :: "); +    for (i = 0; i < b->count; i++) +        printf("0x%08x ", b->hops[i].virtual); +    printf("\n"); + +      for (i = 0; i < a->count && !result; i++)          if (is_addr_in_branch(b, &a->hops[i]))          { @@ -621,6 +676,13 @@ static bool compute_first_common_addr(const branch_info *a, const branch_info *b              copy_vmpa(c, &a->hops[i]);          } +    if (result) +        printf(" N :: 0x%08x\n", (unsigned int)c->virtual); +    else +        printf(" N :: ----\n"); + +    printf("....................\n"); +      return result;  } @@ -862,6 +924,7 @@ static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_      GInstrBlock *block;                     /* Nouveau bloc mis en place   */      has_common = compute_first_common_addr(true_branch, false_branch, next); +    if (!has_common) printf("   === nothing in common\n");      if (!has_common) return NULL;      result = g_virtual_block_new(); @@ -980,7 +1043,7 @@ static void add_instruction_blocks_except(GInstrBlock **result, GInstrBlock **ca  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ - +#include "../../arch/instruction-int.h"  static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_coverage *coverage)  {      GInstrBlock *result;                    /* Regroupement à retourner    */ @@ -1059,11 +1122,25 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove                  case ILT_EXEC_FLOW:                  case ILT_JUMP: + +                    //break; +                { +                    GArchInstruction *_saved0; + +                    _saved0 = first; +                      block = build_instruction_block_simple(instrs, coverage, &first, iter); +                    printf(" -- simple block JMP -- @ 0x%08x <-> 0x%08x\n", +                           (unsigned int)(_saved0 ? _saved0->range.addr.virtual : ~0), +                           (unsigned int)iter->range.addr.virtual); +                    fflush(NULL); +                }                      DELAYED_BLOCK_ADDING(result, result_cached, block);                      range = g_arch_instruction_get_range(iter); -                    copy_vmpa(&next_addr, get_mrange_addr(range)); +                    compute_mrange_end_addr(range, &next_addr); + +                    first = NULL;                      break; @@ -1072,10 +1149,12 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove                      break;                  case ILT_JUMP_IF_TRUE: +                    printf("FIND TRUE BRANCH @ 0x%08x\n", (unsigned int)iter->range.addr.virtual);                      branch = &true_branch;                      break;                  case ILT_JUMP_IF_FALSE: +                    printf("FIND FALSE BRANCH @ 0x%08x\n", (unsigned int)iter->range.addr.virtual);                      branch = &false_branch;                      break; @@ -1097,10 +1176,13 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove              /* Si on a une branche à compléter... */              if (branch != NULL)              { -                range = g_arch_instruction_get_range(iter); +                range = g_arch_instruction_get_range(dests[i]);                  addr = get_mrange_addr(range); +                printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); +                printf("BUILD @ 0x%08x\n", (unsigned int)addr->virtual);                  find_next_hops(instrs, addr, coverage, branch); +                printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");              } @@ -1126,10 +1208,25 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove          else if (true_branch.count > 0 || false_branch.count > 0)          {              block = build_instruction_block_simple(instrs, coverage, &first, iter); + +            GArchInstruction *_saved1; + +            _saved1 = first; + + + +            printf(" -- branches -- %d vs %d\n", (int)true_branch.count, (int)false_branch.count); + +            printf(" -- simple block ITE -- @ 0x%08x <-> 0x%08x\n", +                   (unsigned int)(_saved1 ? _saved1->range.addr.virtual : ~0), +                   (unsigned int)iter->range.addr.virtual); +            fflush(NULL);              DELAYED_BLOCK_ADDING(result, result_cached, block);              group = build_instruction_blocks_ite(instrs, coverage, &true_branch, &false_branch, &next_addr); +            printf(" --> group = %p  -  next = 0x%08x\n", group, next_addr.virtual); +              if (group != NULL)              {                  DELAYED_BLOCK_ADDING(result, result_cached, group); diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am index 33747fb..aab7ec8 100644 --- a/src/arch/Makefile.am +++ b/src/arch/Makefile.am @@ -9,6 +9,7 @@ libarch_la_SOURCES =					\  	immediate.h immediate.c				\  	instruction-int.h					\  	instruction.h instruction.c			\ +	link.h link.c						\  	operand-int.h						\  	operand.h operand.c					\  	processor-int.h						\ diff --git a/src/arch/arm/v7/Makefile.am b/src/arch/arm/v7/Makefile.am index 22e93d4..f9b35b6 100644 --- a/src/arch/arm/v7/Makefile.am +++ b/src/arch/arm/v7/Makefile.am @@ -4,9 +4,9 @@ noinst_LTLIBRARIES = libarcharmv7.la  libarcharmv7_la_SOURCES =				\  	arm.h arm.c							\  	context.h context.c					\ +	fetch.h fetch.c						\  	helpers.h helpers.c					\  	instruction.h instruction.c			\ -	link.h link.c						\  	post.h post.c						\  	processor.h processor.c				\  	pseudo.h pseudo.c					\ diff --git a/src/arch/arm/v7/link.c b/src/arch/arm/v7/fetch.c index 308d4e5..18d61f0 100644 --- a/src/arch/arm/v7/link.c +++ b/src/arch/arm/v7/fetch.c @@ -1,6 +1,6 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * post.c - traitements complémentaires à la phase de désassemblage + * fetch.c - traitements complémentaires à la phase de désassemblage   *   * Copyright (C) 2014 Cyrille Bagard   * @@ -21,7 +21,7 @@   */ -#include "link.h" +#include "fetch.h"  #include <assert.h> @@ -40,6 +40,7 @@  /******************************************************************************  *                                                                             *  *  Paramètres  : instr   = instruction ARMv7 à traiter.                       * +*                proc    = représentation de l'architecture utilisée.         *  *                context = contexte associé à la phase de désassemblage.      *  *                format  = acès aux données du binaire d'origine.             *  *                iset    = type de jeu d'instructions courant à faire suivre. * @@ -52,7 +53,7 @@  *                                                                             *  ******************************************************************************/ -void handle_links_with_instruction_b_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset) +void help_fetching_with_instruction_b_with_orig(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)  {      const mrange_t *range;                  /* Emplacementt d'instruction  */      virt_t pc;                              /* Position dans l'exécution   */ @@ -106,6 +107,7 @@ void handle_links_with_instruction_b_with_orig(GArchInstruction *instr, GArmV7Co  /******************************************************************************  *                                                                             *  *  Paramètres  : instr   = instruction ARMv7 à traiter.                       * +*                proc    = représentation de l'architecture utilisée.         *  *                context = contexte associé à la phase de désassemblage.      *  *                format  = acès aux données du binaire d'origine.             *  *                iset    = type de jeu d'instructions courant à faire suivre. * @@ -118,7 +120,7 @@ void handle_links_with_instruction_b_with_orig(GArchInstruction *instr, GArmV7Co  *                                                                             *  ******************************************************************************/ -void handle_links_with_instruction_bl_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset) +void help_fetching_with_instruction_bl_with_orig(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)  {      const mrange_t *range;                  /* Emplacementt d'instruction  */      virt_t pc;                              /* Position dans l'exécution   */ @@ -163,6 +165,7 @@ void handle_links_with_instruction_bl_with_orig(GArchInstruction *instr, GArmV7C  /******************************************************************************  *                                                                             *  *  Paramètres  : instr   = instruction ARMv7 à traiter.                       * +*                proc    = représentation de l'architecture utilisée.         *  *                context = contexte associé à la phase de désassemblage.      *  *                format  = acès aux données du binaire d'origine.             *  *                iset    = type de jeu d'instructions courant à inverser.     * @@ -175,7 +178,7 @@ void handle_links_with_instruction_bl_with_orig(GArchInstruction *instr, GArmV7C  *                                                                             *  ******************************************************************************/ -void handle_links_with_instruction_blx_with_dest(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset) +void help_fetching_with_instruction_blx_with_dest(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)  {      const mrange_t *range;                  /* Emplacementt d'instruction  */      virt_t pc;                              /* Position dans l'exécution   */ @@ -221,6 +224,7 @@ void handle_links_with_instruction_blx_with_dest(GArchInstruction *instr, GArmV7  /******************************************************************************  *                                                                             *  *  Paramètres  : instr   = instruction ARMv7 à traiter.                       * +*                proc    = représentation de l'architecture utilisée.         *  *                context = contexte associé à la phase de désassemblage.      *  *                format  = acès aux données du binaire d'origine.             *  *                iset    = type de jeu d'instructions courant à faire suivre. * @@ -233,7 +237,7 @@ void handle_links_with_instruction_blx_with_dest(GArchInstruction *instr, GArmV7  *                                                                             *  ******************************************************************************/ -void handle_links_with_instruction_bx_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset) +void help_fetching_with_instruction_bx_with_orig(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)  {      GArchOperand *op;                       /* Opérande numérique en place */      GArmRegister *reg;                      /* Registre matériel manipulé  */ @@ -283,6 +287,7 @@ void handle_links_with_instruction_bx_with_orig(GArchInstruction *instr, GArmV7C  /******************************************************************************  *                                                                             *  *  Paramètres  : instr   = instruction ARMv7 à traiter.                       * +*                proc    = représentation de l'architecture utilisée.         *  *                context = contexte associé à la phase de désassemblage.      *  *                format  = acès aux données du binaire d'origine.             *  *                                                                             * @@ -294,7 +299,7 @@ void handle_links_with_instruction_bx_with_orig(GArchInstruction *instr, GArmV7C  *                                                                             *  ******************************************************************************/ -void handle_links_with_instruction_cb_n_z(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format) +void help_fetching_with_instruction_cb_n_z(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GBinFormat *format)  {      const mrange_t *range;                  /* Emplacementt d'instruction  */      virt_t pc;                              /* Position dans l'exécution   */ @@ -334,6 +339,7 @@ void handle_links_with_instruction_cb_n_z(GArchInstruction *instr, GArmV7Context  /******************************************************************************  *                                                                             *  *  Paramètres  : instr   = instruction ARMv7 à traiter.                       * +*                proc    = représentation de l'architecture utilisée.         *  *                context = contexte associé à la phase de désassemblage.      *  *                format  = acès aux données du binaire d'origine.             *  *                iset    = type de jeu d'instructions courant à inverser.     * @@ -346,7 +352,7 @@ void handle_links_with_instruction_cb_n_z(GArchInstruction *instr, GArmV7Context  *                                                                             *  ******************************************************************************/ -void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset) +void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)  {      const mrange_t *range;                  /* Emplacementt d'instruction  */      phys_t phys_pc;                         /* Position dans l'exécution   */ diff --git a/src/arch/arm/v7/fetch.h b/src/arch/arm/v7/fetch.h new file mode 100644 index 0000000..af42f2e --- /dev/null +++ b/src/arch/arm/v7/fetch.h @@ -0,0 +1,113 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * fetch.h - prototypes pour l'édition des liens durant la phase de désassemblage + * + * Copyright (C) 2014 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_ARM_V7_FETCH_H +#define _ARCH_ARM_V7_FETCH_H + + +#include "context.h" +#include "../../instruction.h" +#include "../../../format/format.h" + + + +/* Complète un désassemblage accompli pour une instruction. */ +void help_fetching_with_instruction_b_with_orig(GArchInstruction *, GArchProcessor *, GArmV7Context *, GBinFormat *, ArmV7InstrSet); + + +static inline void help_fetching_with_instruction_b_from_arm(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt) +{ +    help_fetching_with_instruction_b_with_orig(ins, proc, ctx, fmt, AV7IS_ARM); +} + +static inline void help_fetching_with_instruction_b_from_thumb(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt) +{ +    help_fetching_with_instruction_b_with_orig(ins, proc, ctx, fmt, AV7IS_THUMB); +} + + +/* Complète un désassemblage accompli pour une instruction. */ +void help_fetching_with_instruction_bl_with_orig(GArchInstruction *, GArchProcessor *, GArmV7Context *, GBinFormat *, ArmV7InstrSet); + + +static inline void help_fetching_with_instruction_bl_from_arm(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt) +{ +    help_fetching_with_instruction_bl_with_orig(ins, proc, ctx, fmt, AV7IS_ARM); +} + +static inline void help_fetching_with_instruction_bl_from_thumb(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt) +{ +    help_fetching_with_instruction_bl_with_orig(ins, proc, ctx, fmt, AV7IS_THUMB); +} + + +/* Complète un désassemblage accompli pour une instruction. */ +void help_fetching_with_instruction_blx_with_dest(GArchInstruction *, GArchProcessor *, GArmV7Context *, GBinFormat *, ArmV7InstrSet); + + +static inline void help_fetching_with_instruction_blx_from_arm(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt) +{ +    help_fetching_with_instruction_blx_with_dest(ins, proc, ctx, fmt, AV7IS_THUMB); +} + +static inline void help_fetching_with_instruction_blx_from_thumb(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt) +{ +    help_fetching_with_instruction_blx_with_dest(ins, proc, ctx, fmt, AV7IS_ARM); +} + + +/* Complète un désassemblage accompli pour une instruction. */ +void help_fetching_with_instruction_bx_with_orig(GArchInstruction *, GArchProcessor *, GArmV7Context *, GBinFormat *, ArmV7InstrSet); + + +static inline void help_fetching_with_instruction_bx_from_arm(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt) +{ +    help_fetching_with_instruction_bx_with_orig(ins, proc, ctx, fmt, AV7IS_ARM); +} + +static inline void help_fetching_with_instruction_bx_from_thumb(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt) +{ +    help_fetching_with_instruction_bx_with_orig(ins, proc, ctx, fmt, AV7IS_THUMB); +} + + +/* Complète un désassemblage accompli pour une instruction. */ +void help_fetching_with_instruction_cb_n_z(GArchInstruction *, GArchProcessor *, GArmV7Context *, GBinFormat *); + +/* Complète un désassemblage accompli pour une instruction. */ +void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *, GArchProcessor *, GArmV7Context *, GBinFormat *, ArmV7InstrSet); + + +static inline void help_fetching_with_instruction_ldr_literal_from_arm(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt) +{ +    help_fetching_with_instruction_ldr_literal_with_orig(ins, proc, ctx, fmt, AV7IS_ARM); +} + +static inline void help_fetching_with_instruction_ldr_literal_from_thumb(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt) +{ +    help_fetching_with_instruction_ldr_literal_with_orig(ins, proc, ctx, fmt, AV7IS_THUMB); +} + + + +#endif  /* _ARCH_ARM_V7_FETCH_H */ diff --git a/src/arch/arm/v7/link.h b/src/arch/arm/v7/link.h deleted file mode 100644 index 9e52fe6..0000000 --- a/src/arch/arm/v7/link.h +++ /dev/null @@ -1,113 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * link.h - prototypes pour l'édition des liens durant la phase de désassemblage - * - * Copyright (C) 2014 Cyrille Bagard - * - *  This file is part of Chrysalide. - * - *  OpenIDA is free software; you can redistribute it and/or modify - *  it under the terms of the GNU General Public License as published by - *  the Free Software Foundation; either version 3 of the License, or - *  (at your option) any later version. - * - *  OpenIDA is distributed in the hope that it will be useful, - *  but WITHOUT ANY WARRANTY; without even the implied warranty of - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *  GNU General Public License for more details. - * - *  You should have received a copy of the GNU General Public License - *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. - */ - - -#ifndef _ARCH_ARM_V7_LINK_H -#define _ARCH_ARM_V7_LINK_H - - -#include "context.h" -#include "../../instruction.h" -#include "../../../format/format.h" - - - -/* Complète un désassemblage accompli pour une instruction. */ -void handle_links_with_instruction_b_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet); - - -static inline void handle_links_with_instruction_b_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt) -{ -    handle_links_with_instruction_b_with_orig(ins, ctx, fmt, AV7IS_ARM); -} - -static inline void handle_links_with_instruction_b_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt) -{ -    handle_links_with_instruction_b_with_orig(ins, ctx, fmt, AV7IS_THUMB); -} - - -/* Complète un désassemblage accompli pour une instruction. */ -void handle_links_with_instruction_bl_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet); - - -static inline void handle_links_with_instruction_bl_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt) -{ -    handle_links_with_instruction_bl_with_orig(ins, ctx, fmt, AV7IS_ARM); -} - -static inline void handle_links_with_instruction_bl_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt) -{ -    handle_links_with_instruction_bl_with_orig(ins, ctx, fmt, AV7IS_THUMB); -} - - -/* Complète un désassemblage accompli pour une instruction. */ -void handle_links_with_instruction_blx_with_dest(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet); - - -static inline void handle_links_with_instruction_blx_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt) -{ -    handle_links_with_instruction_blx_with_dest(ins, ctx, fmt, AV7IS_THUMB); -} - -static inline void handle_links_with_instruction_blx_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt) -{ -    handle_links_with_instruction_blx_with_dest(ins, ctx, fmt, AV7IS_ARM); -} - - -/* Complète un désassemblage accompli pour une instruction. */ -void handle_links_with_instruction_bx_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet); - - -static inline void handle_links_with_instruction_bx_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt) -{ -    handle_links_with_instruction_bx_with_orig(ins, ctx, fmt, AV7IS_ARM); -} - -static inline void handle_links_with_instruction_bx_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt) -{ -    handle_links_with_instruction_bx_with_orig(ins, ctx, fmt, AV7IS_THUMB); -} - - -/* Complète un désassemblage accompli pour une instruction. */ -void handle_links_with_instruction_cb_n_z(GArchInstruction *, GArmV7Context *, GBinFormat *); - -/* Complète un désassemblage accompli pour une instruction. */ -void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet); - - -static inline void handle_links_with_instruction_ldr_literal_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt) -{ -    handle_links_with_instruction_ldr_literal_with_orig(ins, ctx, fmt, AV7IS_ARM); -} - -static inline void handle_links_with_instruction_ldr_literal_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt) -{ -    handle_links_with_instruction_ldr_literal_with_orig(ins, ctx, fmt, AV7IS_THUMB); -} - - - -#endif  /* _ARCH_ARM_V7_LINK_H */ diff --git a/src/arch/arm/v7/opdefs/Makefile.am b/src/arch/arm/v7/opdefs/Makefile.am index 318e20b..b95b588 100644 --- a/src/arch/arm/v7/opdefs/Makefile.am +++ b/src/arch/arm/v7/opdefs/Makefile.am @@ -106,7 +106,7 @@ fmk.done: $(ARMV7_DEFS)  fix_includes_in_c_templates:  	@for f in `find .gen/ -name '*tmpl.c'`; do			\  		if grep -q '##INCLUDES##' $$f; then				\ -			$(fix_verbose)sed -i 's/##INCLUDES##/\n#include "..\/helpers.h"\n#include "..\/instruction.h"\n#include "..\/link.h"\n#include "..\/post.h"\n#include "..\/..\/instruction.h"\n#include "..\/..\/..\/..\/common\/bconst.h"\n\n/' $$f;	\ +			$(fix_verbose)sed -i 's/##INCLUDES##/\n#include "..\/helpers.h"\n#include "..\/instruction.h"\n#include "..\/fetch.h"\n#include "..\/post.h"\n#include "..\/..\/instruction.h"\n#include "..\/..\/..\/link.h"\n#include "..\/..\/..\/..\/common\/bconst.h"\n\n/' $$f;	\  		fi;												\  	done diff --git a/src/arch/arm/v7/opdefs/b_A8818.d b/src/arch/arm/v7/opdefs/b_A8818.d index 50bdda9..a275177 100644 --- a/src/arch/arm/v7/opdefs/b_A8818.d +++ b/src/arch/arm/v7/opdefs/b_A8818.d @@ -38,7 +38,8 @@      @hooks { -        link = handle_links_with_instruction_b_from_thumb +        fetch = help_fetching_with_instruction_b_from_thumb +        link = handle_branch_if_true_as_link          post = post_process_branch_instructions      } @@ -47,7 +48,7 @@          //if cond == '1110' then UNDEFINED;          //if cond == '1111' then SEE SVC; -        chk_call DefineAsReturn(1) +        //chk_call DefineAsReturn(1)      } @@ -67,7 +68,8 @@      @hooks { -        link = handle_links_with_instruction_b_from_thumb +        fetch = help_fetching_with_instruction_b_from_thumb +        link = handle_branch_if_true_as_link          post = post_process_branch_instructions      } @@ -75,7 +77,7 @@      @rules {          //if InITBlock() && !LastInITBlock() then UNPREDICTABLE; -        chk_call DefineAsReturn(1) +        //chk_call DefineAsReturn(1)      } @@ -96,7 +98,8 @@      @hooks { -        link = handle_links_with_instruction_b_from_thumb +        fetch = help_fetching_with_instruction_b_from_thumb +        link = handle_branch_if_true_as_link          post = post_process_branch_instructions      } @@ -105,7 +108,7 @@          //if cond<3:1> == '111' then SEE "Related encodings";          //if InITBlock() then UNPREDICTABLE; -        chk_call DefineAsReturn(1) +        //chk_call DefineAsReturn(1)      } @@ -127,7 +130,8 @@      @hooks { -        link = handle_links_with_instruction_b_from_thumb +        fetch = help_fetching_with_instruction_b_from_thumb +        link = handle_branch_if_true_as_link          post = post_process_branch_instructions      } @@ -135,7 +139,7 @@      @rules {          //if InITBlock() && !LastInITBlock() then UNPREDICTABLE; -        chk_call DefineAsReturn(1) +        //chk_call DefineAsReturn(1)      } @@ -156,14 +160,15 @@      @hooks { -        link = handle_links_with_instruction_b_from_arm +        fetch = help_fetching_with_instruction_b_from_arm +        link = handle_branch_if_true_as_link          post = post_process_branch_instructions      }      @rules { -        chk_call DefineAsReturn(1) +        //chk_call DefineAsReturn(1)      } diff --git a/src/arch/arm/v7/opdefs/bl_A8825.d b/src/arch/arm/v7/opdefs/bl_A8825.d index 63922dd..62ac8f9 100644 --- a/src/arch/arm/v7/opdefs/bl_A8825.d +++ b/src/arch/arm/v7/opdefs/bl_A8825.d @@ -39,7 +39,7 @@      @hooks { -        link = handle_links_with_instruction_bl_from_thumb +        fetch = help_fetching_with_instruction_bl_from_thumb          post = post_process_branch_and_link_instructions      } @@ -68,7 +68,7 @@      @hooks { -        link = handle_links_with_instruction_blx_from_thumb +        fetch = help_fetching_with_instruction_blx_from_thumb          post = post_process_branch_and_link_instructions      } @@ -95,7 +95,7 @@      @hooks { -        link = handle_links_with_instruction_bl_from_arm +        fetch = help_fetching_with_instruction_bl_from_arm          post = post_process_branch_and_link_instructions      } @@ -122,7 +122,7 @@      @hooks { -        link = handle_links_with_instruction_blx_from_arm +        fetch = help_fetching_with_instruction_blx_from_arm          post = post_process_branch_and_link_instructions      } diff --git a/src/arch/arm/v7/opdefs/bx_A8827.d b/src/arch/arm/v7/opdefs/bx_A8827.d index 4856885..f8027a4 100644 --- a/src/arch/arm/v7/opdefs/bx_A8827.d +++ b/src/arch/arm/v7/opdefs/bx_A8827.d @@ -38,7 +38,7 @@      @hooks { -        link = handle_links_with_instruction_bx_from_thumb +        fetch = help_fetching_with_instruction_bx_from_thumb      } @@ -65,7 +65,7 @@      @hooks { -        link = handle_links_with_instruction_bx_from_thumb +        fetch = help_fetching_with_instruction_bx_from_thumb      } diff --git a/src/arch/arm/v7/opdefs/cbnz_A8829.d b/src/arch/arm/v7/opdefs/cbnz_A8829.d index 93a8d1f..d9815c1 100644 --- a/src/arch/arm/v7/opdefs/cbnz_A8829.d +++ b/src/arch/arm/v7/opdefs/cbnz_A8829.d @@ -38,7 +38,7 @@      @hooks { -        link = handle_links_with_instruction_cb_n_z +        fetch = help_fetching_with_instruction_cb_n_z          post = post_process_comp_and_branch_instructions      } @@ -60,7 +60,7 @@      @hooks { -        link = handle_links_with_instruction_cb_n_z +        fetch = help_fetching_with_instruction_cb_n_z          post = post_process_comp_and_branch_instructions      } diff --git a/src/arch/arm/v7/opdefs/ldr_A8864.d b/src/arch/arm/v7/opdefs/ldr_A8864.d index c5b0dd0..4cf0048 100644 --- a/src/arch/arm/v7/opdefs/ldr_A8864.d +++ b/src/arch/arm/v7/opdefs/ldr_A8864.d @@ -39,7 +39,7 @@      @hooks { -        link = handle_links_with_instruction_ldr_literal_from_thumb +        fetch = help_fetching_with_instruction_ldr_literal_from_thumb          post = post_process_ldr_instructions      } @@ -62,7 +62,7 @@      @hooks { -        link = handle_links_with_instruction_ldr_literal_from_thumb +        fetch = help_fetching_with_instruction_ldr_literal_from_thumb          post = post_process_ldr_instructions      } @@ -93,7 +93,7 @@      @hooks { -        link = handle_links_with_instruction_ldr_literal_from_arm +        fetch = help_fetching_with_instruction_ldr_literal_from_arm          post = post_process_ldr_instructions      } diff --git a/src/arch/arm/v7/opdefs/pop_A88131.d b/src/arch/arm/v7/opdefs/pop_A88131.d index 2663e1b..ef5ab25 100644 --- a/src/arch/arm/v7/opdefs/pop_A88131.d +++ b/src/arch/arm/v7/opdefs/pop_A88131.d @@ -39,6 +39,7 @@          //if BitCount(registers) < 1 then UNPREDICTABLE;          //if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; +        chk_call DefineAsReturn(1)      } @@ -60,6 +61,7 @@          //if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;          //if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; +        chk_call DefineAsReturn(1)      } @@ -81,6 +83,7 @@      @rules {          //if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; +        chk_call DefineAsReturn(1)      } diff --git a/src/arch/arm/v7/opdefs/pop_A88132.d b/src/arch/arm/v7/opdefs/pop_A88132.d index 0c6c1b0..89c51c9 100644 --- a/src/arch/arm/v7/opdefs/pop_A88132.d +++ b/src/arch/arm/v7/opdefs/pop_A88132.d @@ -40,6 +40,7 @@          //if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;          //if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; +        chk_call DefineAsReturn(1)      } @@ -62,6 +63,7 @@      @rules {          //if t == 13 then UNPREDICTABLE; +        chk_call DefineAsReturn(1)      } diff --git a/src/arch/arm/v7/post.c b/src/arch/arm/v7/post.c index e6a6c2e..23d0198 100644 --- a/src/arch/arm/v7/post.c +++ b/src/arch/arm/v7/post.c @@ -34,6 +34,7 @@  /******************************************************************************  *                                                                             *  *  Paramètres  : instr   = instruction ARMv7 à traiter.                       * +*                proc    = représentation de l'architecture utilisée.         *  *                context = contexte associé à la phase de désassemblage.      *  *                format  = accès aux données du binaire d'origine.            *  *                                                                             * @@ -45,7 +46,7 @@  *                                                                             *  ******************************************************************************/ -void post_process_branch_instructions(GArchInstruction *instr, GProcContext *context, GBinFormat *format) +void post_process_branch_instructions(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)  {      GArchOperand *op;                       /* Opérande numérique en place */      uint32_t addr;                          /* Adresse visée par le saut   */ @@ -97,6 +98,7 @@ void post_process_branch_instructions(GArchInstruction *instr, GProcContext *con  /******************************************************************************  *                                                                             *  *  Paramètres  : instr   = instruction ARMv7 à traiter.                       * +*                proc    = représentation de l'architecture utilisée.         *  *                context = contexte associé à la phase de désassemblage.      *  *                format  = accès aux données du binaire d'origine.            *  *                                                                             * @@ -108,7 +110,7 @@ void post_process_branch_instructions(GArchInstruction *instr, GProcContext *con  *                                                                             *  ******************************************************************************/ -void post_process_branch_and_link_instructions(GArchInstruction *instr, GProcContext *context, GBinFormat *format) +void post_process_branch_and_link_instructions(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)  {      GArchOperand *op;                       /* Opérande numérique en place */      uint32_t addr;                          /* Adresse visée par le saut   */ @@ -160,6 +162,7 @@ void post_process_branch_and_link_instructions(GArchInstruction *instr, GProcCon  /******************************************************************************  *                                                                             *  *  Paramètres  : instr   = instruction ARMv7 à traiter.                       * +*                proc    = représentation de l'architecture utilisée.         *  *                context = contexte associé à la phase de désassemblage.      *  *                format  = accès aux données du binaire d'origine.            *  *                                                                             * @@ -171,7 +174,7 @@ void post_process_branch_and_link_instructions(GArchInstruction *instr, GProcCon  *                                                                             *  ******************************************************************************/ -void post_process_comp_and_branch_instructions(GArchInstruction *instr, GProcContext *context, GBinFormat *format) +void post_process_comp_and_branch_instructions(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)  {      GArchOperand *op;                       /* Opérande numérique en place */      uint32_t addr;                          /* Adresse visée par le saut   */ @@ -223,6 +226,7 @@ void post_process_comp_and_branch_instructions(GArchInstruction *instr, GProcCon  /******************************************************************************  *                                                                             *  *  Paramètres  : instr   = instruction ARMv7 à traiter.                       * +*                proc    = représentation de l'architecture utilisée.         *  *                context = contexte associé à la phase de désassemblage.      *  *                format  = accès aux données du binaire d'origine.            *  *                                                                             * @@ -234,7 +238,7 @@ void post_process_comp_and_branch_instructions(GArchInstruction *instr, GProcCon  *                                                                             *  ******************************************************************************/ -void post_process_ldr_instructions(GArchInstruction *instr, GProcContext *context, GBinFormat *format) +void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)  {      GArchOperand *op;                       /* Opérande numérique en place */      uint32_t addr;                          /* Adresse visée par le saut   */ diff --git a/src/arch/arm/v7/post.h b/src/arch/arm/v7/post.h index 79dcaa8..6165597 100644 --- a/src/arch/arm/v7/post.h +++ b/src/arch/arm/v7/post.h @@ -31,16 +31,16 @@  /* Complète un désassemblage accompli pour une instruction. */ -void post_process_branch_instructions(GArchInstruction *, GProcContext *, GBinFormat *); +void post_process_branch_instructions(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);  /* Complète un désassemblage accompli pour une instruction. */ -void post_process_branch_and_link_instructions(GArchInstruction *, GProcContext *, GBinFormat *); +void post_process_branch_and_link_instructions(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);  /* Complète un désassemblage accompli pour une instruction. */ -void post_process_comp_and_branch_instructions(GArchInstruction *, GProcContext *, GBinFormat *); +void post_process_comp_and_branch_instructions(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);  /* Complète un désassemblage accompli pour une instruction. */ -void post_process_ldr_instructions(GArchInstruction *, GProcContext *, GBinFormat *); +void post_process_ldr_instructions(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *); diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 0bcc739..08256d1 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -234,6 +234,7 @@ void g_arch_instruction_set_hook(GArchInstruction *instr, InstrProcessHook type,  *                                                                             *  *  Paramètres  : instr   = instruction quelconque à traiter.                  *  *                type    = type de procédure à utiliser.                      * +*                proc    = représentation de l'architecture utilisée.         *  *                context = contexte associé à la phase de désassemblage.      *  *                format  = accès aux données du binaire d'origine.            *  *                                                                             * @@ -245,12 +246,15 @@ void g_arch_instruction_set_hook(GArchInstruction *instr, InstrProcessHook type,  *                                                                             *  ******************************************************************************/ -void g_arch_instruction_call_hook(GArchInstruction *instr, InstrProcessHook type, GProcContext *context, GBinFormat *format) +void g_arch_instruction_call_hook(GArchInstruction *instr, InstrProcessHook type, GArchProcessor *proc, GProcContext *context, GBinFormat *format)  { +    if (instr->range.addr.virtual == 0x83c2) +        printf(" [%u] HAS BRANCH ? %p\n", (unsigned int)type, instr->hooks[type]); +      assert(type < IPH_COUNT);      if (instr->hooks[type] != NULL) -        instr->hooks[type](instr, context, format); +        instr->hooks[type](instr, proc, context, format);  } diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 9251a34..0198bb5 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -76,22 +76,29 @@ void g_arch_instruction_set_flag(GArchInstruction *, ArchInstrFlag);  /* Fournit les informations complémentaires d'une instruction. */  ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *); +  /**   * La définition de "GBinFormat", utile aux traitements complémentaires, ne peut   * se faire en incluant le fichier d'en-tête "../format/format.h", pour cause   * de références circulaires.   *   * On procède donc à une seconde déclaration, en attendant éventuellement mieux. + * + * Pareil pour "GArchProcessor", définie dans le fichier "processor.h", lequel + * inclut directement ce fichier.   */ -  /* Format binaire générique (instance) */  typedef struct _GBinFormat GBinFormat; +/* Ligne de représentation générique (instance) */ +typedef struct _GArchProcessor GArchProcessor; +  /* Types de crochet de traitement */  typedef enum _InstrProcessHook  { +    IPH_FETCH,                              /* Itinéraire de désassemblage */      IPH_LINK,                               /* Edition des liens           */      IPH_POST,                               /* Résolution des symboles     */ @@ -100,13 +107,13 @@ typedef enum _InstrProcessHook  } InstrProcessHook;  /* Complète un désassemblage accompli pour une instruction. */ -typedef void (* instr_hook_fc) (GArchInstruction *, GProcContext *, GBinFormat *); +typedef void (* instr_hook_fc) (GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);  /* Définit un traitement complémentare au désassemblage. */  void g_arch_instruction_set_hook(GArchInstruction *, InstrProcessHook, instr_hook_fc);  /* Complète un désassemblage accompli pour une instruction. */ -void g_arch_instruction_call_hook(GArchInstruction *, InstrProcessHook, GProcContext *, GBinFormat *); +void g_arch_instruction_call_hook(GArchInstruction *, InstrProcessHook, GArchProcessor *, GProcContext *, GBinFormat *);  /* Définit la localisation d'une instruction. */  void g_arch_instruction_set_range(GArchInstruction *, const mrange_t *); @@ -155,7 +162,8 @@ typedef enum _InstructionLinkType      ILT_JUMP_IF_FALSE,                      /* Saut conditionnel (si faux) */      ILT_LOOP,                               /* Retour en arrière (boucle)  */      ILT_CALL,                               /* Appel d'une fonction        */ -    ILT_CATCH_EXCEPTION                     /* Gestion d'une exception     */ +    ILT_CATCH_EXCEPTION,                    /* Gestion d'une exception     */ +    ILT_REF                                 /* Simple référence croisée    */  } InstructionLinkType; diff --git a/src/arch/link.c b/src/arch/link.c new file mode 100644 index 0000000..bc80e39 --- /dev/null +++ b/src/arch/link.c @@ -0,0 +1,190 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * link.c - édition des liens après la phase de désassemblage + * + * Copyright (C) 2014 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "link.h" + + +#include <assert.h> + + +#include "target.h" + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr   = instruction ARMv7 à traiter.                       * +*                proc    = représentation de l'architecture utilisée.         * +*                context = contexte associé à la phase de désassemblage.      * +*                format  = acès aux données du binaire d'origine.             * +*                                                                             * +*  Description : Etablit un lien de saut selon une instruction donnée.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void handle_jump_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format) +{ +    GArchOperand *op;                       /* Opérande numérique en place */ +    virt_t virt;                            /* Adresse virtuelle           */ +    vmpa2t addr;                            /* Adresse de destination      */ +    GArchInstruction *target;               /* Ligne visée par la référence*/ + +    assert(g_arch_instruction_count_operands(instr) > 0); + +    op = g_arch_instruction_get_operand(instr, 0); + +    if (!G_IS_IMM_OPERAND(op)) return; + +    if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt)) +    { +        init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); + +        target = g_arch_processor_find_instr_by_address(proc, &addr); + +        if (target != NULL) +            g_arch_instruction_link_with(instr, target, ILT_JUMP); + +    } + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr   = instruction ARMv7 à traiter.                       * +*                proc    = représentation de l'architecture utilisée.         * +*                context = contexte associé à la phase de désassemblage.      * +*                format  = acès aux données du binaire d'origine.             * +*                                                                             * +*  Description : Etablit un lien d'appel selon une instruction donnée.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ +#include "instruction-int.h" +void handle_branch_if_true_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format) +{ +    GArchOperand *op;                       /* Opérande numérique en place */ +    virt_t virt;                            /* Adresse virtuelle           */ +    vmpa2t addr;                            /* Adresse de destination      */ +    GArchInstruction *target;               /* Ligne visée par la référence*/ +    GArchInstruction *list;                 /* Ensemble des instructions   */ + +    assert(g_arch_instruction_count_operands(instr) > 0); + +    op = g_arch_instruction_get_operand(instr, 0); + +    virt = VMPA_NO_VIRTUAL; + +    if (G_IS_TARGET_OPERAND(op)) +        virt = g_target_operand_get_addr(G_TARGET_OPERAND(op)); + +    else if (G_IS_IMM_OPERAND(op)) +    { +        if (!g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt)) +            virt = VMPA_NO_VIRTUAL; +    } + +    if (virt != VMPA_NO_VIRTUAL) +    { +        /* TODO : utiliser format pour contruire une adresse avec une position physique, +         * ce qui accélèrerait les recherches. +         */ +        init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); + +        target = g_arch_processor_find_instr_by_address(proc, &addr); + +        printf(" @ 0x%08x BRANCH to 0x%08x -->> %p\n", +               (unsigned int)instr->range.addr.virtual, (unsigned int)virt, target); + +        if (target != NULL) +        { +            g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_TRUE); + +            list = g_arch_processor_get_disassembled_instructions(proc); + +            target = g_arch_instruction_get_next_iter(list, instr, ~0); + +            if (target != NULL) +                g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_FALSE); + +        } + +    } + + +    else printf(" @ 0x%08x FAILED TO BRANCH\n", +                (unsigned int)instr->range.addr.virtual); + + + + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr   = instruction ARMv7 à traiter.                       * +*                proc    = représentation de l'architecture utilisée.         * +*                context = contexte associé à la phase de désassemblage.      * +*                format  = acès aux données du binaire d'origine.             * +*                                                                             * +*  Description : Etablit un lien d'appel selon une instruction donnée.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void handle_call_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format) +{ +    GArchOperand *op;                       /* Opérande numérique en place */ +    virt_t virt;                            /* Adresse virtuelle           */ +    vmpa2t addr;                            /* Adresse de destination      */ +    GArchInstruction *target;               /* Ligne visée par la référence*/ + +    assert(g_arch_instruction_count_operands(instr) > 0); + +    op = g_arch_instruction_get_operand(instr, 0); + +    if (!G_IS_IMM_OPERAND(op)) return; + +    if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt)) +    { +        init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); + +        target = g_arch_processor_find_instr_by_address(proc, &addr); + +        if (target != NULL) +            g_arch_instruction_link_with(instr, target, ILT_CALL); + +    } + +} diff --git a/src/arch/link.h b/src/arch/link.h new file mode 100644 index 0000000..1923e0b --- /dev/null +++ b/src/arch/link.h @@ -0,0 +1,45 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * link.h - prototypes pour l'édition des liens après la phase de désassemblage + * + * Copyright (C) 2015 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_LINK_H +#define _ARCH_LINK_H + + +#include "instruction.h" +#include "processor.h" +#include "../format/format.h" + + + +/* Etablit un lien de saut selon une instruction donnée. */ +void handle_jump_as_link(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *); + +/* Etablit un lien d'appel selon une instruction donnée. */ +void handle_branch_if_true_as_link(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *); + +/* Etablit un lien d'appel selon une instruction donnée. */ +void handle_call_as_link(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *); + + + +#endif  /* _ARCH_LINK_H */ diff --git a/src/arch/processor-int.h b/src/arch/processor-int.h index 2b91b36..d387bde 100644 --- a/src/arch/processor-int.h +++ b/src/arch/processor-int.h @@ -43,6 +43,9 @@ +/* Taille des pré-allocations pour les instructions */ +#define INSTR_ALLOC_BLOCK 100 +  /* Fournit un contexte propre au processeur d'une architecture. */ @@ -70,6 +73,10 @@ struct _GArchProcessor      get_processor_context_fc get_ctx;       /* Obtention d'un contexte #1  */      get_decomp_context_fc get_dec_ctx;      /* Obtention d'un contexte #2  */ +    GArchInstruction **instructions;        /* Instructions désassemblées  */ +    size_t instr_allocated;                 /* Taille de la liste allouée  */ +    size_t instr_count;                     /* Taille de la liste aplatie  */ +  }; diff --git a/src/arch/processor.c b/src/arch/processor.c index 0b33552..c2d190b 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -24,12 +24,16 @@  #include "processor.h" +#include <malloc.h> +#include <stdlib.h> +  #include "instruction-int.h"  #include "processor-int.h" +#include "raw.h" @@ -294,3 +298,146 @@ GArchInstruction *g_arch_processor_disassemble(const GArchProcessor *proc, GProc      return result;  } + + + +/* ---------------------------------------------------------------------------------- */ +/*                    MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES                    */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : proc = architecture visée par la procédure.                  * +*                list = liste des instructions désassemblées.                 * +*                                                                             * +*  Description : Note les instructions désassemblées avec une architecture.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_arch_processor_set_disassembled_instructions(GArchProcessor *proc, GArchInstruction *list) +{ +    GArchInstruction *iter;                 /* Boucle de parcours          */ + +    ainstr_list_for_each(iter, list) +    { +        /* Mise à disposition de d'avantage d'espace */ +        if (proc->instr_allocated == proc->instr_count) +        { +            proc->instr_allocated += INSTR_ALLOC_BLOCK; + +            proc->instructions = (GArchInstruction **)realloc(proc->instructions, +                                                              proc->instr_allocated * sizeof(GArchInstruction  *)); + +        } + +        proc->instructions[proc->instr_count++] = iter; + +    } + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : proc = architecture visée par la procédure.                  * +*                                                                             * +*  Description : Fournit les instructions désassemblées pour une architecture.* +*                                                                             * +*  Retour      : Liste des instructions désassemblées ou NULL si aucune.      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProcessor *proc) +{ +    return (proc->instr_count > 0 ? proc->instructions[0] : NULL); + +} + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : proc = processeur recensant diverses instructions.           * +*                addr = position en mémoire ou physique à chercher.           * +*                                                                             * +*  Description : Recherche une instruction d'après son adresse.               * +*                                                                             * +*  Retour      : Instruction trouvée à l'adresse donnée, NULL si aucune.      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchInstruction *g_arch_processor_find_instr_by_address(const GArchProcessor *proc, const vmpa2t *addr) +{ +    GArchInstruction *result;               /* Trouvaille à retourner      */ +    GArchInstruction *fake;                 /* Coquille vide à comparer    */ +    void *ptr;                              /* Résultat des recherches     */ +    size_t i;                               /* Boucle de parcours          */ +    const mrange_t *range;                  /* Emplacement d'instruction   */ + +    if (has_phys_addr(addr)) +    { +        fake = g_raw_instruction_new_from_value(addr, MDS_8_BITS_UNSIGNED, 0); + +        int search_for_instr_by_addr(const GArchInstruction **a, const GArchInstruction **b) +        { +            const mrange_t *range_a;        /* Emplacement pour l'instr. A */ +            const mrange_t *range_b;        /* Emplacement pour l'instr. B */ + +            range_a = g_arch_instruction_get_range(*a); +            range_b = g_arch_instruction_get_range(*b); + +            /* +            printf("  -- cmp -- 0x%08x vs 0x%08x => %d\n", +                   (unsigned int)range_a->addr.virtual, +                   (unsigned int)range_b->addr.virtual, +                   cmp_vmpa(get_mrange_addr(range_a), get_mrange_addr(range_b))); +            */ + +            return cmp_vmpa(get_mrange_addr(range_a), get_mrange_addr(range_b)); + +        } + +        ptr = bsearch(&fake, proc->instructions, proc->instr_count, +                      sizeof(GArchInstruction *), (__compar_fn_t)search_for_instr_by_addr); + +        g_object_unref(G_OBJECT(fake)); + +        result = (ptr != NULL ? *((GArchInstruction **)ptr) : NULL); + +    } + +    else +    { +        result = NULL; + +        for (i = 0; i < proc->instr_count && result == NULL; i++) +        { +            range = g_arch_instruction_get_range(proc->instructions[i]); + +            if (cmp_vmpa(addr, get_mrange_addr(range)) == 0) +                result = proc->instructions[i]; + +        } + +        /* +        for (i = 0; i < proc->instr_count; i++) +            printf("  # %04zu  0x%08x\n", i, proc->instructions[i]->range.addr.virtual); +        */ + +    } + +    return result; + +} diff --git a/src/arch/processor.h b/src/arch/processor.h index 725307f..3eeefd5 100644 --- a/src/arch/processor.h +++ b/src/arch/processor.h @@ -78,4 +78,20 @@ GArchInstruction *g_arch_processor_disassemble(const GArchProcessor *, GProcCont +/* ------------------ MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES ------------------ */ + + +/* Note les instructions désassemblées avec une architecture. */ +void g_arch_processor_set_disassembled_instructions(GArchProcessor *, GArchInstruction *); + +/* Fournit les instructions désassemblées pour une architecture. */ +GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProcessor *); + + + +/* Recherche une instruction d'après son adresse. */ +GArchInstruction *g_arch_processor_find_instr_by_address(const GArchProcessor *, const vmpa2t *); + + +  #endif  /* _ARCH_PROCESSOR_H */  | 
