diff options
Diffstat (limited to 'src/format/format.c')
-rw-r--r-- | src/format/format.c | 375 |
1 files changed, 375 insertions, 0 deletions
diff --git a/src/format/format.c b/src/format/format.c new file mode 100644 index 0000000..912cdd7 --- /dev/null +++ b/src/format/format.c @@ -0,0 +1,375 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * format.c - support des différents formats binaires + * + * Copyright (C) 2009 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 <http://www.gnu.org/licenses/>. + */ + + +#include "format.h" + + +#include <malloc.h> + + +#include "format-int.h" +#include "dwarf/dwarf.h" +#include "elf/elf.h" +#include "../panel/log.h" + + + +#ifndef _ +# define _(str) str +#endif + + + + +/* ------------------------ TRAITEMENT INDIVIDUEL DE FORMATS ------------------------ */ + + +/* Initialise la classe des formats binaires génériques. */ +static void g_binary_format_class_init(GBinFormatClass *); + +/* Initialise une instance de format binaire générique. */ +static void g_binary_format_init(GBinFormat *); + + + +/* ----------------------- MANIPULATION D'ENSEMBLE DE FORMATS ----------------------- */ + + +/* Format d'exécutables enregistré */ +typedef struct _registered_format +{ + const char *name; /* Désignation du format */ + + FormatType type; /* Type de format */ + + format_match_fc match; /* Procédure de reconnaissance */ + format_load_fc load; /* Fonction de chargement */ + +} registered_format; + + +/* Liste des formats d'exécutables enregistrés */ +static registered_format _formats[FID_COUNT]; + + +#define register_format(id, n, t, m, l) \ + do \ + { \ + _formats[id].name = n; \ + _formats[id].type = t; \ + _formats[id].match = m; \ + _formats[id].load = l; \ + } \ + while (0) + + + +/* ---------------------------------------------------------------------------------- */ +/* TRAITEMENT INDIVIDUEL DE FORMATS */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour un format binaire générique. */ +G_DEFINE_TYPE(GBinFormat, g_binary_format, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des formats binaires génériques. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_format_class_init(GBinFormatClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : format = instance à initialiser. * +* * +* Description : Initialise une instance de format binaire générique. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_format_init(GBinFormat *format) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* content = contenu binaire à parcourir. * +* length = taille du contenu fourni. * +* * +* Description : Définit le contenu binaire à analyser. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_format_set_content(GBinFormat *format, bin_t *content, off_t length) +{ + format->content = content; + format->length = length; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* length = taille du contenu à fournir. [OUT] * +* * +* Description : Fournit une référence vers le contenu binaire analysé. * +* * +* Retour : Adresse du tampon contenant le contenu du binaire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const bin_t *g_binary_format_get_content(const GBinFormat *format, off_t *length) +{ + if (length != NULL) *length = format->length; + + return format->content; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à compléter. * +* symbol = symbole à ajouter à la liste. * +* * +* Description : Ajoute un symbole à la collection du format binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol) +{ + format->symbols = (GBinSymbol **)realloc(format->symbols, + ++format->symbols_count * sizeof(GBinSymbol *)); + + format->symbols[format->symbols_count - 1] = symbol; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* count = taille du tableau créé. [OUT] * +* * +* Description : Fournit la liste de tous les symboles détectés. * +* * +* Retour : Tableau créé ou NULL si aucun symbole trouvé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinSymbol **g_binary_format_get_symbols(const GBinFormat *format, size_t *count) +{ + *count = format->symbols_count; + + return format->symbols; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à compléter. * +* routine = routine à ajouter à la liste. * +* * +* Description : Ajoute une routine à la collection du format binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_format_add_routine(GBinFormat *format, GBinRoutine *routine) +{ + format->routines = (GBinRoutine **)realloc(format->routines, + ++format->routines_count * sizeof(GBinRoutine *)); + + format->routines[format->routines_count - 1] = routine; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* count = taille du tableau créé. [OUT] * +* * +* Description : Fournit le prototype de toutes les routines détectées. * +* * +* Retour : Tableau créé ou NULL si aucun symbole de routine trouvé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinRoutine **g_binary_format_get_routines(const GBinFormat *format, size_t *count) +{ + *count = format->routines_count; + + return format->routines; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* label = étiquette du symbole si trouvé. [OUT] * +* type = type du symbole trouvé. [OUT] * +* address = adresse à cibler, puis décallage final. [OUT] * +* * +* Description : Recherche le symbole correspondant à une adresse. * +* * +* Retour : true si l'opération a été un succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_format_resolve_symbol(const GBinFormat *format, const char **label, SymbolType *type, vmpa_t *address) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + vmpa_t addr; /* Adresse de symbole */ + off_t size; /* Taille du symole */ + + result = false; + + for (i = 0; i < format->symbols_count && !result; i++) + { + addr = g_binary_symbol_get_address(format->symbols[i]); + size = g_binary_symbol_get_size(format->symbols[i]); + + if (addr <= *address && *address < (addr + size)) + { + *label = g_binary_symbol_to_string(format->symbols[i]); + *type = g_binary_symbol_get_target_type(format->symbols[i]); + *address -= addr; + + if (*type == STP_STRING) + *label += *address; + + result = true; + + } + + } + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* MANIPULATION D'ENSEMBLE DE FORMATS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Procède au chargement des formats binaires reconnus. * +* * +* Retour : true pour indiquer un chargement réussi, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool init_all_formats(void) +{ + register_format(FID_ELF, _("ELF"), FMT_EXEC, elf_is_matching, g_elf_format_new); + register_format(FID_DWARF, _("Dwarf"), FMT_DEBUG, dwarf_is_matching, g_dwarf_format_new); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type de format recherché. * +* content = contenu binaire à parcourir. * +* length = taille du contenu en question. * +* * +* Description : Charge si possible un nouveau format binaire. * +* * +* Retour : Adresse du nouveau gestionnaire de format ou NULL si erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinFormat *load_new_format(FormatType type, const uint8_t *content, off_t length) +{ + GBinFormat *result; /* Adresse à retourner */ + size_t i; /* Boucle de parcours */ + + result = NULL; + + for (i = 0; i < FID_COUNT && result == NULL; i++) + if (_formats[i].type == type && _formats[i].match(type, content, length)) + { + log_variadic_message(LMT_INFO, _("%s is matching..."), _formats[i].name); + + result = _formats[i].load(content, length); + + } + + return result; + +} |