diff options
Diffstat (limited to 'src/format/elf/elf.c')
-rw-r--r-- | src/format/elf/elf.c | 168 |
1 files changed, 27 insertions, 141 deletions
diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c index e7bb48c..ccd00ae 100644 --- a/src/format/elf/elf.c +++ b/src/format/elf/elf.c @@ -25,10 +25,12 @@ #include <malloc.h> +#include <stddef.h> #include <string.h> #include "elf-int.h" +#include "program.h" #include "section.h" #include "strings.h" #include "symbols.h" @@ -50,9 +52,6 @@ static void g_elf_format_class_init(GElfFormatClass *); /* Initialise une instance de format d'exécutable ELF. */ static void g_elf_format_init(GElfFormat *); -/* Procède à la lecture de l'en-tête d'un contenu binaire. */ -static bool read_elf_header(const bin_t *, off_t, elf_header *, bool *, SourceEndian *); - /* Indique le type d'architecture visée par le format. */ static FormatTargetMachine g_elf_format_get_target_machine(const GElfFormat *); @@ -152,126 +151,6 @@ static void g_elf_format_init(GElfFormat *format) * * * Paramètres : content = contenu binaire à parcourir. * * length = taille du contenu en question. * -* header = en-tête à déterminer. [OUT] * -* is_32b = indique si le format est en 32 ou 64 bits. [OUT] * -* endian = boutisme reconnu dans le format. [OUT] * -* * -* Description : Procède à la lecture de l'en-tête d'un contenu binaire. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool read_elf_header(const bin_t *content, off_t length, elf_header *header, bool *is_32b, SourceEndian *endian) -{ - bool result; /* Bilan à retourner */ - off_t pos; /* Position de lecture */ - - result = (length >= EI_NIDENT); - - pos = 0; - - if (result) - { - memcpy(header->e_ident, content, EI_NIDENT); - pos += EI_NIDENT; - } - - /* Détermination de l'espace d'adressage */ - if (result) - switch (header->e_ident[EI_CLASS]) - { - case ELFCLASS32: - *is_32b = true; - break; - case ELFDATA2MSB: - *is_32b = false; - break; - default: - result = false; - break; - } - - /* Détermination du boutisme */ - if (result) - switch (header->e_ident[EI_DATA]) - { - case ELFDATA2LSB: - *endian = SRE_LITTLE; - break; - case ELFDATA2MSB: - *endian = SRE_BIG; - break; - default: - result = false; - break; - } - - if (result) - result = read_u16(&header->e_type, content, &pos, length, *endian); - - if (result) - result = read_u16(&header->e_machine, content, &pos, length, *endian); - - if (result) - result = read_u32(&header->e_version, content, &pos, length, *endian); - - if (result) - { - if (*is_32b) - result = read_u32(&header->e_entry.addr32, content, &pos, length, *endian); - else - result = read_u64(&header->e_entry.addr64, content, &pos, length, *endian); - } - - if (result) - { - if (*is_32b) - result = read_u32(&header->e_phoff.off32, content, &pos, length, *endian); - else - result = read_u64(&header->e_phoff.off64, content, &pos, length, *endian); - } - - if (result) - { - if (*is_32b) - result = read_u32(&header->e_shoff.off32, content, &pos, length, *endian); - else - result = read_u64(&header->e_shoff.off64, content, &pos, length, *endian); - } - - if (result) - result = read_u32(&header->e_flags, content, &pos, length, *endian); - - if (result) - result = read_u16(&header->e_ehsize, content, &pos, length, *endian); - - if (result) - result = read_u16(&header->e_phentsize, content, &pos, length, *endian); - - if (result) - result = read_u16(&header->e_phnum, content, &pos, length, *endian); - - if (result) - result = read_u16(&header->e_shentsize, content, &pos, length, *endian); - - if (result) - result = read_u16(&header->e_shnum, content, &pos, length, *endian); - - if (result) - result = read_u16(&header->e_shstrndx, content, &pos, length, *endian); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à parcourir. * -* length = taille du contenu en question. * * * * Description : Prend en charge un nouveau format ELF. * * * @@ -298,25 +177,31 @@ GBinFormat *g_elf_format_new(const bin_t *content, off_t length) /* Vérification des tailles d'entrée de table */ - if (result->header.e_phentsize != ELF_SIZEOF_PHDR(result)) + if (ELF_HDR(result, result->header, e_phentsize) != ELF_SIZEOF_PHDR(result)) { - log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed !"), - result->header.e_phentsize); - result->header.e_phentsize = ELF_SIZEOF_PHDR(result); + log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed ! -- replacing 0x%04hx by 0x%04hx at offset 0x%x"), + ELF_HDR(result, result->header, e_phentsize), + ELF_HDR(result, result->header, e_phentsize), + ELF_SIZEOF_PHDR(result), ELF_HDR_OFFSET_OF(result, e_phentsize)); + ELF_HDR_SET(result, result->header, e_phentsize, ELF_SIZEOF_PHDR(result)); } - if (result->header.e_shentsize != ELF_SIZEOF_SHDR(result)) + if (ELF_HDR(result, result->header, e_shentsize) != ELF_SIZEOF_SHDR(result)) { - log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed !"), - result->header.e_shentsize); - result->header.e_shentsize = ELF_SIZEOF_SHDR(result); + log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed ! -- replacing 0x%04hx by 0x%04hx at offset 0x%x"), + ELF_HDR(result, result->header, e_shentsize), + ELF_HDR(result, result->header, e_shentsize), + ELF_SIZEOF_SHDR(result), ELF_HDR_OFFSET_OF(result, e_shentsize)); + ELF_HDR_SET(result, result->header, e_shentsize, ELF_SIZEOF_SHDR(result)); } /* FIXME : à améliorer */ - if ((result->header.e_shnum * result->header.e_shentsize) >= length) + if ((ELF_HDR(result, result->header, e_shnum) * ELF_HDR(result, result->header, e_shentsize)) >= length) { - log_variadic_message(LMT_BAD_BINARY, ("Suspicious section table (bigger than the binary !) ; reset !")); - result->header.e_shnum = 0; + log_variadic_message(LMT_BAD_BINARY, ("Suspicious section table (bigger than the binary !) ; reset ! -- replacing 0x%04hx by 0x%04hx at offset 0x%x"), + ELF_HDR(result, result->header, e_shnum), + 0, ELF_HDR_OFFSET_OF(result, e_shnum)); + ELF_HDR_SET(result, result->header, e_shnum, 0); } @@ -358,7 +243,7 @@ static FormatTargetMachine g_elf_format_get_target_machine(const GElfFormat *for { FormatTargetMachine result; /* Identifiant à retourner */ - switch (format->header.e_machine) + switch (ELF_HDR(format, format->header, e_machine)) { case EM_MIPS: result = FTM_MIPS; @@ -394,7 +279,7 @@ static FormatTargetMachine g_elf_format_get_target_machine(const GElfFormat *for static vmpa_t g_elf_format_get_entry_point(const GElfFormat *format) { - return (format->is_32b ? format->header.e_entry.addr32 : format->header.e_entry.addr64); + return ELF_HDR(format, format->header, e_entry); } @@ -427,11 +312,11 @@ static GBinPart **g_elf_format_get_parts(const GElfFormat *format, size_t *count result = NULL; *count = 0; - has_strings = find_elf_section_by_index(format, format->header.e_shstrndx, &strings); + has_strings = find_elf_section_by_index(format, ELF_HDR(format, format->header, e_shstrndx), &strings); /* Première tentative : les sections */ - for (i = 0; i < format->header.e_shnum; i++) + for (i = 0; i < ELF_HDR(format, format->header, e_shnum); i++) { if (!find_elf_section_by_index(format, i, §ion)) continue; @@ -465,9 +350,10 @@ static GBinPart **g_elf_format_get_parts(const GElfFormat *format, size_t *count /* En désespoir de cause, on se rabbat sur les parties de programme directement */ if (*count == 0) - for (i = 0; i < format->header.e_phnum; i++) + for (i = 0; i < ELF_HDR(format, format->header, e_phnum); i++) { - offset = ELF_OFF(format, format->header.e_phoff) + format->header.e_phentsize * i; + offset = ELF_HDR(format, format->header, e_phoff) + + ELF_HDR(format, format->header, e_phentsize) * i; if (!read_elf_program_header(format, &offset, &phdr)) continue; @@ -517,7 +403,7 @@ static bool g_elf_format_translate_address_into_offset(const GElfFormat *format, result = translate_address_into_offset_using_elf_sections(format, addr, pos); if (!result) - /* TODO : prgm... */; + result = translate_address_into_offset_using_elf_programs(format, addr, pos); return result; |