diff options
-rw-r--r-- | ChangeLog | 25 | ||||
-rw-r--r-- | src/arch/x86/instruction.c | 19 | ||||
-rw-r--r-- | src/arch/x86/instruction.h | 3 | ||||
-rw-r--r-- | src/format/elf/Makefile.am | 1 | ||||
-rw-r--r-- | src/format/elf/e_elf.c | 18 | ||||
-rw-r--r-- | src/format/elf/elf-int.h | 14 | ||||
-rw-r--r-- | src/format/elf/helper_mips.c | 2 | ||||
-rw-r--r-- | src/format/elf/helper_x86.c | 226 | ||||
-rw-r--r-- | src/format/elf/helper_x86.h | 41 | ||||
-rw-r--r-- | src/format/elf/symbol.c | 251 |
10 files changed, 384 insertions, 216 deletions
@@ -1,3 +1,28 @@ +09-07-15 Cyrille Bagard <nocbos@gmail.com> + + * src/arch/x86/instruction.c: + * src/arch/x86/instruction.h: + Provide the opcode of an x86 instruction. + + * src/format/elf/e_elf.c: + Provide found routines instead of building routines from symbols. + + * src/format/elf/elf-int.h: + Store all found ELF relocations and routines. + + * src/format/elf/helper_mips.c: + Typo. + + * src/format/elf/helper_x86.c: + * src/format/elf/helper_x86.h: + New entries: load ELF relocations as new routines. + + * src/format/elf/Makefile.am: + Add the helper_x86.[ch] files to libformatelf_la_SOURCES. + + * src/format/elf/symbol.c: + Call x86 functions from helper_x86.[ch] and clean the code. + 09-07-14 Cyrille Bagard <nocbos@gmail.com> * src/configuration.c: diff --git a/src/arch/x86/instruction.c b/src/arch/x86/instruction.c index 3cf4a6b..0321e88 100644 --- a/src/arch/x86/instruction.c +++ b/src/arch/x86/instruction.c @@ -403,6 +403,25 @@ GArchInstruction *g_x86_instruction_new(X86Opcodes type) /****************************************************************************** * * +* Paramètres : instr = instruction à consulter. * +* * +* Description : Fournit l'identifiant de l'opcode représenté. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +X86Opcodes g_x86_instruction_get_opcode(const GX86Instruction *instr) +{ + return instr->type; + +} + + +/****************************************************************************** +* * * Paramètres : instr = instruction à venir compléter. * * prefixes = listes des préfixes rencontrés. * * * diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h index 2f59c46..d3b68c9 100644 --- a/src/arch/x86/instruction.h +++ b/src/arch/x86/instruction.h @@ -276,6 +276,9 @@ GType g_x86_instruction_get_type(void); /* Crée une instruction pour l'architecture x86. */ GArchInstruction *g_x86_instruction_new(X86Opcodes); +/* Fournit l'identifiant de l'opcode représenté. */ +X86Opcodes g_x86_instruction_get_opcode(const GX86Instruction *); + /* Attache à une instructions ses préfixes associés. */ void g_x86_instruction_set_prefixes(GX86Instruction *, X86Prefix); diff --git a/src/format/elf/Makefile.am b/src/format/elf/Makefile.am index fa481ca..822ea44 100644 --- a/src/format/elf/Makefile.am +++ b/src/format/elf/Makefile.am @@ -5,6 +5,7 @@ libformatelf_la_SOURCES = \ e_elf.h e_elf.c \ elf-int.h \ helper_mips.h helper_mips.c \ + helper_x86.h helper_x86.c \ section.h section.c \ strings.h strings.c \ symbol.h symbol.c diff --git a/src/format/elf/e_elf.c b/src/format/elf/e_elf.c index e974b51..081e245 100644 --- a/src/format/elf/e_elf.c +++ b/src/format/elf/e_elf.c @@ -590,22 +590,8 @@ bool resolve_elf_symbol(const elf_format *format, char **label, SymbolType *type GBinRoutine **get_all_elf_routines(const elf_format *format, size_t *count) { - GBinRoutine **result; /* Tableau à retourner */ - size_t i; /* Boucle de parcours */ - - result = (GBinRoutine **)calloc(format->sym_count, sizeof(GBinRoutine *)); - *count = format->sym_count; - - for (i = 0; i < format->sym_count; i++) - { - result[i] = g_binary_routine_new(); + *count = format->routines_count; - g_binary_routine_set_address(result[i], format->symbols[i].address); - g_binary_routine_set_size(result[i], format->symbols[i].size); - g_binary_routine_set_name(result[i], strdup(format->symbols[i].name)); - - } - - return result; + return format->routines; } diff --git a/src/format/elf/elf-int.h b/src/format/elf/elf-int.h index 65fc922..b828a88 100644 --- a/src/format/elf/elf-int.h +++ b/src/format/elf/elf-int.h @@ -52,6 +52,14 @@ typedef struct _elf_symbol } elf_symbol; +/* Relocalisation trouvée */ +typedef struct _elf_relocation +{ + const char *name; /* Désignation du symbole */ + vmpa_t address; /* Adresse du symbole */ + +} elf_relocation; + /* Description du format ELF */ @@ -65,6 +73,12 @@ struct _elf_format char *sec_names; /* Noms des sections */ size_t sec_size; /* Taille de ces définitions */ + elf_relocation *relocations; /* Liste des relocalisations */ + size_t rel_count; /* Taille de cette liste */ + + GBinRoutine **routines; /* Liste des routines trouvées */ + size_t routines_count; /* Nombre de ces routines */ + elf_symbol *symbols; /* Liste des symboles */ size_t sym_count; /* Taille de cette liste */ diff --git a/src/format/elf/helper_mips.c b/src/format/elf/helper_mips.c index b56db5d..7b1da76 100644 --- a/src/format/elf/helper_mips.c +++ b/src/format/elf/helper_mips.c @@ -41,7 +41,7 @@ * * * Description : Déduit les adresses effectives des appels externes. * * * -* Retour : - * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * diff --git a/src/format/elf/helper_x86.c b/src/format/elf/helper_x86.c new file mode 100644 index 0000000..39bdcfc --- /dev/null +++ b/src/format/elf/helper_x86.c @@ -0,0 +1,226 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * helper_x86.c - gestion auxiliaire de l'architecture x86 + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * 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 <malloc.h> +#include <string.h> + + +#include "elf-int.h" +#include "section.h" +#include "../../arch/immediate.h" +#include "../../arch/processor.h" +#include "../../arch/x86/instruction.h" +#include "../../panel/log.h" + + + +/* Décode les instructions liées à la relocalisation. */ +GArchInstruction **decode_elf_relocations(elf_format *, size_t *); + +/* Déduit les adresses effectives des relocalisations. */ +void translate_elf_relocations(elf_format *, GArchInstruction **, size_t); + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* dyn_start = début des informations dynamiques associées. * +* dyn_size = taille de la zone associée. * +* str_start = début de la zone de chaîne de caractères. * +* str_size = taille de la zone de chaînes de caractères. * +* * +* Description : Déduit les adresses effectives des appels externes. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_elf_format_find_x86_dynamic_symbols(elf_format *format, off_t dyn_start, off_t dyn_size, off_t str_start, off_t str_size) +{ + GArchInstruction **instructions; /* Instructions décodées */ + size_t count; /* Quantité d'instructions */ + size_t i; /* Boucle de parcours */ + + instructions = decode_elf_relocations(format, &count); + + translate_elf_relocations(format, instructions, count); + + 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. * +* 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(elf_format *format, 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 */ + Elf_Shdr *sections; /* Groupe de sections trouvées */ + size_t sec_count; /* Quantité de données */ + size_t i; /* Boucle de parcours */ + 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; + + if (!find_elf_section_content_by_name(format, ".plt", &plt_start, &plt_size, &plt_address)) + { + log_simple_message(LMT_BAD_BINARY, _("No .plt section found ! Trying to guess it...")); + + /* FIXME : 64 bits ! */ + + find_elf_section_by_type(format, SHT_PROGBITS, §ions, &sec_count); + + for (i = 0; i < sec_count; i++) + if (ELF_SHDR(format, §ions[i], sh_entsize) > 0) + { + get_elf_section_content(format, §ions[i], &plt_start, &plt_size, &plt_address); + break; + } + + free(sections); + + if (i == sec_count) return NULL; + + } + + 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, &EXE_FORMAT(format)->content[plt_start], + &pos, plt_size, 0/* FIXME*/, address); + + 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_elf_relocations(elf_format *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 */ + GArchOperand *operand; /* Valeur du saut */ + vmpa_t address; /* Adresse virtuelle finale */ + 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 */ + + 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); + + + g_imm_operand_to_vmpa_t(G_IMM_OPERAND(operand), &address); + + if (g_imm_operand_to_vmpa_t(G_IMM_OPERAND(operand), &address)) + for (j = 0; j < format->rel_count; j++) + if (format->relocations[j].address == address) + { + new_len = strlen(format->relocations[j].name) + 4 + 1; + new_name = calloc(new_len, sizeof(char)); + snprintf(new_name, new_len, "%s@plt", format->relocations[j].name); + + g_arch_instruction_get_location(instructions[i], NULL, NULL, &address); + + routine = g_binary_routine_new(); + + g_binary_routine_set_name(routine, new_name); + g_binary_routine_set_address(routine, address); + + format->routines = (GBinRoutine **)realloc(format->routines, + ++format->routines_count * sizeof(GBinRoutine *)); + + format->routines[format->routines_count - 1] = routine; + + } + + i += 3; + + } + else i++; + + } + +} diff --git a/src/format/elf/helper_x86.h b/src/format/elf/helper_x86.h new file mode 100644 index 0000000..957c8c3 --- /dev/null +++ b/src/format/elf/helper_x86.h @@ -0,0 +1,41 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * helper_x86.h - prototypes pour la gestion auxiliaire de l'architecture x86 + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * 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_X86_H +#define _FORMAT_ELF_HELPER_X86_H + + +#include <stdbool.h> +#include <sys/types.h> + + +#include "e_elf.h" + + + +/* Déduit les adresses effectives des appels externes. */ +bool g_elf_format_find_x86_dynamic_symbols(elf_format *, off_t, off_t, off_t, off_t); + + + +#endif /* _FORMAT_ELF_HELPER_X86_H */ diff --git a/src/format/elf/symbol.c b/src/format/elf/symbol.c index 225e032..4fd56fe 100644 --- a/src/format/elf/symbol.c +++ b/src/format/elf/symbol.c @@ -36,6 +36,7 @@ #include "elf-int.h" +#include "helper_mips.h" #include "section.h" @@ -51,12 +52,6 @@ bool load_elf_relocation_table(elf_format *, const off_t *, const off_t *, const /* Récupère les informations d'un symbole dynamique donné. */ char *get_elf_dynamic_symbol_info(elf_format *, const off_t *, const off_t *, const off_t *, const off_t *, const off_t *); -/* Décode les instructions liées à la relocalisation. */ -//asm_instr **decode_elf_relocations(elf_format *, size_t *); - -/* Déduit les adresses effectives des relocalisations. */ -//void translate_elf_relocations(elf_format *, asm_instr **, size_t); - @@ -102,8 +97,6 @@ bool load_elf_symbols(elf_format *format) off_t dyn_size; /* Taille de section */ - //asm_instr **instructions; /* Instructions décodées */ - result = true; @@ -137,56 +130,11 @@ bool load_elf_symbols(elf_format *format) } - /* Liaison dynamique (si elle existe) */ - - test = find_elf_section_by_name(format, ".dynsym", §ion); - - if (!test) - { - test = find_elf_section_by_type(format, SHT_HASH, §ions, &count); - - if (test) - test = find_elf_section_by_index(format, ELF_SHDR(format, §ions[0], sh_link), §ion); - - } - - if (test) - { - get_elf_section_content(format, §ion, &dyn_start, &dyn_size, NULL); - - result &= find_elf_section_by_index(format, ELF_SHDR(format, §ion, sh_link), §ion); - - } - - if (result) - { - get_elf_section_content(format, §ion, &str_start, &str_size, NULL); + /* Relocalisations */ - switch (get_elf_target_machine(format)) - { - case FTM_MIPS: - result = g_elf_format_find_mips_dynamic_symbols(format, dyn_start, dyn_size, str_start, str_size); - break; - default: - break; - - } - - } - - - - - - - - - - - -#if 0 + /* TODO : fixme ! */ find_elf_section_by_type(format, SHT_REL, §ions, &count); @@ -215,35 +163,59 @@ bool load_elf_symbols(elf_format *format) result = load_elf_relocation_table(format, &rel_start, &rel_size, &dyn_start, &dyn_size, &str_start, &str_size); - } } free(sections); - /* Récupération (seconde partie) */ + /* TODO : fixme ! */ - /* switch ... */ - g_elf_format_translate_mips_external_calls(format); - exit(0); + /* Liaison dynamique (si elle existe) */ - if (result) + test = find_elf_section_by_name(format, ".dynsym", §ion); + + if (!test) { -#if 0 - instructions = decode_elf_relocations(format, &count); + test = find_elf_section_by_type(format, SHT_HASH, §ions, &count); - translate_elf_relocations(format, instructions, count); + if (test) + test = find_elf_section_by_index(format, ELF_SHDR(format, §ions[0], sh_link), §ion); + + } + + if (test) + { + get_elf_section_content(format, §ion, &dyn_start, &dyn_size, NULL); + + result &= find_elf_section_by_index(format, ELF_SHDR(format, §ion, sh_link), §ion); - /* TODO : free instructions */ -#endif } -#endif + if (result) + { + get_elf_section_content(format, §ion, &str_start, &str_size, NULL); + + switch (get_elf_target_machine(format)) + { + case FTM_MIPS: + result = g_elf_format_find_mips_dynamic_symbols(format, dyn_start, dyn_size, str_start, str_size); + break; + + case FTM_386: + result = g_elf_format_find_x86_dynamic_symbols(format, dyn_start, dyn_size, str_start, str_size); + break; + + default: + break; + + } + + } return result; @@ -274,6 +246,7 @@ bool load_elf_symbol_table_32(elf_format *format, const off_t *sym_start, const { off_t iter; /* Boucle de parcours */ Elf32_Sym symbol; /* Symbole ELF lu */ + GBinRoutine *routine; /* Nouvelle routine trouvée */ if (*sym_size % sizeof(Elf32_Sym) != 0) return false; @@ -293,11 +266,16 @@ bool load_elf_symbol_table_32(elf_format *format, const off_t *sym_start, const /* Si le symbole possède un nom... */ if (strlen(&EXE_FORMAT(format)->content[*str_start + symbol.st_name]) > 0) { - format->symbols = (elf_symbol *)realloc(format->symbols, ++format->sym_count * sizeof(elf_symbol)); + routine = g_binary_routine_new(); - format->symbols[format->sym_count - 1].name = &EXE_FORMAT(format)->content[*str_start + symbol.st_name]; - format->symbols[format->sym_count - 1].address = symbol.st_value; - format->symbols[format->sym_count - 1].size = symbol.st_size; + g_binary_routine_set_name(routine, strdup(&EXE_FORMAT(format)->content[*str_start + symbol.st_name])); + g_binary_routine_set_address(routine, symbol.st_value); + g_binary_routine_set_size(routine, symbol.st_size); + + format->routines = (GBinRoutine **)realloc(format->routines, + ++format->routines_count * sizeof(GBinRoutine *)); + + format->routines[format->routines_count - 1] = routine; } @@ -456,10 +434,10 @@ bool load_elf_relocation_table(elf_format *format, const off_t *plt_start, const if (name != NULL) { - format->symbols = (elf_symbol *)realloc(format->symbols, ++format->sym_count * sizeof(elf_symbol)); + format->relocations = (elf_symbol *)realloc(format->relocations, ++format->rel_count * sizeof(elf_symbol)); - format->symbols[format->sym_count - 1].name = name; - format->symbols[format->sym_count - 1].address = ELF_REL(format, reloc, r_offset); + format->relocations[format->rel_count - 1].name = name; + format->relocations[format->rel_count - 1].address = ELF_REL(format, reloc, r_offset); } @@ -519,128 +497,3 @@ char *get_elf_dynamic_symbol_info(elf_format *format, const off_t *dyn_start, co return (char *)&EXE_FORMAT(format)->content[*str_start + ELF_SYM(format, symbol, st_name)]; } - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* 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 : - * -* * -******************************************************************************/ -#if 0 -asm_instr **decode_elf_relocations(elf_format *format, size_t *count) -{ - asm_instr **result; /* Liste à renvoyer */ - off_t rel_start; /* Début de section */ - off_t rel_size; /* Taille de section */ - uint64_t rel_vaddress; /* Adresse virtuelle associée */ - Elf_Shdr *sections; /* Groupe de sections trouvées */ - size_t sec_count; /* Quantité de données */ - size_t i; /* Boucle de parcours */ - off_t pos; /* Tête de lecture */ - uint64_t offset; /* Adresse virtuelle courante */ - asm_instr *instr; /* Instruction décodée */ -#if 0 - asm_processor *proc; /* TODO : remove me ! */ - proc = create_x86_processor(); - - result = NULL; - *count = 0; - - if (!find_elf_section_content_by_name(format, ".plt", &rel_start, &rel_size, &rel_vaddress)) - { - printf("No .plt section found ! Trying to guess it...\n"); - - find_elf_section_by_type(format, SHT_PROGBITS, §ions, &sec_count); - - for (i = 0; i < sec_count; i++) - if (ELF_SHDR(format, §ions[i], sh_entsize) > 0) - { - get_elf_section_content(format, §ions[i], &rel_start, &rel_size, &rel_vaddress); - break; - } - - free(sections); - - if (i == sec_count) return NULL; - - } - - for (pos = 0; pos < rel_size; ) - { - offset = rel_vaddress + pos; - - instr = decode_instruction(proc, &EXE_FORMAT(format)->content[rel_start], &pos, rel_size, 0/* FIXME*/, offset); - - result = (asm_instr **)realloc(result, ++(*count) * sizeof(asm_instr *)); - result[*count - 1] = instr; - - } -#endif - - result = NULL; - *count = 0; - - return result; - -} -#endif -#if 0 -/****************************************************************************** -* * -* 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_elf_relocations(elf_format *format, asm_instr **instructions, size_t count) -{ - size_t i; /* Boucle de parcours #1 */ - uint64_t address; /* Adresse virtuelle finale */ - size_t j; /* Boucle de parcours #2 */ - size_t new_len; /* Taille du nouveau nom */ - char *new_name; /* Nom avec suffixe @plt */ - - for (i = 0; (i + 2) < count; ) - { - if ((instructions[i]->type == AIT_JUMP || instructions[i]->type == AIT_CALL) - && instructions[i + 1]->type == AIT_PUSH - && instructions[i + 2]->type == AIT_JUMP) - { - if (get_imm_operand_value(instructions[i]->operands[0], AOS_64_BITS_UNSIGNED, &address)) - for (j = 0; j < format->sym_count; j++) - if (format->symbols[j].address == address) - { - new_len = strlen(format->symbols[j].name) + 4 + 1; - new_name = calloc(new_len, sizeof(char)); - snprintf(new_name, new_len, "%s@plt", format->symbols[j].name); - - format->symbols = (elf_symbol *)realloc(format->symbols, ++format->sym_count * sizeof(elf_symbol)); - - format->symbols[format->sym_count - 1].name = new_name; - format->symbols[format->sym_count - 1].address = instructions[i]->vaddress; - - } - - i += 3; - - } - else i++; - - } - -} -#endif |