diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2015-04-04 17:35:53 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2015-04-04 17:35:53 (GMT) | 
| commit | c9391d0a1d42a05c72fd1c909a00774561ac9f81 (patch) | |
| tree | ac19dc8ff1b7ca2aadd3a3af804e72897738806f /src/analysis/disass | |
| parent | 46e46c2894ea92502734c7bbd1cbcc6cb2e46d17 (diff) | |
Detected loops in disassembled instructions once again.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@502 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/analysis/disass')
| -rw-r--r-- | src/analysis/disass/disassembler.c | 9 | ||||
| -rw-r--r-- | src/analysis/disass/loop.c | 91 | ||||
| -rw-r--r-- | src/analysis/disass/loop.h | 3 | ||||
| -rw-r--r-- | src/analysis/disass/rank.c | 63 | 
4 files changed, 130 insertions, 36 deletions
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c index 50c71da..1227e84 100644 --- a/src/analysis/disass/disassembler.c +++ b/src/analysis/disass/disassembler.c @@ -323,12 +323,19 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta +    /* Troisième  étape */ +    id = gtk_extended_status_bar_push(statusbar, _("Detecting loops..."), true); +    detect_loops_in_code(proc, routines, routines_count, statusbar, id); +    gtk_extended_status_bar_remove(statusbar, id); +    /// -    /* Troisième  étape */ + + +    /* Quatrième étape */      id = gtk_extended_status_bar_push(statusbar, _("Establishing links..."), true); diff --git a/src/analysis/disass/loop.c b/src/analysis/disass/loop.c index 0a06748..0cb346b 100644 --- a/src/analysis/disass/loop.c +++ b/src/analysis/disass/loop.c @@ -30,14 +30,10 @@ -#include "../../arch/instruction.h" - - -  /* Suivi du flot d'exécution */  typedef struct _exec_flow  { -    vmpa_t *steps;                          /* Jalons dans l'exécution     */ +    vmpa2t *steps;                          /* Jalons dans l'exécution     */      size_t count;                           /* Quantité de ces points      */  } exec_flow; @@ -53,13 +49,13 @@ static exec_flow *dup_exec_flow(const exec_flow *);  static void delete_exec_flow(exec_flow *);  /* Recherche si le chemin d'exécution a déjà mené à une adresse. */ -static bool is_new_exec_flow(const exec_flow *, vmpa_t); +static bool is_new_exec_flow(const exec_flow *, const vmpa2t *);  /* Ajoute une adresse jalon dans un flot d'exécution. */ -static void add_step_into_exec_flow(exec_flow *, vmpa_t); +static void add_step_into_exec_flow(exec_flow *, const vmpa2t *);  /* Suit un flot d'exécution à la recherche de boucles. */ -static void track_loops_in_code(GArchInstruction *, vmpa_t, vmpa_t, exec_flow *); +static void track_loops_in_code(const GArchProcessor *, const mrange_t *, const vmpa2t *, exec_flow *); @@ -104,8 +100,8 @@ static exec_flow *dup_exec_flow(const exec_flow *src)      result = (exec_flow *)calloc(1, sizeof(exec_flow)); -    result->steps = (vmpa_t *)malloc(src->count * sizeof(vmpa_t)); -    memcpy(result->steps, src->steps, src->count * sizeof(vmpa_t)); +    result->steps = (vmpa2t *)malloc(src->count * sizeof(vmpa2t)); +    memcpy(result->steps, src->steps, src->count * sizeof(vmpa2t));      result->count = src->count; @@ -128,7 +124,8 @@ static exec_flow *dup_exec_flow(const exec_flow *src)  static void delete_exec_flow(exec_flow *flow)  { -    free(flow->steps); +    if (flow->steps != NULL) +        free(flow->steps);      free(flow); @@ -148,12 +145,12 @@ static void delete_exec_flow(exec_flow *flow)  *                                                                             *  ******************************************************************************/ -static bool is_new_exec_flow(const exec_flow *flow, vmpa_t addr) +static bool is_new_exec_flow(const exec_flow *flow, const vmpa2t *addr)  {      void *ret;                              /* Conclusion d'une recherche  */ -    ret = bsearch(&addr, flow->steps, flow->count, -                  sizeof(vmpa_t), (__compar_fn_t)compare_vmpa); +    ret = bsearch(addr, flow->steps, flow->count, +                  sizeof(vmpa2t), (__compar_fn_t)cmp_vmpa);      return (ret == NULL); @@ -173,19 +170,19 @@ static bool is_new_exec_flow(const exec_flow *flow, vmpa_t addr)  *                                                                             *  ******************************************************************************/ -static void add_step_into_exec_flow(exec_flow *flow, vmpa_t addr) +static void add_step_into_exec_flow(exec_flow *flow, const vmpa2t *addr)  { -    flow->steps = (vmpa_t *)realloc(flow->steps, ++flow->count * sizeof(vmpa_t)); -    flow->steps[flow->count - 1] = addr; +    flow->steps = (vmpa2t *)realloc(flow->steps, ++flow->count * sizeof(vmpa2t)); +    copy_vmpa(&flow->steps[flow->count - 1], addr); -    qsort(flow->steps, flow->count, sizeof(vmpa_t), (__compar_fn_t)compare_vmpa); +    qsort(flow->steps, flow->count, sizeof(vmpa2t), (__compar_fn_t)cmp_vmpa);  }  /******************************************************************************  *                                                                             * -*  Paramètres  : list  = ensemble d'instructions à parcourir.                 * +*  Paramètres  : proc  = ensemble d'instructions à parcourir.                 *  *                start = adresse du début de l'analyse.                       *  *                end   = adresse de fin de la routine traitée.                *  *                flow  = ensemble des jalons de l'exécution du code.          * @@ -198,28 +195,40 @@ static void add_step_into_exec_flow(exec_flow *flow, vmpa_t addr)  *                                                                             *  ******************************************************************************/ -static void track_loops_in_code(GArchInstruction *list, vmpa_t start, vmpa_t end, exec_flow *flow) +static void track_loops_in_code(const GArchProcessor *proc, const mrange_t *range, const vmpa2t *start, exec_flow *flow)  {      bool exit_track;                        /* Détermine la fin du parcours*/      GArchInstruction *iter;                 /* Boucle de parcours          */ +    const mrange_t *irange;                 /* Emplacement d'instruction   */      GArchInstruction **dests;               /* Instr. visée par une autre  */      InstructionLinkType *types;             /* Type de lien entre lignes   */      size_t dcount;                          /* Nombre de liens de dest.    */      size_t i;                               /* Boucle de parcours          */ -    vmpa_t addr;                            /* Prochaine adresse de saut   */ +    const vmpa2t *addr;                     /* Prochaine adresse de saut   */      exec_flow *next_flow;                   /* Suite de l'exécution        */      add_step_into_exec_flow(flow, start);      exit_track = false; -    for (iter = g_arch_instruction_find_by_address(list, start, true); +    for (iter = g_arch_processor_find_instr_by_address(proc, start);           iter != NULL && !exit_track; -         iter = g_arch_instruction_get_next_iter(list, iter, end)) +         iter = g_arch_instruction_get_next_iter(iter /* FIXME : list*/, iter, ~0))      { +        /* L'instruction sort-elle des clous ? */ + +        irange = g_arch_instruction_get_range(iter); + +        if (!mrange_contains_mrange(range, irange)) +            break; + +        /* Fin de parcours ? */ +          if (g_arch_instruction_is_return(iter))              break; +        /* Analyse des destinations */ +          dcount = g_arch_instruction_get_destinations(iter, &dests, &types, NULL);          if (dcount == 0) continue; @@ -233,18 +242,31 @@ static void track_loops_in_code(GArchInstruction *list, vmpa_t start, vmpa_t end                      exit_track = true;                      break; -                case ILT_CALL:                  case ILT_CATCH_EXCEPTION: + +                    irange = g_arch_instruction_get_range(dests[i]); +                    addr = get_mrange_addr(irange); + +                    next_flow = create_exec_flow(); +                    track_loops_in_code(proc, range, addr, next_flow); +                    delete_exec_flow(next_flow); +                      break; -                default: +                case ILT_EXEC_FLOW: +                case ILT_JUMP: +                case ILT_CASE_JUMP: +                case ILT_JUMP_IF_TRUE: +                case ILT_JUMP_IF_FALSE: +                      /**                       * On se lance dans d'autres suivis qui vont parcourir le reste des                       * instructions, donc on peut arrêter le parcours courant ici.                       */                      exit_track = true; -                    g_arch_instruction_get_location(dests[i], NULL, NULL, &addr); +                    irange = g_arch_instruction_get_range(dests[i]); +                    addr = get_mrange_addr(irange);                      if (!is_new_exec_flow(flow, addr))                          types[i] = ILT_LOOP; @@ -252,12 +274,15 @@ static void track_loops_in_code(GArchInstruction *list, vmpa_t start, vmpa_t end                      else                      {                          next_flow = dup_exec_flow(flow); -                        track_loops_in_code(list, addr, end, next_flow); +                        track_loops_in_code(proc, range, addr, next_flow);                          delete_exec_flow(next_flow);                      }                      break; +                default: +                    break; +              }      } @@ -267,7 +292,7 @@ static void track_loops_in_code(GArchInstruction *list, vmpa_t start, vmpa_t end  /******************************************************************************  *                                                                             * -*  Paramètres  : list      = ensemble d'instructions à relier.                * +*  Paramètres  : proc      = ensemble d'instructions à relier.                *  *                routines  = prototypes existants à insérer.                  *  *                count     = quantité de ces prototypes.                      *  *                statusbar = barre de statut avec progression à mettre à jour.* @@ -281,20 +306,18 @@ static void track_loops_in_code(GArchInstruction *list, vmpa_t start, vmpa_t end  *                                                                             *  ******************************************************************************/ -void detect_loops_in_code(GArchInstruction *list, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id) +void detect_loops_in_code(const GArchProcessor *proc, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id)  {      size_t i;                               /* Boucle de parcours          */ -    vmpa_t start;                           /* Adresse de départ           */ -    vmpa_t end;                             /* Adresse de fin              */ +    const mrange_t *range;                  /* Couverture d'une routine    */      exec_flow *flow;                        /* Flot d'exécution à suivre   */      for (i = 0; i < count; i++)      { -        start = g_binary_routine_get_address(routines[i]); -        end = start + g_binary_routine_get_size(routines[i]); +        range = g_binary_routine_get_range(routines[i]);          flow = create_exec_flow(); -        track_loops_in_code(list, start, end, flow); +        track_loops_in_code(proc, range, get_mrange_addr(range), flow);          delete_exec_flow(flow);          gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / count); diff --git a/src/analysis/disass/loop.h b/src/analysis/disass/loop.h index 7c8d7b3..f4b05cf 100644 --- a/src/analysis/disass/loop.h +++ b/src/analysis/disass/loop.h @@ -26,12 +26,13 @@  #include "../routine.h" +#include "../../arch/processor.h"  #include "../../gtkext/gtkextstatusbar.h"  /* Détecte les boucles dans du code machine. */ -void detect_loops_in_code(GArchInstruction *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t); +void detect_loops_in_code(const GArchProcessor *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t); diff --git a/src/analysis/disass/rank.c b/src/analysis/disass/rank.c index 94494d5..758e15d 100644 --- a/src/analysis/disass/rank.c +++ b/src/analysis/disass/rank.c @@ -202,6 +202,69 @@ void rank_routines_blocks(GBinRoutine **routines, size_t count, GtkExtStatusBar          g_instr_block_visit(main_block, (instr_block_visitor_cb)rank_flow_block, main_block); + + +        printf("===== BLOCK(S) xXXx ======\n"); + + +        bool visit_ranked_block(GInstrBlock *blk, BlockVisitOrder order, int *indent) +        { +            int i; + +            switch (order) +            { +                case BVO_IN: +                case BVO_PENDING: + +                    for (i = 0; i < *indent; i++) +                        printf("   "); + +                    printf("%p '%s'", blk, G_OBJECT_TYPE_NAME(blk)); + +                    if (G_IS_FLOW_BLOCK(blk)) +                    { +                        vmpa2t start; +                        vmpa2t end; + +                        g_flow_block_get_boundary_addresses(G_FLOW_BLOCK(blk), &start, &end); + +                        printf("  0x%08x -> 0x%08x (rank = %u)", +                               (unsigned int)start.virtual, +                               (unsigned int)end.virtual, +                               g_flow_block_get_rank(G_FLOW_BLOCK(blk))); + +                    } + +                    printf("\n"); + +                    if (order == BVO_IN) (*indent)++; +                    break; + +                case BVO_OUT: +                    (*indent)--; +                    break; + +            } + +            return true; + +        } + +        g_instr_block_visit(main_block, (instr_block_visitor_cb)visit_ranked_block, (int []){ 0 }); + +        printf("\n"); + + + + + + + + + + + +      }  }  | 
