diff options
Diffstat (limited to 'src/analysis/line_code.c')
| -rw-r--r-- | src/analysis/line_code.c | 283 | 
1 files changed, 283 insertions, 0 deletions
diff --git a/src/analysis/line_code.c b/src/analysis/line_code.c new file mode 100644 index 0000000..2dd5a7c --- /dev/null +++ b/src/analysis/line_code.c @@ -0,0 +1,283 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * line_code.c - représentation des lignes de code binaire. + * + * Copyright (C) 2008 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 "line_code.h" + + +#include <malloc.h> +#include <string.h> + + +#include "line-int.h" + + + +/* Ligne de représentation de code binaire (instance) */ +struct _GCodeLine +{ +    GRenderingLine parent;                  /* Instance parente            */ + +    asm_instr *instr;                       /* Instruction représentée     */ +    const disass_options *options;          /* Options de représentation   */ + +}; + + +/* Ligne de représentation de code binaire (classe) */ +struct _GCodeLineClass +{ +    GRenderingLineClass parent;             /* Classe parente              */ + +}; + + +/* Initialise la classe des lignes de code binaire. */ +static void g_code_line_class_init(GCodeLineClass *); + +/* Initialise la classe des lignes de code binaire. */ +static void g_code_line_init(GCodeLine *); + +/* Met à jour le nombre d'octets maximal par instruction. */ +void g_code_line_get_binary_len(GCodeLine *, off_t *); + +/* Met à jour la ligne de représentation de code. */ +void g_code_line_refresh_markup(GCodeLine *); + + + +/* Indique le type définit par la GLib pour la ligne. */ +G_DEFINE_TYPE(GCodeLine, g_code_line, G_TYPE_RENDERING_LINE); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des lignes de code binaire.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_code_line_class_init(GCodeLineClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : line = instance à initialiser.                               * +*                                                                             * +*  Description : Initialise la classe des lignes de code binaire.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_code_line_init(GCodeLine *line) +{ +    GRenderingLine *parent;                 /* Instance parente            */ + +    parent = G_RENDERING_LINE(line); + +    parent->offset = 0; + +    parent->type = RLT_CODE; + +    parent->get_bin_len = (get_bin_len_fc)g_code_line_get_binary_len; +    parent->refresh_markup = (refresh_markup_fc)g_code_line_refresh_markup; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : line = ligne de représentation à actualiser.                 * +*                blen = longueur maximale à mettre à jour. [OUT]              * +*                                                                             * +*  Description : Met à jour le nombre d'octets maximal par instruction.       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_code_line_get_binary_len(GCodeLine *line, off_t *blen) +{ +    off_t len;                              /* Taille propre à la ligne    */ + +    get_asm_instr_offset_and_length(line->instr, NULL, &len); + +    *blen = MAX(*blen, len); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : line = ligne de représentation à actualiser.                 * +*                                                                             * +*  Description : Met à jour la ligne de représentation de code.               * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_code_line_refresh_markup(GCodeLine *line) +{ +    size_t len;                             /* Taille du contenu           */ +    char *content;                          /* Contenu réellement imprimé  */ +    off_t bin_offset;                       /* Début de l'instruction      */ +    off_t bin_len;                          /* Taille d'instruction        */ +    char buffer[CODE_BUFFER_LEN];           /* Zone tampon à utiliser      */ +    const uint8_t *exe_content;             /* Contenu binaire global      */ +    char *bin_code;                         /* Tampon du code binaire      */ +    off_t k;                                /* Boucle de parcours #2       */ +    off_t j;                                /* Boucle de parcours #1       */ + +    len = strlen("<tt>") + 1; +    content = (char *)calloc(len, sizeof(char)); +    strcpy(content, "<tt>"); + +    if (line->options->show_code) +        get_asm_instr_offset_and_length(line->instr, &bin_offset, &bin_len); + +    /* Eventuelle adresse virtuelle */ + +    if (line->options->show_address) +    { +        switch (ADM_32BITS  /* FIXME */) +        { +            case ADM_32BITS: +                snprintf(buffer, CODE_BUFFER_LEN, +                         "<span foreground='#333333'>0x%08llx</span>", +                         G_RENDERING_LINE(line)->offset); +                break; + +            case ADM_64BITS: +                snprintf(buffer, CODE_BUFFER_LEN, +                         "<span foreground='#333333'>0x%16llx</span>", +                         G_RENDERING_LINE(line)->offset); +                break; + +        } + +        len += strlen(buffer); +        content = (char *)realloc(content, len * sizeof(char)); +        strcat(content, buffer); + +    } + +    /* Eventuel code brut */ + +    if (line->options->show_code) +    { +        exe_content = get_exe_content(line->options->format, NULL); + +        bin_code = (char *)calloc(G_RENDERING_LINE(line)->max_bin_len + 1, sizeof(char)); + +        k = 0; + +        for (j = 0; j < bin_len; j++) +        { +            if ((j + 1) < bin_len) +                k += snprintf(&bin_code[j * (2 + 1)], 4, "%02hhx ", exe_content[bin_offset + j]); +            else +                k += snprintf(&bin_code[j * (2 + 1)], 3, "%02hhx", exe_content[bin_offset + j]); +        } +  +        for (; k < G_RENDERING_LINE(line)->max_bin_len; k++) +            snprintf(&bin_code[k], 2, " "); + +        if (line->options->show_address) len += strlen("\t"); +        len += strlen(bin_code); +        content = (char *)realloc(content, len * sizeof(char)); +        if (line->options->show_address) strcat(content, "\t"); +        strcat(content, bin_code); + +        free(bin_code); + +    } + +    /* Instruction proprement dite */ + +    print_hinstruction(line->options->proc, line->options->format, +                       line->instr, buffer, CODE_BUFFER_LEN, ASX_INTEL/*FIXME*/); + +    if (line->options->show_address || line->options->show_code) len += strlen("\t"); +    len += strlen(buffer); + +    content = (char *)realloc(content, len * sizeof(char)); +    if (line->options->show_address || line->options->show_code) strcat(content, "\t"); +    strcat(content, buffer); + +    /* Finalisation */ + +    len += strlen("</tt>"); +    content = (char *)realloc(content, len * sizeof(char)); +    strcat(content, "</tt>"); + +    pango_layout_set_markup(G_RENDERING_LINE(line)->layout, content, len - 1); + +    free(content); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : offset  = emplacement physique ou en mémoire.                * +*                instr   = instruction à représenter.                         * +*                options = paramétrage du rendu.                              * +*                                                                             * +*  Description : Crée une ligne de code binaire.                              * +*                                                                             * +*  Retour      : Adresse de la structure mise en place.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GRenderingLine *g_code_line_new(uint64_t offset, asm_instr *instr, const disass_options *options) +{ +    GCodeLine *result;                      /* Structure à retourner       */ + +    result = g_object_new(G_TYPE_CODE_LINE, NULL); + +    G_RENDERING_LINE(result)->offset = offset; + +    result->instr = instr; +    result->options = options; + +    return G_RENDERING_LINE(result); + +}  | 
