diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/analysis/exporter-int.h | 7 | ||||
| -rw-r--r-- | src/analysis/exporter.c | 49 | ||||
| -rw-r--r-- | src/analysis/exporter.h | 4 | ||||
| -rw-r--r-- | src/analysis/line_code.c | 84 | ||||
| -rw-r--r-- | src/analysis/line_comment.c | 62 | ||||
| -rw-r--r-- | src/analysis/line_prologue.c | 34 | ||||
| -rw-r--r-- | src/analysis/roptions.c | 21 | ||||
| -rw-r--r-- | src/analysis/roptions.h | 3 | ||||
| -rw-r--r-- | src/arch/immediate.c | 146 | ||||
| -rw-r--r-- | src/arch/instruction.c | 58 | ||||
| -rw-r--r-- | src/arch/x86/operand.c | 225 | ||||
| -rw-r--r-- | src/arch/x86/registers.c | 93 | ||||
| -rw-r--r-- | src/dialogs/Makefile.am | 3 | ||||
| -rw-r--r-- | src/dialogs/export.c | 637 | ||||
| -rw-r--r-- | src/dialogs/export.h | 37 | ||||
| -rw-r--r-- | src/editor.c | 49 | ||||
| -rw-r--r-- | src/gtkext/easygtk.c | 38 | ||||
| -rw-r--r-- | src/gtkext/easygtk.h | 3 | 
18 files changed, 1511 insertions, 42 deletions
| diff --git a/src/analysis/exporter-int.h b/src/analysis/exporter-int.h index 097b48b..4219be2 100644 --- a/src/analysis/exporter-int.h +++ b/src/analysis/exporter-int.h @@ -29,6 +29,9 @@ +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +typedef void (* add_text_fc) (GContentExporter *, GRenderingOptions *, MainRendering, FILE *); +  /* Ajoute à un texte GTK le contenu de la ligne de rendu. */  typedef void (* add_to_gtk_buffer_fc) (GContentExporter *, MainRendering, GtkTextBuffer *, GtkTextIter *, size_t [SAR_COUNT]); @@ -42,6 +45,7 @@ struct _GContentExporter  {      GObject parent;                         /* A laisser en premier        */ +    add_text_fc add_text;                   /* Remplissage simple          */      add_to_gtk_buffer_fc add_to_gtk_buffer; /* Constitution du texte GTK   */      add_arch_to_gtk_buffer_fc add_arch_to_gtk_buffer;   /* Constitution... */ @@ -59,6 +63,9 @@ struct _GContentExporterClass  }; +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +void g_content_exporter_insert_text(GContentExporter *, FILE *, const char *, size_t, RenderingTagType); +  /* Ajoute du texte à un texte GTK via l'instance spécifiée. */  void g_content_exporter_insert_with_gtk_tag(GContentExporter *, GtkTextBuffer *, GtkTextIter *, const char *, size_t, RenderingTagType); diff --git a/src/analysis/exporter.c b/src/analysis/exporter.c index e78fd54..e1e9160 100644 --- a/src/analysis/exporter.c +++ b/src/analysis/exporter.c @@ -181,6 +181,32 @@ GtkTextTagTable *_get_gtk_tag_table(GtkTextTagTable *table)  /******************************************************************************  *                                                                             *  *  Paramètres  : exporter = instance sachant exporter son contenu.            * +*                stream   = flux ouvert en écriture.                          * +*                text     = texte à insérer dans l'existant.                  * +*                length   = taille du texte à traiter.                        * +*                tag      = type de décorateur à utiliser.                    * +*                                                                             * +*  Description : Ajoute du texte simple à un fichier ouvert en écriture.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_content_exporter_insert_text(GContentExporter *exporter, FILE *stream, const char *text, size_t length, RenderingTagType tag) +{ +    size_t ret;                             /* Quantité d'octets écrite    */ + +    ret = fwrite(text, sizeof(char), length, stream); +    if (ret != length) perror("fwrite"); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : exporter = instance sachant exporter son contenu.            *  *                buffer   = zone de texte à venir compléter.                  *  *                iter     = point d'insertion du nouveau texte. [OUT]         *  *                text     = texte à insérer dans l'existant.                  * @@ -212,6 +238,29 @@ void g_content_exporter_insert_with_gtk_tag(GContentExporter *exporter, GtkTextB  /******************************************************************************  *                                                                             *  *  Paramètres  : exporter  = instance sachant exporter son contenu.           * +*                options   = options de rendu.                                * +*                rendering = support effectif final des lignes de code.       * +*                stream    = flux ouvert en écriture.                         * +*                                                                             * +*  Description : Ajoute du texte simple à un fichier ouvert en écriture.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_content_exporter_add_text(GContentExporter *exporter, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ +    if (exporter->add_text != NULL) +        exporter->add_text(exporter, options, rendering, stream); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : exporter  = instance sachant exporter son contenu.           *  *                rendering = support effectif final des lignes de code.       *  *                buffer    = zone de texte à venir compléter.                 *  *                iter      = point d'insertion du nouveau texte.              * diff --git a/src/analysis/exporter.h b/src/analysis/exporter.h index 60c37b1..524d800 100644 --- a/src/analysis/exporter.h +++ b/src/analysis/exporter.h @@ -26,6 +26,7 @@  #include <glib-object.h> +#include <stdio.h>  #include <gtk/gtktextbuffer.h> @@ -85,6 +86,9 @@ GtkTextTagTable *_get_gtk_tag_table(GtkTextTagTable *);  #define get_gtk_tag_table() _get_gtk_tag_table(NULL) +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +void g_content_exporter_add_text(GContentExporter *, GRenderingOptions *, MainRendering, FILE *); +  /* Ajoute à un texte GTK le contenu de l'instance spécifiée. */  void g_content_exporter_add_to_gtk_buffer(GContentExporter *, MainRendering, GtkTextBuffer *, GtkTextIter *, size_t [SAR_COUNT]); diff --git a/src/analysis/line_code.c b/src/analysis/line_code.c index 5787e2a..24f3ec9 100644 --- a/src/analysis/line_code.c +++ b/src/analysis/line_code.c @@ -58,6 +58,9 @@ static void g_code_line_class_init(GCodeLineClass *);  /* Initialise la classe des lignes de code binaire. */  static void g_code_line_init(GCodeLine *); +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +static void g_code_line_add_text(GCodeLine *, GRenderingOptions *, MainRendering, FILE *); +  /* Ajoute à un texte GTK le contenu de la ligne de code. */  static void g_code_line_add_to_gtk_buffer(GCodeLine *, MainRendering, GtkTextBuffer *, GtkTextIter *, size_t [SAR_COUNT]); @@ -105,6 +108,7 @@ static void g_code_line_init(GCodeLine *line)      exporter_parent = G_CONTENT_EXPORTER(line); +    exporter_parent->add_text = (add_text_fc)g_code_line_add_text;      exporter_parent->add_to_gtk_buffer = (add_to_gtk_buffer_fc)g_code_line_add_to_gtk_buffer;      line_parent = G_RENDERING_LINE(line); @@ -114,6 +118,86 @@ static void g_code_line_init(GCodeLine *line)  } + +/****************************************************************************** +*                                                                             * +*  Paramètres  : line      = ligne de représentation à actualiser.            * +*                options   = options de rendu.                                * +*                rendering = support effectif final des lignes de code.       * +*                stream    = flux ouvert en écriture.                         * +*                                                                             * +*  Description : Ajoute du texte simple à un fichier ouvert en écriture.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_code_line_add_text(GCodeLine *line, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ +    GContentExporter *exporter;             /* Autre vision de la ligne    */ +    bool show_address;                      /* Affichage de l'adresse ?    */ +    bool show_code;                         /* Affichage du code brut ?    */ +    MemoryDataSize msize;                   /* Taille du bus d'adresses    */ +    char address[VMPA_MAX_SIZE];            /* Adresse au format texte     */ +    size_t len;                             /* Taille de l'élément inséré  */ +    const bin_t *content;                   /* Contenu binaire global      */ +    off_t bin_offset;                       /* Début de l'instruction      */ +    off_t bin_len;                          /* Taille d'instruction        */ +    char *bin_code;                         /* Tampon du code binaire      */ +    off_t i;                                /* Boucle de parcours          */ + +    exporter = G_CONTENT_EXPORTER(line); + +    show_address = g_rendering_options_has_to_show_address(options, rendering); +    show_code = g_rendering_options_has_to_show_code(options, rendering); + +    /* Eventuelle adresse virtuelle ou physique */ + +    if (show_address) +    { +        msize = g_arch_processor_get_memory_size(g_rendering_options_get_processor(options)); + +        len = vmpa_to_string(G_RENDERING_LINE(line)->offset, msize, address); + +        g_content_exporter_insert_text(exporter, stream, address, len, RTT_NONE); +        g_content_exporter_insert_text(exporter, stream, "\t", 1, RTT_NONE); + +    } + +    /* Eventuel code brut */ + +    if (show_code) +    { +        content = g_binary_format_get_content(G_BIN_FORMAT(g_rendering_options_get_format(options)), NULL); +        g_arch_instruction_get_location(line->instr, &bin_offset, &bin_len, NULL); + +        bin_code = (char *)calloc(bin_len * 3, sizeof(char)); + +        for (i = 0; i < bin_len; i++) +        { +            if ((i + 1) < bin_len) +                snprintf(&bin_code[i * (2 + 1)], 4, "%02hhx ", content[bin_offset + i]); +            else +                snprintf(&bin_code[i * (2 + 1)], 3, "%02hhx", content[bin_offset + i]); +        } +  +        g_content_exporter_insert_text(exporter, stream, bin_code, bin_len * 3 - 1, RTT_RAW_CODE); + +        free(bin_code); + +        g_content_exporter_insert_text(exporter, stream, "\t", 1, RTT_NONE); + +    } + +    /* Instruction proprement dite */ + +    g_content_exporter_add_text(G_CONTENT_EXPORTER(line->instr), options, rendering, stream); + +} + +  /******************************************************************************  *                                                                             *  *  Paramètres  : line      = ligne de représentation à actualiser.            * diff --git a/src/analysis/line_comment.c b/src/analysis/line_comment.c index aa6ae10..8af1777 100644 --- a/src/analysis/line_comment.c +++ b/src/analysis/line_comment.c @@ -57,6 +57,9 @@ static void g_comment_line_class_init(GCommentLineClass *);  /* Initialise la classe des lignes de commentaires entière. */  static void g_comment_line_init(GCommentLine *); +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +static void g_comment_line_add_text(GCommentLine *, GRenderingOptions *, MainRendering, FILE *); +  /* Ajoute à un texte GTK le contenu de la ligne de commentaires. */  static void g_comment_line_add_to_gtk_buffer(GCommentLine *, MainRendering, GtkTextBuffer *, GtkTextIter *, size_t [SAR_COUNT]); @@ -104,6 +107,7 @@ static void g_comment_line_init(GCommentLine *line)      exporter_parent = G_CONTENT_EXPORTER(line); +    exporter_parent->add_text = (add_text_fc)g_comment_line_add_text;      exporter_parent->add_to_gtk_buffer = (add_to_gtk_buffer_fc)g_comment_line_add_to_gtk_buffer;      line_parent = G_RENDERING_LINE(line); @@ -116,6 +120,64 @@ static void g_comment_line_init(GCommentLine *line)  /******************************************************************************  *                                                                             *  *  Paramètres  : line      = ligne de représentation à actualiser.            * +*                options   = options de rendu.                                * +*                rendering = support effectif final des lignes de code.       * +*                stream    = flux ouvert en écriture.                         * +*                                                                             * +*  Description : Ajoute du texte simple à un fichier ouvert en écriture.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_comment_line_add_text(GCommentLine *line, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ +    GContentExporter *exporter;             /* Autre vision de la ligne    */ +    bool show_address;                      /* Affichage de l'adresse ?    */ +    bool show_code;                         /* Affichage du code brut ?    */ +    MemoryDataSize msize;                   /* Taille du bus d'adresses    */ +    char address[VMPA_MAX_SIZE];            /* Adresse au format texte     */ +    size_t len;                             /* Taille de l'élément inséré  */ + +    exporter = G_CONTENT_EXPORTER(line); + +    show_address = g_rendering_options_has_to_show_address(options, rendering); +    show_code = g_rendering_options_has_to_show_code(options, rendering); + +    /* Eventuelle adresse virtuelle ou physique */ + +    if (show_address) +    { +        msize = g_arch_processor_get_memory_size(g_rendering_options_get_processor(options)); + +        len = vmpa_to_string(G_RENDERING_LINE(line)->offset, msize, address); + +        g_content_exporter_insert_text(exporter, stream, address, len, RTT_NONE); +        g_content_exporter_insert_text(exporter, stream, "\t", 1, RTT_NONE); + +    } + +    /* Eventuel code brut (sauté) */ + +    if (show_code) +        g_content_exporter_insert_text(exporter, stream, "\t", 1, RTT_NONE); + +    /* Commentaire proprement dit */ + +    g_content_exporter_insert_text(exporter, stream, "; ", 2, RTT_COMMENT); + +    len = strlen(line->comment); + +    g_content_exporter_insert_text(exporter, stream, line->comment, len, RTT_COMMENT); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : line      = ligne de représentation à actualiser.            *  *                rendering = support effectif final des lignes de code.       *  *                buffer    = zone de texte à venir compléter.                 *  *                iter      = point d'insertion du nouveau texte.              * diff --git a/src/analysis/line_prologue.c b/src/analysis/line_prologue.c index f0f5db9..007804b 100644 --- a/src/analysis/line_prologue.c +++ b/src/analysis/line_prologue.c @@ -56,6 +56,9 @@ static void g_prologue_line_class_init(GPrologueLineClass *);  /* Initialise la classe des lignes de descriptions initiales. */  static void g_prologue_line_init(GPrologueLine *); +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +static void g_prologue_line_add_text(GPrologueLine *, GRenderingOptions *, MainRendering, FILE *); +  /* Ajoute à un texte GTK le contenu de la ligne d'ouverture. */  static void g_prologue_line_add_to_gtk_buffer(GPrologueLine *, MainRendering, GtkTextBuffer *, GtkTextIter *, size_t [SAR_COUNT]); @@ -103,6 +106,7 @@ static void g_prologue_line_init(GPrologueLine *line)      exporter_parent = G_CONTENT_EXPORTER(line); +    exporter_parent->add_text = (add_text_fc)g_prologue_line_add_text;      exporter_parent->add_to_gtk_buffer = (add_to_gtk_buffer_fc)g_prologue_line_add_to_gtk_buffer;      line_parent = G_RENDERING_LINE(line); @@ -115,6 +119,36 @@ static void g_prologue_line_init(GPrologueLine *line)  /******************************************************************************  *                                                                             *  *  Paramètres  : line      = ligne de représentation à actualiser.            * +*                options   = options de rendu.                                * +*                rendering = support effectif final des lignes de code.       * +*                stream    = flux ouvert en écriture.                         * +*                                                                             * +*  Description : Ajoute du texte simple à un fichier ouvert en écriture.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_prologue_line_add_text(GPrologueLine *line, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ +    GContentExporter *exporter;             /* Autre vision de la ligne    */ +    size_t len;                             /* Taille de l'élément inséré  */ + +    exporter = G_CONTENT_EXPORTER(line); + +    len = strlen(line->comment); + +    g_content_exporter_insert_text(exporter, stream, "; ", 2, RTT_COMMENT); +    g_content_exporter_insert_text(exporter, stream, line->comment, len, RTT_COMMENT); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : line      = ligne de représentation à actualiser.            *  *                rendering = support effectif final des lignes de code.       *  *                buffer    = zone de texte à venir compléter.                 *  *                iter      = point d'insertion du nouveau texte.              * diff --git a/src/analysis/roptions.c b/src/analysis/roptions.c index 4c49a15..6aa4262 100644 --- a/src/analysis/roptions.c +++ b/src/analysis/roptions.c @@ -31,6 +31,8 @@ struct _GRenderingOptions      GExeFormat *format;                     /* Format du contenu bianire   */      GArchProcessor *proc;                   /* Architecture utilisée       */ +    AsmSyntax syntax;                       /* Style de rendu ASM          */ +      bool show_address[MRD_COUNT];           /* Affichage de l'adresse ?    */      bool show_code[MRD_COUNT];              /* Affichage du code brut ?    */ @@ -159,6 +161,25 @@ GArchProcessor *g_rendering_options_get_processor(const GRenderingOptions *optio  /******************************************************************************  *                                                                             * +*  Paramètres  : options = options à consulter.                               * +*                                                                             * +*  Description : Fournit le style de rendu pour le contenu ASM.               * +*                                                                             * +*  Retour      : Style de rendu pour le langage d'assemblage.                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +AsmSyntax g_rendering_options_get_syntax(const GRenderingOptions *options) +{ +    return options->syntax; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : options   = options à mettre à jour.                         *  *                rendering = type de rendu impliqué.                          *  *                state     = nouvel état de l'option visée.                   * diff --git a/src/analysis/roptions.h b/src/analysis/roptions.h index b2e4973..d2fbe0b 100644 --- a/src/analysis/roptions.h +++ b/src/analysis/roptions.h @@ -83,6 +83,9 @@ GExeFormat *g_rendering_options_get_format(const GRenderingOptions *);  /* Fournit l'architecture du contenu binaire représenté. */  GArchProcessor *g_rendering_options_get_processor(const GRenderingOptions *); +/* Fournit le style de rendu pour le contenu ASM. */ +AsmSyntax g_rendering_options_get_syntax(const GRenderingOptions *); +  /* Affiche (ou non) les adresses des instructions. */  void g_rendering_options_show_address(GRenderingOptions *, MainRendering, bool); diff --git a/src/arch/immediate.c b/src/arch/immediate.c index 56a6bfc..b9b8a6e 100644 --- a/src/arch/immediate.c +++ b/src/arch/immediate.c @@ -84,6 +84,12 @@ static void g_imm_operand_class_init(GImmOperandClass *);  /* Initialise la classe des lignes de descriptions initiales. */  static void g_imm_operand_init(GImmOperand *); +/* Construit la chaîne de caractères correspondant à l'opérande. */ +static void g_imm_operand_to_string(const GImmOperand *, AsmSyntax, char [VMPA_MAX_SIZE]); + +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +static void g_imm_operand_add_text(const GImmOperand *, GRenderingOptions *, MainRendering, FILE *); +  /* Ajoute à un texte GTK le contenu d'un opérande. */  static void g_imm_operand_add_to_gtk_buffer(const GImmOperand *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *); @@ -129,6 +135,7 @@ static void g_imm_operand_init(GImmOperand *operand)      parent = G_CONTENT_EXPORTER(operand); +    parent->add_text = (add_text_fc)g_imm_operand_add_text;      parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_imm_operand_add_to_gtk_buffer;  } @@ -340,10 +347,141 @@ bool g_imm_operand_is_negative(const GImmOperand *operand)  /******************************************************************************  *                                                                             *  *  Paramètres  : operand = opérande à transcrire.                             * -*                format = format du binaire manipulé.                         * -*                syntax = type de représentation demandée.                    * -*                buffer = zone de texte à venir compléter.                    * -*                iter   = point d'insertion du nouveau texte.                 * +*                syntax  = type de représentation demandée.                   * +*                value   = valeur portée par l'opérande transcrite. [OUT]     * +*                                                                             * +*  Description : Construit la chaîne de caractères correspondant à l'opérande.* +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax syntax, char value[VMPA_MAX_SIZE]) +{ +    switch (syntax) +    { +        case ASX_INTEL: +            switch (operand->size) +            { +                case MDS_UNDEFINED: +                    snprintf(value, VMPA_MAX_SIZE, "0x???"); +                    break; +                case AOS_8_BITS_UNSIGNED: +                    snprintf(value, VMPA_MAX_SIZE, "0x%hhx", operand->unsigned_imm.val8); +                    break; +                case AOS_16_BITS_UNSIGNED: +                    snprintf(value, VMPA_MAX_SIZE, "0x%hx", operand->unsigned_imm.val16); +                    break; +                case AOS_32_BITS_UNSIGNED: +                    snprintf(value, VMPA_MAX_SIZE, "0x%x", operand->unsigned_imm.val32); +                    break; +                case AOS_64_BITS_UNSIGNED: +                    snprintf(value, VMPA_MAX_SIZE, "0x%llx", operand->unsigned_imm.val64); +                    break; +                case AOS_8_BITS_SIGNED: +                    if (g_imm_operand_is_negative(operand)) +                        snprintf(value, VMPA_MAX_SIZE, "0x%hhx", ~operand->signed_imm.val8 + 1); +                    else +                        snprintf(value, VMPA_MAX_SIZE, "0x%hhx", operand->signed_imm.val8); +                    break; +                case AOS_16_BITS_SIGNED: +                    if (g_imm_operand_is_negative(operand)) +                        snprintf(value, VMPA_MAX_SIZE, "0x%hx", ~operand->signed_imm.val16 + 1); +                    else +                        snprintf(value, VMPA_MAX_SIZE, "0x%hx", operand->signed_imm.val16); +                    break; +                case AOS_32_BITS_SIGNED: +                    if (g_imm_operand_is_negative(operand)) +                        snprintf(value, VMPA_MAX_SIZE, "0x%x", ~operand->signed_imm.val32 + 1); +                    else +                        snprintf(value, VMPA_MAX_SIZE, "0x%x", operand->signed_imm.val32); +                    break; +                case AOS_64_BITS_SIGNED: +                    if (g_imm_operand_is_negative(operand)) +                        snprintf(value, VMPA_MAX_SIZE, "0x%llx", ~operand->signed_imm.val64 + 1); +                    else +                        snprintf(value, VMPA_MAX_SIZE, "0x%llx", operand->signed_imm.val64); +                    break; +            } +            break; + +        case ASX_ATT: +            switch (operand->size) +            { +                case MDS_UNDEFINED: +                    snprintf(value, VMPA_MAX_SIZE, "$0x???"); +                    break; +                case AOS_8_BITS_UNSIGNED: +                    snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", operand->unsigned_imm.val8); +                    break; +                case AOS_16_BITS_UNSIGNED: +                    snprintf(value, VMPA_MAX_SIZE, "$0x%hx", operand->unsigned_imm.val16); +                    break; +                case AOS_32_BITS_UNSIGNED: +                    snprintf(value, VMPA_MAX_SIZE, "$0x%x", operand->unsigned_imm.val32); +                    break; +                case AOS_64_BITS_UNSIGNED: +                    snprintf(value, VMPA_MAX_SIZE, "$0x%llx", operand->unsigned_imm.val64); +                    break; +                case AOS_8_BITS_SIGNED: +                    snprintf(value, VMPA_MAX_SIZE, "$0x%hhx", ~operand->signed_imm.val8 + 1); +                    break; +                case AOS_16_BITS_SIGNED: +                    snprintf(value, VMPA_MAX_SIZE, "$0x%hx", ~operand->signed_imm.val16 + 1); +                    break; +                case AOS_32_BITS_SIGNED: +                    snprintf(value, VMPA_MAX_SIZE, "$0x%x", ~operand->signed_imm.val32 + 1); +                    break; +                case AOS_64_BITS_SIGNED: +                    snprintf(value, VMPA_MAX_SIZE, "$0x%llx", ~operand->signed_imm.val64 + 1); +                    break; +            } +            break; + +        default: +            break; + +    } + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand   = opérande à transcrire.                           * +*                options   = options de rendu.                                * +*                rendering = support effectif final des lignes de code.       * +*                stream    = flux ouvert en écriture.                         * +*                                                                             * +*  Description : Ajoute du texte simple à un fichier ouvert en écriture.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_imm_operand_add_text(const GImmOperand *operand, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ +    char value[VMPA_MAX_SIZE];              /* Chaîne à imprimer           */ + +    g_imm_operand_to_string(operand, g_rendering_options_get_syntax(options), value); + +    g_content_exporter_insert_text(G_CONTENT_EXPORTER(operand), stream, +                                   value, strlen(value), RTT_IMMEDIATE); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande à transcrire.                             * +*                format  = format du binaire manipulé.                        * +*                syntax  = type de représentation demandée.                   * +*                buffer  = zone de texte à venir compléter.                   * +*                iter    = point d'insertion du nouveau texte.                *  *                                                                             *  *  Description : Ajoute à un texte GTK le contenu d'un opérande.              *  *                                                                             * diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 16e5c81..ee220a5 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -38,6 +38,9 @@ static void g_arch_instruction_class_init(GArchInstructionClass *);  /* Initialise une instance d'opérande d'architecture. */  static void g_arch_instruction_init(GArchInstruction *); +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +static void g_arch_instruction_add_text(const GArchInstruction *, GRenderingOptions *, MainRendering, FILE *); +  /* Ajoute à un texte GTK le contenu d'une instruction. */  static void g_arch_instruction_add_to_gtk_buffer(const GArchInstruction *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *); @@ -83,6 +86,7 @@ static void g_arch_instruction_init(GArchInstruction *instr)      parent = G_CONTENT_EXPORTER(instr); +    parent->add_text = (add_text_fc)g_arch_instruction_add_text;      parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_arch_instruction_add_to_gtk_buffer;  } @@ -90,6 +94,60 @@ static void g_arch_instruction_init(GArchInstruction *instr)  /******************************************************************************  *                                                                             * +*  Paramètres  : instr     = instruction à transcrire.                        * +*                options   = options de rendu.                                * +*                rendering = support effectif final des lignes de code.       * +*                stream    = flux ouvert en écriture.                         * +*                                                                             * +*  Description : Ajoute du texte simple à un fichier ouvert en écriture.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_arch_instruction_add_text(const GArchInstruction *instr, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ +    GContentExporter *exporter;             /* Autre vision de la ligne    */ +    const char *key;                        /* Mot clef principal          */ +    size_t klen;                            /* Taille de ce mot clef       */ +    size_t i;                               /* Boucle de parcours          */ + +    exporter = G_CONTENT_EXPORTER(instr); + +    key = instr->get_text(instr, +                          g_rendering_options_get_format(options), +                          g_rendering_options_get_syntax(options)); +    klen = strlen(key); + +    g_content_exporter_insert_text(exporter, stream, key, klen, RTT_INSTRUCTION); + +    if (instr->operands_count > 0) +    { +        g_content_exporter_insert_text(exporter, stream, "\t", 1, RTT_NONE); + +        g_content_exporter_add_text(G_CONTENT_EXPORTER(G_ARCH_INSTRUCTION(instr)->operands[0]), +                                    options, rendering, stream); + +        for (i = 1; i < instr->operands_count; i++) +        { +            g_content_exporter_insert_text(exporter, stream, ",", 1, RTT_NONE/* FIXME */); + +            g_content_exporter_insert_text(exporter, stream, " ", 1, RTT_NONE); + +            g_content_exporter_add_text(G_CONTENT_EXPORTER(G_ARCH_INSTRUCTION(instr)->operands[i]), +                                        options, rendering, stream); + +        } + +    } + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : instr   = instruction à transcrire.                          *  *                format = format du binaire manipulé.                         *  *                syntax = type de représentation demandée.                    * diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c index cf4c863..7d6437a 100644 --- a/src/arch/x86/operand.c +++ b/src/arch/x86/operand.c @@ -89,6 +89,9 @@ static void g_x86_register_operand_class_init(GX86RegisterOperandClass *);  /* Initialise une instance d'opérande de registre x86. */  static void g_x86_register_operand_init(GX86RegisterOperand *); +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +static void g_x86_register_operand_add_text(const GX86RegisterOperand *, GRenderingOptions *, MainRendering, FILE *); +  /* Ajoute à un texte GTK le contenu d'un opérande. */  static void g_x86_register_operand_add_to_gtk_buffer(const GX86RegisterOperand *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *); @@ -124,6 +127,9 @@ static void g_x86_mod_rm_operand_class_init(GX86ModRMOperandClass *);  /* Initialise une instance d'opérande x86 de type ModRM. */  static void g_x86_mod_rm_operand_init(GX86ModRMOperand *); +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +static void g_x86_mod_rm_operand_add_text(const GX86ModRMOperand *, GRenderingOptions *, MainRendering, FILE *); +  /* Ajoute à un texte GTK le contenu d'un opérande. */  static void g_x86_mod_rm_operand_add_to_gtk_buffer(const GX86ModRMOperand *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *); @@ -155,6 +161,9 @@ static void g_x86_relative_operand_class_init(GX86RelativeOperandClass *);  /* Initialise une instance d'opérande x86 d'adresse relative. */  static void g_x86_relative_operand_init(GX86RelativeOperand *); +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +static void g_x86_relative_operand_add_text(const GX86RelativeOperand *, GRenderingOptions *, MainRendering, FILE *); +  /* Ajoute à un texte GTK le contenu d'un opérande. */  static void g_x86_relative_operand_add_to_gtk_buffer(const GX86RelativeOperand *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *); @@ -186,6 +195,9 @@ static void g_x86_moffs_operand_class_init(GX86MOffsOperandClass *);  /* Initialise une instance d'opérande d'emplacement mémoire x86. */  static void g_x86_moffs_operand_init(GX86MOffsOperand *); +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +static void g_x86_moffs_operand_add_text(const GX86MOffsOperand *, GRenderingOptions *, MainRendering, FILE *); +  /* Ajoute à un texte GTK le contenu d'un opérande. */  static void g_x86_moffs_operand_add_to_gtk_buffer(const GX86MOffsOperand *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *); @@ -218,6 +230,9 @@ static void g_x86_data_operand_class_init(GX86DataOperandClass *);  /* Initialise une instance d'opérande x86 pointant des données. */  static void g_x86_data_operand_init(GX86DataOperand *); +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +static void g_x86_data_operand_add_text(const GX86DataOperand *, GRenderingOptions *, MainRendering, FILE *); +  /* Ajoute à un texte GTK le contenu d'un opérande. */  static void g_x86_data_operand_add_to_gtk_buffer(const GX86DataOperand *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *); @@ -314,6 +329,7 @@ static void g_x86_register_operand_init(GX86RegisterOperand *operand)      parent = G_CONTENT_EXPORTER(operand); +    parent->add_text = (add_text_fc)g_x86_register_operand_add_text;      parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_x86_register_operand_add_to_gtk_buffer;  } @@ -438,6 +454,28 @@ GArchOperand *g_x86_register_operand_new_from_index(bin_t index, AsmOperandSize  /******************************************************************************  *                                                                             *  *  Paramètres  : operand = opérande à transcrire.                             * +*                options   = options de rendu.                                * +*                rendering = support effectif final des lignes de code.       * +*                stream    = flux ouvert en écriture.                         * +*                                                                             * +*  Description : Ajoute du texte simple à un fichier ouvert en écriture.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_x86_register_operand_add_text(const GX86RegisterOperand *operand, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ +    g_content_exporter_add_text(G_CONTENT_EXPORTER(operand->reg), options, rendering, stream); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande à transcrire.                             *  *                format = format du binaire manipulé.                         *  *                syntax = type de représentation demandée.                    *  *                buffer = zone de texte à venir compléter.                    * @@ -504,6 +542,7 @@ static void g_x86_mod_rm_operand_init(GX86ModRMOperand *operand)      parent = G_CONTENT_EXPORTER(operand); +    parent->add_text = (add_text_fc)g_x86_mod_rm_operand_add_text;      parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_x86_mod_rm_operand_add_to_gtk_buffer;  } @@ -614,11 +653,89 @@ GArchOperand *g_x86_mod_rm_operand_new(const bin_t *data, off_t *pos, off_t len,  /******************************************************************************  *                                                                             * +*  Paramètres  : operand   = opérande à transcrire.                           * +*                options   = options de rendu.                                * +*                rendering = support effectif final des lignes de code.       * +*                stream    = flux ouvert en écriture.                         * +*                                                                             * +*  Description : Ajoute du texte simple à un fichier ouvert en écriture.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_x86_mod_rm_operand_add_text(const GX86ModRMOperand *operand, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ +    GContentExporter *exporter;             /* Autre vision de l'opérande  */ +    char tmp[2];                            /* Echelle en puissance de 2   */ + +    exporter = G_CONTENT_EXPORTER(operand); + +    switch (g_rendering_options_get_syntax(options)) +    { +        case ASX_INTEL: + +            g_content_exporter_insert_text(exporter, stream, "[", 1, RTT_HOOK); + +            if (operand->scale > 0) +            { +                snprintf(tmp, 2, "%d", (int)pow(2, operand->scale));  + +                g_content_exporter_insert_text(exporter, stream, tmp, 1, RTT_IMMEDIATE); + +                g_content_exporter_insert_text(exporter, stream, "*", 1, RTT_SIGNS); + +            } + +            g_content_exporter_add_text(G_CONTENT_EXPORTER(operand->index), +                                        options, rendering, stream); + +            if (operand->base != NULL) +            { +                g_content_exporter_insert_text(exporter, stream, "+", 1, RTT_SIGNS); + +                g_content_exporter_add_text(G_CONTENT_EXPORTER(operand->base), +                                            options, rendering, stream); + +            } + +            if (operand->displacement != NULL) +            { +                if (g_imm_operand_is_negative(operand->displacement)) +                    g_content_exporter_insert_text(exporter, stream, "-", 1, RTT_SIGNS); +                else +                    g_content_exporter_insert_text(exporter, stream, "+", 1, RTT_SIGNS); + +                g_content_exporter_add_text(G_CONTENT_EXPORTER(operand->displacement), +                                            options, rendering, stream); + +            } + +            g_content_exporter_insert_text(exporter, stream, "]", 1, RTT_HOOK); + +            break; + +        case ASX_ATT: + +            /* TODO */ +            g_content_exporter_insert_text(exporter, stream, "[ModRM]", 7, RTT_HOOK); + +            break; + +    } + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : operand = opérande à transcrire.                             * -*                format = format du binaire manipulé.                         * -*                syntax = type de représentation demandée.                    * -*                buffer = zone de texte à venir compléter.                    * -*                iter   = point d'insertion du nouveau texte.                 * +*                format  = format du binaire manipulé.                        * +*                syntax  = type de représentation demandée.                   * +*                buffer  = zone de texte à venir compléter.                   * +*                iter    = point d'insertion du nouveau texte.                *  *                                                                             *  *  Description : Ajoute à un texte GTK le contenu d'un opérande.              *  *                                                                             * @@ -802,6 +919,7 @@ static void g_x86_relative_operand_init(GX86RelativeOperand *operand)      parent = G_CONTENT_EXPORTER(operand); +    parent->add_text = (add_text_fc)g_x86_relative_operand_add_text;      parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_x86_relative_operand_add_to_gtk_buffer;  } @@ -863,11 +981,33 @@ GArchOperand *g_x86_relative_operand_new(const bin_t *data, off_t *pos, off_t le  /******************************************************************************  *                                                                             * +*  Paramètres  : operand   = opérande à transcrire.                           * +*                options   = options de rendu.                                * +*                rendering = support effectif final des lignes de code.       * +*                stream    = flux ouvert en écriture.                         * +*                                                                             * +*  Description : Ajoute du texte simple à un fichier ouvert en écriture.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_x86_relative_operand_add_text(const GX86RelativeOperand *operand, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ +    g_content_exporter_add_text(G_CONTENT_EXPORTER(operand->immediate), options, rendering, stream); + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : operand = opérande à transcrire.                             * -*                format = format du binaire manipulé.                         * -*                syntax = type de représentation demandée.                    * -*                buffer = zone de texte à venir compléter.                    * -*                iter   = point d'insertion du nouveau texte.                 * +*                format  = format du binaire manipulé.                        * +*                syntax  = type de représentation demandée.                   * +*                buffer  = zone de texte à venir compléter.                   * +*                iter    = point d'insertion du nouveau texte.                *  *                                                                             *  *  Description : Ajoute à un texte GTK le contenu d'un opérande.              *  *                                                                             * @@ -950,6 +1090,7 @@ static void g_x86_moffs_operand_init(GX86MOffsOperand *operand)      parent = G_CONTENT_EXPORTER(operand); +    parent->add_text = (add_text_fc)g_x86_moffs_operand_add_text;      parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_x86_moffs_operand_add_to_gtk_buffer;  } @@ -992,6 +1133,30 @@ GArchOperand *g_x86_moffs_operand_new(const bin_t *data, off_t *pos, off_t len,  /******************************************************************************  *                                                                             * +*  Paramètres  : operand   = opérande à transcrire.                           * +*                options   = options de rendu.                                * +*                rendering = support effectif final des lignes de code.       * +*                stream    = flux ouvert en écriture.                         * +*                                                                             * +*  Description : Ajoute du texte simple à un fichier ouvert en écriture.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_x86_moffs_operand_add_text(const GX86MOffsOperand *operand, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ +    g_content_exporter_insert_text(G_CONTENT_EXPORTER(operand), stream, "ds:", 3, RTT_SEGMENT); + +    g_content_exporter_add_text(G_CONTENT_EXPORTER(operand->offset), options, rendering, stream); + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : operand = opérande à transcrire.                             *  *                format = format du binaire manipulé.                         *  *                syntax = type de représentation demandée.                    * @@ -1063,6 +1228,7 @@ static void g_x86_data_operand_init(GX86DataOperand *operand)      parent = G_CONTENT_EXPORTER(operand); +    parent->add_text = (add_text_fc)g_x86_data_operand_add_text;      parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_x86_data_operand_add_to_gtk_buffer;  } @@ -1098,10 +1264,45 @@ GArchOperand *g_x86_data_operand_new(MemoryDataSize size, bool dest)  /******************************************************************************  *                                                                             *  *  Paramètres  : operand = opérande à transcrire.                             * -*                format = format du binaire manipulé.                         * -*                syntax = type de représentation demandée.                    * -*                buffer = zone de texte à venir compléter.                    * -*                iter   = point d'insertion du nouveau texte.                 * +*                options   = options de rendu.                                * +*                rendering = support effectif final des lignes de code.       * +*                stream    = flux ouvert en écriture.                         * +*                                                                             * +*  Description : Ajoute du texte simple à un fichier ouvert en écriture.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_x86_data_operand_add_text(const GX86DataOperand *operand, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ +    GContentExporter *exporter;             /* Autre vision de l'opérande  */ + +    exporter = G_CONTENT_EXPORTER(operand); + +    if (operand->dest) +        g_content_exporter_insert_text(exporter, stream, "es:", 3, RTT_SEGMENT); +    else +        g_content_exporter_insert_text(exporter, stream, "ds:", 3, RTT_SEGMENT); + +    g_content_exporter_insert_text(exporter, stream, "[", 1, RTT_HOOK); + +    g_content_exporter_add_text(G_CONTENT_EXPORTER(operand->reg), options, rendering, stream); + +    g_content_exporter_insert_text(exporter, stream, "]", 1, RTT_HOOK); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande à transcrire.                             * +*                format  = format du binaire manipulé.                        * +*                syntax  = type de représentation demandée.                   * +*                buffer  = zone de texte à venir compléter.                   * +*                iter    = point d'insertion du nouveau texte.                *  *                                                                             *  *  Description : Ajoute à un texte GTK le contenu d'un opérande.              *  *                                                                             * diff --git a/src/arch/x86/registers.c b/src/arch/x86/registers.c index 4e186ed..90346f7 100644 --- a/src/arch/x86/registers.c +++ b/src/arch/x86/registers.c @@ -106,6 +106,15 @@ struct _GX86RegisterClass  }; +#define MAX_REGNAME_LEN 5 + + +/* Construit la chaîne de caractères correspondant à l'opérande. */ +static void g_x86_register_to_string(const GX86Register *, AsmSyntax, char [MAX_REGNAME_LEN], size_t *); + +/* Ajoute du texte simple à un fichier ouvert en écriture. */ +static void g_x86_register_add_text(const GX86Register *, GRenderingOptions *, MainRendering, FILE *); +  /* Ajoute à un texte GTK le contenu d'un opérande. */  static void g_x86_register_add_to_gtk_buffer(const GX86Register *, const GExeFormat *, AsmSyntax, GtkTextBuffer *, GtkTextIter *); @@ -151,6 +160,7 @@ static void g_x86_register_init(GX86Register *reg)      parent = G_CONTENT_EXPORTER(reg); +    parent->add_text = (add_text_fc)g_x86_register_add_text;      parent->add_arch_to_gtk_buffer = (add_arch_to_gtk_buffer_fc)g_x86_register_add_to_gtk_buffer;  } @@ -232,15 +242,15 @@ GX86Register *g_x86_register_new(MemoryDataSize size, bin_t value)  } +  /******************************************************************************  *                                                                             *  *  Paramètres  : operand = opérande à transcrire.                             * -*                format = format du binaire manipulé.                         * -*                syntax = type de représentation demandée.                    * -*                buffer = zone de texte à venir compléter.                    * -*                iter   = point d'insertion du nouveau texte.                 * +*                syntax  = type de représentation demandée.                   * +*                key     = description humaine du registre. [OUT]             * +*                klen    = nombre de caractères utilisés. [OUT]               *  *                                                                             * -*  Description : Ajoute à un texte GTK le contenu d'un opérande.              * +*  Description : Construit la chaîne de caractères correspondant à l'opérande.*  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -248,12 +258,9 @@ GX86Register *g_x86_register_new(MemoryDataSize size, bin_t value)  *                                                                             *  ******************************************************************************/ -static void g_x86_register_add_to_gtk_buffer(const GX86Register *reg, const GExeFormat *format, AsmSyntax syntax, GtkTextBuffer *buffer, GtkTextIter *iter) +static void g_x86_register_to_string(const GX86Register *reg, AsmSyntax syntax, char key[MAX_REGNAME_LEN], size_t *klen)  { -    char key[5];                            /* Mot clef principal          */ -    size_t klen;                            /* Taille de ce mot clef       */ - -    klen = 0; +    *klen = 0;      switch (syntax)      { @@ -261,7 +268,7 @@ static void g_x86_register_add_to_gtk_buffer(const GX86Register *reg, const GExe              switch (reg->size)              {                  case AOS_8_BITS: -                    klen = 2; +                    *klen = 2;                      switch (reg->reg.reg8)                      {                          case X86_REG8_AL: @@ -295,7 +302,7 @@ static void g_x86_register_add_to_gtk_buffer(const GX86Register *reg, const GExe                      break;                  case AOS_16_BITS: -                    klen = 2; +                    *klen = 2;                      switch (reg->reg.reg16)                      {                          case X86_REG16_AX: @@ -329,7 +336,7 @@ static void g_x86_register_add_to_gtk_buffer(const GX86Register *reg, const GExe                      break;                  case AOS_32_BITS: -                    klen = 3; +                    *klen = 3;                      switch (reg->reg.reg32)                      {                          case X86_REG32_EAX: @@ -373,7 +380,7 @@ static void g_x86_register_add_to_gtk_buffer(const GX86Register *reg, const GExe              switch (reg->size)              {                  case AOS_8_BITS: -                    klen = 3; +                    *klen = 3;                      switch (reg->reg.reg8)                      {                          case X86_REG8_AL: @@ -407,7 +414,7 @@ static void g_x86_register_add_to_gtk_buffer(const GX86Register *reg, const GExe                      break;                  case AOS_16_BITS: -                    klen = 3; +                    *klen = 3;                      switch (reg->reg.reg16)                      {                          case X86_REG16_AX: @@ -441,7 +448,7 @@ static void g_x86_register_add_to_gtk_buffer(const GX86Register *reg, const GExe                      break;                  case AOS_32_BITS: -                    klen = 4; +                    *klen = 4;                      switch (reg->reg.reg32)                      {                          case X86_REG32_EAX: @@ -485,6 +492,60 @@ static void g_x86_register_add_to_gtk_buffer(const GX86Register *reg, const GExe      } +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande à transcrire.                             * +*                options   = options de rendu.                                * +*                rendering = support effectif final des lignes de code.       * +*                stream    = flux ouvert en écriture.                         * +*                                                                             * +*  Description : Ajoute du texte simple à un fichier ouvert en écriture.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_x86_register_add_text(const GX86Register *reg, GRenderingOptions *options, MainRendering rendering, FILE *stream) +{ +    char key[MAX_REGNAME_LEN];              /* Mot clef principal          */ +    size_t klen;                            /* Taille de ce mot clef       */ + +    g_x86_register_to_string(reg, g_rendering_options_get_syntax(options), key, &klen); + +    g_content_exporter_insert_text(G_CONTENT_EXPORTER(reg), stream, +                                   key, klen, RTT_REGISTER); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande à transcrire.                             * +*                format = format du binaire manipulé.                         * +*                syntax = type de représentation demandée.                    * +*                buffer = zone de texte à venir compléter.                    * +*                iter   = point d'insertion du nouveau texte.                 * +*                                                                             * +*  Description : Ajoute à un texte GTK le contenu d'un opérande.              * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_x86_register_add_to_gtk_buffer(const GX86Register *reg, const GExeFormat *format, AsmSyntax syntax, GtkTextBuffer *buffer, GtkTextIter *iter) +{ +    char key[MAX_REGNAME_LEN];              /* Mot clef principal          */ +    size_t klen;                            /* Taille de ce mot clef       */ + +    g_x86_register_to_string(reg, syntax, key, &klen); +      g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(reg), buffer, iter,                                             key, klen, RTT_REGISTER); diff --git a/src/dialogs/Makefile.am b/src/dialogs/Makefile.am index 181f418..22eaeac 100644 --- a/src/dialogs/Makefile.am +++ b/src/dialogs/Makefile.am @@ -2,7 +2,8 @@  lib_LIBRARIES = libdialogs.a  libdialogs_a_SOURCES =					\ -	binparts.h binparts.c +	binparts.h binparts.c				\ +	export.h export.c  libdialogs_a_LDFLAGS =  diff --git a/src/dialogs/export.c b/src/dialogs/export.c new file mode 100644 index 0000000..3c97815 --- /dev/null +++ b/src/dialogs/export.c @@ -0,0 +1,637 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * export.c - assistant d'exportation de contenu binaire + * + * 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 "export.h" + + +#include <stdio.h> +#include <string.h> + + +#include "../analysis/exporter.h" +#include "../glibext/delayed-int.h" +#include "../gtkext/easygtk.h" + + + +#ifndef _ +#   define _(str) str +#endif + + + + +/* ------------------------ PARTIE PRINCIPALE DE L'ASSISTANT ------------------------ */ + + +/* Ferme l'assistant sans dérouler la procédure. */ +static void export_assistant_cancel(GtkAssistant *, gpointer); + +/* Ferme l'assistant et déroule la procédure. */ +static void export_assistant_close(GtkAssistant *, GObject *); + + + +/* -------------------- DEFINITION DES REGLAGES DE L'EXPORTATION -------------------- */ + + +/* Ajoute le panneau de choix du type de sortie. */ +static void register_output_panel(GtkAssistant *); + +/* Réagit un changement du nom de fichier pour l'exportation. */ +static void on_export_filename_changed(GtkEntry *, GtkAssistant *); + +/* Sélectionne ou non un nouveau fichier de sortie. */ +static void on_filename_browsing_clicked(GtkButton *, GObject *); + + + +/* ------------------------- SELECTION DU CONTENU A TRAITER ------------------------- */ + + +/* Ajoute le panneau de sélection du contenu à exporter. */ +static void register_content_panel(GtkAssistant *); + + + +/* ------------------------- EXPORTATION DE BINAIRE DIFFERE ------------------------- */ + + +#define G_TYPE_DELAYED_EXPORT               g_delayed_export_get_type() +#define G_DELAYED_EXPORT(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_delayed_export_get_type(), GDelayedExport)) +#define G_IS_DELAYED_EXPORT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_delayed_export_get_type())) +#define G_DELAYED_EXPORT_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DELAYED_EXPORT, GDelayedExportClass)) +#define G_IS_DELAYED_EXPORT_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DELAYED_EXPORT)) +#define G_DELAYED_EXPORT_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DELAYED_EXPORT, GDelayedExportClass)) + + +/* Ensembles binaires à désassembler (instance) */ +typedef struct _GDelayedExport +{ +    GDelayedWork parent;                    /* A laisser en premier        */ + +    char *filename;                         /* Fichier à remplir           */ + +    GOpenidaBinary *binary;                 /* Destinataire final          */ +    GRenderingOptions *options;             /* Options d'exportation       */ + +} GDelayedExport; + +/* Ensembles binaires à désassembler (classe) */ +typedef struct _GDelayedExportClass +{ +    GDelayedWorkClass parent;               /* A laisser en premier        */ + +} GDelayedExportClass; + + +/* Indique le type défini pour les tâches d'exportation différée. */ +static GType g_delayed_export_get_type(void); + +/* Initialise la classe des tâches d'exportation différée. */ +static void g_delayed_export_class_init(GDelayedExportClass *); + +/* Initialise une tâche d'exportation différée. */ +static void g_delayed_export_init(GDelayedExport *); + +/* Crée une tâche d'exportation différée. */ +static GDelayedExport *g_delayed_export_new(const char *, GOpenidaBinary *, GRenderingOptions *); + +/* Assure l'exportation en différé. */ +static void g_delayed_export_process(GDelayedExport *, GtkExtStatusBar *); + + + +/* ---------------------------------------------------------------------------------- */ +/*                          PARTIE PRINCIPALE DE L'ASSISTANT                          */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : binary = binaire chargé en mémoire à traiter.                * +*                parent = fenêtre principale de l'éditeur.                    * +*                                                                             * +*  Description : Crée et affiche un assistant d'aide à l'exportation.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void run_export_assistant(GOpenidaBinary *binary, GtkWindow *parent) +{ +    GtkWidget *assistant;                   /* Fenêtre à afficher          */ +    GObject *ref;                           /* Espace de référencement     */ + +    assistant = gtk_assistant_new(); +    gtk_widget_set_size_request(assistant, 450, 300); +    gtk_window_set_position(GTK_WINDOW(assistant), GTK_WIN_POS_CENTER); +    gtk_window_set_title(GTK_WINDOW(assistant), _("Export assistant")); + +    gtk_window_set_modal(GTK_WINDOW(assistant), TRUE); +    gtk_window_set_transient_for(GTK_WINDOW(assistant), parent); + +    ref = G_OBJECT(assistant); +    g_object_set_data(ref, "binary", binary); + +    register_output_panel(GTK_ASSISTANT(assistant)); +    register_content_panel(GTK_ASSISTANT(assistant)); + +    g_signal_connect(G_OBJECT(assistant), "cancel", G_CALLBACK(export_assistant_cancel), NULL); +    g_signal_connect(G_OBJECT(assistant), "close", G_CALLBACK(export_assistant_close), ref); + +    gtk_widget_show_all(assistant); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : assistant = fenêtre à compléter et référencement global.     * +*                data      = adresse non utilisée ici.                        * +*                                                                             * +*  Description : Ferme l'assistant sans dérouler la procédure.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void export_assistant_cancel(GtkAssistant *assistant, gpointer data) +{ +    gtk_widget_destroy(GTK_WIDGET(assistant)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : assistant = fenêtre à compléter et référencement global.     * +*                ref       = adresse de l'espace de référencement global.     * +*                                                                             * +*  Description : Ferme l'assistant et déroule la procédure.                   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void export_assistant_close(GtkAssistant *assistant, GObject *ref) +{ +    GOpenidaBinary *binary;                 /* Binaire chargé à parcourir  */ +    GExeFormat *format;                     /* Format du binaire           */ +    GArchProcessor *proc;                   /* Architecture visée          */ +    GRenderingOptions *options;             /* Options d'exportation       */ +    GtkToggleButton *checkbutton;           /* Coche à retrouver           */ +    gboolean state;                         /* Valeur à prendre en compte  */ +    GtkEntry *entry;                        /* Zone de saisie              */ +    const gchar *filename;                  /* Chemin d'accès du fichier   */ +    GDelayedExport *export;                 /* Procédure d'exportation     */ +    GWorkQueue *queue;                      /* Gestionnaire de différés    */ + +    binary = G_OPENIDA_BINARY(g_object_get_data(ref, "binary")); + +    format = g_openida_binary_get_format(binary); +    proc = get_arch_processor_from_format(format); + +    options = g_rendering_options_new(format, proc); + +    /* Eléments à afficher */ + +    checkbutton = GTK_TOGGLE_BUTTON(g_object_get_data(ref, "virtual_addr")); +    state = gtk_toggle_button_get_active(checkbutton); +    g_rendering_options_show_address(options, MRD_BLOCK, state); + +    checkbutton = GTK_TOGGLE_BUTTON(g_object_get_data(ref, "binary_code")); +    state = gtk_toggle_button_get_active(checkbutton); +    g_rendering_options_show_code(options, MRD_BLOCK, state); + +    checkbutton = GTK_TOGGLE_BUTTON(g_object_get_data(ref, "assembly_code")); +    state = gtk_toggle_button_get_active(checkbutton); + +    /* Programmation de la tâche */ + +    entry = GTK_ENTRY(g_object_get_data(ref, "filename")); +    filename = gtk_entry_get_text(entry); + +    export = g_delayed_export_new(filename, binary, options); + +    queue = get_work_queue(); +    g_work_queue_schedule_work(queue, G_DELAYED_WORK(export)); + +    gtk_widget_destroy(GTK_WIDGET(assistant)); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                      DEFINITION DES REGLAGES DE L'EXPORTATION                      */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : assistant = fenêtre à compléter et référencement global.     * +*                                                                             * +*  Description : Ajoute le panneau de choix du type de sortie.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void register_output_panel(GtkAssistant *assistant) +{ +    GtkWidget *alignment;                   /* Disposition sur le support  */ +    GtkWidget *vbox;                        /* Support principal #1        */ +    GtkWidget *hbox;                        /* Support principal #2        */ +    GtkWidget *label;                       /* Etiquette d'indication      */ +    GtkWidget *combobox;                    /* Sélection du format         */ +    GtkWidget *entry;                       /* Zone de saisie de texte     */ +    GtkWidget *button;                      /* Sélection de fichier        */ +    GOpenidaBinary *binary;                 /* Binaire chargé à parcourir  */ +    const char *filename;                   /* Chemin d'accès par défaut   */ + +    alignment = qck_create_padded_alignment(8, 8, 8, 8); + +    vbox = gtk_vbox_new(TRUE, 0); +    gtk_widget_show(vbox); +    gtk_container_add(GTK_CONTAINER(alignment), vbox); + +    /* Format de sortie */ + +    hbox = gtk_hbox_new(FALSE, 0); +    gtk_widget_show(hbox); +    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + +    label = qck_create_label(NULL, NULL, _("Format : ")); +    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + +    combobox = qck_create_combobox(NULL, NULL, G_CALLBACK(NULL), NULL); +    gtk_box_pack_start(GTK_BOX(hbox), combobox, TRUE, TRUE, 0); + +    gtk_combo_box_append_text(GTK_COMBO_BOX(combobox), _("Simple text")); + +    gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), 0); + +    /* Fichier de sortie */ + +    hbox = gtk_hbox_new(FALSE, 0); +    gtk_widget_show(hbox); +    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + +    label = qck_create_label(NULL, NULL, _("File : ")); +    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + +    entry = qck_create_entry(G_OBJECT(assistant), "filename", NULL); +    gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); + +    button = qck_create_button(NULL, NULL, "...", G_CALLBACK(on_filename_browsing_clicked), assistant); +    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); + +    /* Intégration */ + +    gtk_assistant_append_page(assistant, alignment); +    gtk_assistant_set_page_title(assistant, alignment, _("Output")); +    gtk_assistant_set_page_type(assistant, alignment, GTK_ASSISTANT_PAGE_INTRO); + +    gtk_assistant_set_page_complete(assistant, alignment, TRUE); + +    /* Choix par défaut */ + +    binary = G_OPENIDA_BINARY(g_object_get_data(G_OBJECT(assistant), "binary")); +    filename = g_openida_binary_get_filename(binary); + +    gtk_entry_set_text(GTK_ENTRY(entry), filename); +    gtk_entry_append_text(GTK_ENTRY(entry), ".txt"); + +    g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(on_export_filename_changed), assistant); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : entry     = zone de texte dont le contenu vient de changer.  * +*                assistant = fenêtre affichée et référencement global.        * +*                                                                             * +*  Description : Réagit un changement du nom de fichier pour l'exportation.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void on_export_filename_changed(GtkEntry *entry, GtkAssistant *assistant) +{ +    const gchar *text;                      /* Texte saisi dans la zone    */ +    gint num;                               /* Etape courante              */ +    GtkWidget *page;                        /* Support de cette étape      */ + +    text = gtk_entry_get_text(entry); + +    num = gtk_assistant_get_current_page(assistant); +    page = gtk_assistant_get_nth_page(assistant, num); + +    gtk_assistant_set_page_complete(assistant, page, (strlen(text) > 0)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : button = bouton d'édition de la sélection.                   * +*                ref    = espace de référencement principal.                  * +*                                                                             * +*  Description : Sélectionne ou non un nouveau fichier de sortie.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void on_filename_browsing_clicked(GtkButton *button, GObject *ref) +{ +    GtkWidget *dialog;                      /* Boîte à afficher            */ +    gchar *filename;                        /* Nom du fichier à intégrer   */ +    GtkEntry *entry;                        /* Zone de saisie à maj.       */ + +    dialog = gtk_file_chooser_dialog_new(_("Choose an output filename"), GTK_WINDOW(ref), +                                         GTK_FILE_CHOOSER_ACTION_SAVE, +                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, +                                         GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, +                                         NULL); + +    entry = GTK_ENTRY(g_object_get_data(ref, "filename")); +    gtk_file_chooser_set_filename(dialog, gtk_entry_get_text(entry)); + +    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) +    { +        filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + +        gtk_entry_set_text(GTK_ENTRY(entry), filename); + +        g_free(filename); + +    } + +    gtk_widget_destroy(dialog); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                           SELECTION DU CONTENU A TRAITER                           */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : assistant = fenêtre à compléter et référencement global.     * +*                                                                             * +*  Description : Ajoute le panneau de sélection du contenu à exporter.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void register_content_panel(GtkAssistant *assistant) +{ +    GtkWidget *alignment;                   /* Disposition sur le support  */ +    GtkWidget *vbox;                        /* Support principal           */ +    GtkWidget *frame;                       /* Support avec encadrement    */ +    GtkWidget *subalign;                    /* Disposition des options     */ + +    GtkWidget *vbox3; +    GtkWidget *checkbutton;                 /* Coche pour une option       */ +    GtkWidget *vbox4; + +    alignment = qck_create_padded_alignment(8, 8, 8, 8); + +    vbox = gtk_vbox_new(TRUE, 0); +    gtk_widget_show(vbox); +    gtk_container_add(GTK_CONTAINER(alignment), vbox); + +    /* Lignes à traiter */ + +    frame = qck_create_frame(_("<b>Lines to process</b>"), &subalign, 0, 0, 12, 0); +    gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0); + +    vbox3 = gtk_vbox_new(FALSE, 0); +    gtk_widget_show(vbox3); +    gtk_container_add(GTK_CONTAINER(subalign), vbox3); + +    checkbutton = qck_create_check_button(G_OBJECT(assistant), "prologue", _("Prologue"), NULL, NULL); +    gtk_box_pack_start(GTK_BOX(vbox3), checkbutton, FALSE, FALSE, 0); +    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TRUE); + +    checkbutton = qck_create_check_button(G_OBJECT(assistant), "code", _("Code"), NULL, NULL); +    gtk_box_pack_start(GTK_BOX(vbox3), checkbutton, FALSE, FALSE, 0); +    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TRUE); + +    checkbutton = qck_create_check_button(G_OBJECT(assistant), "comments", _("Comments"), NULL, NULL); +    gtk_box_pack_start(GTK_BOX(vbox3), checkbutton, FALSE, FALSE, 0); +    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TRUE); + +    /* Eléments à afficher */ + +    frame = qck_create_frame(_("<b>Items to display</b>"), &subalign, 0, 0, 12, 0); +    gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0); + +    vbox4 = gtk_vbox_new(FALSE, 0); +    gtk_widget_show(vbox4); +    gtk_container_add(GTK_CONTAINER(subalign), vbox4); + +    checkbutton = qck_create_check_button(G_OBJECT(assistant), "virtual_addr", _("Virtual address"), NULL, NULL); +    gtk_box_pack_start(GTK_BOX(vbox4), checkbutton, FALSE, FALSE, 0); +    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TRUE); + +    checkbutton = qck_create_check_button(G_OBJECT(assistant), "binary_code", _("Binary code"), NULL, NULL); +    gtk_box_pack_start(GTK_BOX(vbox4), checkbutton, FALSE, FALSE, 0); +    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TRUE); + +    checkbutton = qck_create_check_button(G_OBJECT(assistant), "assembly_code", _("Assembly code"), NULL, NULL); +    gtk_box_pack_start(GTK_BOX(vbox4), checkbutton, FALSE, FALSE, 0); +    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TRUE); + +    /* Intégration */ + +    gtk_assistant_append_page(assistant, alignment); +    gtk_assistant_set_page_title(assistant, alignment, _("Exported content")); +    gtk_assistant_set_page_type(assistant, alignment, GTK_ASSISTANT_PAGE_CONFIRM); + +    gtk_assistant_set_page_complete(assistant, alignment, TRUE); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                           EXPORTATION DE BINAIRE DIFFERE                           */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour les tâches d'exportation différée. */ +G_DEFINE_TYPE(GDelayedExport, g_delayed_export, G_TYPE_DELAYED_WORK); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des tâches d'exportation différée.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_delayed_export_class_init(GDelayedExportClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : disass = instance à initialiser.                             * +*                                                                             * +*  Description : Initialise une tâche d'exportation différée.                 * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_delayed_export_init(GDelayedExport *disass) +{ +    G_DELAYED_WORK(disass)->run = (run_task_fc)g_delayed_export_process; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : filename = chemin d'accès au fichier à remplir.              * +*                binary   = binaire chargé dont le contenu est à exporter.    * +*                options  = options d'exportation à respecter.                * +*                                                                             * +*  Description : Crée une tâche d'exportation différée.                       * +*                                                                             * +*  Retour      : Tâche créée.                                                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GDelayedExport *g_delayed_export_new(const char *filename, GOpenidaBinary *binary, GRenderingOptions *options) +{ +    GDelayedExport *result;            /* Tâche à retourner           */ + +    result = g_object_new(G_TYPE_DELAYED_EXPORT, NULL); + +    result->filename = strdup(filename); + +    result->binary = binary; +    result->options = options; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : export    = analyse à mener.                                 * +*                statusbar = barre de statut à tenir informée.                * +*                                                                             * +*  Description : Assure l'exportation en différé.                             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_delayed_export_process(GDelayedExport *export, GtkExtStatusBar *statusbar) +{ +    FILE *stream;                           /* Flux ouvert en écriture     */ +    GRenderingLine *lines;                  /* Liste de lignes à intégrer  */ +    vmpa_t start;                           /* Adresse de début de parcours*/ +    GRenderingLine *iter;                   /* Boucle de parcours          */ +    vmpa_t end;                             /* Adresse de fin de parcours  */ +    guint id;                               /* Identifiant de statut       */ +    size_t ret;                             /* Quantité d'octets écrite    */ +    vmpa_t done;                            /* Quantité déjà parcourue     */ + +    stream = fopen(export->filename, "w"); +    if (stream == NULL) +    { +        perror("fopen"); +        return; +    } + +    lines = g_openida_binary_get_lines(export->binary); +    if (lines == NULL) return;  /* FIXME ? */ + +    start = get_rendering_line_address(lines); + +    iter = g_rendering_line_get_last_iter(lines, NULL); +    end = get_rendering_line_address(iter) + get_rendering_line_length(iter) - start; + +    id = gtk_extended_status_bar_push(statusbar, _("Exporting binary lines..."), true); + +    for (iter = lines; +         iter != NULL; +         iter = g_rendering_line_get_next_iter(lines, iter, NULL)) +    { +        /* TODO : filtre... */ + +        g_content_exporter_add_text(G_CONTENT_EXPORTER(iter), export->options, MRD_BLOCK, stream); + +        ret = fwrite("\n", 1, sizeof(char), stream); +        if (ret != 1) perror("fwrite"); + +        done = get_rendering_line_address(iter) + get_rendering_line_length(iter) - start; +        gtk_extended_status_bar_update_activity(statusbar, id, done * 1.0 / end); + +    } + +    gtk_extended_status_bar_remove(statusbar, id); + +    fclose(stream); + +} diff --git a/src/dialogs/export.h b/src/dialogs/export.h new file mode 100644 index 0000000..c14d05d --- /dev/null +++ b/src/dialogs/export.h @@ -0,0 +1,37 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * export.h - prototypes pour l'assistant d'exportation de contenu binaire + * + * 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 _DIALOGS_EXPORT_H +#define _DIALOGS_EXPORT_H + + +#include "../analysis/binary.h" + + + +/* Crée et affiche un assistant d'aide à l'exportation. */ +void run_export_assistant(GOpenidaBinary *, GtkWindow *); + + + +#endif  /* _DIALOGS_EXPORT_H */ diff --git a/src/editor.c b/src/editor.c index 8291a2e..8f6428d 100644 --- a/src/editor.c +++ b/src/editor.c @@ -50,6 +50,7 @@  #include "debug/debuggers.h"  #include "dialogs/binparts.h" +#include "dialogs/export.h"  #include "panels/panel.h" @@ -86,8 +87,6 @@ void mcb_file_save_project(GtkMenuItem *, gpointer);  /* Réagit au menu "Fichier -> Enregistrer le projet sous...". */  void mcb_file_save_project_as(GtkMenuItem *, gpointer); - -  /* Charge un projet récent et met à jour la liste. */  void mcb_open_recent_project(GtkMenuItem *, GObject *); @@ -118,6 +117,9 @@ void reload_menu_project(GObject *);  /* Réagit avec le menu "Binaire -> Sélectionner les parties...". */  static void mcb_binary_select_parts(GtkMenuItem *, GObject *); +/* Réagit au menu "Binaire -> Exporter...". */ +static void mcb_binary_export(GtkMenuItem *, GObject *); +  /*Réagit avec le menu "Débogage -> Démarrer". */  void mcb_debug_start(GtkCheckMenuItem *, gpointer); @@ -326,6 +328,12 @@ GtkWidget *create_editor(void)      submenuitem = qck_create_menu_item(NULL, NULL, _("Select parts..."), G_CALLBACK(mcb_binary_select_parts), ref);      gtk_container_add(GTK_CONTAINER(menubar), submenuitem); +    submenuitem = qck_create_menu_separator(); +    gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + +    submenuitem = qck_create_menu_item(ref, "mnu_binary_export", _("Export..."), G_CALLBACK(mcb_binary_export), ref); +    gtk_container_add(GTK_CONTAINER(menubar), submenuitem); +      menuitem = gtk_menu_item_new_with_mnemonic(_("_Debug")); @@ -798,8 +806,6 @@ void mcb_file_save_project_as(GtkMenuItem *menuitem, gpointer data)  } - -  /******************************************************************************  *                                                                             *  *  Paramètres  : menuitem = élément de menu sélectionné.                      * @@ -960,11 +966,11 @@ void mcb_project_add_binary(GtkMenuItem *menuitem, gpointer data)      gchar *filename;                        /* Nom du fichier à intégrer   */      GOpenidaBinary *binary;                 /* Représentation chargée      */ -    dialog = gtk_file_chooser_dialog_new (_("Open a binary file"), GTK_WINDOW(data), -                                          GTK_FILE_CHOOSER_ACTION_OPEN, -                                          GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, -                                          GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, -                                          NULL); +    dialog = gtk_file_chooser_dialog_new(_("Open a binary file"), GTK_WINDOW(data), +                                         GTK_FILE_CHOOSER_ACTION_OPEN, +                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, +                                         GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, +                                         NULL);      if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)      { @@ -1105,6 +1111,31 @@ static void mcb_binary_select_parts(GtkMenuItem *menuitem, GObject *ref)  } +/****************************************************************************** +*                                                                             * +*  Paramètres  : menuitem = élément de menu sélectionné.                      * +*                ref      = adresse de l'espace de référencement global.      * +*                                                                             * +*  Description : Réagit au menu "Binaire -> Exporter...".                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void mcb_binary_export(GtkMenuItem *menuitem, GObject *ref) +{ +    GOpenidaBinary *binary;                 /* Edition courante            */ + +    binary = (GOpenidaBinary *)g_object_get_data(ref, "current_binary"); + +    run_export_assistant(binary, GTK_WINDOW(ref)); + +} + + +  void debugger_stopped_cb(GBinaryDebugger *debugger, uint64_t last, uint64_t cur, gpointer data)  { diff --git a/src/gtkext/easygtk.c b/src/gtkext/easygtk.c index 253b4bc..5d44723 100644 --- a/src/gtkext/easygtk.c +++ b/src/gtkext/easygtk.c @@ -395,6 +395,44 @@ GtkWidget *qck_create_button_with_img(GObject *object, const char *name, const c  *                                                                             *  *  Paramètres  : object  = espace dédié à l'inscription de références.        *  *                name    = nom à donner au nouveau composant.                 * +*                caption = désignation apparaîssant sur le corps de l'objet.  * +*                handler = éventuelle fonction de sélection associée.         * +*                data    = données à transmettre avec l'événement si besoin.  * +*                                                                             * +*  Description : Crée et enregistre un composant 'GtkCheckButton'.            * +*                                                                             * +*  Retour      : Composant mis en place.                                      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GtkWidget *qck_create_check_button(GObject *object, const char *name, const char *caption, GCallback handler, gpointer data) +{ +    GtkWidget *result;                      /* Résultat à renvoyer         */ + +	result = gtk_check_button_new_with_label(caption); + +    if (G_IS_OBJECT(object) && name != NULL) +    { +        gtk_widget_ref(result); +        g_object_set_data_full(object, name, result, (GtkDestroyNotify)gtk_widget_unref); +    } + +    gtk_widget_show(result); + +    if (handler != NULL) +        g_signal_connect(result, "toggled", handler, data); + +	return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : object  = espace dédié à l'inscription de références.        * +*                name    = nom à donner au nouveau composant.                 *  *                handler = éventuelle fonction de sélection associée.         *  *                data    = données à transmettre avec l'événement si besoin.  *  *                                                                             * diff --git a/src/gtkext/easygtk.h b/src/gtkext/easygtk.h index d1d7fbf..d7ed830 100644 --- a/src/gtkext/easygtk.h +++ b/src/gtkext/easygtk.h @@ -59,6 +59,9 @@ GtkWidget *qck_create_button_from_stock(GObject *, const char *, const char *, G  /* Crée et enregistre un composant 'GtkButton'. */  GtkWidget *qck_create_button_with_img(GObject *, const char *, const char *, GCallback, gpointer); +/* Crée et enregistre un composant 'GtkCheckButton'. */ +GtkWidget *qck_create_check_button(GObject *, const char *, const char *, GCallback, gpointer); +  /* Crée et enregistre un composant 'GtkComboBox'. */  GtkWidget *qck_create_combobox(GObject *, const char *, GCallback, gpointer); | 
