diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2016-12-30 10:38:52 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2016-12-30 10:38:52 (GMT) |
commit | 932ea7c83c07d3982fee605c6dd9895fd2753874 (patch) | |
tree | 766ad53bab9e3e3005334c30e823493de8e84168 /src/analysis/disass | |
parent | 1b5d39bfbc48c33a0ea0924b60e48448c8b45dd4 (diff) |
Rewritten the line buffers using generators and on-demand building to save memory.
Diffstat (limited to 'src/analysis/disass')
-rw-r--r-- | src/analysis/disass/area.h | 1 | ||||
-rw-r--r-- | src/analysis/disass/disassembler.c | 127 | ||||
-rw-r--r-- | src/analysis/disass/disassembler.h | 2 | ||||
-rw-r--r-- | src/analysis/disass/output.c | 183 | ||||
-rw-r--r-- | src/analysis/disass/output.h | 8 |
5 files changed, 98 insertions, 223 deletions
diff --git a/src/analysis/disass/area.h b/src/analysis/disass/area.h index d5f910b..155db7c 100644 --- a/src/analysis/disass/area.h +++ b/src/analysis/disass/area.h @@ -28,6 +28,7 @@ #include "../binary.h" #include "../../arch/instruction.h" #include "../../format/symbol.h" +#include "../../glibext/delayed.h" #include "../../gtkext/gtkstatusstack.h" diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c index 5326c36..246a5b2 100644 --- a/src/analysis/disass/disassembler.c +++ b/src/analysis/disass/disassembler.c @@ -39,11 +39,16 @@ #include "routines.h" #include "../../format/format.h" #include "../../glibext/delayed-int.h" +#include "../../glibext/generators/prologue.h" #include "../../gui/panels/log.h" #include "../../plugins/pglist.h" +#include "../human/asm/lang.h" // TODO : REMME -> format ! + + + /* ------------------------ DESASSEMBLAGE DE BINAIRE DIFFERE ------------------------ */ @@ -54,8 +59,9 @@ struct _GDelayedDisassembly GLoadedBinary *binary; /* Destinataire final */ GExeFormat *format; /* Format du binaire représenté*/ + GCodingLanguage *lang; /* Traduction en ASM préférée */ - GCodeBuffer *buffer; /* Tampon pour le rendu */ + GBufferCache *cache; /* Tampon pour le rendu */ }; @@ -80,7 +86,7 @@ static void g_delayed_disassembly_dispose(GDelayedDisassembly *); static void g_delayed_disassembly_finalize(GDelayedDisassembly *); /* Crée une tâche de désassemblage différé. */ -static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *, GCodeBuffer *); +static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *, GBufferCache *); /* Opère sur toutes les instructions. */ static void process_all_instructions(wgroup_id_t, GtkStatusStack *, const char *, ins_fallback_cb, GArchProcessor *, GProcContext *, GExeFormat *); @@ -97,7 +103,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *, GtkStatusStack /* Construit la description d'introduction du désassemblage. */ -static void build_disass_prologue(GCodeBuffer *, const char *, const char *); +static void build_disass_prologue(GBufferCache *, const GCodingLanguage *, const char *, const char *); @@ -172,6 +178,7 @@ static void g_delayed_disassembly_init(GDelayedDisassembly *disass) static void g_delayed_disassembly_dispose(GDelayedDisassembly *disass) { g_object_unref(G_OBJECT(disass->format)); + g_object_unref(G_OBJECT(disass->lang)); G_OBJECT_CLASS(g_delayed_disassembly_parent_class)->dispose(G_OBJECT(disass)); @@ -211,7 +218,7 @@ static void g_delayed_disassembly_finalize(GDelayedDisassembly *disass) * * ******************************************************************************/ -static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GCodeBuffer *buffer) +static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GBufferCache *cache) { GDelayedDisassembly *result; /* Tâche à retourner */ @@ -219,8 +226,9 @@ static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GCo result->binary = binary; result->format = g_loaded_binary_get_format(binary); + result->lang = g_asm_language_new(); - result->buffer = buffer; + result->cache = cache; return result; @@ -568,7 +576,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus - print_disassembled_instructions(disass->buffer, disass->format, proc, status); + print_disassembled_instructions(disass->cache, disass->lang, disass->binary, status); @@ -612,10 +620,10 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus /****************************************************************************** * * -* Paramètres : buffer = tampon de destination pour le texte. * +* Paramètres : cache = tampon de destination pour le texte. * +* lang = trauducteur pour l'impression finale. * * filename = nom du fichier ciblé à décompiler. * -* data = données en mémoire pour l'empreinte. * -* length = quantité de données à prendre en compte. * +* checksum = empreinte identifiant le binaire chargé. * * * * Description : Construit la description d'introduction du désassemblage. * * * @@ -625,96 +633,32 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkStatus * * ******************************************************************************/ -static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, const char *checksum) +static void build_disass_prologue(GBufferCache *cache, const GCodingLanguage *lang, const char *filename, const char *checksum) { -#if 0 - GLangOutput *output; /* Modèle de sortie adéquat */ - GBufferLine *line; /* Ligne de destination */ - bool managed; /* Groupe déjà défini ? */ - size_t len; /* Taille du texte */ - char *content; /* Contenu textuel d'une ligne */ - - output = g_asm_output_new(); + char **text; /* Contenu brute à imprimer */ + GIntroGenerator *generator; /* Générateur constitué */ - line = g_lang_output_start_comments(output, buffer); - if (line != NULL) - { - g_buffer_line_start_merge_at(line, BLC_PHYSICAL); - g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER); - - g_code_buffer_append_new_line(buffer, line); - - } - - managed = (line != NULL); + text = calloc(4, sizeof(char *)); /* Introduction */ - line = g_lang_output_continue_comments(output, buffer, - SL(_("Disassembly generated by Chrysalide"))); - g_buffer_line_start_merge_at(line, BLC_PHYSICAL); - - if (!managed) - g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER); - - g_code_buffer_append_new_line(buffer, line); - - line = g_lang_output_continue_comments(output, buffer, - SL(_("Chrysalide is free software - © 2008-2015 Cyrille Bagard"))); - g_buffer_line_start_merge_at(line, BLC_PHYSICAL); - - g_code_buffer_append_new_line(buffer, line); - - line = g_lang_output_continue_comments(output, buffer, NULL, 0); - g_buffer_line_start_merge_at(line, BLC_PHYSICAL); - - g_code_buffer_append_new_line(buffer, line); + text[0] = strdup(_("Disassembly generated by Chrysalide")); + text[1] = strdup(_("Chrysalide is free software - © 2008-2016 Cyrille Bagard")); /* 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_PHYSICAL); - - g_code_buffer_append_new_line(buffer, line); - - free(content); + asprintf(&text[2], "%s%s", _("File: "), filename); /* Checksum SHA256 */ - len = strlen(_("Sha256: ")) + strlen(checksum); - content = (char *)calloc(len + 1, sizeof(char)); - - snprintf(content, len + 1, "%s%s", _("Sha256: "), checksum); - - line = g_lang_output_continue_comments(output, buffer, content, len - 1); - g_buffer_line_start_merge_at(line, BLC_PHYSICAL); - - g_code_buffer_append_new_line(buffer, line); + asprintf(&text[3], "%s%s", _("Sha256: "), checksum); - free(content); + /* Intégration finale */ - /* Ligne de séparation */ + generator = g_intro_generator_new(lang, text, 4); - line = g_lang_output_continue_comments(output, buffer, NULL, 0); - g_buffer_line_start_merge_at(line, BLC_PHYSICAL); - g_code_buffer_append_new_line(buffer, line); + g_buffer_cache_append(cache, G_LINE_GENERATOR(generator), BLF_NONE); - /* Conclusion */ - - line = g_lang_output_end_comments(output, buffer); - if (line != NULL) - { - g_buffer_line_start_merge_at(line, BLC_PHYSICAL); - g_code_buffer_append_new_line(buffer, line); - } - - g_object_unref(G_OBJECT(output)); -#endif } @@ -724,7 +668,7 @@ static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, con * parts = parties binaires à désassembler. * * count = nombre de parties à traiter. * * instrs = liste des instructions chargées. [OUT] * -* buffer = tampon de code mis en place. [OUT] * +* cache = tampon de code mis en place. [OUT] * * ack = fonction à appeler une fois l'opération terminée. * * * * Description : Procède au désassemblage d'un contenu binaire donné. * @@ -735,30 +679,35 @@ static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, con * * ******************************************************************************/ -void disassemble_binary(GLoadedBinary *binary, GCodeBuffer **buffer, disassembly_ack_fc ack) +void disassemble_binary(GLoadedBinary *binary, GBufferCache **cache, disassembly_ack_fc ack) { GBinFormat *format; /* Format associé au binaire */ + GCodingLanguage *lang; /* Langage de sortie préféré */ GBinContent *content; /* Contenu bianire manipulé */ const gchar *checksum; /* Identifiant de binaire */ GDelayedDisassembly *disass; /* Désassemblage à mener */ GWorkQueue *queue; /* Gestionnaire de différés */ - *buffer = g_code_buffer_new(BLC_ASSEMBLY); + *cache = g_buffer_cache_new(); format = G_BIN_FORMAT(g_loaded_binary_get_format(binary)); + lang = g_asm_language_new(); + content = g_binary_format_get_content(format); checksum = g_binary_content_get_checksum(content); g_object_unref(G_OBJECT(content)); g_object_unref(G_OBJECT(format)); - build_disass_prologue(*buffer, g_binary_content_describe(content, true), checksum); + build_disass_prologue(*cache, lang, g_binary_content_describe(content, true), checksum); - disass = g_delayed_disassembly_new(binary, *buffer); + disass = g_delayed_disassembly_new(binary, *cache); g_signal_connect(disass, "work-completed", G_CALLBACK(ack), binary); queue = get_work_queue(); g_work_queue_schedule_work(queue, G_DELAYED_WORK(disass), DEFAULT_WORK_GROUP); + g_object_unref(G_OBJECT(lang)); + } diff --git a/src/analysis/disass/disassembler.h b/src/analysis/disass/disassembler.h index 9151d23..20c7bdd 100644 --- a/src/analysis/disass/disassembler.h +++ b/src/analysis/disass/disassembler.h @@ -59,7 +59,7 @@ GType g_delayed_disassembly_get_type(void); typedef void (* disassembly_ack_fc) (GDelayedDisassembly *, GLoadedBinary *); /* Procède à la décompilation des routines d'un fichier donné. */ -void disassemble_binary(GLoadedBinary *, GCodeBuffer **, disassembly_ack_fc); +void disassemble_binary(GLoadedBinary *, GBufferCache **, disassembly_ack_fc); diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c index fe4d705..6c044be 100644 --- a/src/analysis/disass/output.c +++ b/src/analysis/disass/output.c @@ -27,27 +27,18 @@ #include <i18n.h> -#include "../../arch/processor.h" -#include "../../common/extstr.h" #include "../../format/format.h" +#include "../../glibext/generators/rborder.h" #include "../../gui/panels/log.h" -#define ROUTINE_INTRO_MSG "; --------------- BEGIN OF PROCEDURE ---------------" - -#define ROUTINE_OUTRO_MSG "; ---------------- END OF PROCEDURE ----------------" - - - /****************************************************************************** * * -* Paramètres : buffer = tampon de récueil des résultats d'impression. * -* format = format du binaire traité. * -* instrs = ensemble d'instructions à traiter. * -* routines = liste de routines intervenant dans le flot. * -* count = quantité de ces routines. * -* status = barre de statut avec progression à mettre à jour. * +* Paramètres : cache = tampon de récueil des résultats d'impression. * +* lang = langage de haut niveau préféré pour l'impression. * +* binary = tampon de récueil des résultats d'impression. * +* status = barre de statut avec progression à mettre à jour. * * * * Description : Transcrit du code désassemblé en texte humainement lisible. * * * @@ -57,8 +48,10 @@ * * ******************************************************************************/ -void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GArchProcessor *proc, GtkStatusStack *status) +void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang, GLoadedBinary *binary, GtkStatusStack *status) { + GExeFormat *format; /* Format associé au binaire */ + GArchProcessor *proc; /* Processeur de l'architecture*/ GBinPortion *root; /* Couche première de portions */ GBinPortion **portions; /* Morceaux d'encadrement */ size_t portions_count; /* Taille de cette liste */ @@ -74,22 +67,21 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA size_t i; /* Boucle de parcours */ GArchInstruction *instr; /* Instruction à traiter */ const vmpa2t *iaddr; /* Adresse d'instruction */ - vmpa2t outro_addr; /* Adresse de fin de code */ - GBufferLine *line; + GBorderGenerator *border; /* Délimitation de routine */ const vmpa2t *paddr; /* Adresse de portion */ + GLineGenerator *generator; /* Générateur de contenu ajouté*/ const vmpa2t *saddr; /* Adresse de symbole */ int compared; /* Bilan d'une comparaison */ SymbolType stype; /* Type de symbole trouvé */ - const char *label; /* Etiquette ciblant un symbole*/ - mrange_t range; /* Couverture sans surface */ + vmpa2t intro_addr; /* Adresse de début de code */ + vmpa2t outro_addr; /* Adresse de fin de code */ + BufferLineFlags flags; /* Propriétés pour la ligne */ + //mrange_t range; /* Couverture sans surface */ GDbComment *comment; /* Commentaire à ajouter */ - const char *text; - - char *prefixed; @@ -98,6 +90,8 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA + format = g_loaded_binary_get_format(binary); + proc = g_loaded_binary_get_processor(binary); bool collect_all_portions(GBinPortion *portion, GBinPortion *parent, BinaryPortionVisit visit, void *unused) { @@ -149,29 +143,8 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA { expect_outro = false; - init_mrange(&range, &outro_addr, 0); - - line = g_code_buffer_prepare_new_line(buffer, &range); - g_buffer_line_add_flag(line, BLF_IS_LABEL); - g_buffer_line_fill_mrange(line, msize, msize); - - g_code_buffer_append_new_line(buffer, line); - - line = g_code_buffer_prepare_new_line(buffer, &range); - g_buffer_line_add_flag(line, BLF_IS_LABEL); - g_buffer_line_fill_mrange(line, msize, msize); - - g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); - g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, - ROUTINE_OUTRO_MSG, strlen(ROUTINE_OUTRO_MSG), RTT_COMMENT, NULL); - - g_code_buffer_append_new_line(buffer, line); - - line = g_code_buffer_prepare_new_line(buffer, &range); - g_buffer_line_add_flag(line, BLF_IS_LABEL); - g_buffer_line_fill_mrange(line, msize, msize); - - g_code_buffer_append_new_line(buffer, line); + border = g_border_generator_new(lang, &outro_addr, false, msize); + g_buffer_cache_append(cache, G_LINE_GENERATOR(border), BLF_NONE); } @@ -184,7 +157,11 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA if (cmp_vmpa_by_phy(iaddr, paddr) != 0) break; - g_binary_portion_print(portions[portion_index], buffer, msize); + generator = G_LINE_GENERATOR(portions[portion_index]); + + /* Si elle comporte une description ! */ + if (g_line_generator_count_lines(generator) > 0) + g_buffer_cache_append(cache, generator, BLF_NONE); portion_index++; @@ -192,7 +169,10 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA /* Début d'un nouveau symbole ? */ - if (sym_index < sym_count) + if (sym_index == sym_count) + compared = -1; + + else { iaddr = get_mrange_addr(g_arch_instruction_get_range(instr)); saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index])); @@ -225,29 +205,10 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA { /* Impression de la marque de début */ - init_mrange(&range, get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index])), 0); - - line = g_code_buffer_prepare_new_line(buffer, &range); - g_buffer_line_add_flag(line, BLF_IS_LABEL); - g_buffer_line_fill_mrange(line, msize, msize); - - g_code_buffer_append_new_line(buffer, line); - - line = g_code_buffer_prepare_new_line(buffer, &range); - g_buffer_line_add_flag(line, BLF_IS_LABEL); - g_buffer_line_fill_mrange(line, msize, msize); - - g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); - g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, - ROUTINE_INTRO_MSG, strlen(ROUTINE_INTRO_MSG), RTT_COMMENT, NULL); - - g_code_buffer_append_new_line(buffer, line); + copy_vmpa(&intro_addr, get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index]))); - line = g_code_buffer_prepare_new_line(buffer, &range); - g_buffer_line_add_flag(line, BLF_IS_LABEL); - g_buffer_line_fill_mrange(line, msize, msize); - - g_code_buffer_append_new_line(buffer, line); + border = g_border_generator_new(lang, &intro_addr, true, msize); + g_buffer_cache_append(cache, G_LINE_GENERATOR(border), BLF_NONE); /* Mémorisation de la fin */ @@ -259,23 +220,10 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA /* Etiquette ? */ - label = g_binary_symbol_get_label(symbols[sym_index]); - - if (label != NULL) - { - init_mrange(&range, get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index])), 0); - - line = g_code_buffer_prepare_new_line(buffer, &range); - g_buffer_line_add_flag(line, BLF_IS_LABEL); - g_buffer_line_fill_mrange(line, msize, msize); - - g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); - g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, label, strlen(label), RTT_LABEL, NULL); - g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, ":", 1, RTT_PUNCT, NULL); - - g_code_buffer_append_new_line(buffer, line); + generator = g_binary_symbol_produce_label(symbols[sym_index]); - } + if (generator != NULL) + g_buffer_cache_append(cache, generator, BLF_NONE); } @@ -283,64 +231,37 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA no_more_symbol_finally: + flags = BLF_NONE; - - line = g_arch_instruction_print(instr, buffer, msize, content, ASX_INTEL); - - - if (g_arch_instruction_get_flags(instr) & AIF_RETURN_POINT) - g_buffer_line_add_flag(line, BLF_BOOKMARK); - - - if (sym_index < sym_count) + if (compared == 0) { - iaddr = get_mrange_addr(g_arch_instruction_get_range(instr)); - saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index])); - - if (cmp_vmpa(iaddr, saddr) == 0) - { - /* Point d'entrée ? */ - - if (g_binary_symbol_get_target_type(symbols[sym_index]) == STP_ENTRY_POINT) - g_buffer_line_add_flag(line, BLF_ENTRYPOINT); + /* Point d'entrée ? */ - /* Début d'un groupe bien cohérent avec les alignements ? */ + if (g_binary_symbol_get_target_type(symbols[sym_index]) == STP_ENTRY_POINT) + flags |= BLF_ENTRYPOINT; - if (g_binary_symbol_is_block_start(symbols[sym_index])) - g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER); + /* Début d'un groupe bien cohérent avec les alignements ? */ - /* Commentaire ? */ - - comment = g_binary_symbol_get_comment(symbols[sym_index]); - - if (comment != NULL) - { + if (g_binary_symbol_is_block_start(symbols[sym_index])) + flags |= BLF_WIDTH_MANAGER; - /* FIXME : appliquer ! */ - - text = g_db_comment_get_text(comment); - - - prefixed = strdup("; "); - prefixed = stradd(prefixed, text); - - - - g_buffer_line_append_text(line, BLC_COMMENTS, prefixed, strlen(prefixed), RTT_COMMENT, NULL); + } + g_buffer_cache_append(cache, G_LINE_GENERATOR(instr), flags); - free(prefixed); + if (compared == 0) + { + /* Commentaire ? */ - } + comment = g_binary_symbol_get_comment(symbols[sym_index]); - sym_index++; + if (comment != NULL) + g_db_item_apply(G_DB_ITEM(comment), binary); - } + sym_index++; } - g_code_buffer_append_new_line(buffer, line); - g_object_unref(G_OBJECT(instr)); gtk_status_stack_update_activity_value(status, id, 1); @@ -356,6 +277,10 @@ void print_disassembled_instructions(GCodeBuffer *buffer, GExeFormat *format, GA if (portions != NULL) free(portions); + g_object_unref(G_OBJECT(proc)); + g_object_unref(G_OBJECT(format)); + + fprintf(stderr, "MISSING :: %u symbols\n", _missing); diff --git a/src/analysis/disass/output.h b/src/analysis/disass/output.h index 801d3f4..35a0108 100644 --- a/src/analysis/disass/output.h +++ b/src/analysis/disass/output.h @@ -25,15 +25,15 @@ #define _ANALYSIS_DISASS_OUTPUT_H -#include "../../arch/processor.h" -#include "../../format/executable.h" -#include "../../glibext/gcodebuffer.h" +#include "../binary.h" +#include "../human/lang.h" +#include "../../glibext/gbuffercache.h" #include "../../gtkext/gtkstatusstack.h" /* Transcrit du code désassemblé en texte humainement lisible. */ -void print_disassembled_instructions(GCodeBuffer *, GExeFormat *, GArchProcessor *, GtkStatusStack *); +void print_disassembled_instructions(GBufferCache *, GCodingLanguage *, GLoadedBinary *, GtkStatusStack *); |