summaryrefslogtreecommitdiff
path: root/src/format/elf/e_elf.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2009-03-15 13:38:22 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2009-03-15 13:38:22 (GMT)
commit4ad9e532a78401f787f0a8a6742095512b520488 (patch)
tree2b71914a52fc930be78939362b16756efe9caa68 /src/format/elf/e_elf.c
parenta2b767b244e03f00c6a987bbd9872796ed385f47 (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/elf/e_elf.c')
-rw-r--r--src/format/elf/e_elf.c131
1 files changed, 128 insertions, 3 deletions
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;
}