/* Chrysalide - Outil d'analyse de fichiers binaires * gbincontent.c - prototypes pour le chargement de données binaires en mémoire * * Copyright (C) 2015 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 "gbincontent.h" #include #include #include #include #include #include #include /* Aire de contenu binaire */ typedef struct _binary_part { bin_t *data; /* Contenu binaire représenté */ mrange_t range; /* Couverture du binaire */ } binary_part; /* Content de données binaires quelconques (instance) */ struct _GBinContent { GObject parent; /* A laisser en premier */ binary_part *parts; /* Parties prises en compte */ size_t count; /* Nombre de ces parties */ }; /* Content de données binaires quelconques (classe) */ struct _GBinContentClass { GObjectClass parent; /* A laisser en premier */ }; /* Initialise la classe des contenus de données binaires. */ static void g_binary_content_class_init(GBinContentClass *); /* Initialise une instance de contenu de données binaires. */ static void g_binary_content_init(GBinContent *); /* Supprime toutes les références externes. */ static void g_binary_content_dispose(GBinContent *); /* Procède à la libération totale de la mémoire. */ static void g_binary_content_finalize(GBinContent *); /* Indique le type défini par la GLib pour les contenus de données. */ G_DEFINE_TYPE(GBinContent, g_binary_content, G_TYPE_OBJECT); /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * * * * Description : Initialise la classe des contenus de données binaires. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_binary_content_class_init(GBinContentClass *klass) { GObjectClass *object; /* Autre version de la classe */ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_binary_content_dispose; object->finalize = (GObjectFinalizeFunc)g_binary_content_finalize; } /****************************************************************************** * * * Paramètres : content = instance à initialiser. * * * * Description : Initialise une instance de contenu de données binaires. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_binary_content_init(GBinContent *content) { } /****************************************************************************** * * * Paramètres : content = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_binary_content_dispose(GBinContent *content) { G_OBJECT_CLASS(g_binary_content_parent_class)->dispose(G_OBJECT(content)); } /****************************************************************************** * * * Paramètres : content = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_binary_content_finalize(GBinContent *content) { size_t i; /* Boucle de parcours */ for (i = 0; i < content->count; i++) free(content->parts[i].data); if (content->parts != NULL) free(content->parts); G_OBJECT_CLASS(g_binary_content_parent_class)->finalize(G_OBJECT(content)); } /****************************************************************************** * * * Paramètres : filename = chemin d'accès au fichier à charger. * * * * Description : Charge en mémoire le contenu d'un fichier donné. * * * * Retour : Représentation de contenu à manipuler ou NULL en cas d'échec.* * * * Remarques : - * * * ******************************************************************************/ GBinContent *g_binary_content_new_from_file(const char *filename) { GBinContent *result; /* Structure à retourner */ int fd; /* Descripteur du fichier */ struct stat info; /* Informations sur le fichier */ int ret; /* Bilan d'un appel */ void *content; /* Contenu brut du fichier */ vmpa2t base; /* Localisation des données */ /* Récupération des données */ fd = open(filename, O_RDONLY); if (fd == -1) { perror("open"); goto gbcnff_error; } ret = fstat(fd, &info); if (ret == -1) { close(fd); perror("fstat"); goto gbcnff_error; } content = mmap(NULL, info.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (content == MAP_FAILED) { close(fd); perror("mmap"); goto gbcnff_error; } /* Constitution du contenu officiel */ result = g_object_new(G_TYPE_BIN_CONTENT, NULL); result->parts = (binary_part *)calloc(1, sizeof(binary_part)); result->count = 1; result->parts[0].data = (bin_t *)malloc(info.st_size); memcpy(result->parts[0].data, content, info.st_size); munmap(content, info.st_size); close(fd); init_vmpa(&base, 0, VMPA_NO_VIRTUAL); init_mrange(&result->parts[0].range, &base, info.st_size); return result; gbcnff_error: return NULL; } /****************************************************************************** * * * Paramètres : content = contenu binaire à venir lire. * * addr = position de la tête de lecture. * * length = quantité d'octets à lire. * * out = réceptacle disponible pour ces données. [OUT] * * * * Description : Fournit une portion des données représentées. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool g_binary_content_get_raw(const GBinContent *content, const vmpa2t *addr, phys_t length, bin_t *out) { /* FIXME */ memcpy(out, &content->parts[0].data[get_phy_addr(addr)], length); return true; } const bin_t *g_binary_content_get(GBinContent *content, off_t *length) { *length = content->parts[0].range.length; return content->parts[0].data; }