/* 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 . */ #include "line_code.h" #include #include #include "line-int.h" #include "../format/format.h" /* Ligne de représentation de code binaire (instance) */ struct _GCodeLine { GRenderingLine parent; /* Instance parente */ GArchInstruction *instr; /* Instruction représentée */ const GRenderingOptions *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 *, MainRendering); /* 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->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 */ g_arch_instruction_get_location(line->instr, NULL, &len, NULL); *blen = MAX(*blen, len); } /****************************************************************************** * * * Paramètres : line = ligne de représentation à actualiser. * * rendering = support effectif final des lignes de code. * * * * Description : Met à jour la ligne de représentation de code. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_code_line_refresh_markup(GCodeLine *line, MainRendering rendering) { bool show_address; /* Affichage de l'adresse ? */ bool show_code; /* Affichage du code brut ? */ 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 #1 */ char *buffer2; /* Zone tampon à utiliser #2 */ const uint8_t *exe_content; /* Contenu binaire global */ const off_t *max_bin_len; /* Taille de ligne max/globale */ char *bin_code; /* Tampon du code binaire */ off_t k; /* Boucle de parcours #2 */ off_t j; /* Boucle de parcours #1 */ show_address = g_rendering_options_has_to_show_address(line->options, rendering); show_code = g_rendering_options_has_to_show_code(line->options, rendering); len = strlen("") + 1; content = (char *)calloc(len, sizeof(char)); strcpy(content, ""); if (show_code) g_arch_instruction_get_location(line->instr, &bin_offset, &bin_len, NULL); /* Eventuelle adresse virtuelle */ if (show_address) { switch (g_arch_processor_get_memory_size(g_rendering_options_get_processor(line->options))) { case MDS_8_BITS: snprintf(buffer, CODE_BUFFER_LEN, "0x%02llx", G_RENDERING_LINE(line)->offset); break; case MDS_16_BITS: snprintf(buffer, CODE_BUFFER_LEN, "0x%04llx", G_RENDERING_LINE(line)->offset); break; case MDS_32_BITS: snprintf(buffer, CODE_BUFFER_LEN, "0x%08llx", G_RENDERING_LINE(line)->offset); break; default: case MDS_64_BITS: snprintf(buffer, CODE_BUFFER_LEN, "0x%16llx", G_RENDERING_LINE(line)->offset); break; } len += strlen(buffer); content = (char *)realloc(content, len * sizeof(char)); strcat(content, buffer); } /* Eventuel code brut */ if (show_code) { exe_content = g_binary_format_get_content(G_BIN_FORMAT(g_rendering_options_get_format(line->options)), NULL); max_bin_len = &G_RENDERING_LINE(line)->max_bin_len[rendering]; bin_code = (char *)calloc(*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 < *max_bin_len; k++) snprintf(&bin_code[k], 2, " "); if (show_address) len += strlen("\t"); len += strlen(bin_code); content = (char *)realloc(content, len * sizeof(char)); if (show_address) strcat(content, "\t"); strcat(content, bin_code); free(bin_code); } /* Instruction proprement dite */ buffer2 = g_arch_instruction_get_text(line->instr, g_rendering_options_get_format(line->options), ASX_INTEL/*FIXME*/); if (show_address || show_code) len += strlen("\t"); len += strlen(buffer2); content = (char *)realloc(content, len * sizeof(char)); if (show_address || show_code) strcat(content, "\t"); strcat(content, buffer2); free(buffer2); /* Finalisation */ len += strlen(""); content = (char *)realloc(content, len * sizeof(char)); strcat(content, ""); pango_layout_set_markup(G_RENDERING_LINE(line)->layout[rendering], 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, GArchInstruction *instr, const GRenderingOptions *options) { GCodeLine *result; /* Structure à retourner */ result = g_object_new(G_TYPE_CODE_LINE, NULL); G_RENDERING_LINE(result)->offset = offset; g_arch_instruction_get_location(instr, NULL, &G_RENDERING_LINE(result)->length, NULL); result->instr = instr; result->options = options; return G_RENDERING_LINE(result); } /****************************************************************************** * * * Paramètres : line = line de rendu à consulter. * * * * Description : Fournit l'instruction associée à la ligne de code binaire. * * * * Retour : Adresse de l'instruction associée. * * * * Remarques : - * * * ******************************************************************************/ GArchInstruction *g_code_line_get_instruction(const GCodeLine *line) { return line->instr; }