diff options
Diffstat (limited to 'src/format/elf/helper_x86.c')
-rw-r--r-- | src/format/elf/helper_x86.c | 166 |
1 files changed, 118 insertions, 48 deletions
diff --git a/src/format/elf/helper_x86.c b/src/format/elf/helper_x86.c index 1975709..82be74c 100644 --- a/src/format/elf/helper_x86.c +++ b/src/format/elf/helper_x86.c @@ -25,37 +25,117 @@ #include <malloc.h> +#include <stdio.h> #include <string.h> #include "elf-int.h" -#include "section.h" +#include "../symbol.h" #include "../../arch/immediate.h" #include "../../arch/processor.h" #include "../../arch/x86/instruction.h" -#include "../../panel/log.h" -#define _(str) (str) - +/* 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(elf_format *, size_t *); +GArchInstruction **decode_elf_relocations(GElfFormat *, const elf_shdr *, size_t *); /* Déduit les adresses effectives des relocalisations. */ -void translate_elf_relocations(elf_format *, GArchInstruction **, size_t); +void translate_elf_relocations(GElfFormat *, 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. * +* 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). * * * * Description : Déduit les adresses effectives des appels externes. * * * @@ -65,13 +145,13 @@ void translate_elf_relocations(elf_format *, GArchInstruction **, size_t); * * ******************************************************************************/ -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) +bool find_elf_x86_dynamic_symbols(GElfFormat *format, const elf_shdr *plt) { GArchInstruction **instructions; /* Instructions décodées */ size_t count; /* Quantité d'instructions */ size_t i; /* Boucle de parcours */ - instructions = decode_elf_relocations(format, &count); + instructions = decode_elf_relocations(format, plt, &count); translate_elf_relocations(format, instructions, count); @@ -89,6 +169,7 @@ bool g_elf_format_find_x86_dynamic_symbols(elf_format *format, off_t dyn_start, /****************************************************************************** * * * 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. * @@ -99,15 +180,12 @@ bool g_elf_format_find_x86_dynamic_symbols(elf_format *format, off_t dyn_start, * * ******************************************************************************/ -GArchInstruction **decode_elf_relocations(elf_format *format, size_t *count) +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 */ - 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 */ @@ -116,26 +194,7 @@ GArchInstruction **decode_elf_relocations(elf_format *format, size_t *count) 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; - - } + get_elf_section_content(format, plt, &plt_start, &plt_size, &plt_address); proc = get_arch_processor_for_type(APT_386); @@ -143,7 +202,7 @@ GArchInstruction **decode_elf_relocations(elf_format *format, size_t *count) { address = plt_address + pos; - instr = g_arch_processor_decode_instruction(proc, &EXE_FORMAT(format)->content[plt_start], + instr = g_arch_processor_decode_instruction(proc, &G_BIN_FORMAT(format)->content[plt_start], &pos, plt_size, 0/* FIXME*/, address); result = (GArchInstruction **)realloc(result, ++(*count) * sizeof(GArchInstruction *)); @@ -170,18 +229,21 @@ GArchInstruction **decode_elf_relocations(elf_format *format, size_t *count) * * ******************************************************************************/ -void translate_elf_relocations(elf_format *format, GArchInstruction **instructions, size_t count) +void translate_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 */ - GArchOperand *operand; /* Valeur du saut */ + 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; ) { @@ -195,31 +257,39 @@ void translate_elf_relocations(elf_format *format, GArchInstruction **instructio { 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) + { + 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) { - new_len = strlen(format->relocations[j].name) + 4 + 1; + 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", format->relocations[j].name); + 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 = 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 *)); + g_binary_format_add_routine(G_BIN_FORMAT(format), routine); + + /* Symbole uniquement */ - format->routines[format->routines_count - 1] = routine; + symbol = g_binary_symbol_new(STP_FUNCTION, new_name, address); + g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); } + } + i += 3; } |