/* 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. * * 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 "executable.h" #include "executable-int.h" #include "format.h" #include /* 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 à consulter. * * * * Description : Indique le type d'architecture visée par le format. * * * * Retour : Identifiant de l'architecture ciblée par le format. * * * * Remarques : - * * * ******************************************************************************/ FormatTargetMachine g_exe_format_get_target_machine(const GExeFormat *format) { return format->get_machine(format); } /****************************************************************************** * * * Paramètres : format = informations chargées à consulter. * * * * Description : Fournit l'adresse mémoire du point d'entrée du programme. * * * * Retour : Adresse de mémoire. * * * * Remarques : - * * * ******************************************************************************/ vmpa_t g_exe_format_get_entry_point(const GExeFormat *format) { return format->get_entry_point(format); } /****************************************************************************** * * * Paramètres : format = description de l'exécutable à consulter. * * * * Description : Décrit les différentes portions qui composent le binaire. * * * * Retour : Défintions de zones. * * * * Remarques : - * * * ******************************************************************************/ GBinPortion *g_exe_format_get_portions(GExeFormat *format) { vmpa2t addr; /* Emplacement vide de sens */ if (format->portions == NULL) { format->portions = g_binary_portion_new(BPC_RAW); init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); g_binary_portion_set_values(format->portions, &addr, G_BIN_FORMAT(format)->length); if (format->refine_portions != NULL) format->refine_portions(format, format->portions); } return format->portions; } /****************************************************************************** * * * Paramètres : format = description de l'exécutable à consulter. * * level = étage des portions à considérer ou -1 pour tous. * * count = nombre de portions trouvées et renvoyées. [OUT] * * * * Description : Fournit une liste choisie de portions d'un binaire. * * * * Retour : Liste de définitins de zones à libérer après usage. * * * * Remarques : - * * * ******************************************************************************/ GBinPortion **g_exe_format_get_portions_at_level(GExeFormat *format, unsigned int level, size_t *count) { GBinPortion **result; /* Liste à retourner */ typedef struct _portions_list { unsigned int required; GBinPortion **portions; size_t length; } portions_list; portions_list list; /* Sauvegarde de la liste */ bool visit_for_level(GBinPortion *portion, portions_list *list) { if (list->required == -1 || g_binary_portion_get_level(portion) == list->required) { list->portions = (GBinPortion **)realloc(list->portions, ++list->length * sizeof(GBinPortion *)); list->portions[list->length - 1] = portion; } return true; } list.required = level; list.portions = NULL; list.length = 0; g_binary_portion_visit(g_exe_format_get_portions(format), (visit_portion_fc)visit_for_level, &list); result = list.portions; *count = list.length; qsort(result, *count, sizeof(GBinPortion *), (__compar_fn_t)g_binary_portion_compare); return result; } /****************************************************************************** * * * 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 */ 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; g_binary_portion_visit(g_exe_format_get_portions(format), (visit_portion_fc)visit_for_x, &tmp); result = tmp.list; *count = tmp.length; return result; } /****************************************************************************** * * * Paramètres : format = informations chargées à consulter. * * count = quantité de zones listées. [OUT] * * * * Description : Fournit les références aux zones binaires à analyser. * * * * Retour : Zones binaires à analyser. * * * * Remarques : - * * * ******************************************************************************/ GBinPart **g_exe_format_get_parts(const GExeFormat *format, size_t *count) { return format->get_parts(format, count); } /****************************************************************************** * * * Paramètres : format = description de l'exécutable à consulter. * * addr = adresse virtuelle à retrouver. * * pos = position correspondante. [OUT] * * * * Description : Fournit la position correspondant à une adresse virtuelle. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool g_exe_format_translate_address_into_offset(const GExeFormat *format, vmpa_t addr, off_t *pos) { return format->translate_addr(format, addr, pos); } /****************************************************************************** * * * Paramètres : format = description de l'exécutable à consulter. * * pos = position dans le flux binaire à retrouver. * * addr = adresse virtuelle correspondante. [OUT] * * * * Description : Fournit l'adresse virtuelle correspondant à une position. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool g_exe_format_translate_offset_into_address(const GExeFormat *format, off_t pos, vmpa_t *addr) { return format->translate_off(format, pos, addr); }