/* OpenIDA - Outil d'analyse de fichiers binaires * fetch.c - récupération d'instructions à partir de binaire brut * * Copyright (C) 2010-2012 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 "fetch.h" #ifdef DEBUG # include "../../arch/artificial.h" #endif /****************************************************************************** * * * Paramètres : binary = représentation de binaire chargé. * * parts = parties binaires à désassembler. * * count = nombre de parties à traiter. * * statusbar = barre de statut avec progression à mettre à jour.* * id = identifiant du message affiché à l'utilisateur. * * * * Description : Procède au désassemblage basique d'un contenu binaire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ GArchInstruction *disassemble_binary_parts(const GLoadedBinary *binary, GBinPart **parts, size_t count, GtkExtStatusBar *statusbar, guint id) { GArchInstruction *result; /* Liste d'instr. à renvoyer */ GBinFormat *format; /* Format du fichier binaire */ GArchProcessor *proc; /* Architecture du binaire */ off_t bin_length; /* Taille des données à lire */ bin_t *bin_data; /* Données binaires à lire */ size_t i; /* Boucle de parcours #1 */ off_t sum; /* Somme de toutes les tailles */ off_t done; /* Quantité déjà traitée */ #ifdef DEBUG unsigned int valid; /* Instructions traduites */ unsigned int db; /* Instructions non décodées */ #endif off_t pos; /* Début d'une zone binaire */ off_t len; /* Taille de cette même zone */ vmpa_t base; /* Adresse de la zone binaire */ off_t start; /* Conservation du pt de départ*/ GProcContext *context; /* Contexte pour le décodage */ vmpa_t addr; /* Adresse d'une instruction */ GArchInstruction *instr; /* Instruction décodée */ result = NULL; format = G_BIN_FORMAT(g_loaded_binary_get_format(binary)); proc = get_arch_processor_from_format(G_EXE_FORMAT(format)); bin_data = g_loaded_binary_get_data(binary, &bin_length); /* Préparation du suivi de la progression */ sum = 0; for (i = 0; i < count; i++) { g_binary_part_get_values(parts[i], NULL, &len, NULL); if (len > bin_length) continue; sum += len; } done = 0; for (i = 0; i < count; i++) { g_binary_part_get_values(parts[i], &pos, &len, &base); if (len > bin_length) continue; context = g_arch_processor_get_context(proc); /* Décodage des instructions */ #ifdef DEBUG valid = 0; db = 0; #endif start = pos; pos = 0; while (pos < len) { addr = base + pos; instr = g_arch_processor_decode_instruction(proc, context, &bin_data[start], &pos, len, start, addr, format); g_arch_instruction_add_to_list(&result, instr); #ifdef DEBUG if (G_IS_DB_INSTRUCTION(instr) && !g_db_instruction_is_skipped(G_DB_INSTRUCTION(instr))) db++; else valid++; #endif if (pos < len) gtk_extended_status_bar_update_activity(statusbar, id, (done + pos) * 1.0 / sum); } if (context != NULL) g_object_unref(context); #ifdef DEBUG g_binary_part_set_checkup(parts[i], valid, db); #endif done += len; gtk_extended_status_bar_update_activity(statusbar, id, done * 1.0 / sum); } return result; }