From a1c2bc0c3b6f4b4fda9c50beeb09a1f699419e2a Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 14 Dec 2014 23:32:23 +0000 Subject: Shown label of loaded symbols when possible. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@441 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 23 ++ src/analysis/disass/output.c | 60 ++++- src/format/elf/Makefile.am | 1 + src/format/elf/elf_def.h | 3 + src/format/elf/helper_arm.c | 576 +++++++++++++++++++++++++++++++++++++++++++ src/format/elf/helper_arm.h | 37 +++ src/format/elf/symbols.c | 128 ++++++++-- src/format/symbol.c | 92 +++++++ src/format/symbol.h | 6 + 9 files changed, 907 insertions(+), 19 deletions(-) create mode 100644 src/format/elf/helper_arm.c create mode 100644 src/format/elf/helper_arm.h diff --git a/ChangeLog b/ChangeLog index 0fa2ff3..0803f95 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +14-12-15 Cyrille Bagard + + * src/analysis/disass/output.c: + Show label of loaded symbols when possible. + + * src/format/elf/elf_def.h: + Define R_ARM_JUMP_SLOT value. + + * src/format/elf/helper_arm.c: + * src/format/elf/helper_arm.h: + New entries: load symbols from ARM relocations. + + * src/format/elf/Makefile.am: + Add the new 'helper_arm.[ch]' files to libformatelf_la_SOURCES. + + * src/format/elf/symbols.c: + Define an entry point and provide a way to get a full symbol definition. + Sort all loaded symbols. + + * src/format/symbol.c: + * src/format/symbol.h: + Create a function to compare two symbols and provide labels when requested. + 14-12-10 Cyrille Bagard * src/glibext/gbufferline.c: diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c index 2007f48..97924cd 100644 --- a/src/analysis/disass/output.c +++ b/src/analysis/disass/output.c @@ -80,6 +80,9 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form const vmpa2t *paddr; /* Adresse de portion */ + + const char *label; /* Etiquette ciblant un symbole*/ + GDbComment *comment; /* Commentaire à ajouter */ @@ -89,7 +92,6 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form char *prefixed; - output = g_asm_output_new(); @@ -100,8 +102,20 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form symbols = g_binary_format_get_symbols(format, &sym_count); sym_index = 0; +#if 0 + for (i = 0; i < sym_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(" '%s' -> 0x%08lx\n", + "g_binary_symbol_to_string(symbols[i])", + saddr->virtual); + } +#endif //GDbCollection *g_loaded_binary_find_collection(GLoadedBinary *, DBFeatures); @@ -157,6 +171,39 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form + + if (sym_index < sym_count) + { + iaddr = get_mrange_addr(g_arch_instruction_get_range(iter)); + saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index])); + + if (cmp_vmpa_by_virt(iaddr, saddr) == 0) + { + /* Etiquette ? */ + + label = g_binary_symbol_get_label(symbols[sym_index]); + + if (label != NULL) + { + line = g_code_buffer_append_new_line(buffer, g_binary_symbol_get_range(symbols[sym_index])); + g_buffer_line_fill_mrange(line, msize, msize); + + g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); + g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, label, strlen(label), RTT_COMMENT); + g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, ":", 1, RTT_PUNCT); + + + } + + } + + } + + + + + + line = g_arch_instruction_print(iter, buffer, msize, content, ASX_INTEL); if (sym_index < sym_count) @@ -164,9 +211,18 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form iaddr = get_mrange_addr(g_arch_instruction_get_range(iter)); saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index])); - if (cmp_vmpa_by_phy(iaddr, saddr) == 0) + /* + if (saddr->virtual == 0x8590) { + printf("instr = 0x%08x sym = 0x%08x\n", iaddr->virtual, saddr->virtual); + printf("COMP :: %d\n", cmp_vmpa_by_virt(iaddr, saddr)); + if (cmp_vmpa_by_virt(iaddr, saddr) == 0) exit(0); + } + */ + if (cmp_vmpa_by_virt(iaddr, saddr) == 0) + { + /* Commentaire ? */ comment = g_binary_symbol_get_comment(symbols[sym_index]); 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 . + */ + + +#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 +#include +#include + + +#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 . + */ + + +#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 /****************************************************************************** * * @@ -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(" '% 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 *); -- cgit v0.11.2-87-g4458