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); + +} |