diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2010-12-20 00:28:36 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2010-12-20 00:28:36 (GMT) |
commit | 56deaf395c65658102ef0111cfc072d65335331a (patch) | |
tree | ba6d6fd0dbc781e9ad3b3cf6b2eb529a7d7a6aa3 /src/analysis/disass/disassembler.c | |
parent | d9fdfcf887a7a596a68db2500bb5e4d0b692abb6 (diff) |
Begun to clean the code by moving the disassembling process into disass/.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@202 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/analysis/disass/disassembler.c')
-rw-r--r-- | src/analysis/disass/disassembler.c | 374 |
1 files changed, 374 insertions, 0 deletions
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c new file mode 100644 index 0000000..4004de9 --- /dev/null +++ b/src/analysis/disass/disassembler.c @@ -0,0 +1,374 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * disassembler.c - encadrement des phases de désassemblage + * + * Copyright (C) 2010 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 "disassembler.h" + + +#include <malloc.h> +#include <stdio.h> +#include <string.h> + + +#include <i18n.h> + + +#include "fetch.h" +#include "links.h" +#include "output.h" +#include "../../decomp/lang/asm.h" +#include "../../format/format.h" +#include "../../glibext/delayed-int.h" + + + +/* ------------------------ DESASSEMBLAGE DE BINAIRE DIFFERE ------------------------ */ + + +#define G_TYPE_DELAYED_DISASSEMBLY g_delayed_disassembly_get_type() +#define G_DELAYED_DISASSEMBLY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_delayed_disassembly_get_type(), GDelayedDisassembly)) +#define G_IS_DELAYED_DISASSEMBLY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_delayed_disassembly_get_type())) +#define G_DELAYED_DISASSEMBLY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DELAYED_DISASSEMBLY, GDelayedDisassemblyClass)) +#define G_IS_DELAYED_DISASSEMBLY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DELAYED_DISASSEMBLY)) +#define G_DELAYED_DISASSEMBLY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DELAYED_DISASSEMBLY, GDelayedDisassemblyClass)) + + +/* Ensembles binaires à désassembler (instance) */ +typedef struct _GDelayedDisassembly +{ + GDelayedWork parent; /* A laisser en premier */ + + const GOpenidaBinary *binary; /* Destinataire final */ + const GBinFormat *format; /* Format du binaire représenté*/ + + GBinPart **parts; /* Parties binaires à traiter */ + size_t count; /* Nombre de ces parties */ + + GArchInstruction *instrs; /* Instructions résultantes */ + GCodeBuffer *buffer; /* Tampon pour le rendu */ + +} GDelayedDisassembly; + +/* Ensembles binaires à désassembler (classe) */ +typedef struct _GDelayedDisassemblyClass +{ + GDelayedWorkClass parent; /* A laisser en premier */ + +} GDelayedDisassemblyClass; + + +/* Indique le type défini pour les tâches de désassemblage différé. */ +static GType g_delayed_disassembly_get_type(void); + +/* Initialise la classe des tâches de désassemblage différé. */ +static void g_delayed_disassembly_class_init(GDelayedDisassemblyClass *); + +/* Initialise une tâche de désassemblage différé. */ +static void g_delayed_disassembly_init(GDelayedDisassembly *); + +/* Crée une tâche de désassemblage différé. */ +static GDelayedDisassembly *g_delayed_disassembly_new(const GOpenidaBinary *, GBinPart **, size_t, GCodeBuffer *); + +/* Assure le désassemblage en différé. */ +static void g_delayed_disassembly_process(GDelayedDisassembly *, GtkExtStatusBar *); + + + +/* -------------------------- GESTION GLOBALE DE PROCEDURE -------------------------- */ + +/* Construit la description d'introduction du désassemblage. */ +static void build_disass_prologue(GCodeBuffer *, const char *, const uint8_t *, off_t); + + + +/* ---------------------------------------------------------------------------------- */ +/* DESASSEMBLAGE DE BINAIRE DIFFERE */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour les tâches de désassemblage différé. */ +G_DEFINE_TYPE(GDelayedDisassembly, g_delayed_disassembly, G_TYPE_DELAYED_WORK); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des tâches de désassemblage différé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_delayed_disassembly_class_init(GDelayedDisassemblyClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : disass = instance à initialiser. * +* * +* Description : Initialise une tâche de désassemblage différé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_delayed_disassembly_init(GDelayedDisassembly *disass) +{ + G_DELAYED_WORK(disass)->run = (run_task_fc)g_delayed_disassembly_process; + +} + + +/****************************************************************************** +* * +* Paramètres : binary = binaire chargé en attente des résultats. * +* format = format du binaire représenté. * +* parts = parties binaires à désassembler. * +* count = nombre de parties à traiter. * +* buffer = tampon de sortie pour les instructions. * +* * +* Description : Crée une tâche de désassemblage différé. * +* * +* Retour : Tâche créée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GDelayedDisassembly *g_delayed_disassembly_new(const GOpenidaBinary *binary, GBinPart **parts, size_t count, GCodeBuffer *buffer) +{ + GDelayedDisassembly *result; /* Tâche à retourner */ + + result = g_object_new(G_TYPE_DELAYED_DISASSEMBLY, NULL); + + result->binary = binary; + result->format = G_BIN_FORMAT(g_openida_binary_get_format(binary)); + + result->parts = parts; + result->count = count; + + result->buffer = buffer; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : disass = analyse à mener. * +* statusbar = barre de statut à tenir informée. * +* * +* Description : Assure le désassemblage en différé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtStatusBar *statusbar) +{ + GBinRoutine **routines; /* Liste des routines trouvées */ + size_t routines_count; /* Nombre de ces routines */ + guint id; /* Identifiant de statut */ + + routines = g_binary_format_get_routines(disass->format, &routines_count); + qsort(routines, routines_count, sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_rcompare); + + /* Première étape */ + + id = gtk_extended_status_bar_push(statusbar, _("Disassembling..."), true); + + disass->instrs = disassemble_binary_parts(disass->binary, disass->parts, disass->count, + statusbar, id); + + gtk_extended_status_bar_remove(statusbar, id); + + /* Seconde étape */ + + id = gtk_extended_status_bar_push(statusbar, _("Establishing links..."), true); + + establish_links_between_lines(disass->instrs, routines, routines_count, statusbar, id); + + gtk_extended_status_bar_remove(statusbar, id); +#if 0 + /* Troisième étape */ + + id = gtk_extended_status_bar_push(statusbar, _("Finding remaining limits..."), true); + + limit_all_routines(disass->lines, routines, routines_count, statusbar, id); + + gtk_extended_status_bar_remove(statusbar, id); +#endif + /* Quatrième étape */ + + id = gtk_extended_status_bar_push(statusbar, _("Printing disassembled code..."), true); + + print_disassembled_instructions(disass->buffer, disass->instrs, routines, routines_count); + + gtk_extended_status_bar_remove(statusbar, id); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* GESTION GLOBALE DE PROCEDURE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : buffer = tampon de destination pour le texte. * +* filename = nom du fichier ciblé à décompiler. * +* 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 : - * +* * +******************************************************************************/ + +static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, const uint8_t *data, off_t length) +{ + GLangOutput *output; /* Modèle de sortie adéquat */ + GBufferLine *line; /* Ligne de destination */ + size_t len; /* Taille du texte */ + char *content; /* Contenu textuel d'une ligne */ + GChecksum *checksum; /* Calcul de l'empreinte */ + const gchar *hex; /* Valeur hexadécimale du SHA */ + + output = g_asm_output_new(); + + line = g_lang_output_start_comments(output, buffer); + if (line != NULL) g_buffer_line_start_merge_at(line, BLC_ADDRESS); + + /* Introduction */ + + line = g_lang_output_continue_comments(output, buffer, + SL(_("Disassembly generated by OpenIDA"))); + g_buffer_line_start_merge_at(line, BLC_ADDRESS); + + line = g_lang_output_continue_comments(output, buffer, + SL(_("OpenIDA is free software - © 2008-2010 Cyrille Bagard"))); + g_buffer_line_start_merge_at(line, BLC_ADDRESS); + + line = g_lang_output_continue_comments(output, buffer, NULL, 0); + g_buffer_line_start_merge_at(line, BLC_ADDRESS); + + /* Fichier */ + + len = strlen(_("File: ")) + strlen(filename) + 1; + content = (char *)calloc(len, sizeof(char)); + + snprintf(content, len, "%s%s", _("File: "), filename); + + line = g_lang_output_continue_comments(output, buffer, content, len - 1); + g_buffer_line_start_merge_at(line, BLC_ADDRESS); + + 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_lang_output_continue_comments(output, buffer, content, len - 1); + g_buffer_line_start_merge_at(line, BLC_ADDRESS); + + free(content); + + /* Ligne de séparation */ + + line = g_lang_output_continue_comments(output, buffer, NULL, 0); + g_buffer_line_start_merge_at(line, BLC_ADDRESS); + + /* Conclusion */ + + line = g_lang_output_end_comments(output, buffer); + if (line != NULL) g_buffer_line_start_merge_at(line, BLC_ADDRESS); + + g_object_unref(G_OBJECT(output)); + +} + + +/****************************************************************************** +* * +* Paramètres : binary = représentation de binaire chargé. * +* parts = parties binaires à désassembler. * +* count = nombre de parties à traiter. * +* * +* Description : Procède au désassemblage d'un contenu binaire donné. * +* * +* Retour : Tampon de code mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GCodeBuffer *disassemble_binary(const GOpenidaBinary *binary, GBinPart **parts, size_t parts_count) +{ + GCodeBuffer *result; /* Tampon constitué à renvoyer */ + const uint8_t *data; /* Données binaires brutes */ + off_t length; /* Quantité de ces données */ + GDelayedDisassembly *disass; /* Désassemblage à mener */ + GWorkQueue *queue; /* Gestionnaire de différés */ + + result = g_code_buffer_new(); + + data = g_openida_binary_get_data(binary, &length); + build_disass_prologue(result, g_openida_binary_get_filename(binary), data, length); + + disass = g_delayed_disassembly_new(binary, parts, parts_count, result); + + queue = get_work_queue(); + g_work_queue_schedule_work(queue, G_DELAYED_WORK(disass)); + + g_delayed_work_wait_for_completion(G_DELAYED_WORK(disass)); + + g_object_unref(G_OBJECT(disass)); + + return result; + +} |