/* Chrysalide - Outil d'analyse de fichiers binaires * fetch.c - récupération d'instructions à partir de binaire brut * * Copyright (C) 2010-2014 Cyrille Bagard * * This file is part of Chrysalide. * * 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" #include #include #include "area.h" /* Suit un flot d'exécution pour désassembler du code. */ static void follow_execution_flow(const GLoadedBinary *, GProcContext *, mem_area **, size_t *, status_blob_info *); /* S'assure que l'ensemble des aires est entièrement décodé. */ static void ensure_all_mem_areas_are_filled(mem_area **, size_t *, const GLoadedBinary *, GProcContext *, status_blob_info *); /****************************************************************************** * * * Paramètres : binary = représentation de binaire chargé. * * ctx = contexte offert en soutien à un désassemblage. * * areas = liste de zones contenant des données à traiter. * * count = nombre de ces aires à disposition. * * info = informations liées à l'affichage de la progression. * * * * Description : Suit un flot d'exécution pour désassembler du code. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void follow_execution_flow(const GLoadedBinary *binary, GProcContext *ctx, mem_area **areas, size_t *count, status_blob_info *info) { virt_t virt; /* Adresse de départ dépilée */ vmpa2t addr; /* Conversion en pleine adresse*/ GExeFormat *format; /* Format du fichier binaire */ size_t index; /* Zone trouvée à traiter */ while (g_proc_context_has_drop_points(ctx)) { virt = g_proc_context_pop_drop_point(ctx); format = g_loaded_binary_get_format(binary); if (!g_exe_format_translate_address_into_vmpa(format, virt, &addr)) init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); printf(" ++ point 0x%08x\n", (unsigned int)virt); printf("looking area for 0x%08x\n", (unsigned int)virt); index = find_memory_area_by_addr(*areas, *count, &addr); if (index == *count) continue; assert(index < *count); load_code_from_mem_area(areas, count, &index, binary, ctx, &addr, info); printf(" ++\n"); } } /****************************************************************************** * * * Paramètres : list = liste de zones délimitant des contenus à traiter. * * count = nombre de zones à disposition. * * binary = représentation de binaire chargé. * * ctx = contexte offert en soutien à un désassemblage. * * info = indications quant à la progression à afficher. * * * * Description : S'assure que l'ensemble des aires est entièrement décodé. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void ensure_all_mem_areas_are_filled(mem_area **list, size_t *count, const GLoadedBinary *binary, GProcContext *ctx, status_blob_info *info) { size_t i; /* Boucle de parcours */ for (i = 0; i < *count; i++) fill_mem_area(list, count, &i, binary, ctx, info); } /****************************************************************************** * * * Paramètres : binary = représentation de binaire chargé. * * 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_content(const GLoadedBinary *binary, GtkExtStatusBar *statusbar) { GArchInstruction *result; /* Instruction désassemblées */ GBinFormat *format; /* Format du fichier binaire */ GArchProcessor *proc; /* Architecture du binaire */ GProcContext *ctx; /* Contexte de désassemblage */ GBinContent *content; /* Contenu binaire à manipuler */ phys_t length; /* Taille des données à lire */ mem_area *areas; /* Zone de productions */ size_t count; /* Nombre de ces zones */ status_blob_info *info; /* Informations de progression */ double done; /* Portion de travail accompli */ format = G_BIN_FORMAT(g_loaded_binary_get_format(binary)); proc = g_loaded_binary_get_processor(binary); ctx = g_arch_processor_get_context(proc); g_binary_format_setup_disassembling_context(format, ctx); /* Définition à la découpe des parties à traiter */ content = g_binary_format_get_content(format); length = g_binary_content_compute_size(content); areas = compute_memory_areas(G_EXE_FORMAT(format), length, &count); /** * Première phase de désassemblage : suivi des chemins tracés. */ info = init_progessive_status(statusbar, _("Disassembling following the execution flow..."), 0, length); follow_execution_flow(binary, ctx, &areas, &count, info); done = get_current_progessive_status(info); fini_progessive_status(info); /** * Seconde phase : on comble les trous laissés. */ info = init_progessive_status(statusbar, _("Disassembling the remaining instructions..."), done, length); ensure_all_mem_areas_are_filled(&areas, &count, binary, ctx, info); fini_progessive_status(info); /** * Troisième et dernière phase : récolte des fruits. */ info = init_progessive_status(statusbar, _("Collecting disassembled instructions..."), 0, length); result = collect_instructions_from_mem_areas(areas, count); fini_progessive_status(info); /* free */ g_object_unref(G_OBJECT(content)); g_object_unref(G_OBJECT(proc)); return result; }