diff options
Diffstat (limited to 'src/glibext/gbincontent.c')
-rw-r--r-- | src/glibext/gbincontent.c | 782 |
1 files changed, 0 insertions, 782 deletions
diff --git a/src/glibext/gbincontent.c b/src/glibext/gbincontent.c deleted file mode 100644 index 0230e70..0000000 --- a/src/glibext/gbincontent.c +++ /dev/null @@ -1,782 +0,0 @@ - -/* 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 <http://www.gnu.org/licenses/>. - */ - - -#include "gbincontent.h" - - -#include <assert.h> -#include <fcntl.h> -#include <malloc.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <sys/mman.h> -#include <sys/stat.h> - - -#include "../common/endianness.h" - - - -/* 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 */ - - GChecksum *checksum; /* Calcul de l'empreinte */ - bool cs_computed; /* Calcul effectué ? */ - -}; - -/* 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 *); - -/* Retrouve la zone adaptée pour une localisation de données. */ -static const binary_part *g_binary_content_find_part(const GBinContent *, const vmpa2t *, phys_t *); - - - -/* 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) -{ - content->checksum = g_checksum_new(G_CHECKSUM_SHA256); - assert(content->checksum != NULL); - - content->cs_computed = false; - -} - - -/****************************************************************************** -* * -* 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_checksum_free(content->checksum); - - 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. * -* * -* Description : Fournit une empreinte unique (SHA256) pour les données. * -* * -* Retour : Chaîne représentant l'empreinte du contenu binaire. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const gchar *g_binary_content_get_cheksum(GBinContent *content) -{ - size_t i; /* Boucle de parcours */ - binary_part *part; /* Bloc parcouru pour analyse */ - - if (!content->cs_computed) - { - g_checksum_reset(content->checksum); - - for (i = 0; i < content->count; i++) - { - part = &content->parts[i]; - g_checksum_update(content->checksum, part->data, get_mrange_length(&part->range)); - } - - content->cs_computed = true; - - } - - return g_checksum_get_string(content->checksum); - -} - - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à venir lire. * -* * -* Description : Détermine le nombre d'octets lisibles. * -* * -* Retour : Quantité représentée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -phys_t g_binary_content_compute_size(const GBinContent *content) -{ - phys_t result; /* Quantité trouvée à retourner*/ - size_t i; /* Boucle de parcours */ - - result = 0; - - for (i = 0; i < content->count; i++) - result = get_mrange_length(&content->parts[i].range); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à venir lire. * -* addr = position de la tête de lecture globale demandée. * -* start = position de la tête de lecture dans la zone. [OUT] * -* * -* Description : Retrouve la zone adaptée pour une localisation de données. * -* * -* Retour : Partie trouvée ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static const binary_part *g_binary_content_find_part(const GBinContent *content, const vmpa2t *addr, phys_t *start) -{ - const binary_part *result; /* Trouvaille à retourner */ - size_t i; /* Boucle de parcours */ - binary_part *part; /* Zone mémoire manipulée */ - - result = NULL; - - for (i = 0; i < content->count && result == NULL; i++) - { - part = &content->parts[i]; - - if (mrange_contains_addr(&part->range, addr)) - result = part; - - } - - if (result != NULL) - *start = compute_vmpa_diff(get_mrange_addr(&result->range), addr); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à venir lire. * -* addr = position de la tête de lecture. * -* length = quantité d'octets à lire. * -* * -* Description : Donne accès à une portion des données représentées. * -* * -* Retour : Pointeur vers les données à lire ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const bin_t *g_binary_content_get_raw_access(const GBinContent *content, vmpa2t *addr, phys_t length) -{ - phys_t offset; /* Emplacement de départ */ - - /* FIXME */ - - offset = get_phy_addr(addr); - - if ((offset + length) >= get_mrange_length(&content->parts[0].range)) - return NULL; - - advance_vmpa(addr, length); - - return &content->parts[0].data[offset]; - -} - - -/****************************************************************************** -* * -* 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, vmpa2t *addr, phys_t length, bin_t *out) -{ - bool result; /* Bilan à remonter */ - const bin_t *data; /* Pointeur vers données utiles*/ - - data = g_binary_content_get_raw_access(content, addr, length); - - if (data != NULL) - { - result = true; - memcpy(out, data, length); - } - else - result = false; - - return result; - -} - - - - - - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à venir lire. * -* addr = position de la tête de lecture. * -* low = position éventuelle des 4 bits visés. [OUT] * -* endian = ordre des bits dans la source. * -* val = lieu d'enregistrement de la lecture. [OUT] * -* * -* Description : Lit un nombre non signé sur quatre bits. * -* * -* Retour : Bilan de l'opération : true en cas de succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_binary_content_read_u4(const GBinContent *content, vmpa2t *addr, bool *low, SourceEndian endian, uint8_t *val) -{ - phys_t start; /* Tête de lecture relative */ - const binary_part *part; /* Zone de mémoire effective */ - bin_t *data; /* Contenu binaire représenté */ - - part = g_binary_content_find_part(content, addr, &start); - if (part == NULL) return false; - - if ((get_mrange_length(&part->range) - start) < 1) return false; - - data = part->data; - - if (*low) - { - *val = data[start] & 0x0f; - *low = false; - } - else - { - *val = (data[start] & 0xf0) >> 4; - *low = true; - advance_vmpa(addr, 4); - } - - return true; - -} - - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à venir lire. * -* addr = position de la tête de lecture. * -* val = lieu d'enregistrement de la lecture. [OUT] * -* * -* Description : Lit un nombre non signé sur un octet. * -* * -* Retour : Bilan de l'opération : true en cas de succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_binary_content_read_u8(const GBinContent *content, vmpa2t *addr, uint8_t *val) -{ - phys_t start; /* Tête de lecture relative */ - const binary_part *part; /* Zone de mémoire effective */ - bin_t *data; /* Contenu binaire représenté */ - - part = g_binary_content_find_part(content, addr, &start); - if (part == NULL) return false; - - if ((get_mrange_length(&part->range) - start) < 1) return false; - - data = part->data; - - *val = data[start]; - - advance_vmpa(addr, 1); - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à venir lire. * -* addr = position de la tête de lecture. * -* endian = ordre des bits dans la source. * -* val = lieu d'enregistrement de la lecture. [OUT] * -* * -* Description : Lit un nombre non signé sur deux octets. * -* * -* Retour : Bilan de l'opération : true en cas de succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_binary_content_read_u16(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint16_t *val) -{ - phys_t start; /* Tête de lecture relative */ - const binary_part *part; /* Zone de mémoire effective */ - bin_t *data; /* Contenu binaire représenté */ - - part = g_binary_content_find_part(content, addr, &start); - if (part == NULL) return false; - - if ((get_mrange_length(&part->range) - start) < 2) return false; - - data = part->data; - - switch (endian) - { - case SRE_LITTLE: - -#if __BYTE_ORDER == __LITTLE_ENDIAN - - *val = data[start] | (uint16_t)data[start + 1] << 8; - -#elif __BYTE_ORDER == __BIG_ENDIAN - - *val = data[start + 1] | (uint16_t)data[start] << 8; - -#else - -# error "TODO : extra byte order !" - -#endif - - break; - - case SRE_MIDDLE: - assert(false); /* TODO */ - break; - - case SRE_BIG: - -#if __BYTE_ORDER == __LITTLE_ENDIAN - - *val = data[start + 1] | (uint16_t)data[start] << 8; - -#elif __BYTE_ORDER == __BIG_ENDIAN - - *val = data[start] | (uint16_t)data[start + 1] << 8; - -#else - -# error "TODO : extra byte order !" - -#endif - - break; - - - } - - advance_vmpa(addr, 2); - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à venir lire. * -* addr = position de la tête de lecture. * -* endian = ordre des bits dans la source. * -* val = lieu d'enregistrement de la lecture. [OUT] * -* * -* Description : Lit un nombre non signé sur quatre octets. * -* * -* Retour : Bilan de l'opération : true en cas de succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_binary_content_read_u32(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint32_t *val) -{ - phys_t start; /* Tête de lecture relative */ - const binary_part *part; /* Zone de mémoire effective */ - bin_t *data; /* Contenu binaire représenté */ - - part = g_binary_content_find_part(content, addr, &start); - if (part == NULL) return false; - - if ((get_mrange_length(&part->range) - start) < 4) return false; - - data = part->data; - - switch (endian) - { - case SRE_LITTLE: - -#if __BYTE_ORDER == __LITTLE_ENDIAN - - *val = data[start] | (uint32_t)data[start + 1] << 8; - *val |= data[start + 2] << 16 | (uint32_t)data[start + 3] << 24; - -#elif __BYTE_ORDER == __BIG_ENDIAN - - *val = data[start + 3] | (uint32_t)data[start + 2] << 8; - *val |= data[start + 1] << 16 | (uint32_t)data[start] << 24; - -#else - -# error "TODO : extra byte order !" - -#endif - - break; - - case SRE_MIDDLE: - assert(false); /* TODO */ - break; - - case SRE_BIG: - -#if __BYTE_ORDER == __LITTLE_ENDIAN - - *val = data[start + 3] | (uint32_t)data[start + 2] << 8; - *val |= data[start + 1] << 16 | (uint32_t)data[start] << 24; - -#elif __BYTE_ORDER == __BIG_ENDIAN - - *val = data[start] | (uint32_t)data[start + 1] << 8; - *val |= data[start + 2] << 16 | (uint32_t)data[start + 3] << 24; - -#else - -# error "TODO : extra byte order !" - -#endif - - break; - - - } - - advance_vmpa(addr, 4); - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à venir lire. * -* addr = position de la tête de lecture. * -* endian = ordre des bits dans la source. * -* val = lieu d'enregistrement de la lecture. [OUT] * -* * -* Description : Lit un nombre non signé sur huit octets. * -* * -* Retour : Bilan de l'opération : true en cas de succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_binary_content_read_u64(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint64_t *val) -{ - phys_t start; /* Tête de lecture relative */ - const binary_part *part; /* Zone de mémoire effective */ - bin_t *data; /* Contenu binaire représenté */ - - part = g_binary_content_find_part(content, addr, &start); - if (part == NULL) return false; - - if ((get_mrange_length(&part->range) - start) < 8) return false; - - data = part->data; - - switch (endian) - { - case SRE_LITTLE: - -#if __BYTE_ORDER == __LITTLE_ENDIAN - - *val = (uint64_t)data[start] | (uint64_t)data[start + 1] << 8; - *val |= (uint64_t)data[start + 2] << 16 | (uint64_t)data[start + 3] << 24; - *val |= (uint64_t)data[start + 4] << 32 | (uint64_t)data[start + 5] << 40; - *val |= (uint64_t)data[start + 6] << 48 | (uint64_t)data[start + 7] << 56; - -#elif __BYTE_ORDER == __BIG_ENDIAN - - *val = (uint64_t)data[start + 7] | (uint64_t)data[start + 6] << 8; - *val |= (uint64_t)data[start + 5] << 16 | (uint64_t)data[start + 4] << 24; - *val |= (uint64_t)data[start + 3] << 32 | (uint64_t)data[start + 2] << 40; - *val |= (uint64_t)data[start + 1] << 48 | (uint64_t)data[start] << 56; - -#else - -# error "TODO : extra byte order !" - -#endif - - break; - - case SRE_MIDDLE: - assert(false); /* TODO */ - break; - - case SRE_BIG: - -#if __BYTE_ORDER == __LITTLE_ENDIAN - - *val = (uint64_t)data[start + 7] | (uint64_t)data[start + 6] << 8; - *val |= (uint64_t)data[start + 5] << 16 | (uint64_t)data[start + 4] << 24; - *val |= (uint64_t)data[start + 3] << 32 | (uint64_t)data[start + 2] << 40; - *val |= (uint64_t)data[start + 1] << 48 | (uint64_t)data[start] << 56; - -#elif __BYTE_ORDER == __BIG_ENDIAN - - *val = (uint64_t)data[start] | (uint64_t)data[start + 1] << 8; - *val |= (uint64_t)data[start + 2] << 16 | (uint64_t)data[start + 3] << 24; - *val |= (uint64_t)data[start + 4] << 32 | (uint64_t)data[start + 5] << 40; - *val |= (uint64_t)data[start + 6] << 48 | (uint64_t)data[start + 7] << 56; - -#else - -# error "TODO : extra byte order !" - -#endif - - break; - - - } - - advance_vmpa(addr, 8); - - 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; - -} - - |