From 04ca0756d59629113bd3f602565850a2910ac84e Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Mon, 1 Sep 2014 22:20:28 +0000 Subject: Loaded some ELF symbols from DYNSYM and SYMTAB sections. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@397 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 28 ++++++++ src/analysis/disass/fetch.c | 27 +++++--- src/analysis/disass/output.c | 2 +- src/analysis/routine.c | 30 +++------ src/analysis/routine.h | 4 +- src/arch/vmpa.c | 4 +- src/core/params.c | 3 + src/core/params.h | 1 + src/format/elf/symbols.c | 150 ++++++++++++++++++++++++++++++++----------- src/format/format.h | 2 +- src/format/symbol.c | 24 +++---- src/format/symbol.h | 7 +- 12 files changed, 194 insertions(+), 88 deletions(-) diff --git a/ChangeLog b/ChangeLog index c759cf0..0837dfe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +14-09-02 Cyrille Bagard + + * src/analysis/disass/fetch.c: + * src/analysis/disass/output.c: + Update code. + + * src/analysis/routine.c: + * src/analysis/routine.h: + Replace all vmpa_t by the new vmpa2t types. + + * src/arch/vmpa.c: + Change the default behavior when printing addresses. + + * src/core/params.c: + * src/core/params.h: + Add a new configuration parameter for choosing between physical and virtual + addresses when naming a symbol which has no name. + + * src/format/elf/symbols.c: + Load some ELF symbols from DYNSYM and SYMTAB sections. + + * src/format/format.h: + Mark g_binary_format_add_routine() as deprecated. + + * src/format/symbol.c: + * src/format/symbol.h: + Support routines as symbols and provide the location of each kind of symbols. + 14-08-27 Cyrille Bagard * src/analysis/disass/fetch.c: diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c index 20128aa..55ea1d4 100644 --- a/src/analysis/disass/fetch.c +++ b/src/analysis/disass/fetch.c @@ -135,22 +135,26 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt + vmpa2t *last; /* Dernière bordure rencontrée */ + + + GBinSymbol **symbols; /* Symboles à représenter */ size_t sym_count; /* Qté de symboles présents */ size_t i; /* Boucle de parcours */ - GArchInstruction *instr; /* Instruction à insérer */ - - - vmpa2t *last; /* Dernière bordure rencontrée */ const vmpa2t *border; /* Nouvelle bordure rencontrée */ off_t length; /* Taille d'une partie traitée */ + GArchInstruction *instr; /* Instruction à insérer */ + + + GArchInstruction *joint; /* Jointure entre deux lots */ @@ -179,19 +183,26 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt + border = g_binary_symbol_get_location(symbols[i], &length); switch (g_binary_symbol_get_target_type(symbols[i])) { case STP_DATA: instr = g_binary_symbol_get_instruction(symbols[i]); g_object_ref(G_OBJECT(instr)); - border = g_arch_instruction_get_location2(instr, &length); - - // Utiliser : ??? - // const vmpa2t *g_binary_symbol_get_address2(const GBinSymbol *symbol) + break; + case STP_ROUTINE: + instr = load_raw_binary(binary, border, + get_phy_addr(border) + length, + statusbar, id); break; + default: + printf("BADDD !\n"); + exit(0); + break; + } /* Traiter la diff */ diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c index 927088f..f368796 100644 --- a/src/analysis/disass/output.c +++ b/src/analysis/disass/output.c @@ -130,7 +130,7 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form if (sym_index < sym_count) { iaddr = g_arch_instruction_get_location2(iter, NULL); - saddr = g_binary_symbol_get_address2(symbols[sym_index]); + saddr = g_binary_symbol_get_location(symbols[sym_index], NULL); if (cmp_vmpa_by_phy(iaddr, saddr) == 0) { diff --git a/src/analysis/routine.c b/src/analysis/routine.c index d97dfc7..eebcb69 100644 --- a/src/analysis/routine.c +++ b/src/analysis/routine.c @@ -38,7 +38,7 @@ struct _GBinRoutine { GObject parent; /* A laisser en premier */ - vmpa_t addr; /* Position physique/mémoire */ + vmpa2t addr; /* Position physique/mémoire */ off_t size; /* Taille du code associé */ RoutineType type; /* Type de routine */ @@ -214,13 +214,7 @@ void g_binary_routine_finalize(GBinRoutine *routine) int g_binary_routine_compare(const GBinRoutine **a, const GBinRoutine **b) { - int result; /* Bilan à renvoyer */ - - if ((*a)->addr < (*b)->addr) result = -1; - else if((*a)->addr > (*b)->addr) result = 1; - else result = 0; - - return result; + return cmp_vmpa(&(*a)->addr, &(*b)->addr); } @@ -232,7 +226,7 @@ int g_binary_routine_compare(const GBinRoutine **a, const GBinRoutine **b) * * * Description : Etablit la comparaison descendante entre deux routines. * * * -* Retour : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b). * +* Retour : Bilan : 1 (a < b), 0 (a == b) ou -1 (a > b). * * * * Remarques : - * * * @@ -240,13 +234,7 @@ int g_binary_routine_compare(const GBinRoutine **a, const GBinRoutine **b) int g_binary_routine_rcompare(const GBinRoutine **a, const GBinRoutine **b) { - int result; /* Bilan à renvoyer */ - - if ((*a)->addr > (*b)->addr) result = -1; - else if((*a)->addr < (*b)->addr) result = 1; - else result = 0; - - return result; + return (-1) * cmp_vmpa(&(*a)->addr, &(*b)->addr); } @@ -264,9 +252,9 @@ int g_binary_routine_rcompare(const GBinRoutine **a, const GBinRoutine **b) * * ******************************************************************************/ -void g_binary_routine_set_address(GBinRoutine *routine, vmpa_t addr) +void g_binary_routine_set_address(GBinRoutine *routine, const vmpa2t *addr) { - routine->addr = addr; + copy_vmpa(&routine->addr, addr); } @@ -283,9 +271,9 @@ void g_binary_routine_set_address(GBinRoutine *routine, vmpa_t addr) * * ******************************************************************************/ -vmpa_t g_binary_routine_get_address(const GBinRoutine *routine) +const vmpa2t *g_binary_routine_get_address(const GBinRoutine *routine) { - return routine->addr; + return &routine->addr; } @@ -293,7 +281,7 @@ vmpa_t g_binary_routine_get_address(const GBinRoutine *routine) /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * -* addr = taille du code associé. * +* size = taille du code associé. * * * * Description : Définit la taille du code d'une routine. * * * diff --git a/src/analysis/routine.h b/src/analysis/routine.h index de1b6ba..29f6e63 100644 --- a/src/analysis/routine.h +++ b/src/analysis/routine.h @@ -87,10 +87,10 @@ int g_binary_routine_compare(const GBinRoutine **, const GBinRoutine **); int g_binary_routine_rcompare(const GBinRoutine **, const GBinRoutine **); /* Définit la position physique / en mémoire d'une routine. */ -void g_binary_routine_set_address(GBinRoutine *, vmpa_t); +void g_binary_routine_set_address(GBinRoutine *, const vmpa2t *); /* Fournit la position physique / en mémoire d'une routine. */ -vmpa_t g_binary_routine_get_address(const GBinRoutine *); +const vmpa2t *g_binary_routine_get_address(const GBinRoutine *); /* Définit la taille du code d'une routine. */ void g_binary_routine_set_size(GBinRoutine *, off_t); diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c index 297a0ca..aa97eba 100644 --- a/src/arch/vmpa.c +++ b/src/arch/vmpa.c @@ -368,7 +368,7 @@ char *vmpa2_phys_to_string(const vmpa2t *addr, MemoryDataSize msize, char buffer break; default: - ret = snprintf(buffer, VMPA_MAX_SIZE, "???"); + ret = snprintf(buffer, VMPA_MAX_SIZE, "0x%" PRIx64, addr->physical); break; } @@ -419,7 +419,7 @@ char *vmpa2_virt_to_string(const vmpa2t *addr, MemoryDataSize msize, char buffer break; default: - ret = snprintf(buffer, VMPA_MAX_SIZE, "???"); + ret = snprintf(buffer, VMPA_MAX_SIZE, "0x%" PRIx64, addr->virtual); break; } diff --git a/src/core/params.c b/src/core/params.c index 7bc1162..fdcbe3f 100644 --- a/src/core/params.c +++ b/src/core/params.c @@ -135,6 +135,9 @@ bool load_main_config_parameters(void) param = g_generic_config_create_param(config, MPK_SERVER_BACKLOG, CPT_INTEGER, 20); if (param == NULL) return false; + param = g_generic_config_create_param(config, MPK_FORMAT_NO_NAME, CPT_BOOLEAN, false); + if (param == NULL) return false; + param = g_generic_config_create_param(config, MPK_LAST_PROJECT, CPT_STRING, NULL); if (param == NULL) return false; diff --git a/src/core/params.h b/src/core/params.h index db01d20..3e78945 100644 --- a/src/core/params.h +++ b/src/core/params.h @@ -39,6 +39,7 @@ #define MPK_LOCAL_HOST "cdb.network.local.server" #define MPK_LOCAL_PORT "cdb.network.local.port" #define MPK_SERVER_BACKLOG "cdb.network.server.backlog" +#define MPK_FORMAT_NO_NAME "format.symbols.use_phy_instead_of_virt" #define MPK_LAST_PROJECT "gui.editor.last_project" #define MPK_ELLIPSIS_HEADER "gui.editor.panels.ellipsis_header" #define MPK_ELLIPSIS_TAB "gui.editor.panels.ellipsis_tab" diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c index dc3fbe0..06d7cab 100644 --- a/src/format/elf/symbols.c +++ b/src/format/elf/symbols.c @@ -37,6 +37,7 @@ #include "../mangling/demangler.h" #include "../../arch/raw.h" #include "../../common/extstr.h" +#include "../../core/params.h" #include "../../gui/panels/log.h" @@ -123,6 +124,12 @@ bool load_elf_symbols(GElfFormat *format) + /* Symboles internes */ + result = load_elf_internal_symbols(format); + + + + /* Symboles externes */ if (find_elf_sections_by_type(format, SHT_DYNAMIC, §ions, &count)) @@ -137,7 +144,7 @@ bool load_elf_symbols(GElfFormat *format) else log_variadic_message(LMT_INFO, _("Binary is statically linked")); /* Symboles internes */ - result &= load_elf_internal_symbols(format); + //result &= load_elf_internal_symbols(format); return result; @@ -1272,70 +1279,137 @@ static bool annotate_elf_section_header_table(GElfFormat *format) static bool load_elf_internal_symbols(GElfFormat *format) { bool result; /* Bilan à retourner */ - elf_shdr *symtabs; /* Groupe de sections trouvées */ + bool no_name; /* Choix de construction de nom*/ + elf_shdr *sections; /* Groupe de sections trouvées */ size_t count; /* Quantité de données */ size_t i; /* Boucle de parcours */ - elf_shdr strtab; /* Section .strtab trouvée */ - bool has_strtab; /* Présence de cette section */ - off_t sym_start; /* Début de la zone à traiter */ - off_t sym_size; /* Taille de cette même zone */ - off_t iter; /* Boucle de parcours */ - const char *name; /* Nom du symbole trouvé */ - elf_sym sym; /* Symbole aux infos visées */ - GBinRoutine *routine; /* Nouvelle routine trouvée */ - GBinSymbol *symbol; /* Nouveau symbole construit */ result = true; - if (find_elf_sections_by_type(format, SHT_SYMTAB, &symtabs, &count)) - for (i = 0; i < count && result; i++) + /* Charge tous les symboles définis dans une section */ + bool add_all_symbols_from_section(GElfFormat *format, const elf_shdr *section, bool use_virt) + { + elf_shdr strtab; /* Section .strtab trouvée */ + bool has_strtab; /* Présence de cette section */ + off_t start; /* Début de la zone à traiter */ + off_t size; /* Taille de cette même zone */ + off_t iter; /* Boucle de parcours */ + elf_sym sym; /* Symbole aux infos visées */ + vmpa2t addr; /* Localisation d'une routine */ + const char *name; /* Nom du symbole trouvé */ + char alt_name[5 + VMPA_MAX_LEN]; /* Nom abstrait de substitution*/ + GBinRoutine *routine; /* Nouvelle routine trouvée */ + GBinSymbol *symbol; /* Nouveau symbole construit */ + + has_strtab = find_elf_section_by_index(format, ELF_SHDR(format, *section, sh_link), &strtab); + + get_elf_section_content(format, section, &start, &size, NULL); + + for (iter = start; iter < (start + size); ) { - has_strtab = find_elf_section_by_index(format, ELF_SHDR(format, symtabs[i], sh_link), &strtab); + result = read_elf_symbol(format, &iter, &sym); + if (!result) break; + + if (ELF_SYM(format, sym, st_value) == 0) continue; + + /* Résolution précise d'adresse */ + + + /* TODO */ + + init_vmpa(&addr, ELF_SYM(format, sym, st_value), VMPA_NO_VIRTUAL); - get_elf_section_content(format, &symtabs[i], &sym_start, &sym_size, NULL); - for (iter = sym_start; iter < (sym_start + sym_size); ) + + /* Première ébauche de nom */ + + if (!has_strtab) name = NULL; + else name = get_elf_symbol_name(format, section, &strtab, + ((iter - start) / ELF_SIZEOF_SYM(format)) - 1); + + /* Traitements particuliers */ + + switch (ELF_ST_TYPE(format, sym)) { - result = read_elf_symbol(format, &iter, &sym); - if (!result) break; + case STT_OBJECT: - if (ELF_SYM(format, sym, st_value) == 0) continue; + /* Création d'un nom unique ? */ - if (!(ELF_ST_TYPE(format, sym) == STT_FUNC)) continue; + if (name != NULL) + { + strcpy(alt_name, "obj_"); - if (!has_strtab) name = NULL; - else name = get_elf_symbol_name(format, &symtabs[i], &strtab, - ((iter - sym_start) / ELF_SIZEOF_SYM(format)) - 1); + if (use_virt) + vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 4, NULL); + else + vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 4, NULL); - if (name == NULL) - { - /* FIXME */ - name = "unknown"; - } + } + + + /* TODO */ + + symbol = NULL; - /* Routine */ - routine = try_to_demangle_routine(name); + break; + + case STT_FUNC: + + /* Création d'un nom unique ? */ + + if (name != NULL) + { + strcpy(alt_name, "func_"); + + if (use_virt) + vmpa2_virt_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL); + else + vmpa2_phys_to_string(&addr, MDS_UNDEFINED, alt_name + 5, NULL); - g_binary_routine_set_address(routine, ELF_SYM(format, sym, st_value)); - g_binary_routine_set_size(routine, ELF_SYM(format, sym, st_size)); + } + + /* Routine */ + + routine = try_to_demangle_routine(name); - ///// reactiver g_binary_format_add_routine(G_BIN_FORMAT(format), routine); + g_binary_routine_set_address(routine, &addr); + g_binary_routine_set_size(routine, ELF_SYM(format, sym, st_size)); - /* Symbole uniquement */ + /* Symbole uniquement */ - symbol = g_binary_symbol_new(STP_FUNCTION, name, ELF_SYM(format, sym, st_value)); + symbol = g_binary_symbol_new(STP_ROUTINE, name, ~0); + g_binary_symbol_attach_routine(symbol, routine); - g_binary_symbol_attach_routine(symbol, routine); + break; - ///// reactiver g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); + default: + symbol = NULL; + break; } + if (symbol != NULL) + g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); } - return true; + return true; + + } + + if (!g_generic_config_get_value(get_main_configuration(), MPK_FORMAT_NO_NAME, &no_name)) + return false; + + if (find_elf_sections_by_type(format, SHT_DYNSYM, §ions, &count)) + for (i = 0; i < count && result; i++) + result = add_all_symbols_from_section(format, §ions[i], no_name); + + if (find_elf_sections_by_type(format, SHT_SYMTAB, §ions, &count)) + for (i = 0; i < count && result; i++) + result = add_all_symbols_from_section(format, §ions[i], no_name); + + return result; } diff --git a/src/format/format.h b/src/format/format.h index d87735d..2eed669 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -65,7 +65,7 @@ void g_binary_format_add_symbol(GBinFormat *, GBinSymbol *); GBinSymbol **g_binary_format_get_symbols(const GBinFormat *, size_t *); /* Ajoute une routine à la collection du format binaire. */ -void g_binary_format_add_routine(GBinFormat *, GBinRoutine *); +void g_binary_format_add_routine(GBinFormat *, GBinRoutine *) __attribute__ ((deprecated)); /* Fournit le prototype de toutes les routines détectées. */ GBinRoutine **g_binary_format_get_routines(const GBinFormat *, size_t *); diff --git a/src/format/symbol.c b/src/format/symbol.c index f1183cb..5b80555 100644 --- a/src/format/symbol.c +++ b/src/format/symbol.c @@ -192,8 +192,9 @@ vmpa_t g_binary_symbol_get_address(const GBinSymbol *symbol) /****************************************************************************** * * * Paramètres : symbol = symbole à venir consulter. * +* length = taille de l'instruction ou NULL. [OUT] * * * -* Description : Fournit l'adresse associée à un symbole. * +* Description : Fournit l'emplacement où se situe un symbole. * * * * Retour : Adresse virtuelle ou physique associée. * * * @@ -201,7 +202,7 @@ vmpa_t g_binary_symbol_get_address(const GBinSymbol *symbol) * * ******************************************************************************/ -const vmpa2t *g_binary_symbol_get_address2(const GBinSymbol *symbol) +const vmpa2t *g_binary_symbol_get_location(const GBinSymbol *symbol, off_t *length) { const vmpa2t *result; /* Localisation à retourner */ @@ -210,19 +211,20 @@ const vmpa2t *g_binary_symbol_get_address2(const GBinSymbol *symbol) switch (symbol->type) { case STP_DATA: - result = g_arch_instruction_get_location2(symbol->extra.instr, NULL); + result = g_arch_instruction_get_location2(symbol->extra.instr, length); break; - default: - result = NULL; - break; - - } - + case STP_ROUTINE: + result = g_binary_routine_get_address(symbol->extra.routine); + if (length != NULL) + *length = g_binary_routine_get_size(symbol->extra.routine); + break; - if (result == NULL) - printf("got addr=%p for symbol=%p (data=%d)\n", result, symbol, symbol->type == STP_DATA); + default: + result = NULL; + break; + } return result; diff --git a/src/format/symbol.h b/src/format/symbol.h index 407375f..8d27f97 100644 --- a/src/format/symbol.h +++ b/src/format/symbol.h @@ -37,6 +37,7 @@ typedef enum _SymbolType { STP_DATA, /* Données brutes */ + STP_ROUTINE, /* Simple morceau de code */ STP_OBJECT, /* Objet quelconque */ STP_FUNCTION, /* Simple morceau de code */ STP_STRING /* Chaîne de caractères */ @@ -73,10 +74,8 @@ const char *g_binary_symbol_to_string(const GBinSymbol *); /* Fournit l'adresse associée à un symbole. */ vmpa_t g_binary_symbol_get_address(const GBinSymbol *); - -/* Fournit l'adresse associée à un symbole. */ -const vmpa2t *g_binary_symbol_get_address2(const GBinSymbol *); - +/* Fournit l'emplacement où se situe un symbole. */ +const vmpa2t *g_binary_symbol_get_location(const GBinSymbol *, off_t *); /* Fournit la taille officielle d'un symbole. */ off_t g_binary_symbol_get_size(const GBinSymbol *); -- cgit v0.11.2-87-g4458