summaryrefslogtreecommitdiff
path: root/src/analysis
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis')
-rwxr-xr-xsrc/analysis/Makefile.am11
-rw-r--r--src/analysis/binary.c593
-rw-r--r--src/analysis/binary.h73
-rw-r--r--src/analysis/line.c13
4 files changed, 683 insertions, 7 deletions
diff --git a/src/analysis/Makefile.am b/src/analysis/Makefile.am
index e5f7689..8d986a1 100755
--- a/src/analysis/Makefile.am
+++ b/src/analysis/Makefile.am
@@ -1,7 +1,8 @@
-lib_LIBRARIES = libanalysis.a
+lib_LTLIBRARIES = libanalysis.la
-libanalysis_a_SOURCES = \
+libanalysis_la_SOURCES = \
+ binary.h binary.c \
line.h line.c \
line-int.h \
line_code.h line_code.c \
@@ -10,10 +11,12 @@ libanalysis_a_SOURCES = \
prototype.h prototype.c \
variable.h variable.c
-libanalysis_a_CFLAGS = $(AM_CFLAGS)
+libanalysis_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBXML_LIBS) \
+ -L../common/.libs -lcommon \
+ -L../format/.libs -lformat
-INCLUDES = $(LIBGTK_CFLAGS)
+INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
AM_CPPFLAGS =
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
new file mode 100644
index 0000000..95b24b1
--- /dev/null
+++ b/src/analysis/binary.c
@@ -0,0 +1,593 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * binary.c - traitement des flots de code binaire
+ *
+ * Copyright (C) 2008 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "binary.h"
+
+
+#include <fcntl.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+
+#include "line_code.h"
+#include "line_comment.h"
+#include "line_prologue.h"
+#include "prototype.h"
+#include "../arch/processor.h"
+
+
+#include "../format/dbg_format.h"
+#include "../format/exe_format.h"
+
+
+
+
+#ifndef _
+# define _(str) str
+#endif
+
+
+
+extern bool find_line_info(const uint8_t *content, off_t *size);
+
+
+
+
+/* Description d'un fichier binaire */
+struct _openida_binary
+{
+ char *filename; /* Fichier chargé en mémoire */
+
+ off_t bin_length; /* Taille des données brutes */
+ uint8_t *bin_data; /* Données binaires brutes */
+
+ exe_format *format; /* Format du binaire */
+ asm_processor *proc; /* Architecture du binaire */
+
+ GRenderingLine *lines; /* Lignes de rendu en place */
+ disass_options options; /* Options de désassemblage */
+
+};
+
+
+/* Charge en mémoire le contenu d'un fichier à partir d'XML. */
+openida_binary *load_binary_file_from_xml(xmlXPathObjectPtr);
+
+/* Charge en mémoire le contenu d'un fichier. */
+uint8_t *map_binary_file(const char *, off_t *);
+
+/* Construit la description d'introduction du désassemblage. */
+GRenderingLine *build_binary_prologue(const char *, const uint8_t *, off_t);
+
+/* Procède au désassemblage basique d'un contenu binaire. */
+void disassemble_openida_binary(openida_binary *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : filename = nom du fichier à charger. *
+* *
+* Description : Charge en mémoire le contenu d'un fichier. *
+* *
+* Retour : Adresse de la représentation ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+openida_binary *load_binary_file(const char *filename)
+{
+ openida_binary *result; /* Adresse à retourner */
+
+ result = (openida_binary *)calloc(1, sizeof(openida_binary));
+
+ result->filename = strdup(filename);
+
+ result->bin_data = map_binary_file(filename, &result->bin_length);
+ if (result->bin_data == NULL) goto lbf_error;
+
+ result->format = load_new_exe_format(result->bin_data, result->bin_length);
+ if (result->format == NULL) goto lbf_error;
+
+
+ result->proc = create_processor();
+
+
+ result->options.show_address = true;
+ result->options.show_code = true;
+
+ result->options.format = result->format;
+ result->options.proc = result->proc;
+
+ disassemble_openida_binary(result);
+
+ return result;
+
+ lbf_error:
+
+ unload_binary_file(result);
+
+ return NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : xpathObj = point de lecture de tous les éléments. *
+* *
+* Description : Charge en mémoire le contenu d'un fichier à partir d'XML. *
+* *
+* Retour : Adresse de la représentation ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+openida_binary *load_binary_file_from_xml(xmlXPathObjectPtr xpathObj)
+{
+ openida_binary *result; /* Adresse à retourner */
+
+ int i;
+
+ result = (openida_binary *)calloc(1, sizeof(openida_binary));
+
+ for (i = 0; i < XPATH_OBJ_NODES_COUNT(xpathObj); i++)
+ if (xmlStrEqual(NODE_FROM_PATH_OBJ(xpathObj, i)->name, BAD_CAST "Filename"))
+ result->filename = qck_get_node_text_value(NODE_FROM_PATH_OBJ(xpathObj, i));
+
+
+
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = élément binaire à supprimer de la mémoire. *
+* *
+* Description : Décharge de la mémoire le contenu d'un fichier. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void unload_binary_file(openida_binary *binary)
+{
+ free(binary->filename);
+
+ free(binary);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = élément binaire à consulter. *
+* *
+* Description : Fournit le fichier correspondant à l'élément binaire. *
+* *
+* Retour : Nom de fichier avec chemin absolu. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const char *openida_binary_get_filename(const openida_binary *binary)
+{
+ return binary->filename;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = élément binaire à consulter. *
+* *
+* Description : Fournit une description humaine d'un élément binaire. *
+* *
+* Retour : Chaîne de caractères humainenement lisible de représentation.*
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const char *openida_binary_to_string(const openida_binary *binary)
+{
+ return binary->filename;
+
+}
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = élément binaire à consulter. *
+* *
+* Description : Fournit les lignes de rendu issues du désassemblage. *
+* *
+* Retour : Lignes issues du désassemblage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GRenderingLine *get_openida_binary_lines(const openida_binary *binary)
+{
+ return binary->lines;
+
+}
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : xpathCtx = contexte à utiliser pour mener les parcours. *
+* base = première partie de l'expression XPath d'accès. *
+* index = indice de la élément dans la liste des voisins. *
+* *
+* Description : Lit un élément binaire depuis un fichier XML. *
+* *
+* Retour : Représentation mise en place à libérer de la mémoire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+openida_binary *read_openida_binary_from_xml(xmlXPathContextPtr xpathCtx, const char *base, unsigned int index)
+{
+ openida_binary *result; /* Représentation à retourner */
+ size_t expr_len; /* Taille d'une expression */
+ char *expr; /* Chemin XPath reconstitué */
+ xmlXPathObjectPtr xpathObj; /* Cible d'une recherche */
+ char *value; /* Type d'élément rencontré */
+ size_t sub_expr_len; /* Taille d'une expression #2 */
+ char *sub_expr; /* Chemin XPath reconstitué #2 */
+ int i; /* Boucle de parcours */
+
+ result = NULL;
+
+ /* S'occupe en premier lieu du niveau courant */
+
+ expr_len = strlen(base) + strlen("/*[position()=") + strlen("4294967295") /* UINT_MAX */ + strlen("]") + 1;
+
+ expr = (char *)calloc(expr_len, sizeof(char));
+ snprintf(expr, expr_len, "%s/*[position()=%u]", base, index);
+
+ xpathObj = get_node_xpath_object(xpathCtx, expr);
+
+ value = qck_get_node_prop_value(NODE_FROM_PATH_OBJ(xpathObj, 0), "type");
+
+ xmlXPathFreeObject(xpathObj);
+
+ if (value == NULL) goto robfx_err1;
+
+ /* Raffinement au second passage */
+
+ sub_expr_len = expr_len + strlen("/*");
+ sub_expr = (char *)calloc(sub_expr_len, sizeof(char));
+ snprintf(sub_expr, sub_expr_len, "%s/*", expr);
+
+ xpathObj = get_node_xpath_object(xpathCtx, sub_expr);
+
+ if (strcmp(value, "file") == 0) result = load_binary_file_from_xml(xpathObj);
+
+ xmlXPathFreeObject(xpathObj);
+
+ free(sub_expr);
+
+ robfx_err1:
+
+ free(expr);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = élément binaire à traiter. *
+* writer = rédacteur dédié à l'écriture. *
+* *
+* Description : Ecrit une sauvegarde du binaire dans un fichier XML. *
+* *
+* Retour : true si l'opération a bien tourné, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool write_openida_binary_to_xml(const openida_binary *binary, xmlTextWriterPtr writer)
+{
+ bool result; /* Bilan à faire remonter */
+
+ result = open_xml_element(writer, "Binary");
+
+ result &= write_xml_attribute(writer, "type", "file");
+
+ result &= write_xml_element_with_content(writer, "Filename", "%s", binary->filename);
+
+ result &= close_xml_element(writer);
+
+ return result;
+
+}
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : filename = nom du fichier à charger. *
+* length = taille des données mises en mémoire. [OUT] *
+* *
+* Description : Charge en mémoire le contenu d'un fichier. *
+* *
+* Retour : Adresse du contenu binaire ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+uint8_t *map_binary_file(const char *filename, off_t *length)
+{
+ uint8_t *result; /* Données à retourner */
+ int fd; /* Fichier ouvert en lecture */
+ struct stat info; /* Informations sur le fichier */
+ int ret; /* Bilan d'un appel */
+
+ fd = open(filename, 0, O_RDONLY);
+ if (fd == -1)
+ {
+ perror("open()");
+ return NULL;
+ }
+
+ ret = fstat(fd, &info);
+ if (ret == -1)
+ {
+ perror("fstat()");
+ close(fd);
+ return NULL;
+ }
+
+ *length = info.st_size;
+
+ result = (uint8_t *)mmap(NULL, *length, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (result == MAP_FAILED)
+ {
+ perror("mmap()");
+ result = NULL;
+ }
+
+ ret = close(fd);
+ if (ret == -1)
+ perror("close()");
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : filename = nom du fichier chargé. *
+* data = données en mémoire pour l'empreinte. *
+* length = quantité de données à prendre en compte. *
+* *
+* Description : Construit la description d'introduction du désassemblage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GRenderingLine *build_binary_prologue(const char *filename, const uint8_t *data, off_t length)
+{
+ GRenderingLine *result; /* Contenu à renvoyer */
+ size_t len; /* Taille du texte */
+ char *content; /* Contenu textuel d'une ligne */
+ GRenderingLine *line; /* Représentation à ajouter */
+ GChecksum *checksum; /* Calcul de l'empreinte */
+ const gchar *hex; /* Valeur hexadécimale du SHA */
+
+ result = NULL;/* FIXME DL_LIST_HEAD_INIT( **/
+
+ line = g_prologue_line_new("Disassembly generated by OpenIDA");
+ g_rendering_line_add_to_lines(&result, line);
+
+ line = g_prologue_line_new("OpenIDA is free software - © 2008-2009 Cyrille Bagard");
+ g_rendering_line_add_to_lines(&result, line);
+
+ line = g_prologue_line_new("");
+ g_rendering_line_add_to_lines(&result, line);
+
+ /* Fichier */
+
+ len = strlen(_("File: ")) + strlen(filename);
+ content = (char *)calloc(len + 1, sizeof(char));
+
+ snprintf(content, len + 1, "%s%s", _("File: "), filename);
+
+ line = g_prologue_line_new(content);
+ g_rendering_line_add_to_lines(&result, line);
+
+ free(content);
+
+ /* Checksum SHA256 */
+
+ checksum = g_checksum_new(G_CHECKSUM_SHA256);
+
+ g_checksum_update(checksum, data, length);
+ hex = g_checksum_get_string(checksum);
+
+ len = strlen(_("Sha256: ")) + strlen(hex);
+ content = (char *)calloc(len + 1, sizeof(char));
+
+ snprintf(content, len + 1, "%s%s", _("Sha256: "), hex);
+
+ g_checksum_free(checksum);
+
+ line = g_prologue_line_new(content);
+ g_rendering_line_add_to_lines(&result, line);
+
+ free(content);
+
+ line = g_prologue_line_new("");
+ g_rendering_line_add_to_lines(&result, line);
+
+ line = g_prologue_line_new("");
+ g_rendering_line_add_to_lines(&result, line);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = binaire dont le contenu est à analyser. *
+* *
+* Description : Procède au désassemblage basique d'un contenu binaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void disassemble_openida_binary(openida_binary *binary)
+{
+ asm_instr *instr;
+
+ bin_routine **routines; /* Liste des routines trouvées */
+ size_t routines_count; /* Nombre de ces routines */
+
+ bin_part **parts;
+ size_t parts_count;
+
+
+
+ GRenderingLine *line;
+
+
+ off_t start;
+ off_t pos;
+ off_t len;
+
+ uint64_t base = 0;
+ uint64_t offset = 0;
+
+ size_t i;
+
+ size_t k;
+
+ uint64_t routine_offset; /* Point de départ de routine */
+ char *routine_desc; /* Prototype d'une routine */
+
+
+
+
+ binary->lines = build_binary_prologue(binary->filename, binary->bin_data, binary->bin_length);
+
+
+ routines = get_all_exe_routines(binary->format, &routines_count);
+
+
+ parts = get_elf_default_code_parts(binary->format, &parts_count);
+ qsort(parts, parts_count, sizeof(bin_part *), compare_bin_parts);
+
+
+
+
+ for (i = 0; i < parts_count; i++)
+ {
+ get_bin_part_values(parts[i], &pos, &len, &base);
+
+ /* Décodage des instructions */
+
+ start = pos;
+ pos = 0;
+
+ while (pos < len)
+ {
+ offset = base + pos;
+
+
+ instr = decode_instruction(binary->proc, &binary->bin_data[start], &pos, len, start, offset);
+
+
+ line = g_code_line_new(offset, instr, &binary->options);
+ g_rendering_line_add_to_lines(&binary->lines, line);
+
+ }
+
+ /* Ajout des prototypes de fonctions */
+
+ for (k = 0; k < routines_count; k++)
+ {
+ routine_offset = get_binary_routine_offset(routines[k]);
+
+ if (!(base <= routine_offset && routine_offset < (base + len))) continue;
+
+ routine_desc = routine_to_string(routines[k]);
+
+ line = g_comment_line_new(routine_offset, routine_desc, &binary->options);
+ g_rendering_line_insert_into_lines(&binary->lines, line, true);
+
+ free(routine_desc);
+
+ }
+
+ }
+
+
+
+
+
+
+ line = g_rendering_line_find_by_offset(binary->lines, get_exe_entry_point(binary->format));
+ g_rendering_line_add_flag(line, RLF_ENTRY_POINT);
+
+
+
+
+}
diff --git a/src/analysis/binary.h b/src/analysis/binary.h
new file mode 100644
index 0000000..69da2a7
--- /dev/null
+++ b/src/analysis/binary.h
@@ -0,0 +1,73 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * binary.h - prototypes pour le traitement des flots de code binaire
+ *
+ * Copyright (C) 2008 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _BINARY_H
+#define _BINARY_H
+
+
+#include <stdbool.h>
+
+
+#include "line.h"
+#include "../xml.h"
+
+
+
+/* Description d'un fichier binaire */
+typedef struct _openida_binary openida_binary;
+
+
+/* Charge en mémoire le contenu d'un fichier. */
+openida_binary *load_binary_file(const char *);
+
+/* Décharge de la mémoire le contenu d'un fichier. */
+void unload_binary_file(openida_binary *);
+
+/* Fournit une description humaine d'un élément binaire. */
+const char *openida_binary_to_string(const openida_binary *);
+
+/* Fournit le fichier correspondant à l'élément binaire. */
+const char *openida_binary_get_filename(const openida_binary *);
+
+/* Fournit les lignes de rendu issues du désassemblage. */
+GRenderingLine *get_openida_binary_lines(const openida_binary *);
+
+
+
+/* Lit un élément binaire depuis un fichier XML. */
+openida_binary *read_openida_binary_from_xml(xmlXPathContextPtr, const char *, unsigned int);
+
+/* Ecrit une sauvegarde du binaire dans un fichier. */
+bool write_openida_binary_to_xml(const openida_binary *, xmlTextWriterPtr);
+
+
+
+
+
+
+
+
+
+
+
+#endif /* _BINARY_H */
diff --git a/src/analysis/line.c b/src/analysis/line.c
index 4fc0ac5..bba601c 100644
--- a/src/analysis/line.c
+++ b/src/analysis/line.c
@@ -39,7 +39,7 @@
/* FIXME */
-extern GtkWidget *mywid;
+//extern GtkWidget *mywid;
@@ -96,9 +96,15 @@ static void g_rendering_line_class_init(GRenderingLineClass *klass)
static void g_rendering_line_init(GRenderingLine *line)
{
+ GdkScreen *screen;
+ PangoContext *context;
+
DL_LIST_ITEM_INIT(&line->link);
- line->layout = gtk_widget_create_pango_layout(mywid, NULL);
+ screen = gdk_screen_get_default();
+ context = gdk_pango_context_get_for_screen(screen);
+
+ line->layout = pango_layout_new(context);
line->get_bin_len = NULL;
line->refresh_markup = NULL;
@@ -230,6 +236,7 @@ RenderingLineFlag g_rendering_line_get_flags(const GRenderingLine *line)
void g_rendering_line_draw(GRenderingLine *line, GdkDrawable *drawable, GdkGC *gc, gint x0, gint x1, gint y, gint h)
{
+#if 0
GdkPixbuf *pixbuf; /* Données utiles au dessin */
gdk_draw_layout(drawable, gc, x1, y, line->layout);
@@ -268,7 +275,7 @@ void g_rendering_line_draw(GRenderingLine *line, GdkDrawable *drawable, GdkGC *g
g_object_unref(pixbuf);
}
-
+#endif
}