diff options
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | src/analysis/disass/output.c | 5 | ||||
-rw-r--r-- | src/format/elf/symbols.c | 103 | ||||
-rw-r--r-- | src/format/format.c | 140 | ||||
-rw-r--r-- | src/format/format.h | 6 | ||||
-rw-r--r-- | src/gui/panels/symbols.c | 4 |
6 files changed, 225 insertions, 50 deletions
@@ -1,4 +1,19 @@ -15-04-25 Cyrille Bagard <nocbos@gmail.com> +115-04-26 Cyrille Bagard <nocbos@gmail.com> + + * src/analysis/disass/output.c: + Give more information about not found symbols. + + * src/format/elf/symbols.c: + Load internal smybols ; create entry points only when needed. + + * src/format/format.c: + * src/format/format.h: + Allow to remove symbols and/or routines. + + * src/gui/panels/symbols.c + Display entry points as symbols too. + +115-04-25 Cyrille Bagard <nocbos@gmail.com> * src/analysis/disass/macro.c: Use an uniq coverage memory for all visited branches. diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c index f2c49bb..324975b 100644 --- a/src/analysis/disass/output.c +++ b/src/analysis/disass/output.c @@ -188,8 +188,9 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form compared > 0; compared = cmp_vmpa(iaddr, saddr)) { - log_variadic_message(LMT_BAD_BINARY, _("Unable to find a proper location for symbol '%s'"), - g_binary_symbol_to_string(symbols[sym_index])); + log_variadic_message(LMT_BAD_BINARY, + _("Unable to find a proper location for symbol '%s' @ 0x%08x"), + g_binary_symbol_get_label(symbols[sym_index]), get_virt_addr(saddr)); if (++sym_index == sym_count) goto no_more_symbol_finally; diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c index b57c601..4c1811f 100644 --- a/src/format/elf/symbols.c +++ b/src/format/elf/symbols.c @@ -93,7 +93,7 @@ static bool load_elf_external_symbols(GElfFormat *, const elf_shdr *); -#include <stdlib.h> + /****************************************************************************** * * @@ -116,18 +116,10 @@ bool load_elf_symbols(GElfFormat *format) result = true; + /* Symboles internes */ + result &= load_elf_internal_symbols(format); - result &= load_all_elf_basic_entry_points(format); - - - - - - /* Symboles internes */ -#if 0 - result = load_elf_internal_symbols(format); -#endif @@ -149,34 +141,9 @@ bool load_elf_symbols(GElfFormat *format) - qsort(G_BIN_FORMAT(format)->symbols, G_BIN_FORMAT(format)->symbols_count, - sizeof(GBinSymbol *), (__compar_fn_t)g_binary_symbol_cmp); + /* Symboles d'entrée, si encore besoin */ -#if 0 - - const vmpa2t *saddr; /* Adresse de symbole */ - size_t i; /* Boucle de parcours #2 */ - GBinSymbol **symbols; /* Symboles à représenter */ - - symbols = G_BIN_FORMAT(format)->symbols; - - for (i = 0; i < G_BIN_FORMAT(format)->symbols_count; i++) - { - saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[i])); - if (saddr == NULL) continue; - - //if (g_binary_symbol_to_string(symbols[i]) == NULL) continue; - - printf(" <symbol % 2zu> '% 22s'-> 0x%08lx 0x%08lx\n", - i, - g_binary_symbol_to_string(symbols[i]), - saddr->physical, - saddr->virtual); - - } - - //exit(0); -#endif + result &= load_all_elf_basic_entry_points(format); return result; @@ -220,13 +187,31 @@ static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t le init_vmpa(&addr, VMPA_NO_PHYSICAL, vaddr); - init_mrange(&range, &addr, len); + if (g_binary_format_find_symbol_at(format, &addr, &symbol)) + { + g_object_unref(G_OBJECT(routine)); + + routine = g_binary_symbol_get_routine(symbol); + g_object_ref(G_OBJECT(routine)); + + printf(" -- SYM CHANGE @ 0x%08x\n", vaddr); - g_binary_routine_set_range(routine, &range); + _g_binary_symbol_attach_routine(symbol, routine, STP_ENTRY_POINT); + + } + else + { + printf(" -- SYM ENTRY @ 0x%08x\n", vaddr); - symbol = g_binary_symbol_new(STP_ENTRY_POINT, "XXX", ~0); - g_binary_symbol_attach_routine(symbol, routine); - g_binary_format_add_symbol(base, symbol); + init_mrange(&range, &addr, len); + + g_binary_routine_set_range(routine, &range); + + symbol = g_binary_symbol_new(STP_ENTRY_POINT, "XXX", ~0); + g_binary_symbol_attach_routine(symbol, routine); + g_binary_format_add_symbol(base, symbol); + + } } @@ -530,6 +515,7 @@ static bool load_elf_internal_symbols(GElfFormat *format) off_t size; /* Taille de cette même zone */ off_t iter; /* Boucle de parcours */ elf_sym sym; /* Symbole aux infos visées */ + virt_t virt; /* Adresse virtuelle */ vmpa2t addr; /* Localisation d'une routine */ mrange_t range; /* Couverture mémoire associée */ const char *name; /* Nom du symbole trouvé */ @@ -546,6 +532,21 @@ static bool load_elf_internal_symbols(GElfFormat *format) result = read_elf_symbol(format, &iter, &sym); if (!result) break; + /* On rejette les symboles qui ne sont pas définis au sein du binaire */ + if (ELF_SYM(format, sym, st_shndx) == 0) continue; + +#if 0 + + Elf64_Word st_name; /* Symbol name (string tbl index) */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* Symbol visibility */ + Elf64_Section st_shndx; /* Section index */ + Elf64_Addr st_value; /* Symbol value */ + Elf64_Xword st_size; /* Symbol size */ + +#endif + + if (ELF_SYM(format, sym, st_value) == 0) continue; /* Résolution précise d'adresse */ @@ -553,10 +554,20 @@ static bool load_elf_internal_symbols(GElfFormat *format) /* TODO */ - init_vmpa(&addr, ELF_SYM(format, sym, st_value), VMPA_NO_VIRTUAL); + //init_vmpa(&addr, VMPA_NO_PHYSICAL, ELF_SYM(format, sym, st_value)); + + 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, ELF_SYM(format, sym, st_size)); + init_mrange(&range, &addr, 0); /* Première ébauche de nom */ @@ -609,7 +620,7 @@ static bool load_elf_internal_symbols(GElfFormat *format) /* Routine */ - printf("ADDING>> '%s'\n", name); + printf("SYM ADDING>> '%s'\n", name); routine = try_to_demangle_routine(name); diff --git a/src/format/format.c b/src/format/format.c index 5478d3c..2256160 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -49,6 +49,9 @@ static void g_binary_format_class_init(GBinFormatClass *); /* Initialise une instance de format binaire générique. */ static void g_binary_format_init(GBinFormat *); +/* Retire un symbole de la collection du format binaire. */ +static void _g_binary_format_remove_symbol(GBinFormat *, size_t); + /* Indique le type défini pour un format binaire générique. */ @@ -222,6 +225,96 @@ void g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol) /****************************************************************************** * * +* Paramètres : format = informations chargées à compléter. * +* index = indice du symbole à retirer de la liste. * +* * +* Description : Retire un symbole de la collection du format binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void _g_binary_format_remove_symbol(GBinFormat *format, size_t index) +{ + GBinSymbol *symbol; /* Symbole visé par l'opération*/ + GBinRoutine *routine; /* Eventuelle routine associée */ + size_t i; /* Boucle de parcours */ + + /** + * TODO : envoyer un signal pour avertir les opérandes concernées. + */ + + symbol = format->symbols[index]; + + switch (g_binary_symbol_get_target_type(symbol)) + { + case STP_ROUTINE: + case STP_ENTRY_POINT: + + routine = g_binary_symbol_get_routine(symbol); + + for (i = 0; i < format->routines_count; i++) + if (format->routines[i] == routine) + break; + + assert(i < format->routines_count); + + if ((i + 1) < format->routines_count) + memmove(&format->routines[i], &format->routines[i + 1], + (format->routines_count - i - 1) * sizeof(GBinRoutine *)); + + format->routines = (GBinRoutine **)realloc(format->routines, + --format->routines_count * sizeof(GBinRoutine *)); + + break; + + default: + break; + + } + + assert(index < format->symbols_count); + + if ((index + 1) < format->symbols_count) + memmove(&format->symbols[index], &format->symbols[index + 1], + (format->symbols_count - index - 1) * sizeof(GBinSymbol *)); + + format->symbols = (GBinSymbol **)realloc(format->symbols, + --format->symbols_count * sizeof(GBinSymbol *)); + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à compléter. * +* symbol = symbole à retirer de la liste. * +* * +* Description : Retire un symbole de la collection du format binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_format_remove_symbol(GBinFormat *format, GBinSymbol *symbol) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < format->symbols_count; i++) + if (format->symbols[i] == symbol) + break; + + _g_binary_format_remove_symbol(format, i); + +} + + +/****************************************************************************** +* * * Paramètres : format = informations chargées à consulter. * * count = taille du tableau créé. [OUT] * * * @@ -480,6 +573,53 @@ void g_binary_format_add_routine(GBinFormat *format, GBinRoutine *routine) /****************************************************************************** * * +* Paramètres : format = informations chargées à compléter. * +* routine = routine à ajouter à la liste. * +* * +* Description : Retire une routine de la collection du format binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_format_remove_routine(GBinFormat *format, GBinRoutine *routine) +{ + size_t index; /* Indice trouvé à utiliser */ + size_t i; /* Boucle de parcours */ + GBinSymbol *symbol; /* Symbole en cours d'analyse */ + + index = format->symbols_count; + + for (i = 0; i < format->symbols_count && index == format->symbols_count; i++) + { + symbol = format->symbols[i]; + + switch (g_binary_symbol_get_target_type(symbol)) + { + case STP_ROUTINE: + case STP_ENTRY_POINT: + + if (g_binary_symbol_get_routine(symbol) == routine) + index = i; + + break; + + default: + break; + + } + + } + + _g_binary_format_remove_symbol(format, index); + +} + + +/****************************************************************************** +* * * Paramètres : format = informations chargées à consulter. * * count = taille du tableau créé. [OUT] * * * diff --git a/src/format/format.h b/src/format/format.h index 38418b3..66f014b 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -67,6 +67,9 @@ void g_binary_format_setup_disassembling_context(const GBinFormat *, GProcContex /* Ajoute un symbole à la collection du format binaire. */ void g_binary_format_add_symbol(GBinFormat *, GBinSymbol *); +/* Retire un symbole de la collection du format binaire. */ +void g_binary_format_remove_symbol(GBinFormat *, GBinSymbol *); + /* Fournit la liste de tous les symboles détectés. */ GBinSymbol **g_binary_format_get_symbols(const GBinFormat *, size_t *); @@ -85,6 +88,9 @@ bool g_binary_format_resolve_symbol(const GBinFormat *, const vmpa2t *, GBinSymb /* Ajoute une routine à la collection du format binaire. */ void g_binary_format_add_routine(GBinFormat *, GBinRoutine *) __attribute__ ((deprecated)); +/* Retire une routine de la collection du format binaire. */ +void g_binary_format_remove_routine(GBinFormat *, GBinRoutine *); + /* Fournit le prototype de toutes les routines détectées. */ GBinRoutine **g_binary_format_get_routines(const GBinFormat *, size_t *); diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c index b523cd2..42098c8 100644 --- a/src/gui/panels/symbols.c +++ b/src/gui/panels/symbols.c @@ -662,6 +662,7 @@ static void reload_symbols_for_new_list_view(GSymbolsPanel *panel) switch (g_binary_symbol_get_target_type(symbols[i])) { case STP_ROUTINE: + case STP_ENTRY_POINT: icon = G_SYMBOLS_PANEL_GET_CLASS(panel)->routine_img; break; case STP_OBJECT: @@ -843,6 +844,7 @@ static void reload_symbols_for_new_tree_view(GSymbolsPanel *panel) switch (g_binary_symbol_get_target_type(symbols[i])) { case STP_ROUTINE: + case STP_ENTRY_POINT: icon = G_SYMBOLS_PANEL_GET_CLASS(panel)->routine_img; break; case STP_OBJECT: @@ -1044,7 +1046,7 @@ static bool is_symbol_filtered(GSymbolsPanel *panel, const GBinSymbol *symbol) type = g_binary_symbol_get_target_type(symbol); - if (type != STP_ROUTINE && type != STP_OBJECT) + if (type != STP_ROUTINE && type != STP_ENTRY_POINT && type != STP_OBJECT) return true; if (panel->filter == NULL) |