summaryrefslogtreecommitdiff
path: root/src/glibext/gbincontent.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/glibext/gbincontent.c')
-rw-r--r--src/glibext/gbincontent.c782
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;
-
-}
-
-