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/binary.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/binary.c')
-rw-r--r-- | src/analysis/binary.c | 529 |
1 files changed, 33 insertions, 496 deletions
diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 4093f6e..f13a887 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -41,10 +41,11 @@ #include "line_comment.h" /* TODO : supprimer ? */ #include "line_prologue.h" #include "routine.h" +#include "decomp/decompiler.h" +#include "disass/disassembler.h" #include "../common/cpp.h" #include "../common/extstr.h" #include "../debug/break.h" -#include "../glibext/delayed-int.h" #include "../format/format.h" #include "../panels/log.h" #include "../plugins/pglist.h" @@ -59,56 +60,8 @@ /* ------------------------ 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 */ - - GOpenidaBinary *binary; /* Destinataire final */ - - GBinPart **parts; /* Parties binaires à traiter */ - size_t count; /* Nombre de ces parties */ - - GRenderingLine *lines; /* Lignes de rendu résultantes */ - -} 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(GOpenidaBinary *, GBinPart **, size_t); - -/* Assure le désassemblage en différé. */ -static void g_delayed_disassembly_process(GDelayedDisassembly *, GtkExtStatusBar *); - -/* Procède au désassemblage basique d'un contenu binaire. */ -static GRenderingLine *disassemble_binary_parts(GDelayedDisassembly *, GBinRoutine **, size_t, GtkExtStatusBar *, guint); +#if 0 -/* Etablit les liens entres les différentes lignes de code. */ -static void establish_links_between_lines(GRenderingLine *, GBinRoutine **, size_t, GtkExtStatusBar *, guint); /* S'assure que toutes les routines ont une taille définie. */ static void limit_all_routines(GRenderingLine *, GBinRoutine **, size_t, GtkExtStatusBar *, guint); @@ -118,6 +71,7 @@ static vmpa_t find_best_ending_address_for_routine(GRenderingLine *, size_t, con +#endif @@ -142,6 +96,7 @@ struct _GOpenidaBinary GRenderingLine *lines; /* Lignes de rendu en place */ GRenderingOptions *options; /* Options de désassemblage */ + GCodeBuffer *disass_buffer; /* Instructions lisibles */ GCodeBuffer **dec_buffers; /* Sources sous forme de texte */ size_t decbuf_count; /* Taille des tableaux */ size_t defsrc; /* Fichier source principal */ @@ -173,11 +128,8 @@ static void g_openida_binary_init(GOpenidaBinary *); /* Charge en mémoire le contenu d'un fichier. */ bin_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); - /* Acquitte la fin d'un désasemblage différé et complet. */ -void ack_completed_disassembly(GDelayedDisassembly *, GOpenidaBinary *); +void ack_completed_disassembly(void/*GDelayedDisassembly*/ *, GOpenidaBinary *); @@ -193,361 +145,9 @@ static void g_openida_binary_breakpoint_added(GBreakGroup *, GBreakPoint *, GOpe static void g_openida_binary_breakpoint_removed(GBreakGroup *, GBreakPoint *, GOpenidaBinary *); - -/* ---------------------------------------------------------------------------------- */ -/* 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. * -* parts = parties binaires à désassembler. * -* count = nombre de parties à traiter. * -* * -* Description : Crée une tâche de désassemblage différé. * -* * -* Retour : Tâche créée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GDelayedDisassembly *g_delayed_disassembly_new(GOpenidaBinary *binary, GBinPart **parts, size_t count) -{ - GDelayedDisassembly *result; /* Tâche à retourner */ - - result = g_object_new(G_TYPE_DELAYED_DISASSEMBLY, NULL); - - result->binary = binary; - - result->parts = parts; - result->count = count; - - 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(G_BIN_FORMAT(disass->binary->format), &routines_count); - qsort(routines, routines_count, sizeof(GBinRoutine *), g_binary_routine_rcompare); - - /* Première étape */ - - id = gtk_extended_status_bar_push(statusbar, _("Disassembling..."), true); - - disass->lines = disassemble_binary_parts(disass, routines, routines_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->lines, routines, routines_count, statusbar, id); - - gtk_extended_status_bar_remove(statusbar, id); - - /* 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); - -} - - -/****************************************************************************** -* * -* Paramètres : disass = tâche à l'origine du traitement. * -* routines = prototypes existants à insérer. * -* count = quantité de ces prototypes. * -* statusbar = barre de statut avec progression à mettre à jour.* -* id = identifiant du message affiché à l'utilisateur. * -* * -* Description : Procède au désassemblage basique d'un contenu binaire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GRenderingLine *disassemble_binary_parts(GDelayedDisassembly *disass, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, guint id) -{ - GRenderingLine *result; /* Ligne de rendu à retourner */ - GArchInstruction *first; /* Première instruction vue */ - GArchProcessor *proc; /* Architecture du binaire */ - GRenderingOptions *options; /* Options de désassemblage */ - bin_t *bin_data; /* Données binaires à lire */ - size_t i; /* Boucle de parcours #1 */ - off_t sum; /* Somme de toutes les tailles */ - off_t done; /* Quantité déjà traitée */ - off_t pos; /* Début d'une zone binaire */ - off_t len; /* Taille de cette même zone */ - vmpa_t base; /* Adresse de la zone binaire */ - off_t start; /* Conservation du pt de départ*/ - vmpa_t addr; /* Adresse d'une instruction */ - GArchInstruction *instr; /* Instruction décodée */ - GRenderingLine *line; /* Nouvelle ligne de rendu */ - size_t k; /* Boucle de parcours #2 */ - uint64_t routine_offset; /* Point de départ de routine */ - char *routine_desc; /* Prototype d'une routine */ - - result = NULL; - - first = NULL; - - proc = get_arch_processor_from_format(g_openida_binary_get_format(disass->binary)); - options = g_openida_binary_get_options(disass->binary); - bin_data = g_openida_binary_get_data(disass->binary, NULL); - - /* Préparation du suivi de la progression */ - - sum = 0; - - for (i = 0; i < disass->count; i++) - { - g_binary_part_get_values(disass->parts[i], NULL, &len, NULL); - if (len > disass->binary->bin_length) continue; - sum += len; - } - - done = 0; - - k = 0; - - for (i = 0; i < disass->count; i++) - { - g_binary_part_get_values(disass->parts[i], &pos, &len, &base); - - if (len > disass->binary->bin_length) continue; - - /* Décodage des instructions */ - - start = pos; - pos = 0; - - while (pos < len) - { - addr = base + pos; - - instr = g_arch_processor_decode_instruction(proc, &bin_data[start], - &pos, len, start, addr); - g_arch_instruction_add_to_list(&first, instr); - - line = g_code_line_new(addr, instr, options); - g_rendering_line_add_to_lines(&result, line); - - /* Ajout des prototypes de fonctions */ - - for (; k < count; k++) - { - routine_offset = g_binary_routine_get_address(routines[k]); - - if (routine_offset > addr) break; - - routine_desc = g_binary_routine_to_string(routines[k]); - - line = g_comment_line_new(routine_offset, routine_desc, options); - g_rendering_line_insert_into_lines(&result, line, true); - - free(routine_desc); - - } - - if (pos < len) - gtk_extended_status_bar_update_activity(statusbar, id, (done + pos) * 1.0 / sum); - - } - - done += len; - gtk_extended_status_bar_update_activity(statusbar, id, done * 1.0 / sum); #if 0 - /* Ajout des prototypes de fonctions */ - - printf("BASE == 0x%08llx\n", base); - - for (; k < count; k++) - { - routine_offset = g_binary_routine_get_address(routines[k]); - - if (!(base <= routine_offset && routine_offset < (base + len))) continue; - routine_desc = g_binary_routine_to_string(routines[k]); - line = g_comment_line_new(routine_offset, routine_desc, options); - g_rendering_line_insert_into_lines(&result, line, true); - - free(routine_desc); - - } -#endif - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : lines = lignes de rendu à relier. * -* routines = prototypes existants à insérer. * -* count = quantité de ces prototypes. * -* statusbar = barre de statut avec progression à mettre à jour.* -* id = identifiant du message affiché à l'utilisateur. * -* * -* Description : Etablit les liens entres les différentes lignes de code. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void establish_links_between_lines(GRenderingLine *lines, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, guint id) -{ - size_t i; /* Boucle de parcours */ - vmpa_t start; /* Adresse de départ */ - vmpa_t end; /* Adresse de fin */ - GRenderingLine *iter; /* Boucle de parcours */ - GArchInstruction *instr; /* Instruction à ausculter */ - vmpa_t addr; /* Adresse référencée */ - InstructionLinkType type; /* Type de référence */ - GRenderingLine *target; /* Ligne visée par la référence*/ - - for (i = 0; i < count; i++) - { - start = g_binary_routine_get_address(routines[i]); - end = start + g_binary_routine_get_size(routines[i]); - - for (iter = g_rendering_line_find_by_address(lines, NULL, start); - iter != NULL; - iter = g_rendering_line_get_next_iter(lines, iter, NULL)) - { - /* Si on sort de la zone... */ - if (get_rendering_line_address(iter) >= end) break; - - /* On ne traite que du code ici ! */ - if (!G_IS_CODE_LINE(iter)) continue; - - instr = g_code_line_get_instruction(G_CODE_LINE(iter)); - type = g_arch_instruction_get_link(instr, &addr); - - switch (type) - { - case ILT_NONE: - break; - - case ILT_JUMP: - - target = g_rendering_line_find_by_address(lines, NULL, addr); - - if (target != NULL) - g_rendering_line_link_with(iter, target, type); - - break; - - case ILT_JUMP_IF_FALSE: - break; - - case ILT_JUMP_IF_TRUE: - - target = g_rendering_line_find_by_address(lines, NULL, addr); - - if (target != NULL) - { - g_rendering_line_link_with(iter, target, type); - - target = g_rendering_line_get_next_iter(lines, iter, NULL); - if (target != NULL) - g_rendering_line_link_with(iter, target, ILT_JUMP_IF_FALSE); - - } - - break; - - case ILT_CALL: - - target = g_rendering_line_find_by_address(lines, NULL, addr); - - if (target != NULL) - g_rendering_line_link_with(iter, target, type); - - break; - - } - - } - - gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / count); - - } - -} /****************************************************************************** @@ -696,7 +296,7 @@ static vmpa_t find_best_ending_address_for_routine(GRenderingLine *line, size_t } - +#endif @@ -806,7 +406,7 @@ GOpenidaBinary *g_openida_binary_new_from_file(const char *filename) break; } - result->lines = build_binary_prologue(filename, result->bin_data, result->bin_length); + result->lines = NULL; result->proc = get_arch_processor_from_format(result->format); @@ -1148,13 +748,8 @@ GBinPart ***g_openida_binary_get_parts(const GOpenidaBinary *binary, BinaryPartM void g_openida_binary_analyse(GOpenidaBinary *binary) { - GWorkQueue *queue; /* Gestionnaire de différés */ GBinPart **parts; /* Parties d'élément binaire */ size_t parts_count; /* Nombre de ces parties */ - GDelayedDisassembly *disass; /* Désassemblage à mener */ - - queue = get_work_queue(); - if (binary->parts_count[BPM_ROUTINES] > 0) binary->model = BPM_ROUTINES; @@ -1179,12 +774,10 @@ void g_openida_binary_analyse(GOpenidaBinary *binary) } } - disass = g_delayed_disassembly_new(binary, parts, parts_count); + binary->disass_buffer = disassemble_binary(binary, parts, parts_count); - g_signal_connect(disass, "work-completed", - G_CALLBACK(ack_completed_disassembly), binary); - - g_work_queue_schedule_work(queue, G_DELAYED_WORK(disass)); + /* TODO : remme ! */ + ack_completed_disassembly(NULL, binary); } @@ -1363,6 +956,25 @@ GArchInstruction *g_openida_binary_get_instructions(const GOpenidaBinary *binary /****************************************************************************** * * * Paramètres : binary = élément binaire à consulter. * +* * +* Description : Fournit le tampon associé au contenu assembleur d'un binaire.* +* * +* Retour : Tampon mis en place ou NULL si aucun (!). * +* * +* Remarques : - * +* * +******************************************************************************/ + +GCodeBuffer *g_openida_binary_get_disassembled_buffer(const GOpenidaBinary *binary) +{ + return binary->disass_buffer; + +} + + +/****************************************************************************** +* * +* Paramètres : binary = élément binaire à consulter. * * index = indice du fichier à retrouver. * * * * Description : Fournit le tampon associé au contenu d'un fichier source. * @@ -1443,82 +1055,6 @@ bin_t *map_binary_file(const char *filename, off_t *length) /****************************************************************************** * * -* 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-2010 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 : disass = travail de désassemblage mené à bien. * * binary = représentation de binaire à l'origine de l'opérat°. * * * @@ -1530,7 +1066,7 @@ GRenderingLine *build_binary_prologue(const char *filename, const uint8_t *data, * * ******************************************************************************/ -void ack_completed_disassembly(GDelayedDisassembly *disass, GOpenidaBinary *binary) +void ack_completed_disassembly(void/*GDelayedDisassembly*/ *disass, GOpenidaBinary *binary) { GRenderingLine *line; /* "Première" ligne de rendu */ GPluginModule **pglist; /* Liste de greffons */ @@ -1556,7 +1092,7 @@ void ack_completed_disassembly(GDelayedDisassembly *disass, GOpenidaBinary *bina - +#if 0 g_rendering_line_merge(&binary->lines, &disass->lines); @@ -1580,6 +1116,7 @@ void ack_completed_disassembly(GDelayedDisassembly *disass, GOpenidaBinary *bina } /* On réintègre le flot premier */ +#endif g_signal_emit_by_name(binary, "disassembly-done"); |