summaryrefslogtreecommitdiff
path: root/src/format
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
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')
-rw-r--r--src/format/elf/Makefile.am2
-rw-r--r--src/format/elf/e_elf.c131
-rw-r--r--src/format/elf/elf-int.h2
-rw-r--r--src/format/exe_format-int.h4
-rw-r--r--src/format/exe_format.c30
-rw-r--r--src/format/exe_format.h6
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 *);