summaryrefslogtreecommitdiff
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
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
-rw-r--r--ChangeLog32
-rw-r--r--src/analysis/line.c107
-rw-r--r--src/analysis/line.h25
-rw-r--r--src/arch/processor.c4
-rw-r--r--src/binary.c3
-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
-rw-r--r--src/gtksnippet.c3
12 files changed, 336 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 30e3904..b94f587 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2009-03-15 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/analysis/line.c:
+ * src/analysis/line.h:
+ Add flags to lines and draw them in the margin if needed. Find lines by
+ their offset.
+
+ * src/arch/processor.c:
+ Typo.
+
+ * src/binary.c:
+ Specify the entry point for rendering.
+
+ * src/format/elf/e_elf.c:
+ Handle some corrupted fields in the ELF header (sizes and quantities of
+ the section and program (!?) entries). Rely on program header to provide
+ code to analyse if none is found.
+
+ * src/format/elf/elf-int.h:
+ Fix the ELF_PHDR macro (. -> ()->).
+
+ * src/format/elf/Makefile.am:
+ Add LIBGTK_CFLAGS to INCLUDES in order to be able to print log messages.
+
+ * src/format/exe_format.c:
+ * src/format/exe_format.h:
+ * src/format/exe_format-int.h:
+ Give the entry point of a loaded program.
+
+ * src/gtksnippet.c:
+ Update a call to draw_rendering_line().
+
2009-03-14 Cyrille Bagard <nocbos@gmail.com>
* configure.ac:
diff --git a/src/analysis/line.c b/src/analysis/line.c
index f5f3d9c..62acb8e 100644
--- a/src/analysis/line.c
+++ b/src/analysis/line.c
@@ -58,6 +58,7 @@ struct _rendering_line
uint64_t offset; /* Position en mémoire/physique*/
RenderingLineType type; /* Type de représentation */
+ RenderingLineFlag flags; /* Extension d'informations */
PangoLayout *layout; /* Moteur de rendu du code/txt */
@@ -169,6 +170,63 @@ void init_rendering_line(rendering_line *line)
}
+/******************************************************************************
+* *
+* Paramètres : line = ligne dont les informations sont à mettre à jour. *
+* flag = extension d'information à ajouter. *
+* *
+* Description : Ajoute une information supplémentaire à une ligne. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void add_rendering_line_flag(rendering_line *line, RenderingLineFlag flag)
+{
+ line->flags |= flag;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : line = ligne dont les informations sont à mettre à jour. *
+* flag = extension d'information à retirer. *
+* *
+* Description : Retire une information supplémentaire sur d'une ligne. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void remove_rendering_line_flag(rendering_line *line, RenderingLineFlag flag)
+{
+ line->flags &= ~flag;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : line = ligne dont les informations sont à mettre à jour. *
+* *
+* Description : Fournit les informations supplémentaires d'une ligne. *
+* *
+* Retour : Extensions d'informations courantes. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+RenderingLineFlag get_rendering_line_flags(const rendering_line *line)
+{
+ return line->flags;
+
+}
@@ -236,6 +294,30 @@ void insert_line_into_rendering_lines(rendering_line **lines, rendering_line *li
}
+/******************************************************************************
+* *
+* Paramètres : lines = liste de lignes à parcourir. *
+* offset = position en mémoire ou physique à chercher. *
+* *
+* Description : Recherche une ligne d'après sa position en mémoire/physique. *
+* *
+* Retour : Ligne représentant l'adresse donnée, NULL si aucune trouvée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+rendering_line *find_offset_in_rendering_lines(const rendering_line **lines, uint64_t offset)
+{
+ rendering_line *result;
+
+ dl_list_for_each(result, DLL_HCAST(lines), rendering_line *)
+ if (result->offset == offset) break;
+
+ return result;
+
+}
+
/******************************************************************************
@@ -313,8 +395,10 @@ void get_rendering_line_size(rendering_line *line, int *width, int *height)
* Paramètres : line = adresse de la structure à représenter. *
* drawable = support de rendu pour le dessin. *
* gc = contexte graphique à utiliser. *
-* x = abscisse de la zone de rendu. *
+* x0 = abscisse de la zone de rendu (marge). *
+* x1 = abscisse de la zone de rendu (texte). *
* y = ordonnée de la zone de rendu. *
+* h = hauteur réservée pour la ligne. *
* *
* Description : Procède à l'initialisation des bases d'une représentation. *
* *
@@ -324,9 +408,26 @@ void get_rendering_line_size(rendering_line *line, int *width, int *height)
* *
******************************************************************************/
-void draw_rendering_line(rendering_line *line, GdkDrawable *drawable, GdkGC *gc, gint x, gint y)
+void draw_rendering_line(rendering_line *line, GdkDrawable *drawable, GdkGC *gc, gint x0, gint x1, gint y, gint h)
{
- gdk_draw_layout(drawable, gc, x, y, line->layout);
+ GdkPixbuf *pixbuf; /* Données utiles au dessin */
+
+ gdk_draw_layout(drawable, gc, x1, y, line->layout);
+
+ if (line->flags & RLF_ENTRY_POINT)
+ pixbuf = gtk_widget_render_icon(mywid, "gtk-go-forward", GTK_ICON_SIZE_MENU, NULL);
+
+ else pixbuf = NULL;
+
+ if (pixbuf != NULL)
+ {
+ gdk_draw_pixbuf(drawable, gc, pixbuf, 0, 0, x0, y,
+ gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf),
+ GDK_RGB_DITHER_NORMAL, 0, 0);
+
+ g_object_unref(pixbuf);
+
+ }
}
diff --git a/src/analysis/line.h b/src/analysis/line.h
index b0635bf..bb628b6 100644
--- a/src/analysis/line.h
+++ b/src/analysis/line.h
@@ -43,6 +43,15 @@ typedef enum _RenderingLineType
} RenderingLineType;
+/* Image à afficher en marge de ligne */
+typedef enum _RenderingLineFlag
+{
+ RLF_NONE = (0 << 0), /* Ligne commune */
+ RLF_ENTRY_POINT = (1 << 0), /* Point d'entrée du prgm. */
+ RLF_BREAK_POINT = (1 << 1) /* Point d'arrêt */
+
+} RenderingLineFlag;
+
/* Passage de paramètres compact */
typedef struct _disass_options
{
@@ -60,6 +69,17 @@ typedef struct _disass_options
typedef struct _rendering_line rendering_line;
+/* Ajoute une information supplémentaire à une ligne. */
+void add_rendering_line_flag(rendering_line *, RenderingLineFlag);
+
+/* Retire une information supplémentaire d'une ligne. */
+void remove_rendering_line_flag(rendering_line *, RenderingLineFlag);
+
+/* Fournit les informations supplémentaires d'une ligne. */
+RenderingLineFlag get_rendering_line_flags(const rendering_line *);
+
+
+
/* Ajoute une ligne à un ensemble existant. */
void add_line_to_rendering_lines(rendering_line **, rendering_line *);
@@ -67,6 +87,9 @@ void add_line_to_rendering_lines(rendering_line **, rendering_line *);
/* Insère une ligne dans un ensemble existant. */
void insert_line_into_rendering_lines(rendering_line **, rendering_line *, bool);
+/* Recherche une ligne d'après sa position en mémoire/physique. */
+rendering_line *find_offset_in_rendering_lines(const rendering_line **, uint64_t);
+
/* Met à jour la nombre d'octets maximale par instruction. */
@@ -79,7 +102,7 @@ void set_rendering_line_max_binary_len(rendering_line *, off_t);
void get_rendering_line_size(rendering_line *, int *, int *);
/* Procède à l'initialisation des bases d'une représentation. */
-void draw_rendering_line(rendering_line *, GdkDrawable *, GdkGC *, gint, gint);
+void draw_rendering_line(rendering_line *, GdkDrawable *, GdkGC *, gint, gint, gint, gint);
diff --git a/src/arch/processor.c b/src/arch/processor.c
index 71cdfba..d367949 100644
--- a/src/arch/processor.c
+++ b/src/arch/processor.c
@@ -65,14 +65,14 @@ asm_instr *decode_instruction(const asm_processor *proc, const uint8_t *data, of
result = proc->fetch_instr(proc, data, pos, len, offset);
-#define NULL ((void *)0)
+#define NULL ((void *)0) /* FIXME */
if (result == NULL)
{
*pos = old_pos;
- printf("err while decoding opcode 0x%0hhx at 0x%08llx\n", data[*pos], offset);
+ printf("err while decoding opcode 0x%02hhx at 0x%08llx\n", data[*pos], offset);
result = create_db_instruction(data, pos, len);
}
diff --git a/src/binary.c b/src/binary.c
index 5093335..e43d644 100644
--- a/src/binary.c
+++ b/src/binary.c
@@ -566,7 +566,8 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2)
-
+ line = find_offset_in_rendering_lines(lines, get_exe_entry_point(format));
+ add_rendering_line_flag(line, RLF_ENTRY_POINT);
gtk_snippet_set_rendering_lines(snippet, lines);
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 *);
diff --git a/src/gtksnippet.c b/src/gtksnippet.c
index 989e22b..bd5b3df 100644
--- a/src/gtksnippet.c
+++ b/src/gtksnippet.c
@@ -413,7 +413,8 @@ gtk_snippet_paint(GtkSnippet *snippet)
dl_list_for_each(/**/liter, snippet->lines, rendering_line *)
{
draw_rendering_line(liter, GDK_DRAWABLE(widget->window), snippet->gc,
- 2 * MARGIN_SPACE + snippet->line_height, y0);
+ MARGIN_SPACE, 2 * MARGIN_SPACE + snippet->line_height,
+ y0, snippet->line_height);
y0 += snippet->line_height;