/* Chrysalide - Outil d'analyse de fichiers binaires * executable.c - support des formats d'exécutables * * Copyright (C) 2009-2013 Cyrille Bagard * * This file is part of Chrysalide. * * Chrysalide 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. * * Chrysalide 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 "executable.h" #include #include #include "executable-int.h" #include "format.h" /* Initialise la classe des formats d'exécutables génériques. */ static void g_executable_format_class_init(GExeFormatClass *); /* Initialise une instance de format d'exécutable générique. */ static void g_executable_format_init(GExeFormat *); /* Indique le type défini pour un format d'exécutable générique. */ G_DEFINE_TYPE(GExeFormat, g_executable_format, G_TYPE_BIN_FORMAT); /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * * * * Description : Initialise la classe des formats d'exécutables génériques. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_executable_format_class_init(GExeFormatClass *klass) { } /****************************************************************************** * * * Paramètres : format = instance à initialiser. * * * * Description : Initialise une instance de format d'exécutable générique. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_executable_format_init(GExeFormat *format) { } /****************************************************************************** * * * Paramètres : format = informations chargées à compléter. * * info = informations de débogage à lier. * * * * Description : Rajoute des informations de débogage à un exécutable. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_exe_format_add_debug_info(GExeFormat *format, GDbgFormat *info) { /* Ajout dans la liste */ format->debugs = (GDbgFormat **)realloc(format->debugs, ++format->debugs_count * sizeof(GDbgFormat *)); format->debugs[format->debugs_count - 1] = info; /* Intégration des symboles */ /* TODO */ } /****************************************************************************** * * * Paramètres : format = informations chargées à consulter. * * * * Description : Compte le nombre de formats de débogage liés à l'exécutable. * * * * Retour : Nombre de formats de débogage attachés. * * * * Remarques : - * * * ******************************************************************************/ size_t g_exe_format_count_debug_info(const GExeFormat *format) { return format->debugs_count; } /****************************************************************************** * * * Paramètres : format = informations chargées à consulter. * * index = indice des informations à transmettre. * * * * Description : Fournit un format de débogage attaché à l'exécutable. * * * * Retour : Informations de débogage attachées. * * * * Remarques : - * * * ******************************************************************************/ GDbgFormat *g_exe_format_get_debug_info(const GExeFormat *format, size_t index) { GDbgFormat *result; /* Format à retourner */ if (index >= format->debugs_count) result = NULL; else { result = format->debugs[index]; g_object_ref(G_OBJECT(result)); } return result; } /****************************************************************************** * * * Paramètres : format = informations chargées à consulter. * * * * Description : Indique le type d'architecture visée par le format. * * * * Retour : Identifiant de l'architecture ciblée par le format. * * * * Remarques : - * * * ******************************************************************************/ const char *g_exe_format_get_target_machine(const GExeFormat *format) { return G_EXE_FORMAT_GET_CLASS(format)->get_machine(format); } /****************************************************************************** * * * Paramètres : format = description de l'exécutable à consulter. * * * * Description : Fournit la première couche des portions composent le binaire.* * * * Retour : Couche brute des différentes portions. * * * * Remarques : Le compteur de références de l'instance renvoyée doit être * * décrémenté après usage. * * * ******************************************************************************/ GPortionLayer *g_exe_format_get_main_layer(GExeFormat *format) { GBinPortion *portion; /* Portion brute globale */ vmpa2t addr; /* Emplacement vide de sens */ phys_t length; /* Taille de portion globale */ GPortionLayer *layer; /* Couche à mettre en place */ if (format->layers == NULL) { /* Création d'une portion globale */ portion = g_binary_portion_new(BPC_RAW); init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); length = g_binary_content_compute_size(G_BIN_FORMAT(format)->content); g_binary_portion_set_values(portion, &addr, length); /* Création d'une couche de base brute */ layer = g_portion_layer_new(length, NULL); g_portion_layer_include(layer, portion); /* Remplissage */ G_EXE_FORMAT_GET_CLASS(format)->refine_portions(format, layer); format->layers = layer; } g_object_ref(G_OBJECT(format->layers)); return format->layers; } /****************************************************************************** * * * Paramètres : format = informations chargées à consulter. * * count = quantité de zones listées. [OUT] * * * * Description : Fournit les espaces mémoires des portions exécutables. * * * * Retour : Liste de zones binaires exécutables à libérer après usage. * * * * Remarques : - * * * ******************************************************************************/ mrange_t *g_exe_format_get_x_ranges(GExeFormat *format, size_t *count) { mrange_t *result; /* Liste à retourner */ typedef struct _x_ranges { mrange_t *list; size_t length; } x_ranges; x_ranges tmp; /* Sauvegarde de la liste */ GPortionLayer *layer; /* Couche première de portions */ bool visit_for_x(GBinPortion *portion, x_ranges *ranges) { const mrange_t *range; if (g_binary_portion_get_rights(portion) & PAC_EXEC) { range = g_binary_portion_get_range(portion); ranges->list = (mrange_t *)realloc(ranges->list, ++ranges->length * sizeof(mrange_t)); copy_mrange(&ranges->list[ranges->length - 1], range); } return true; } tmp.list = NULL; tmp.length = 0; layer = g_exe_format_get_main_layer(format); g_portion_layer_visit(format->layers, (visit_portion_fc)visit_for_x, &tmp); g_object_unref(G_OBJECT(layer)); result = tmp.list; *count = tmp.length; return result; } /****************************************************************************** * * * Paramètres : format = description de l'exécutable à consulter. * * off = position physique à retrouver. * * pos = position correspondante. [OUT] * * * * Description : Fournit l'emplacement correspondant à une position physique. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool g_exe_format_translate_offset_into_vmpa(const GExeFormat *format, phys_t off, vmpa2t *pos) { bool result; /* Bilan à retourner */ result = G_EXE_FORMAT_GET_CLASS(format)->translate_phys(format, off, pos); return result; } /****************************************************************************** * * * Paramètres : format = description de l'exécutable à consulter. * * addr = adresse virtuelle à retrouver. * * pos = position correspondante. [OUT] * * * * Description : Fournit l'emplacement correspondant à une adresse virtuelle. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool g_exe_format_translate_address_into_vmpa(const GExeFormat *format, virt_t addr, vmpa2t *pos) { bool result; /* Bilan à retourner */ result = G_EXE_FORMAT_GET_CLASS(format)->translate_virt(format, addr, pos); return result; } /****************************************************************************** * * * Paramètres : format = description de l'exécutable à consulter. * * name = nom de la section recherchée. * * range = emplacement en mémoire à renseigner. [OUT] * * * * Description : Fournit l'emplacement d'une section donnée. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool g_exe_format_get_section_range_by_name(const GExeFormat *format, const char *name, mrange_t *range) { bool result; /* Bilan à retourner */ result = G_EXE_FORMAT_GET_CLASS(format)->get_range_by_name(format, name, range); return result; }