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; - -} - -  | 
