summaryrefslogtreecommitdiff
path: root/src/analysis/disass
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/disass')
-rw-r--r--src/analysis/disass/area.h1
-rw-r--r--src/analysis/disass/disassembler.c127
-rw-r--r--src/analysis/disass/disassembler.h2
-rw-r--r--src/analysis/disass/output.c183
-rw-r--r--src/analysis/disass/output.h8
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 *);