diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2014-12-14 23:32:23 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2014-12-14 23:32:23 (GMT) |
commit | a1c2bc0c3b6f4b4fda9c50beeb09a1f699419e2a (patch) | |
tree | 7856d9bc8fd702d0499f8a09156a555406eaaea9 /src/format | |
parent | 16d37d997b84c75c1f9b877fe446b3b3e5ce2495 (diff) |
Shown label of loaded symbols when possible.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@441 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format')
-rw-r--r-- | src/format/elf/Makefile.am | 1 | ||||
-rw-r--r-- | src/format/elf/elf_def.h | 3 | ||||
-rw-r--r-- | src/format/elf/helper_arm.c | 576 | ||||
-rw-r--r-- | src/format/elf/helper_arm.h | 37 | ||||
-rw-r--r-- | src/format/elf/symbols.c | 128 | ||||
-rw-r--r-- | src/format/symbol.c | 92 | ||||
-rw-r--r-- | src/format/symbol.h | 6 |
7 files changed, 826 insertions, 17 deletions
diff --git a/src/format/elf/Makefile.am b/src/format/elf/Makefile.am index fb76a9d..67fe148 100644 --- a/src/format/elf/Makefile.am +++ b/src/format/elf/Makefile.am @@ -5,6 +5,7 @@ libformatelf_la_SOURCES = \ elf-int.h elf-int.c \ elf.h elf.c \ elf_def.h \ + helper_arm.h helper_arm.c \ helper_x86.h helper_x86.c \ program.h program.c \ section.h section.c \ diff --git a/src/format/elf/elf_def.h b/src/format/elf/elf_def.h index f863257..b02469a 100644 --- a/src/format/elf/elf_def.h +++ b/src/format/elf/elf_def.h @@ -589,6 +589,9 @@ typedef union _elf_rel #define R_386_NONE 0 /* Pas de relocalisation */ #define R_386_JMP_SLOT 7 /* Entrée PLT */ +/* Type de relocalisation (ARM) */ + +#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ #endif /* _FORMAT_ELF_ELF_DEF_H */ diff --git a/src/format/elf/helper_arm.c b/src/format/elf/helper_arm.c new file mode 100644 index 0000000..d5e8af8 --- /dev/null +++ b/src/format/elf/helper_arm.c @@ -0,0 +1,576 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * helper_x86.c - gestion auxiliaire de l'architecture x86 + * + * Copyright (C) 2009-2012 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "helper_x86.h" + + +#include "elf-int.h" + + + + + + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* relxxx = section .rel.xxx trouvée (zone à traiter). * +* dynsym = section .dynsym trouvée (info. dynamiques). * +* dynstr = section .dynstr trouvée (chaînes de caractères). * +* * +* Description : Charge en mémoire la liste des symboles relogés. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_elf_arm_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx, const elf_shdr *dynsym, const elf_shdr *dynstr) +{ + bool result; /* Bilan à retourner */ + off_t rel_start; /* Début de la zone à traiter */ + off_t rel_size; /* Taille de cette même zone */ + off_t iter; /* Boucle de parcours */ + elf_rel reloc; /* Infos de relocalisation */ + off_t index; /* Indice de la portion visée */ + elf_sym sym; /* Définition complète */ + const char *name; /* Nom du symbole trouvé */ + + + + virt_t virt; /* Adresse en mémoire virtuelle */ + vmpa2t addr; /* Localisation d'une routine */ + mrange_t range; /* Couverture mémoire associée */ + GBinRoutine *routine; /* Nouvelle routine trouvée */ + GBinSymbol *symbol; /* Nouveau symbole construit */ + + + + + result = true; + + + + get_elf_section_content(format, relxxx, &rel_start, &rel_size, NULL); + + + printf("rel :: %d -> %d\n", rel_start, rel_start + rel_size); + + + + for (iter = rel_start; iter < (rel_start + rel_size); ) + { + result = read_elf_relocation(format, &iter, &reloc); + if (!result) break; + + index = ELF_REL_SYM(format, reloc); + + if (!get_elf_symbol_by_index(format, dynsym, index, &sym)) + continue; + + name = get_elf_symbol_name(format, dynsym, dynstr, index); + if (name == NULL) + { + /* FIXME */ + name = "unknown"; + } + + switch (ELF_REL_TYPE(format, reloc)) + { + case R_ARM_JUMP_SLOT: + + + virt = ELF_SYM(format, sym, st_value); + + + if (virt == 0) continue; + + + init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); + init_mrange(&range, &addr, 0); + + routine = try_to_demangle_routine(name); + + g_binary_routine_set_range(routine, &range); + + symbol = g_binary_symbol_new(STP_ROUTINE, NULL, ~0); + g_binary_symbol_attach_routine(symbol, routine); + g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); + + + + /* + printf("got a jump ! >> %d - %s\n", index, name); + printf(" -->> val = 0x%08lx\n", ELF_SYM(format, sym, st_value)); + printf(" -->> 0x%08lx =>> 0x%08lx\n", (unsigned int)ELF_REL(format, reloc, r_offset), + ((unsigned int)ELF_SHDR(format, (*relxxx), sh_addr) + ELF_REL(format, reloc, r_offset))); + */ + + //symbol = g_binary_symbol_new(STP_FUNCTION, name, ELF_REL(format, reloc, r_offset)); + //g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); + + break; + + default: + printf("Relocation not supported (%lld) !\n", ELF_REL_TYPE(format, reloc)); + break; + + } + + } + + return result; + +} + + + + + + + + + + + + + + + + + + + + + + + +#if 0 + +#include <malloc.h> +#include <stdio.h> +#include <string.h> + + +#include "elf-int.h" +#include "../symbol.h" +#include "../mangling/demangler.h" +#include "../../arch/immediate.h" +#include "../../arch/processor.h" +#include "../../arch/x86/instruction.h" + + +// Désactivation +#define g_x86_instruction_get_opcode(i) 0 + + +/* symbols.c : Récupère la désignation d'un symbole donné. */ +extern const char *get_elf_symbol_name(GElfFormat *, const elf_shdr *, const elf_shdr *, off_t); + + +/* Décode les instructions liées à la relocalisation. */ +GArchInstruction **decode_elf_relocations(GElfFormat *, const elf_shdr *, size_t *); + +/* Déduit les adresses effectives des relocalisations. */ +void translate_exe_elf_relocations(GElfFormat *, GArchInstruction **, size_t); + +/* Déduit les adresses effectives des relocalisations. */ +void translate_dyn_elf_relocations(GElfFormat *, GArchInstruction **, size_t, const elf_shdr *, const elf_shdr *, const elf_shdr *); + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* relxxx = section .rel.xxx trouvée (zone à traiter). * +* dynsym = section .dynsym trouvée (info. dynamiques). * +* dynstr = section .dynstr trouvée (chaînes de caractères). * +* * +* Description : Charge en mémoire la liste des symboles dynamiques. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_elf_x86_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx, const elf_shdr *dynsym, const elf_shdr *dynstr) +{ + bool result; /* Bilan à retourner */ + off_t rel_start; /* Début de la zone à traiter */ + off_t rel_size; /* Taille de cette même zone */ + off_t iter; /* Boucle de parcours */ + elf_rel reloc; /* Infos de relocalisation */ + off_t index; /* Indice de la portion visée */ + const char *name; /* Nom du symbole trouvé */ + GBinSymbol *symbol; /* Nouveau symbole construit */ + + + + + result = true; + + + + get_elf_section_content(format, relxxx, &rel_start, &rel_size, NULL); + + + printf("rel :: %d -> %d\n", rel_start, rel_start + rel_size); + + + + for (iter = rel_start; iter < (rel_start + rel_size); ) + { + result = read_elf_relocation(format, &iter, &reloc); + if (!result) break; + + switch (ELF_REL_TYPE(format, reloc)) + { + case R_386_NONE: + break; + + case R_386_JMP_SLOT: + + index = ELF_REL_SYM(format, reloc); + name = get_elf_symbol_name(format, dynsym, dynstr, index); + + + //printf("got a jump ! >> %d - %s\n", index, name); + + + if (name == NULL) + { + /* FIXME */ + name = "unknown"; + } + + symbol = g_binary_symbol_new(STP_FUNCTION, name, ELF_REL(format, reloc, r_offset)); + g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); + + break; + + default: + printf("Relocation not supported (%lld) !\n", ELF_REL_TYPE(format, reloc)); + break; + + } + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* plt = section .plt trouvée (points d'entrées dynamiques). * +* rel = section .rel.plt présentant la table des symboles. * +* dynsym = section listant tous les symboles. * +* dynstr = section contenant le nom de ces symboles. * +* * +* Description : Déduit les adresses effectives des appels externes. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool find_elf_x86_dynamic_symbols(GElfFormat *format, const elf_shdr *plt, const elf_shdr *rel, const elf_shdr *dynsym, const elf_shdr *dynstr) +{ + GArchInstruction **instructions; /* Instructions décodées */ + size_t count; /* Quantité d'instructions */ + size_t i; /* Boucle de parcours */ + + instructions = decode_elf_relocations(format, plt, &count); + + switch (ELF_HDR(format, format->header, e_type)) + { + case ET_EXEC: + translate_exe_elf_relocations(format, instructions, count); + break; + + case ET_DYN: + translate_dyn_elf_relocations(format, instructions, count, rel, dynsym, dynstr); + break; + + } + + for (i = 0; i < count; i++) + /* TODO : free instructions[i] */; + + if (instructions != NULL) + free(instructions); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* plt = section .plt trouvée (points d'entrées dynamiques). * +* count = nombre d'instructions lues. [OUT] * +* * +* Description : Décode les instructions liées à la relocalisation. * +* * +* Retour : Liste des instructions décodées ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction **decode_elf_relocations(GElfFormat *format, const elf_shdr *plt, size_t *count) +{ + GArchInstruction **result; /* Liste à renvoyer */ + off_t plt_start; /* Début de section */ + off_t plt_size; /* Taille de section */ + vmpa_t plt_address; /* Adresse virtuelle associée */ + GArchProcessor *proc; /* Processeur pour le décodage */ + off_t pos; /* Tête de lecture */ + vmpa_t address; /* Adresse virtuelle courante */ + GArchInstruction *instr; /* Instruction décodée */ + + result = NULL; + *count = 0; + + get_elf_section_content(format, plt, &plt_start, &plt_size, &plt_address); + + proc = get_arch_processor_for_type(APT_386); + + for (pos = 0; pos < plt_size; ) + { + address = plt_address + pos; + + instr = g_arch_processor_decode_instruction(proc, NULL /*FIXME*/, &G_BIN_FORMAT(format)->content[plt_start], + &pos, plt_size, address, NULL /*FIXME*/); + + result = (GArchInstruction **)realloc(result, ++(*count) * sizeof(GArchInstruction *)); + result[*count - 1] = instr; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* instructions = listes des instructions à interpréter. * +* count = nombre d'instructions lues. * +* * +* Description : Déduit les adresses effectives des relocalisations. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void translate_exe_elf_relocations(GElfFormat *format, GArchInstruction **instructions, size_t count) +{ + size_t i; /* Boucle de parcours #1 */ + X86Opcodes opcode_n0; /* Opcode de l'instruction n */ + X86Opcodes opcode_n1; /* Opcode de l'instruction n+1 */ + X86Opcodes opcode_n2; /* Opcode de l'instruction n+2 */ + const GArchOperand *operand; /* Valeur du saut */ + vmpa_t address; /* Adresse virtuelle finale */ + GBinSymbol **symbols; /* Liste des symboles existants*/ + size_t symbols_count; /* Taille de cette liste */ + size_t j; /* Boucle de parcours #2 */ + size_t new_len; /* Taille du nouveau nom */ + char *new_name; /* Nom avec suffixe @plt */ + GBinRoutine *routine; /* Nouvelle routine déduite */ + GBinSymbol *symbol; /* Nouveau symbole construit */ + + for (i = 0; (i + 2) < count; ) + { + opcode_n0 = g_x86_instruction_get_opcode(G_X86_INSTRUCTION(instructions[i])); + opcode_n1 = g_x86_instruction_get_opcode(G_X86_INSTRUCTION(instructions[i + 1])); + opcode_n2 = g_x86_instruction_get_opcode(G_X86_INSTRUCTION(instructions[i + 2])); + + if (opcode_n0 == XOP_JMP_RM1632 + && opcode_n1 == XOP_PUSH_IMM1632 + && opcode_n2 == XOP_JMP_REL1632) + { + operand = g_arch_instruction_get_operand(instructions[i], 0); + + if (g_imm_operand_to_vmpa_t(G_IMM_OPERAND(operand), &address)) + { + symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &symbols_count); + + for (j = 0; j < symbols_count; j++) + if (g_binary_symbol_get_address(symbols[j]) == address) + { + /* Nom final */ + + new_len = strlen(g_binary_symbol_to_string(symbols[j])) + 4 + 1; + new_name = calloc(new_len, sizeof(char)); + snprintf(new_name, new_len, "%s@plt", g_binary_symbol_to_string(symbols[j])); + + g_arch_instruction_get_location(instructions[i], NULL, NULL, &address); + + /* Routine */ + + routine = try_to_demangle_routine(g_binary_symbol_to_string(symbols[j])); + + ///g_binary_routine_set_address(routine, address); + + ///// reactiver g_binary_format_add_routine(G_BIN_FORMAT(format), routine); + + /* Symbole uniquement */ + + symbol = g_binary_symbol_new(STP_FUNCTION, new_name, address); + + g_binary_symbol_attach_routine(symbol, routine); + + g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); + + break; + + } + + } + + i += 3; + + } + else i++; + + } + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* instructions = listes des instructions à interpréter. * +* count = nombre d'instructions lues. * +* * +* Description : Déduit les adresses effectives des relocalisations. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void translate_dyn_elf_relocations(GElfFormat *format, GArchInstruction **instructions, size_t count, const elf_shdr *rel, const elf_shdr *dynsym, const elf_shdr *dynstr) +{ + off_t rel_start; /* Début de la zone à traiter */ + off_t rel_size; /* Taille de cette même zone */ + size_t i; /* Boucle de parcours #1 */ + X86Opcodes opcode_n0; /* Opcode de l'instruction n */ + X86Opcodes opcode_n1; /* Opcode de l'instruction n+1 */ + X86Opcodes opcode_n2; /* Opcode de l'instruction n+2 */ + const GArchOperand *operand; /* Valeur du saut */ + off_t pos; /* Tête de lecture */ + bool negative; /* Tête de lecture invalide ? */ + elf_rel reloc; /* Infos de relocalisation */ + off_t index; /* Indice de la portion visée */ + const char *name; /* Nom du symbole trouvé */ + size_t new_len; /* Taille du nouveau nom */ + char *new_name; /* Nom avec suffixe @plt */ + vmpa_t address; /* Adresse virtuelle finale */ + GBinRoutine *routine; /* Nouvelle routine déduite */ + GBinSymbol *symbol; /* Nouveau symbole construit */ + + get_elf_section_content(format, rel, &rel_start, &rel_size, NULL); + + for (i = 0; (i + 2) < count; ) + { + opcode_n0 = g_x86_instruction_get_opcode(G_X86_INSTRUCTION(instructions[i])); + opcode_n1 = g_x86_instruction_get_opcode(G_X86_INSTRUCTION(instructions[i + 1])); + opcode_n2 = g_x86_instruction_get_opcode(G_X86_INSTRUCTION(instructions[i + 2])); + + if (opcode_n0 == XOP_JMP_RM1632 + && opcode_n1 == XOP_PUSH_IMM1632 + && opcode_n2 == XOP_JMP_REL1632) + { + operand = g_arch_instruction_get_operand(instructions[i + 1], 0); + + if (!g_imm_operand_to_off_t(G_IMM_OPERAND(operand), &pos, &negative)) + goto next_op; + + if ((pos + ELF_SIZEOF_REL(format)) > rel_size) + goto next_op; + + pos += rel_start; + + if (!read_elf_relocation(format, &pos, &reloc)) + goto next_op; + + index = ELF_REL_SYM(format, reloc); + name = get_elf_symbol_name(format, dynsym, dynstr, index); + + if (name == NULL) + { + /* FIXME */ + name = "unknown"; + } + + /* Nom final */ + + new_len = strlen(name) + 4 + 1; + new_name = calloc(new_len, sizeof(char)); + snprintf(new_name, new_len, "%s@plt", name); + + g_arch_instruction_get_location(instructions[i], NULL, NULL, &address); + + /* Routine */ + + routine = try_to_demangle_routine(name); + + ////g_binary_routine_set_address(routine, address); + + ///// reactiver g_binary_format_add_routine(G_BIN_FORMAT(format), routine); + + /* Symbole uniquement */ + + symbol = g_binary_symbol_new(STP_FUNCTION, new_name, address); + + g_binary_symbol_attach_routine(symbol, routine); + + g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); + + next_op: + + i += 3; + + } + else i++; + + } + +} + +#endif diff --git a/src/format/elf/helper_arm.h b/src/format/elf/helper_arm.h new file mode 100644 index 0000000..d3fdcfa --- /dev/null +++ b/src/format/elf/helper_arm.h @@ -0,0 +1,37 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * helper_arm.h - prototypes pour la gestion auxiliaire de l'architecture ARM + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _FORMAT_ELF_HELPER_ARM_H +#define _FORMAT_ELF_HELPER_ARM_H + + +#include "section.h" + + + +/* Charge en mémoire la liste des symboles relogés. */ +bool load_elf_arm_relocated_symbols(GElfFormat *, const elf_shdr *, const elf_shdr *, const elf_shdr *); + + + +#endif /* _FORMAT_ELF_HELPER_ARM_H */ diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c index 15c3a6b..30bdcca 100644 --- a/src/format/elf/symbols.c +++ b/src/format/elf/symbols.c @@ -32,6 +32,7 @@ #include "elf-int.h" +#include "helper_arm.h" #include "helper_x86.h" #include "section.h" #include "../mangling/demangler.h" @@ -46,6 +47,10 @@ + +/* Récupère la définition complète d'un symbole donné. */ +bool get_elf_symbol_by_index(GElfFormat *, const elf_shdr *, off_t, elf_sym *); + /* Récupère la désignation d'un symbole donné. */ const char *get_elf_symbol_name(GElfFormat *, const elf_shdr *, const elf_shdr *, off_t); @@ -92,7 +97,7 @@ static bool load_elf_external_symbols(GElfFormat *, const elf_shdr *); - +#include <stdlib.h> /****************************************************************************** * * @@ -109,29 +114,57 @@ static bool load_elf_external_symbols(GElfFormat *, const elf_shdr *); bool load_elf_symbols(GElfFormat *format) { bool result; /* Bilan à retourner */ + + virt_t entry_point; + vmpa2t addr; /* Localisation d'une routine */ + mrange_t range; /* Couverture mémoire associée */ + GBinRoutine *routine; /* Nouvelle routine trouvée */ + GBinSymbol *symbol; /* Nouveau symbole construit */ + elf_shdr *sections; /* Groupe de sections trouvées */ size_t count; /* Quantité de données */ result = true; - +#if 1 annotate_elf_header(format); annotate_elf_program_header_table(format); annotate_elf_section_header_table(format); - +#endif /* Symboles internes */ +#if 0 result = load_elf_internal_symbols(format); +#endif + entry_point = ELF_HDR(format, format->header, e_entry); + printf("E_ENTRY : 0x%08lx\n", (unsigned long)entry_point); - /* Symboles externes */ + if (ELF_HDR(format, format->header, e_machine) == EM_ARM) + entry_point &= ~0x1; + + + init_vmpa(&addr, VMPA_NO_PHYSICAL, entry_point); + + init_mrange(&range, &addr, 0); + + routine = try_to_demangle_routine("entry_point"); + + g_binary_routine_set_range(routine, &range); + + symbol = g_binary_symbol_new(STP_ROUTINE, "entry_point", ~0); + g_binary_symbol_attach_routine(symbol, routine); + g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); + + /* Symboles externes */ +#if 1 if (find_elf_sections_by_type(format, SHT_DYNAMIC, §ions, &count)) { log_variadic_message(LMT_INFO, _("Binary is dynamically linked")); @@ -142,10 +175,41 @@ bool load_elf_symbols(GElfFormat *format) } else log_variadic_message(LMT_INFO, _("Binary is statically linked")); - +#endif /* Symboles internes */ //result &= load_elf_internal_symbols(format); + + + qsort(G_BIN_FORMAT(format)->symbols, G_BIN_FORMAT(format)->symbols_count, + sizeof(GBinSymbol *), (__compar_fn_t)g_binary_symbol_cmp); + +#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 + return result; } @@ -155,36 +219,56 @@ bool load_elf_symbols(GElfFormat *format) * * * Paramètres : format = description de l'exécutable à consulter. * * sym = section comprenant les symboles à venir lire. * -* str = section de chaînes de caractères pour les noms. * * index = indice de l'entrée à venir lire. * +* symbol = ensemble d'informations lues. [OUT] * * * -* Description : Récupère la désignation d'un symbole donné. * +* Description : Récupère la définition complète d'un symbole donné. * * * -* Retour : Nom du symbole trouvé, ou NULL si erreur ou non adapté. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -const char *get_elf_symbol_name(GElfFormat *format, const elf_shdr *sym, const elf_shdr *str, off_t index) +bool get_elf_symbol_by_index(GElfFormat *format, const elf_shdr *sym, off_t index, elf_sym *symbol) { - const char *result; /* Résultat à retourner */ off_t sym_start; /* Début de section */ off_t sym_size; /* Taille de section */ - off_t str_start; /* Début de section */ - off_t str_size; /* Taille de section */ off_t offset; /* Emplacement à venir lire */ - elf_sym symbol; /* Symbole aux infos visées */ - - result = NULL; get_elf_section_content(format, sym, &sym_start, &sym_size, NULL); - get_elf_section_content(format, str, &str_start, &str_size, NULL); offset = sym_start + index * ELF_SIZEOF_SYM(format); if ((offset + ELF_SIZEOF_SYM(format)) > (sym_start + sym_size)) return NULL; - if (read_elf_symbol(format, &offset, &symbol)) + return read_elf_symbol(format, &offset, symbol); + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* sym = section comprenant les symboles à venir lire. * +* str = section de chaînes de caractères pour les noms. * +* index = indice de l'entrée à venir lire. * +* * +* Description : Récupère la désignation d'un symbole donné. * +* * +* Retour : Nom du symbole trouvé, ou NULL si erreur ou non adapté. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *get_elf_symbol_name(GElfFormat *format, const elf_shdr *sym, const elf_shdr *str, off_t index) +{ + const char *result; /* Résultat à retourner */ + elf_sym symbol; /* Symbole aux infos visées */ + + result = NULL; + + if (get_elf_symbol_by_index(format, sym, index, &symbol)) result = extract_name_from_elf_string_section(format, str, ELF_SYM(format, symbol, st_name)); return result; @@ -1374,6 +1458,8 @@ static bool load_elf_internal_symbols(GElfFormat *format) /* Routine */ + printf("ADDING>> '%s'\n", name); + routine = try_to_demangle_routine(name); g_binary_routine_set_range(routine, &range); @@ -1537,6 +1623,10 @@ static bool load_elf_external_symbols(GElfFormat *format, const elf_shdr *sectio if (result) switch (g_exe_format_get_target_machine(G_EXE_FORMAT(format))) { + case FTM_ARM: + result = load_elf_arm_relocated_symbols(format, &relxxx, &dynsym, &dynstr); + break; + case FTM_386: result = load_elf_x86_relocated_symbols(format, &relxxx, &dynsym, &dynstr); break; @@ -1548,6 +1638,8 @@ static bool load_elf_external_symbols(GElfFormat *format, const elf_shdr *sectio } +#if 0 + /* Entrées équivalentes dans le binaire */ if (find_elf_dynamic_item(format, section, DT_SYMTAB, &item)) { @@ -1591,6 +1683,8 @@ static bool load_elf_external_symbols(GElfFormat *format, const elf_shdr *sectio } +#endif + return result; } diff --git a/src/format/symbol.c b/src/format/symbol.c index 0875e1f..3a909b4 100644 --- a/src/format/symbol.c +++ b/src/format/symbol.c @@ -138,6 +138,56 @@ GBinSymbol *g_binary_symbol_new(SymbolType type, const char *name, vmpa_t addres /****************************************************************************** * * +* Paramètres : a = premier symbole à analyser. * +* b = second symbole à analyser. * +* * +* Description : Compare deux symboles d'exécutable selon leurs propriétés. * +* * +* Retour : Bilan de la comparaison : -1, 0 ou 1 (-1 par défaut). * +* * +* Remarques : - * +* * +******************************************************************************/ + +int g_binary_symbol_cmp(const GBinSymbol **a, const GBinSymbol **b) +{ + int result; /* Bilan à retourner */ + const mrange_t *ra; /* Emplacement du symbole A */ + const mrange_t *rb; /* Emplacement du symbole B */ + const vmpa2t *aa; /* Adresse du symbole A */ + const vmpa2t *ab; /* Adresse du symbole B */ + + ra = g_binary_symbol_get_range(*a); + rb = g_binary_symbol_get_range(*b); + + if (ra == NULL && rb == NULL) + result = 0; + + else if (ra != NULL && rb == NULL) + result = 1; + + else if (ra == NULL && rb != NULL) + result = -1; + + else + { + aa = get_mrange_addr(ra); + ab = get_mrange_addr(rb); + + result = aa->virtual < ab->virtual ? -1 : (aa->virtual > ab->virtual ? 1 : 0); + ///result = cmp_mrange(ra, rb); + + //printf(" ?? 0x%08lx vs 0x%08lx -> %d\n", aa->virtual, ab->virtual, result); + + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : symbol = symbole à venir consulter. * * * * Description : Fournit le type du symbole. * @@ -189,6 +239,48 @@ vmpa_t g_binary_symbol_get_address(const GBinSymbol *symbol) } + + + + + + + +/****************************************************************************** +* * +* Paramètres : symbol = symbole à venir consulter. * +* * +* Description : Fournit un étiquette pour viser un symbole. * +* * +* Retour : Chaîne de caractères renvoyant au symbole. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_binary_symbol_get_label(const GBinSymbol *symbol) +{ + const char *result; /* Etiquette à retourner */ + + result = NULL; + + switch (symbol->type) + { + case STP_ROUTINE: + result = g_binary_routine_get_name(symbol->extra.routine); + break; + + default: + result = NULL; + break; + + } + + return result; + +} + + /****************************************************************************** * * * Paramètres : symbol = symbole à venir consulter. * diff --git a/src/format/symbol.h b/src/format/symbol.h index 91268f1..76bf46b 100644 --- a/src/format/symbol.h +++ b/src/format/symbol.h @@ -65,6 +65,9 @@ GType g_binary_symbol_get_type(void); /* Crée un nouveau symbole d'exécutable. */ GBinSymbol *g_binary_symbol_new(SymbolType, const char *, vmpa_t); +/* Compare deux symboles d'exécutable selon leurs propriétés. */ +int g_binary_symbol_cmp(const GBinSymbol **, const GBinSymbol **); + /* Fournit le type du symbole. */ SymbolType g_binary_symbol_get_target_type(const GBinSymbol *); @@ -74,6 +77,9 @@ 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 un étiquette pour viser un symbole. */ +const char *g_binary_symbol_get_label(const GBinSymbol *); + /* Fournit l'emplacement où se situe un symbole. */ const mrange_t *g_binary_symbol_get_range(const GBinSymbol *); |