diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2010-11-06 00:29:36 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2010-11-06 00:29:36 (GMT) |
commit | 828124e38d266e382bb1477ef51c9fac8e81c591 (patch) | |
tree | 37d1d6af336987030791ba4c41b89a8cf144d270 /src | |
parent | c1ff0021b42fb5738a0cb31da15c12eb6dfac816 (diff) |
Defined the entry point for decompilations.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@189 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 9 | ||||
-rwxr-xr-x | src/analysis/Makefile.am | 5 | ||||
-rw-r--r-- | src/analysis/binary.c | 52 | ||||
-rw-r--r-- | src/analysis/binary.h | 6 | ||||
-rwxr-xr-x | src/analysis/decomp/Makefile.am | 14 | ||||
-rw-r--r-- | src/analysis/decomp/decompiler.c | 131 | ||||
-rw-r--r-- | src/analysis/decomp/decompiler.h | 37 | ||||
-rw-r--r-- | src/analysis/exporter.h | 31 | ||||
-rwxr-xr-x | src/decomp/Makefile.am | 20 | ||||
-rwxr-xr-x | src/decomp/lang/Makefile.am | 14 | ||||
-rw-r--r-- | src/decomp/lang/java.c | 155 | ||||
-rw-r--r-- | src/decomp/lang/java.h | 55 | ||||
-rw-r--r-- | src/decomp/output-int.h | 56 | ||||
-rw-r--r-- | src/decomp/output.c | 106 | ||||
-rw-r--r-- | src/decomp/output.h | 58 | ||||
-rw-r--r-- | src/glibext/gbufferline.c | 145 | ||||
-rw-r--r-- | src/glibext/gbufferline.h | 38 | ||||
-rw-r--r-- | src/glibext/gcodebuffer.c | 17 | ||||
-rw-r--r-- | src/gtkext/gtksourceview.c | 261 |
19 files changed, 1165 insertions, 45 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 6d3bac1..f1fce92 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ -lib_LTLIBRARIES = liboidadisass.la liboidaglibext.la liboidagtkext.la liboidagui.la liboidaplugin.la +lib_LTLIBRARIES = liboidaglibext.la liboidadisass.la liboidagtkext.la liboidagui.la liboidaplugin.la bin_PROGRAMS=openida @@ -14,7 +14,7 @@ bin_PROGRAMS=openida liboidadisass_la_SOURCES = liboidadisass_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBXML_LIBS) \ - -Lcommon/.libs -lcommon + -Lcommon/.libs -lcommon -L.libs -loidaglibext liboidadisass_la_LIBADD = \ analysis/libanalysis.la \ @@ -22,6 +22,7 @@ liboidadisass_la_LIBADD = \ debug/libdebug.la \ debug/remgdb/libdebugremgdb.la \ debug/ptrace/libdebugptrace.la \ + decomp/libdecomp.la \ format/libformat.la @@ -40,7 +41,7 @@ liboidaglibext_la_LIBADD = \ liboidagtkext_la_SOURCES = liboidagtkext_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBGRAPH_LIBS) \ - -L.libs -loidadisass -loidaglibext + -L.libs -loidadisass liboidagtkext_la_LIBADD = \ graph/libgraph.la \ @@ -109,4 +110,4 @@ openida_LDADD = $(LIBINTL) \ # gtkext doit être traité en premier, à cause des marshals GLib -SUBDIRS = glibext gtkext analysis arch format common debug dialogs graph panels plugins +SUBDIRS = glibext gtkext analysis arch format common debug decomp dialogs graph panels plugins diff --git a/src/analysis/Makefile.am b/src/analysis/Makefile.am index 3c22aa6..604835d 100755 --- a/src/analysis/Makefile.am +++ b/src/analysis/Makefile.am @@ -15,6 +15,9 @@ libanalysis_la_SOURCES = \ type.h type.c \ variable.h variable.c +libanalysis_la_LIBADD = \ + decomp/libanalysisdecomp.la + libanalysis_la_LDFLAGS = @@ -24,4 +27,4 @@ AM_CPPFLAGS = AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = +SUBDIRS = decomp diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 63450a3..949bb31 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -142,6 +142,10 @@ struct _GOpenidaBinary GRenderingLine *lines; /* Lignes de rendu en place */ GRenderingOptions *options; /* Options de désassemblage */ + char **src_files; /* Nom des fichiers source */ + GCodeBuffer **dec_buffers; /* Sources sous forme de texte */ + size_t decbuf_count; /* Taille des tableaux */ + GBreakGroup **brk_groups; /* Groupes de points d'arrêt */ size_t brk_count; /* Taille de cette liste */ GBreakGroup *brk_default; /* Groupe par défaut */ @@ -1340,9 +1344,41 @@ GArchInstruction *g_openida_binary_get_instructions(const GOpenidaBinary *binary } +/****************************************************************************** +* * +* Paramètres : binary = élément binaire à consulter. * +* filename = nom de fichier à retrouver. * +* * +* Description : Fournit le tampon associé au contenu d'un fichier source. * +* * +* Retour : Tampon mis en place ou NULL si aucun (!). * +* * +* Remarques : - * +* * +******************************************************************************/ +GCodeBuffer *g_openida_binary_get_decompiled_buffer(const GOpenidaBinary *binary, const char *filename) +{ + GCodeBuffer *result; /* Tampon à retourner */ + size_t i; /* Boucle de parcours */ + result = NULL; + for (i = 0; i < binary->decbuf_count; i++) + { + /* Si aucune demande précise, on renvoie le premier ! */ + if (filename == NULL + || strcmp(binary->src_files[i], filename) == 0) + { + result = binary->dec_buffers[i]; + break; + } + + } + + return result; + +} /****************************************************************************** @@ -1495,6 +1531,22 @@ void ack_completed_disassembly(GDelayedDisassembly *disass, GOpenidaBinary *bina size_t i; /* Boucle de parcours */ + /* Décompilation... */ + + + binary->decbuf_count++; + binary->src_files = (char **)calloc(binary->decbuf_count, sizeof(char *)); + binary->dec_buffers = (GCodeBuffer **)calloc(binary->decbuf_count, sizeof(GCodeBuffer *)); + + binary->dec_buffers[0] = decompile_all_from_file(binary, "RC4.java"); + + + + + + + + g_rendering_line_merge(&binary->lines, &disass->lines); diff --git a/src/analysis/binary.h b/src/analysis/binary.h index da0bcf7..666cfaa 100644 --- a/src/analysis/binary.h +++ b/src/analysis/binary.h @@ -31,9 +31,10 @@ #include "line.h" #include "../arch/processor.h" +#include "../common/xml.h" #include "../debug/break.h" #include "../format/executable.h" -#include "../common/xml.h" +#include "../glibext/gcodebuffer.h" @@ -108,6 +109,9 @@ GRenderingLine *g_openida_binary_get_lines(const GOpenidaBinary *); /* Fournit les instructions issues du désassemblage. */ GArchInstruction *g_openida_binary_get_instructions(const GOpenidaBinary *); +/* Fournit le tampon associé au contenu d'un fichier source. */ +GCodeBuffer *g_openida_binary_get_decompiled_buffer(const GOpenidaBinary *, const char *); + /* ------------------------------ ELEMENTS DE DEBOGAGE ------------------------------ */ diff --git a/src/analysis/decomp/Makefile.am b/src/analysis/decomp/Makefile.am new file mode 100755 index 0000000..7b797bd --- /dev/null +++ b/src/analysis/decomp/Makefile.am @@ -0,0 +1,14 @@ + +noinst_LTLIBRARIES = libanalysisdecomp.la + +libanalysisdecomp_la_SOURCES = \ + decompiler.h decompiler.c + +libanalysisdecomp_la_LDFLAGS = + + +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CPPFLAGS = + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/src/analysis/decomp/decompiler.c b/src/analysis/decomp/decompiler.c new file mode 100644 index 0000000..284d3e1 --- /dev/null +++ b/src/analysis/decomp/decompiler.c @@ -0,0 +1,131 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * decompiler.h - prototypes pour l'encadrement des phases de décompilation + * + * 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 "decompiler.h" + + +#include <malloc.h> +#include <stdio.h> +#include <string.h> + + +#include <i18n.h> + + +#include "../../decomp/output.h" +#include "../../decomp/lang/java.h" /* FIXME : remme ! */ + + + +/* Construit la description d'introduction de la décompilation. */ +static void build_decomp_prologue(GCodeBuffer *, const char *); + + + +/****************************************************************************** +* * +* Paramètres : buffer = tampon de destination pour le texte. * +* filename = nom du fichier ciblé à décompiler. * +* * +* Description : Construit la description d'introduction de la décompilation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void build_decomp_prologue(GCodeBuffer *buffer, const char *filename) +{ + 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 */ + + output = g_java_output_new(); + + /* Introduction */ + + line = g_lang_output_write_comments(output, buffer, + SL(_("Binary data decompiled by OpenIDA"))); + g_buffer_line_start_merge_at(line, BLC_ADDRESS); + + line = g_lang_output_write_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_write_comments(output, buffer, NULL, 0); + g_buffer_line_start_merge_at(line, BLC_ADDRESS); + + /* Fichier */ + + if (filename == NULL) + filename = _("whole binary"); + + len = strlen(_("File: ")) + strlen(filename) + 1; + content = (char *)calloc(len, sizeof(char)); + + snprintf(content, len, "%s%s", _("File: "), filename); + + line = g_lang_output_write_comments(output, buffer, content, len - 1); + g_buffer_line_start_merge_at(line, BLC_ADDRESS); + + free(content); + + /* Lignes de séparation */ + + line = g_lang_output_write_comments(output, buffer, NULL, 0); + g_buffer_line_start_merge_at(line, BLC_ADDRESS); + + line = g_lang_output_write_comments(output, buffer, NULL, 0); + g_buffer_line_start_merge_at(line, BLC_ADDRESS); + +} + + +/****************************************************************************** +* * +* Paramètres : binary = représentation de binaire chargé. * +* filename = nom du fichier source à cibler. * +* * +* Description : Procède à la décompilation des routines d'un fichier donné. * +* * +* Retour : Tampon de code mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GCodeBuffer *decompile_all_from_file(const GOpenidaBinary *binary, const char *filename) +{ + GCodeBuffer *result; /* Tampon constitué à renvoyer */ + + result = g_code_buffer_new(); + + + build_decomp_prologue(result, filename); + + + return result; + +} diff --git a/src/analysis/decomp/decompiler.h b/src/analysis/decomp/decompiler.h new file mode 100644 index 0000000..363ad27 --- /dev/null +++ b/src/analysis/decomp/decompiler.h @@ -0,0 +1,37 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * decompiler.h - prototypes pour l'encadrement des phases de décompilation + * + * 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/>. + */ + + +#ifndef _ANALYSIS_DECOMP_DECOMPILER_H +#define _ANALYSIS_DECOMP_DECOMPILER_H + + +#include "../binary.h" + + + +/* Procède à la décompilation des routines d'un fichier donné. */ +GCodeBuffer *decompile_all_from_file(const GOpenidaBinary *, const char *); + + + +#endif /* _ANALYSIS_DECOMP_DECOMPILER_H */ diff --git a/src/analysis/exporter.h b/src/analysis/exporter.h index 56ad2ab..eb4cb5d 100644 --- a/src/analysis/exporter.h +++ b/src/analysis/exporter.h @@ -34,37 +34,6 @@ #include "../glibext/gbufferline.h" -/* Types de partie de rendu */ -typedef enum _RenderingTagType -{ - RTT_RAW, /* Contenu brut */ - - RTT_COMMENT, /* Commentaire */ - RTT_RAW_CODE, /* Code binaire brut */ - - RTT_INSTRUCTION, /* Code binaire brut */ - - RTT_IMMEDIATE, /* Valeur immédiate */ - - RTT_REGISTER, /* Registre */ - - RTT_HOOK, /* Crochets '[' et ']' */ - RTT_SIGNS, /* Signes '+', '-' et '*' */ - RTT_LTGT, /* Caractères '<' et '>' */ - - RTT_SECTION, /* Identifiant de section */ - RTT_SEGMENT, /* Indication de segment */ - RTT_STRING, /* Chaîne de caractères avec " */ - - RTT_VAR_NAME, /* Nom de variable */ - - RTT_COUNT - -} RenderingTagType; - - -#define RTT_NONE RTT_RAW /* TODO : remme */ - #define G_TYPE_CONTENT_EXPORTER g_content_exporter_get_type() #define G_CONTENT_EXPORTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_content_exporter_get_type(), GContentExporter)) diff --git a/src/decomp/Makefile.am b/src/decomp/Makefile.am new file mode 100755 index 0000000..d77ad29 --- /dev/null +++ b/src/decomp/Makefile.am @@ -0,0 +1,20 @@ + +noinst_LTLIBRARIES = libdecomp.la + +libdecomp_la_SOURCES = \ + output-int.h \ + output.h output.c + +libdecomp_la_LIBADD = \ + lang/libdecomplang.la + +libdecomp_la_LDFLAGS = + + +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CPPFLAGS = + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +SUBDIRS = lang diff --git a/src/decomp/lang/Makefile.am b/src/decomp/lang/Makefile.am new file mode 100755 index 0000000..2523bbf --- /dev/null +++ b/src/decomp/lang/Makefile.am @@ -0,0 +1,14 @@ + +noinst_LTLIBRARIES = libdecomplang.la + +libdecomplang_la_SOURCES = \ + java.h java.c + +libdecomplang_la_LDFLAGS = + + +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CPPFLAGS = + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/src/decomp/lang/java.c b/src/decomp/lang/java.c new file mode 100644 index 0000000..d83646d --- /dev/null +++ b/src/decomp/lang/java.c @@ -0,0 +1,155 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * java.c - sorties en langage Java + * + * 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 "java.h" + + +#include "../output-int.h" + + + +/* Sortie selon le langage Java (instance) */ +struct _GJavaOutput +{ + GLangOutput parent; /* A laisser en premier */ + +}; + + +/* Sortie selon le langage Java (classe) */ +struct _GJavaOutputClass +{ + GLangOutputClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des sorties en langage Java. */ +static void g_java_output_class_init(GJavaOutputClass *); + +/* Initialise une instance de sortie en langage Java. */ +static void g_java_output_init(GJavaOutput *); + +/* Ajoute un commentaire à un tampon donné. */ +static GBufferLine *g_java_output_write_comments(GJavaOutput *, GCodeBuffer *, const char *, size_t); + + + +/* Indique le type défini pour une sortie en langage Java. */ +G_DEFINE_TYPE(GJavaOutput, g_java_output, G_TYPE_LANG_OUTPUT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des sorties en langage Java. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_java_output_class_init(GJavaOutputClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : output = instance à initialiser. * +* * +* Description : Initialise une instance de sortie en langage Java. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_java_output_init(GJavaOutput *output) +{ + GLangOutput *lang; /* Autre version de l'objet */ + + lang = G_LANG_OUTPUT(output); + + lang->write_comments = (write_comments_fc)g_java_output_write_comments; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée une nouvelle sortie en langage Java. * +* * +* Retour : Imprimeur créé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GLangOutput *g_java_output_new(void) +{ + GBufferLine *result; /* Composant à retourner */ + + result = g_object_new(G_TYPE_JAVA_OUTPUT, NULL); + + return G_LANG_OUTPUT(result); + +} + + +/****************************************************************************** +* * +* Paramètres : output = encadrant de l'impression en langage de prog. * +* buffer = tampon de sortie à disposition. * +* column = colonne de la ligne visée par l'insertion. * +* text = texte à insérer dans l'existant. * +* length = taille du texte à traiter. * +* * +* Description : Ajoute un commentaire à un tampon donné. * +* * +* Retour : Ligne nouvellement créée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GBufferLine *g_java_output_write_comments(GJavaOutput *output, GCodeBuffer *buffer, const char *text, size_t length) +{ + GBufferLine *result; /* Adresse nouvelle à remonter */ + + result = g_code_buffer_append_new_line(buffer); + + g_buffer_line_insert_text(result, BLC_COMMENTS, "// ", 3, RTT_COMMENT); + + if (length > 0) + g_buffer_line_insert_text(result, BLC_COMMENTS, text, length, RTT_COMMENT); + + return result; + +} diff --git a/src/decomp/lang/java.h b/src/decomp/lang/java.h new file mode 100644 index 0000000..d1e0421 --- /dev/null +++ b/src/decomp/lang/java.h @@ -0,0 +1,55 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * java.h - prototypes pour les sorties en langage Java + * + * 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/>. + */ + + +#ifndef _DECOMP_LANG_JAVA_H +#define _DECOMP_LANG_JAVA_H + + +#include "../output.h" + + + +#define G_TYPE_JAVA_OUTPUT g_java_output_get_type() +#define G_JAVA_OUTPUT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_java_output_get_type(), GJavaOutput)) +#define G_IS_JAVA_OUTPUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_java_output_get_type())) +#define G_JAVA_OUTPUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_JAVA_OUTPUT, GJavaOutputClass)) +#define G_IS_JAVA_OUTPUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_JAVA_OUTPUT)) +#define G_JAVA_OUTPUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_JAVA_OUTPUT, GJavaOutputClass)) + + +/* Sortie selon le langage Java (instance) */ +typedef struct _GJavaOutput GJavaOutput; + +/* Sortie selon le langage Java (classe) */ +typedef struct _GJavaOutputClass GJavaOutputClass; + + +/* Indique le type défini pour une sortie en langage Java. */ +GType g_java_output_get_type(void); + +/* Crée une nouvelle sortie en langage Java. */ +GLangOutput *g_java_output_new(void); + + + +#endif /* _DECOMP_LANG_JAVA_H */ diff --git a/src/decomp/output-int.h b/src/decomp/output-int.h new file mode 100644 index 0000000..eb22fd6 --- /dev/null +++ b/src/decomp/output-int.h @@ -0,0 +1,56 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * output-int.h - définitions internes pour les sorties en langage de programmation + * + * 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/>. + */ + + +#ifndef _DECOMP_OUTPUT_INT_H +#define _DECOMP_OUTPUT_INT_H + + +#include "output.h" + + + +/* Ajoute un commentaire à un tampon donné. */ +typedef GBufferLine * (* write_comments_fc) (GLangOutput *, GCodeBuffer *, const char *, size_t); + + + +/* Sortie selon un langage de programmation (instance) */ +struct _GLangOutput +{ + GObject parent; /* A laisser en premier */ + + write_comments_fc write_comments; /* Commentaires sur une ligne */ + +}; + + +/* Sortie selon un langage de programmation (classe) */ +struct _GLangOutputClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + + +#endif /* _DECOMP_OUTPUT_INT_H */ diff --git a/src/decomp/output.c b/src/decomp/output.c new file mode 100644 index 0000000..17aaa0e --- /dev/null +++ b/src/decomp/output.c @@ -0,0 +1,106 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * output.c - sorties en langage de programmation + * + * 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 "output.h" + + +#include "output-int.h" + + + +/* Indique le type défini pour une sortie de langage de programmation. */ +G_DEFINE_TYPE(GLangOutput, g_lang_output, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des sorties en langage de programmation.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_lang_output_class_init(GLangOutputClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : output = instance à initialiser. * +* * +* Description : Initialise une instance de sortie en langage de prog. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_lang_output_init(GLangOutput *output) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : output = encadrant de l'impression en langage de prog. * +* buffer = tampon de sortie à disposition. * +* column = colonne de la ligne visée par l'insertion. * +* text = texte à insérer dans l'existant. * +* length = taille du texte à traiter. * +* * +* Description : Ajoute un commentaire à un tampon donné. * +* * +* Retour : Ligne nouvellement créée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBufferLine *g_lang_output_write_comments(GLangOutput *output, GCodeBuffer *buffer, const char *text, size_t length) +{ + GBufferLine *result; /* Adresse nouvelle à remonter */ + + if (output->write_comments != NULL) + result = output->write_comments(output, buffer, text, length); + + else result = NULL; + + return result; + +} + + + + + + + + diff --git a/src/decomp/output.h b/src/decomp/output.h new file mode 100644 index 0000000..402a73a --- /dev/null +++ b/src/decomp/output.h @@ -0,0 +1,58 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * output.h - prototypes pour les sorties en langage de programmation + * + * 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/>. + */ + + +#ifndef _DECOMP_OUTPUT_H +#define _DECOMP_OUTPUT_H + + +#include "../glibext/gcodebuffer.h" + + + +#define G_TYPE_LANG_OUTPUT g_lang_output_get_type() +#define G_LANG_OUTPUT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_lang_output_get_type(), GLangOutput)) +#define G_IS_LANG_OUTPUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_lang_output_get_type())) +#define G_LANG_OUTPUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_LANG_OUTPUT, GLangOutputClass)) +#define G_IS_LANG_OUTPUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_LANG_OUTPUT)) +#define G_LANG_OUTPUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_LANG_OUTPUT, GLangOutputClass)) + + +/* Sortie selon un langage de programmation (instance) */ +typedef struct _GLangOutput GLangOutput; + +/* Sortie selon un langage de programmation (classe) */ +typedef struct _GLangOutputClass GLangOutputClass; + + +/* Indique le type défini pour une sortie de langage de programmation. */ +GType g_lang_output_get_type(void); + +/* Ajoute un commentaire à un tampon donné. */ +GBufferLine *g_lang_output_write_comments(GLangOutput *, GCodeBuffer *, const char *, size_t); + + + + + + +#endif /* _DECOMP_OUTPUT_H */ diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c index da08184..701cb4b 100644 --- a/src/glibext/gbufferline.c +++ b/src/glibext/gbufferline.c @@ -24,6 +24,8 @@ #include "gbufferline.h" +#include <gtk/gtk.h> /* Récupération du langage par défaut ; FIXME ? */ + #include <malloc.h> /* FIXME : à virer */ @@ -72,6 +74,9 @@ struct _GBufferLineClass { GObjectClass parent; /* A laisser en premier */ + PangoContext *context; /* Contexte graphique Pango */ + PangoAttrList *attribs[RTT_COUNT]; /* Décorateurs pour tampons */ + }; @@ -233,6 +238,117 @@ G_DEFINE_TYPE(GBufferLine, g_buffer_line, G_TYPE_OBJECT); static void g_buffer_line_class_init(GBufferLineClass *class) { + GdkScreen *screen; /* Ecran pour GDK */ + PangoFontDescription *font_desc; /* Police de caractère */ + PangoAttribute *attrib; /* Propriété de rendu */ + + /* Base des exportations */ + + screen = gdk_screen_get_default(); + class->context = gdk_pango_context_get_for_screen(screen); + + font_desc = pango_font_description_from_string("mono 10"); + pango_context_set_font_description(class->context, font_desc); + + pango_context_set_base_dir(class->context, PANGO_DIRECTION_LTR); + pango_context_set_language(class->context, gtk_get_default_language()); + + /* RTT_RAW */ + + class->attribs[RTT_RAW] = pango_attr_list_new(); + + attrib = pango_attr_foreground_new(0, 0, 0); + pango_attr_list_insert(class->attribs[RTT_RAW], attrib); + + /* RTT_COMMENT */ + + class->attribs[RTT_COMMENT] = pango_attr_list_new(); + + attrib = pango_attr_foreground_new(14335, 45311, 23551); + pango_attr_list_insert(class->attribs[RTT_COMMENT], attrib); + + /* RTT_RAW_CODE */ + + class->attribs[RTT_RAW_CODE] = pango_attr_list_new(); + + attrib = pango_attr_foreground_new(48895, 48895, 48895); + pango_attr_list_insert(class->attribs[RTT_RAW_CODE], attrib); + + /* RTT_INSTRUCTION */ + + class->attribs[RTT_INSTRUCTION] = pango_attr_list_new(); + + attrib = pango_attr_foreground_new(0, 0, 0); + pango_attr_list_insert(class->attribs[RTT_INSTRUCTION], attrib); + + /* RTT_IMMEDIATE */ + + class->attribs[RTT_IMMEDIATE] = pango_attr_list_new(); + + attrib = pango_attr_foreground_new(41215, 8447, 61695); + pango_attr_list_insert(class->attribs[RTT_IMMEDIATE], attrib); + + /* RTT_REGISTER */ + + class->attribs[RTT_REGISTER] = pango_attr_list_new(); + + //attrib = pango_attr_foreground_new(23551, 23551, 51455); + attrib = pango_attr_foreground_new(16895, 16895, 53759); + pango_attr_list_insert(class->attribs[RTT_REGISTER], attrib); + + /* RTT_HOOK */ + + class->attribs[RTT_HOOK] = pango_attr_list_new(); + + attrib = pango_attr_foreground_new(0, 0, 0); + pango_attr_list_insert(class->attribs[RTT_HOOK], attrib); + + attrib = pango_attr_weight_new(PANGO_WEIGHT_BOLD); + pango_attr_list_insert(class->attribs[RTT_HOOK], attrib); + + /* RTT_SIGNS */ + + class->attribs[RTT_SIGNS] = pango_attr_list_new(); + + attrib = pango_attr_foreground_new(0, 0, 0); + pango_attr_list_insert(class->attribs[RTT_SIGNS], attrib); + + attrib = pango_attr_weight_new(PANGO_WEIGHT_SEMIBOLD); + pango_attr_list_insert(class->attribs[RTT_SIGNS], attrib); + + /* RTT_LTGT */ + + class->attribs[RTT_LTGT] = pango_attr_list_new(); + + /* RTT_SECTION */ + + class->attribs[RTT_SECTION] = pango_attr_list_new(); + + attrib = pango_attr_foreground_new(51200, 2560, 2560); + pango_attr_list_insert(class->attribs[RTT_SECTION], attrib); + + /* + attrib = pango_attr_foreground_new(56832, 26880, 43008); + pango_attr_list_insert(class->attribs[RTT_SECTION], attrib); + + attrib = pango_attr_weight_new(PANGO_WEIGHT_BOLD); + pango_attr_list_insert(class->attribs[RTT_SECTION], attrib); + */ + + /* RTT_SEGMENT */ + + class->attribs[RTT_SEGMENT] = pango_attr_list_new(); + + /* RTT_STRING */ + + class->attribs[RTT_STRING] = pango_attr_list_new(); + + attrib = pango_attr_foreground_new(52224, 32256, 0); + pango_attr_list_insert(class->attribs[RTT_STRING], attrib); + + /* RTT_VAR_NAME */ + + class->attribs[RTT_VAR_NAME] = pango_attr_list_new(); } @@ -308,6 +424,35 @@ void g_buffer_line_add_segment(GBufferLine *line, BufferLineColumn index, GBuffe /****************************************************************************** * * +* Paramètres : line = ligne à venir compléter. * +* column = colonne de la ligne visée par l'insertion. * +* text = texte à insérer dans l'existant. * +* length = taille du texte à traiter. * +* type = type de décorateur à utiliser. * +* * +* Description : Ajoute du texte à formater dans une ligne donnée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_buffer_line_insert_text(GBufferLine *line, BufferLineColumn column, const char *text, size_t length, RenderingTagType type) +{ + GBufferLineClass *class; /* Stockage de briques de base */ + GBufferSegment *segment; /* Portion de texte à ajouter */ + + class = G_BUFFER_LINE_GET_CLASS(line); + + segment = g_buffer_segment_new(class->context, class->attribs[type], text, length); + g_buffer_line_add_segment(line, column, segment); + +} + + +/****************************************************************************** +* * * Paramètres : line = ligne à venir compléter. * * index = index de la colonne visée par la procédure. * * * diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h index d9e1edb..504f0a3 100644 --- a/src/glibext/gbufferline.h +++ b/src/glibext/gbufferline.h @@ -61,6 +61,41 @@ typedef enum _BufferLineColumn } BufferLineColumn; +/* Types de partie de rendu */ +typedef enum _RenderingTagType +{ + RTT_RAW, /* Contenu brut */ + + RTT_COMMENT, /* Commentaire */ + RTT_RAW_CODE, /* Code binaire brut */ + + RTT_INSTRUCTION, /* Code binaire brut */ + + RTT_IMMEDIATE, /* Valeur immédiate */ + + RTT_REGISTER, /* Registre */ + + RTT_HOOK, /* Crochets '[' et ']' */ + RTT_SIGNS, /* Signes '+', '-' et '*' */ + RTT_LTGT, /* Caractères '<' et '>' */ + + RTT_SECTION, /* Identifiant de section */ + RTT_SEGMENT, /* Indication de segment */ + RTT_STRING, /* Chaîne de caractères avec " */ + + RTT_VAR_NAME, /* Nom de variable */ + + RTT_COUNT + +} RenderingTagType; + + +#define RTT_NONE RTT_RAW /* TODO : remme */ + + +/* Confort pour l'insertion de texte */ +#define SL(str) str, strlen(str) + /* Accompagnement du dessin pour compléments */ typedef void (* buffer_line_draw_fc) (GBufferLine *, GdkDrawable *, GdkGC *, gint, gint, void *); @@ -75,6 +110,9 @@ GBufferLine *g_buffer_line_new(void); /* Ajoute un fragment de texte à une colonne de ligne. */ void g_buffer_line_add_segment(GBufferLine *, BufferLineColumn, GBufferSegment *); +/* Ajoute du texte à formater dans une ligne donnée. */ +void g_buffer_line_insert_text(GBufferLine *, BufferLineColumn, const char *, size_t, RenderingTagType); + /* Fournit la largeur requise pour une colonne de ligne donnée. */ gint g_buffer_line_get_width(GBufferLine *, BufferLineColumn); diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c index 3f9af35..9f22df7 100644 --- a/src/glibext/gcodebuffer.c +++ b/src/glibext/gcodebuffer.c @@ -469,18 +469,19 @@ void g_buffer_view_draw(const GBufferView *view, const GdkEventExpose *event, Gd lines = view->buffer->lines; - for (i = first; i < last; i++) - { - /* TODO : skip if... */ + if (view->buffer->used > 0) + for (i = first; i <= last; i++) + { + /* TODO : skip if... */ - if (view->drawing_extra != NULL) - view->drawing_extra(lines[i], drawable, gc, fake_x, y, view->drawing_data); + if (view->drawing_extra != NULL) + view->drawing_extra(lines[i], drawable, gc, fake_x, y, view->drawing_data); - g_buffer_line_draw(lines[i], drawable, gc, view->max_widths, real_x, y); + g_buffer_line_draw(lines[i], drawable, gc, view->max_widths, real_x, y); - y += view->line_height; + y += view->line_height; - } + } } diff --git a/src/gtkext/gtksourceview.c b/src/gtkext/gtksourceview.c index 14f7f95..63f2926 100644 --- a/src/gtkext/gtksourceview.c +++ b/src/gtkext/gtksourceview.c @@ -36,6 +36,13 @@ struct _GtkSourceView { GtkViewPanel parent; /* A laisser en premier */ + GCodeBuffer *buffer; /* Code sous forme de texte */ + GBufferView *buffer_view; /* Affichage de cette forme */ + + gint line_height; /* Hauteur maximale des lignes */ + gint left_margin; /* Marge gauche + espace */ + gint left_text; /* Début d'impression du code */ + }; /* Composant d'affichage de code source (classe) */ @@ -52,6 +59,18 @@ static void gtk_source_view_class_init(GtkSourceViewClass *); /* Procède à l'initialisation de l'afficheur de code source. */ static void gtk_source_view_init(GtkSourceView *); +/*Encadre la construction graphique initiale de la visualisat°. */ +static void gtk_source_view_realize(GtkWidget *); + +/* Fournit la taille de composant requise pour un plein rendu. */ +static void gtk_source_view_size_request(GtkWidget *, GtkRequisition *); + +/* S'adapte à la surface concédée par le composant parent. */ +static void gtk_source_view_size_allocate(GtkWidget *, GtkAllocation *); + +/* Met à jour l'affichage de la visualisation de code source. */ +static gboolean gtk_source_view_expose(GtkWidget *, GdkEventExpose *); + /* Prend acte de l'association d'un binaire chargé. */ static void gtk_source_view_attach_binary(GtkSourceView *, GOpenidaBinary *); @@ -79,6 +98,14 @@ G_DEFINE_TYPE(GtkSourceView, gtk_source_view, GTK_TYPE_VIEW_PANEL) static void gtk_source_view_class_init(GtkSourceViewClass *class) { + GtkWidgetClass *widget_class; /* Classe version Widget */ + + widget_class = GTK_WIDGET_CLASS(class); + + widget_class->realize = gtk_source_view_realize; + widget_class->size_request = gtk_source_view_size_request; + widget_class->size_allocate = gtk_source_view_size_allocate; + widget_class->expose_event = gtk_source_view_expose; } @@ -105,6 +132,202 @@ static void gtk_source_view_init(GtkSourceView *view) } + +/****************************************************************************** +* * +* Paramètres : widget = composant GTK à redessiner. * +* * +* Description : Encadre la construction graphique initiale de la visualisat°.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_source_view_realize(GtkWidget *widget) +{ + GtkViewPanelClass *parent_class; /* Version pure du parent */ + + parent_class = GTK_VIEW_PANEL_CLASS(g_type_class_peek_parent(GTK_SOURCE_VIEW_GET_CLASS(widget))); + + GTK_WIDGET_CLASS(parent_class)->realize(widget); + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant GTK à consulter. * +* requisition = dimensions souhaitées. [OUT] * +* * +* Description : Fournit la taille de composant requise pour un plein rendu. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_source_view_size_request(GtkWidget *widget, GtkRequisition *requisition) +{ + if (GTK_SOURCE_VIEW(widget)->buffer_view != NULL) + { + + g_buffer_view_get_size(GTK_SOURCE_VIEW(widget)->buffer_view, + &requisition->width, &requisition->height); + + printf(" === size req :: (%d ; %d)\n", + requisition->width, requisition->height); + + } + else printf(" === size req :: ??\n"); + +} + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à mettre à jour. * +* allocation = étendue accordée à la vue. * +* * +* Description : S'adapte à la surface concédée par le composant parent. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_source_view_size_allocate(GtkWidget *widget, GtkAllocation *allocation) +{ + GtkViewPanel *panel; /* Autre version du composant */ + gint width; /* Largeur de l'objet actuelle */ + gint height; /* Hauteur de l'objet actuelle */ + GtkAllocation valloc; /* Surface utilisable */ + gboolean changed; /* Changement de valeur ? */ + + /* Mise à jour GTK */ + + widget->allocation = *allocation; + + if (GTK_WIDGET_REALIZED(widget)) + gdk_window_move_resize(widget->window, + allocation->x, allocation->y, + allocation->width, allocation->height); + + panel = GTK_VIEW_PANEL(widget); + + if (panel->hadjustment == NULL || panel->vadjustment == NULL) + return; + + g_buffer_view_get_size(GTK_SOURCE_VIEW(widget)->buffer_view, &width, &height); + + gtk_view_panel_compute_allocation(panel, &valloc); + + /* Défilement horizontal */ + + panel->hadjustment->page_size = valloc.width; + panel->hadjustment->step_increment = valloc.width * 0.1; + panel->hadjustment->page_increment = valloc.width * 0.9; + + panel->hadjustment->upper = MAX(width, valloc.width); + + gtk_view_panel_reclamp_adjustment(panel->hadjustment, &changed); + + gtk_adjustment_changed(panel->hadjustment); + + if (changed) + gtk_adjustment_value_changed(panel->hadjustment); + + /* Défilement vertical */ + + panel->vadjustment->page_size = valloc.height; + panel->vadjustment->step_increment = GTK_SOURCE_VIEW(widget)->line_height; + panel->vadjustment->page_increment = panel->vadjustment->step_increment * 10.0; + + panel->vadjustment->upper = MAX(height, valloc.height); + + gtk_view_panel_reclamp_adjustment(panel->vadjustment, &changed); + + gtk_adjustment_changed(panel->vadjustment); + + if (changed) + gtk_adjustment_value_changed(panel->vadjustment); + +} + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à redessiner. * +* event = informations liées à l'événement. * +* * +* Description : Met à jour l'affichage de la visualisation de code source. * +* * +* Retour : FALSE pour poursuivre la propagation de l'événement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean gtk_source_view_expose(GtkWidget *widget, GdkEventExpose *event) +{ + GtkSourceView *view; /* Autre version du composant */ + GtkViewPanel *pview; /* Autre version du composant */ + GtkStyle *style; /* Style associé au composant */ + GdkDrawable *drawable; /* Surface de dessin */ + gint fake_x; /* Abscisse virtuelle */ + gint fake_y; /* Ordonnée virtuelle */ + GtkViewPanelClass *parent_class; /* Version pure du parent */ + + view = GTK_SOURCE_VIEW(widget); + widget = GTK_WIDGET(view); + pview = GTK_VIEW_PANEL(widget); + + drawable = GDK_DRAWABLE(event->window); + + gdk_window_begin_paint_region(drawable, event->region); + + gdk_gc_set_clip_region(pview->gc, event->region); + + style = gtk_widget_get_style(GTK_WIDGET(view)); + + fake_x = 0; + fake_y = 0; + //gtk_block_view_compute_fake_coord(view, &fake_x, &fake_y); + + /* Dessin de la marge gauche */ + + gdk_gc_set_foreground(pview->gc, &style->mid[GTK_WIDGET_STATE(widget)]); + + gdk_draw_rectangle(drawable, pview->gc, TRUE, + fake_x, event->area.y, view->left_margin, event->area.y + event->area.height); + + gdk_gc_set_foreground(pview->gc, &style->dark[GTK_WIDGET_STATE(widget)]); + + gdk_draw_line(drawable, pview->gc, + fake_x + view->left_margin, event->area.y, + fake_x + view->left_margin, event->area.y + event->area.height); + + /* Eventuelle bordure globale */ + + parent_class = GTK_VIEW_PANEL_CLASS(g_type_class_peek_parent(GTK_SOURCE_VIEW_GET_CLASS(view))); + + GTK_WIDGET_CLASS(parent_class)->expose_event(widget, event); + + /* Impression du désassemblage */ + + if (view->buffer_view != NULL) + g_buffer_view_draw(view->buffer_view, event, pview->gc, fake_x, fake_y); + + gdk_window_end_paint(drawable); + + return TRUE; + +} + + /****************************************************************************** * * * Paramètres : - * @@ -144,4 +367,42 @@ GtkWidget *gtk_source_view_new(void) static void gtk_source_view_attach_binary(GtkSourceView *view, GOpenidaBinary *binary) { + + + + + gint width; /* Largeur de l'objet actuelle */ + gint height; /* Hauteur de l'objet actuelle */ + + + view->buffer = g_openida_binary_get_decompiled_buffer(binary, NULL); + + + view->buffer_view = g_buffer_view_new(view->buffer); + + + + + gdk_threads_enter(); + + /* Taille des marges */ + + view->line_height = g_buffer_view_get_line_height(view->buffer_view); + view->left_margin = 2 * view->line_height; + view->left_text = -2.5 * view->line_height; + + /* Validation finale */ + + g_buffer_view_get_size(view->buffer_view, &width, &height); + + width += -view->left_text + 1; + height += 1; + + gtk_widget_set_size_request(GTK_WIDGET(view), width, height); + + + gdk_flush (); + gdk_threads_leave(); + + } |