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 *); |