diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2014-09-01 22:20:28 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2014-09-01 22:20:28 (GMT) | 
| commit | 04ca0756d59629113bd3f602565850a2910ac84e (patch) | |
| tree | 26c70bc546e4ac55967530beb583dc851b2f82c9 /src/format | |
| parent | a738b482b70d263252ec4dc18919c71503490297 (diff) | |
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
Diffstat (limited to 'src/format')
| -rw-r--r-- | src/format/elf/symbols.c | 150 | ||||
| -rw-r--r-- | src/format/format.h | 2 | ||||
| -rw-r--r-- | src/format/symbol.c | 24 | ||||
| -rw-r--r-- | src/format/symbol.h | 7 | 
4 files changed, 129 insertions, 54 deletions
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 *);  | 
