diff options
| -rw-r--r-- | ChangeLog | 14 | ||||
| -rw-r--r-- | src/analysis/disass/fetch.c | 40 | ||||
| -rw-r--r-- | src/format/elf/helper_arm.c | 14 | ||||
| -rw-r--r-- | src/format/elf/symbols.c | 74 | ||||
| -rw-r--r-- | src/format/format-int.h | 8 | ||||
| -rw-r--r-- | src/format/format.c | 45 | ||||
| -rw-r--r-- | src/format/format.h | 3 | 
7 files changed, 133 insertions, 65 deletions
| @@ -1,3 +1,17 @@ +15-10-14  Cyrille Bagard <nocbos@gmail.com> + +	* src/analysis/disass/fetch.c: +	Update code. + +	* src/format/elf/helper_arm.c: +	* src/format/elf/symbols.c: +	Keep all information about real addresses for routine symbols (ARM vs Thumb). + +	* src/format/format.c: +	* src/format/format.h: +	* src/format/format-int.h: +	Register all starting points for the disassembling process. +  15-10-13  Cyrille Bagard <nocbos@gmail.com>  	* src/analysis/binary.c: diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c index 9ebe231..67a6f3b 100644 --- a/src/analysis/disass/fetch.c +++ b/src/analysis/disass/fetch.c @@ -35,7 +35,7 @@  /* Suit un flot d'exécution pour désassembler du code. */ -static void follow_execution_flow(const GLoadedBinary *, GProcContext *, mem_area **, size_t *, status_blob_info *, virt_t); +static void follow_execution_flow(const GLoadedBinary *, GProcContext *, mem_area **, size_t *, status_blob_info *);  /* S'assure que l'ensemble des aires est entièrement décodé. */  static void ensure_all_mem_areas_are_filled(mem_area **, size_t *, const GLoadedBinary *, GProcContext *, status_blob_info *); @@ -50,7 +50,6 @@ static void ensure_all_mem_areas_are_filled(mem_area **, size_t *, const GLoaded  *                areas  = liste de zones contenant des données à traiter.     *  *                count  = nombre de ces aires à disposition.                  *  *                info   = informations liées à l'affichage de la progression. * -*                virt   = adresse d'un point de départ d'un traitement.       *  *                                                                             *  *  Description : Suit un flot d'exécution pour désassembler du code.          *  *                                                                             * @@ -60,17 +59,13 @@ static void ensure_all_mem_areas_are_filled(mem_area **, size_t *, const GLoaded  *                                                                             *  ******************************************************************************/ -static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx, mem_area **areas, size_t *count, status_blob_info *info, virt_t virt) +static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx, mem_area **areas, size_t *count, status_blob_info *info)  { +    virt_t virt;                            /* Adresse de départ dépilée   */      vmpa2t addr;                            /* Conversion en pleine adresse*/      GExeFormat *format;                     /* Format du fichier binaire   */      size_t index;                           /* Zone trouvée à traiter      */ -    printf("-- follow 0x%08x\n", (unsigned int)virt); - -    if (virt == VMPA_NO_VIRTUAL) -        g_proc_context_push_drop_point(ctx, virt); -      while (g_proc_context_has_drop_points(ctx))      {          virt = g_proc_context_pop_drop_point(ctx); @@ -153,12 +148,6 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt      mem_area *areas;                        /* Zone de productions         */      size_t count;                           /* Nombre de ces zones         */      status_blob_info *info;                 /* Informations de progression */ -    virt_t virt;                            /* Point d'accroche virtuelle  */ -    GBinSymbol **symbols;                   /* Symboles à représenter      */ -    size_t sym_count;                       /* Qté de symboles présents    */ -    size_t i;                               /* Boucle de parcours          */ -    const mrange_t *range;                  /* Couverture d'un symbole     */ -    const vmpa2t *addr;                     /* Point de départ du symbole  */      double done;                            /* Portion de travail accompli */      format = G_BIN_FORMAT(g_loaded_binary_get_format(binary)); @@ -182,28 +171,7 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt                                    _("Disassembling following the execution flow..."),                                    0, length); -    /* Insertion des points de départ */ - -    follow_execution_flow(binary, ctx, &areas, &count, info, VMPA_NO_VIRTUAL); - -    /* Symboles exécutables présents et passés à travers les mailles */ - -    symbols = g_binary_format_get_symbols(format, &sym_count); - -    for (i = 0; i < sym_count; i++) -    { -        if (g_binary_symbol_get_target_type(symbols[i]) != STP_FUNCTION) -            continue; - -        range = g_binary_symbol_get_range(symbols[i]); -        addr = get_mrange_addr(range); -        virt = get_virt_addr(addr); - -        follow_execution_flow(binary, ctx, &areas, &count, info, virt); - -    } - -    printf(" ------------------------------------------- follow done\n"); +    follow_execution_flow(binary, ctx, &areas, &count, info);      done = get_current_progessive_status(info); diff --git a/src/format/elf/helper_arm.c b/src/format/elf/helper_arm.c index cd2d922..f47df5d 100644 --- a/src/format/elf/helper_arm.c +++ b/src/format/elf/helper_arm.c @@ -63,7 +63,9 @@ bool load_elf_arm_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx, -	virt_t virt;                            /* Adresse en mémoire virtuelle */ +    virt_t virt;                            /* Adresse en mémoire virtuelle*/ +    virt_t final_virt;                      /* Adresse virtuelle retenue   */ +    bool status;                            /* Bilan d'une opération       */      vmpa2t addr;                            /* Localisation d'une routine  */      mrange_t range;                         /* Couverture mémoire associée */      GBinRoutine *routine;                   /* Nouvelle routine trouvée    */ @@ -100,14 +102,14 @@ bool load_elf_arm_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx,          {              case R_ARM_JUMP_SLOT: -                  virt = ELF_SYM(format, sym, st_value); - -                  if (virt == 0) continue; +                final_virt = virt & ~0x1; + +                status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_virt, &addr); +                if (!status) continue; -                init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);                  init_mrange(&range, &addr, 0);                  routine = try_to_demangle_routine(name); @@ -118,6 +120,8 @@ bool load_elf_arm_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx,                  g_binary_symbol_attach_routine(symbol, routine);                  g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); +                /* Comptabilisation pour le désassemblage brut */ +                g_binary_format_register_code_point(G_BIN_FORMAT(format), virt, false);                  /* diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c index c3c2ecd..fa7cb8f 100644 --- a/src/format/elf/symbols.c +++ b/src/format/elf/symbols.c @@ -168,26 +168,25 @@ bool load_elf_symbols(GElfFormat *format)  static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t len, GBinRoutine *routine)  { -    GBinFormat *base;                   /* Version basique de l'instance   */ -    vmpa2t addr;                        /* Localisation d'une routine  */ -    mrange_t range;                     /* Couverture mémoire associée */ -    GBinSymbol *symbol;                 /* Nouveau symbole construit   */ - -    base = G_BIN_FORMAT(format); +    GBinFormat *base;                       /* Version basique du format   */ +    virt_t final_vaddr;                     /* Adresse virtuelle retenue   */ +    bool status;                            /* Bilan d'une opération       */ +    vmpa2t addr;                            /* Localisation d'une routine  */ +    mrange_t range;                         /* Couverture mémoire associée */ +    GBinSymbol *symbol;                     /* Nouveau symbole construit   */ -    /* Comptabilisation pour le désassemblage brut */ +    /* Localisation complète du symbole */ -    base->entry_points = (virt_t *)realloc(base->entry_points, ++base->ep_count * sizeof(virt_t)); +	if (ELF_HDR(format, format->header, e_machine) == EM_ARM) +		final_vaddr = vaddr & ~0x1; +    else +        final_vaddr = vaddr; -    base->entry_points[base->ep_count - 1] = vaddr; +    status = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_vaddr, &addr); +    if (!status) return;      /* Comptabilisation en tant que symbole */ -	if (ELF_HDR(format, format->header, e_machine) == EM_ARM) -		vaddr &= ~0x1; - -	init_vmpa(&addr, VMPA_NO_PHYSICAL, vaddr); -      if (g_binary_format_find_symbol_at(G_BIN_FORMAT(format), &addr, &symbol))      {          g_object_unref(G_OBJECT(routine)); @@ -200,6 +199,8 @@ static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t le      }      else      { +        base = G_BIN_FORMAT(format); +          init_mrange(&range, &addr, len);          g_binary_routine_set_range(routine, &range); @@ -208,6 +209,9 @@ static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t le          g_binary_symbol_attach_routine(symbol, routine);          _g_binary_format_add_symbol(base, symbol, false); +        /* Comptabilisation pour le désassemblage brut */ +        g_binary_format_register_code_point(base, vaddr, true); +      }  } @@ -513,6 +517,7 @@ static bool load_elf_internal_symbols(GElfFormat *format)      /* Charge tous les symboles définis dans une section */      bool add_all_symbols_from_section(GElfFormat *format, const elf_shdr *section, bool use_virt)      { +        GBinFormat *base;                   /* Version basique du format   */          elf_shdr strtab;                    /* Section .strtab trouvée     */          bool has_strtab;                    /* Présence de cette section   */          phys_t start;                       /* Début de la zone à traiter  */ @@ -520,6 +525,7 @@ static bool load_elf_internal_symbols(GElfFormat *format)          phys_t iter;                        /* Boucle de parcours          */          elf_sym sym;                        /* Symbole aux infos visées    */          virt_t virt;                        /* Adresse virtuelle           */ +        virt_t final_virt;                  /* Adresse virtuelle retenue   */          vmpa2t addr;                        /* Localisation d'une routine  */          mrange_t range;                     /* Couverture mémoire associée */          const char *name;                   /* Nom du symbole trouvé       */ @@ -527,6 +533,8 @@ static bool load_elf_internal_symbols(GElfFormat *format)          GBinRoutine *routine;               /* Nouvelle routine trouvée    */          GBinSymbol *symbol;                 /* Nouveau symbole construit   */ +        base = G_BIN_FORMAT(format); +          has_strtab = find_elf_section_by_index(format, ELF_SHDR(format, *section, sh_link), &strtab);          get_elf_section_content(format, section, &start, &size, NULL); @@ -562,15 +570,6 @@ static bool load_elf_internal_symbols(GElfFormat *format)              virt = ELF_SYM(format, sym, st_value); -            if (ELF_HDR(format, format->header, e_machine) == EM_ARM) -                virt &= ~0x1; - -            if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, &addr)) -                continue; - - - -            init_mrange(&range, &addr, ELF_SYM(format, sym, st_size));              //init_mrange(&range, &addr, 0); @@ -586,6 +585,14 @@ static bool load_elf_internal_symbols(GElfFormat *format)              {                  case STT_OBJECT: +                    /* Ajustement de la position */ + +                    if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, &addr)) +                    { +                        symbol = NULL; +                        break; +                    } +                      /* Création d'un nom unique ? */                      if (name != NULL) @@ -609,6 +616,21 @@ static bool load_elf_internal_symbols(GElfFormat *format)                  case STT_FUNC: +                    /* Ajustement de la position */ + +                    if (ELF_HDR(format, format->header, e_machine) == EM_ARM) +                        final_virt = virt & ~0x1; +                    else +                        final_virt = virt; + +                    if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), final_virt, &addr)) +                    { +                        symbol = NULL; +                        break; +                    } + +                    init_mrange(&range, &addr, ELF_SYM(format, sym, st_size)); +                      /* Création d'un nom unique ? */                      if (name != NULL) @@ -635,6 +657,10 @@ static bool load_elf_internal_symbols(GElfFormat *format)                      symbol = g_binary_symbol_new(STP_ROUTINE);                      g_binary_symbol_attach_routine(symbol, routine); +                    /* Comptabilisation pour le désassemblage brut */ + +                    g_binary_format_register_code_point(base, virt, false); +                      break;                  default: @@ -644,7 +670,7 @@ static bool load_elf_internal_symbols(GElfFormat *format)              }              if (symbol != NULL) -                _g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol, false); +                _g_binary_format_add_symbol(base, symbol, false);          } diff --git a/src/format/format-int.h b/src/format/format-int.h index 3e6ed9c..f97a4ad 100644 --- a/src/format/format-int.h +++ b/src/format/format-int.h @@ -36,6 +36,10 @@  typedef void (* format_decompile_fc) (const GBinFormat *, GCodeBuffer *, const char *); +/* Rythme des allocations pour les entrées de code */ +#define EXTRA_POINT_BLOCK 100 + +  /* Format binaire générique (instance) */  struct _GBinFormat  { @@ -46,6 +50,10 @@ struct _GBinFormat      virt_t *entry_points;                   /* Points d'entrée du code     */      size_t ep_count;                        /* Nombre de ces points        */ +    virt_t *extra_points;                   /* Autres débuts de code       */ +    size_t xp_allocated;                    /* Taille d'inscription allouée*/ +    size_t xp_count;                        /* Nombre de points enregistrés*/ +      GBinSymbol **symbols;                   /* Liste des symboles trouvés  */      size_t symbols_count;                   /* Quantité de ces symboles    */      GRWLock syms_lock;                      /* Accès à la liste de symboles*/ diff --git a/src/format/format.c b/src/format/format.c index 6128c9a..9f03924 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -147,6 +147,48 @@ GBinContent *g_binary_format_get_content(const GBinFormat *format)  /******************************************************************************  *                                                                             * +*  Paramètres  : format = description de l'exécutable à compléter.            * +*                pt     = point de l'espace mémoire à considérer.             * +*                entry  = nature du point fourni.                             * +*                                                                             * +*  Description : Enregistre une adresse comme début d'une zone de code.       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_binary_format_register_code_point(GBinFormat *format, virt_t pt, bool entry) +{ +    if (entry) +    { +        format->entry_points = (virt_t *)realloc(format->entry_points, +                                                 ++format->ep_count * sizeof(virt_t)); + +        format->entry_points[format->ep_count - 1] = pt; + +    } +    else +    { +        if (format->xp_count == format->xp_allocated) +        { +            format->xp_allocated += EXTRA_POINT_BLOCK; + +            format->extra_points = (virt_t *)realloc(format->extra_points, +                                                     format->xp_allocated * sizeof(virt_t)); + +        } + +        format->extra_points[format->xp_count++] = pt; + +    } + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : format = description de l'exécutable à consulter.            *  *                ctx    = contexte de désassemblage à préparer.               *  *                                                                             * @@ -165,6 +207,9 @@ void g_binary_format_setup_disassembling_context(const GBinFormat *format, GProc      for (i = 0; i < format->ep_count; i++)          g_proc_context_push_drop_point(ctx, format->entry_points[i]); +    for (i = 0; i < format->xp_count; i++) +        g_proc_context_push_drop_point(ctx, format->extra_points[i]); +  } diff --git a/src/format/format.h b/src/format/format.h index 8c06522..314306e 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -57,6 +57,9 @@ GType g_binary_format_get_type(void);  /* Fournit une référence vers le contenu binaire analysé. */  GBinContent *g_binary_format_get_content(const GBinFormat *); +/* Enregistre une adresse comme début d'une zone de code. */ +void g_binary_format_register_code_point(GBinFormat *, virt_t, bool); +  /* Fournit un contexte initialisé pour un désassemblage. */  void g_binary_format_setup_disassembling_context(const GBinFormat *, GProcContext *); | 
