diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2009-03-15 13:38:22 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2009-03-15 13:38:22 (GMT) |
commit | 4ad9e532a78401f787f0a8a6742095512b520488 (patch) | |
tree | 2b71914a52fc930be78939362b16756efe9caa68 /src/format | |
parent | a2b767b244e03f00c6a987bbd9872796ed385f47 (diff) |
Avoided to crash when analysing crackmes such as grainne.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@55 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format')
-rw-r--r-- | src/format/elf/Makefile.am | 2 | ||||
-rw-r--r-- | src/format/elf/e_elf.c | 131 | ||||
-rw-r--r-- | src/format/elf/elf-int.h | 2 | ||||
-rw-r--r-- | src/format/exe_format-int.h | 4 | ||||
-rw-r--r-- | src/format/exe_format.c | 30 | ||||
-rw-r--r-- | src/format/exe_format.h | 6 |
6 files changed, 170 insertions, 5 deletions
diff --git a/src/format/elf/Makefile.am b/src/format/elf/Makefile.am index 03ebed2..663194e 100644 --- a/src/format/elf/Makefile.am +++ b/src/format/elf/Makefile.am @@ -11,7 +11,7 @@ libformatelf_a_SOURCES = \ libformatelf_a_CFLAGS = $(AM_CFLAGS) -INCLUDES = +INCLUDES = $(LIBGTK_CFLAGS) AM_CPPFLAGS = diff --git a/src/format/elf/e_elf.c b/src/format/elf/e_elf.c index 91e0403..1a1fe8d 100644 --- a/src/format/elf/e_elf.c +++ b/src/format/elf/e_elf.c @@ -32,6 +32,18 @@ #include "section.h" #include "strings.h" #include "symbol.h" +#include "../../panel/log.h" + + + + +#define _(str) str + + + +/* Fournit l'adresse mémoire du point d'entrée du programme. */ +uint64_t get_elf_entry_point(const elf_format *); + @@ -101,6 +113,7 @@ elf_format *load_elf(const uint8_t *content, off_t length) EXE_FORMAT(result)->content = content; EXE_FORMAT(result)->length = length; + EXE_FORMAT(result)->get_entry_point = (get_entry_point_fc)get_elf_entry_point; EXE_FORMAT(result)->get_def_parts = (get_def_parts_fc)get_elf_default_code_parts; EXE_FORMAT(result)->find_section = (find_section_fc)find_elf_section_content_by_name; EXE_FORMAT(result)->get_symbols = (get_symbols_fc)get_elf_symbols; @@ -110,7 +123,66 @@ elf_format *load_elf(const uint8_t *content, off_t length) memcpy(&result->header, content, sizeof(Elf32_Ehdr)); - result->is_32b = true; + + /* TODO : endian */ + + + /* Vérification des tailles d'entrée de table */ + switch (result->header.e_ident[EI_CLASS]) + { + case ELFCLASS32: + + if (result->header.e_phentsize != sizeof(Elf32_Phdr)) + { + log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed !"), + result->header.e_phentsize); + result->header.e_phentsize = sizeof(Elf32_Phdr); + } + + if (result->header.e_shentsize != sizeof(Elf32_Shdr)) + { + log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed !"), + result->header.e_shentsize); + result->header.e_shentsize = sizeof(Elf32_Shdr); + } + + break; + + case ELFCLASS64: + + if (result->header.e_phentsize != sizeof(Elf64_Phdr)) + { + log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed !"), + result->header.e_phentsize); + result->header.e_phentsize = sizeof(Elf64_Phdr); + } + + if (result->header.e_shentsize != sizeof(Elf64_Shdr)) + { + log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed !"), + result->header.e_shentsize); + result->header.e_shentsize = sizeof(Elf64_Shdr); + } + + break; + + default: + log_variadic_message(LMT_BAD_BINARY, ("Invalid ELF class '%hhu'"), + result->header.e_ident[EI_CLASS]); + break; + + } + + + /* FIXME : à améliorer */ + if ((result->header.e_shnum * result->header.e_shentsize) >= length) + { + log_variadic_message(LMT_BAD_BINARY, ("Suspicious section table (bigger than the binary !) ; reset !")); + result->header.e_shnum = 0; + } + + + result->is_32b = (result->header.e_ident[EI_CLASS] == ELFCLASS32); for (i = 0; i < result->header.e_phnum; i++) @@ -141,6 +213,12 @@ elf_format *load_elf(const uint8_t *content, off_t length) return result; + lelf: + + /* TODO */ + + return NULL; + } @@ -150,6 +228,25 @@ elf_format *load_elf(const uint8_t *content, off_t length) /****************************************************************************** * * * Paramètres : format = informations chargées à consulter. * +* * +* Description : Fournit l'adresse mémoire du point d'entrée du programme. * +* * +* Retour : Adresse de mémoire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint64_t get_elf_entry_point(const elf_format *format) +{ + return format->header.e_entry; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * * count = quantité de zones listées. [OUT] * * * * Description : Fournit les références aux zones de code à analyser. * @@ -168,7 +265,8 @@ bin_part **get_elf_default_code_parts(const elf_format *format, size_t *count) off_t size; /* Taille de la partie */ uint64_t voffset; /* Adresse virtuelle éventuelle*/ int i; /* Boucle de parcours */ - Elf_Shdr shdr; /* En-tête de programme ELF */ + Elf_Shdr shdr; /* En-tête de section ELF */ + Elf_Phdr phdr; /* En-tête de programme ELF */ result = NULL; *count = 0; @@ -231,7 +329,7 @@ bin_part **get_elf_default_code_parts(const elf_format *format, size_t *count) for (i = 0; i < format->header.e_shnum; i++) { offset = format->header.e_shoff + format->header.e_shentsize * i; - if ((offset + format->header.e_shentsize) >= EXE_FORMAT(format)->length) break; + if ((offset + format->header.e_shentsize) >= EXE_FORMAT(format)->length) continue; memcpy(&shdr, &EXE_FORMAT(format)->content[offset], format->header.e_shentsize); @@ -252,6 +350,33 @@ bin_part **get_elf_default_code_parts(const elf_format *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++) + { + offset = format->header.e_phoff + format->header.e_phentsize * i; + if ((offset + format->header.e_phentsize) >= EXE_FORMAT(format)->length) continue; + + memcpy(&phdr, &EXE_FORMAT(format)->content[offset], format->header.e_phentsize); + + if (ELF_PHDR(format, &phdr, p_flags) & PF_X) + { + part = create_bin_part(); + + /* TODO : nom */ + + set_bin_part_values(part, ELF_PHDR(format, &phdr, p_offset), + ELF_PHDR(format, &phdr, p_filesz), + ELF_PHDR(format, &phdr, p_vaddr)); + + result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *)); + result[*count - 1] = part; + + } + + } + return result; } diff --git a/src/format/elf/elf-int.h b/src/format/elf/elf-int.h index 0931654..4ee3a08 100644 --- a/src/format/elf/elf-int.h +++ b/src/format/elf/elf-int.h @@ -83,7 +83,7 @@ typedef union _Elf_Phdr } Elf_Phdr; -#define ELF_PHDR(fmt, hdr, fld) (fmt->is_32b ? hdr.header32.fld : hdr.header64.fld) +#define ELF_PHDR(fmt, hdr, fld) (fmt->is_32b ? (hdr)->header32.fld : (hdr)->header64.fld) /* Entrée de la table de relocalisation */ diff --git a/src/format/exe_format-int.h b/src/format/exe_format-int.h index a882891..3bba821 100644 --- a/src/format/exe_format-int.h +++ b/src/format/exe_format-int.h @@ -48,6 +48,9 @@ struct _bin_part +/* Fournit l'adresse mémoire du point d'entrée du programme. */ +typedef uint64_t (* get_entry_point_fc) (const exe_format *); + /* Fournit les références aux zones de code à analyser. */ typedef bin_part ** (* get_def_parts_fc) (const exe_format *, size_t *); @@ -73,6 +76,7 @@ struct _exe_format const uint8_t *content; /* Contenu binaire à étudier */ off_t length; /* Taille de ce contenu */ + get_entry_point_fc get_entry_point; /* Obtention du point d'entrée */ get_def_parts_fc get_def_parts; /* Liste des parties de code */ find_section_fc find_section; /* Recherche d'une section */ get_symbols_fc get_symbols; /* Liste des symboles présents */ diff --git a/src/format/exe_format.c b/src/format/exe_format.c index be0e1f1..89b0b3b 100644 --- a/src/format/exe_format.c +++ b/src/format/exe_format.c @@ -316,6 +316,36 @@ const uint8_t *get_exe_content(const exe_format *format, off_t *length) + + + + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* * +* Description : Fournit l'adresse mémoire du point d'entrée du programme. * +* * +* Retour : Adresse de mémoire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint64_t get_exe_entry_point(const exe_format *format) +{ + return format->get_entry_point(format); + +} + + + + + + + + /****************************************************************************** * * * Paramètres : format = description de l'exécutable à consulter. * diff --git a/src/format/exe_format.h b/src/format/exe_format.h index 48cb989..efacfe2 100644 --- a/src/format/exe_format.h +++ b/src/format/exe_format.h @@ -111,6 +111,12 @@ typedef enum _ResolvedType /* Fournit une référence vers le contenu binaire analysé. */ const uint8_t *get_exe_content(const exe_format *, off_t *); + +/* Fournit l'adresse mémoire du point d'entrée du programme. */ +uint64_t get_exe_entry_point(const exe_format *); + + + /* Recherche une section donnée au sein de binaire. */ bool find_exe_section(const exe_format *, const char *, off_t *, off_t *, uint64_t *); |