diff options
Diffstat (limited to 'src/format')
| -rw-r--r-- | src/format/Makefile.am | 1 | ||||
| -rw-r--r-- | src/format/format.c | 91 | ||||
| -rw-r--r-- | src/format/format.h | 3 | ||||
| -rw-r--r-- | src/format/strsym.c | 474 | ||||
| -rw-r--r-- | src/format/strsym.h | 80 | ||||
| -rw-r--r-- | src/format/symbol.h | 5 | 
6 files changed, 558 insertions, 96 deletions
diff --git a/src/format/Makefile.am b/src/format/Makefile.am index 504055d..8a47b82 100644 --- a/src/format/Makefile.am +++ b/src/format/Makefile.am @@ -12,6 +12,7 @@ libformat_la_SOURCES =					\  	format.h format.c					\  	preload-int.h						\  	preload.h preload.c					\ +	strsym.h strsym.c					\  	symiter.h symiter.c					\  	symbol-int.h						\  	symbol.h symbol.c diff --git a/src/format/format.c b/src/format/format.c index 449f0f0..91cca37 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -25,7 +25,6 @@  #include <assert.h> -#include <ctype.h>  #include <malloc.h>  #include <string.h> @@ -957,96 +956,6 @@ static void g_binary_format_delete_duplicated_symbols(GBinFormat *format)  /******************************************************************************  *                                                                             *  *  Paramètres  : format = informations chargées à consulter.                  * -*                addr   = adresse liée à la chaîne à traiter.                 * -*                length = taille de la chaîne à représenter.                  * -*                                                                             * -*  Description : Construit une désignation pour chaîne de caractères.         * -*                                                                             * -*  Retour      : Chaîne de caractères à libérer de la mémoire.                * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -char *create_string_label(GBinFormat *format, const vmpa2t *addr, size_t length) -{ -    char *result;                           /* Nouvelle chaîne à retourner */ -    vmpa2t pos;                             /* Tête de lecture modifiable  */ -    const bin_t *base;                      /* Contenu complet et original */ -    unsigned int wc;                        /* Nombre de mots rencontrés   */ -    size_t iter;                            /* Tête d'écriture de recopie  */ -    size_t i;                               /* Boucle de parcours          */ -    bool empty;                             /* Base de l'étiquette vide ?  */ -    GBinSymbol *found;                      /* Symbole similaire trouvé    */ -    VMPA_BUFFER(last_sfx);                  /* Dernier suffixe à intégrer  */ - -    copy_vmpa(&pos, addr); - -    base = g_binary_content_get_raw_access(format->content, &pos, length); - -    if (base == NULL) -        return NULL; - -    result = (char *)calloc(length + 5 + VMPA_MAX_LEN + 1, sizeof(char)); - -    wc = 0; - -    iter = 0; - -    for (i = 0; i < length; i++) -    { -        if (isalnum(base[i])) result[iter++] = tolower(base[i]); - -        else if (iter > 0) -        { -            if (result[iter - 1] != '_') wc++; - -            if (wc == 3) break; - -            if (result[iter - 1] != '_') result[iter++] = '_'; - -        } - -    } - -    /* Détermination du suffixe suffisant */ - -    empty = (iter == 0); - -    if (iter > 0 && result[iter - 1] != '_') result[iter++] = '_'; - -    strcpy(&result[iter], "str"); -    iter += 3; - -    found = NULL; - -    if (empty || g_binary_format_find_symbol_by_label(format, result, &found)) -    { -        if (found != NULL) -            g_object_unref(G_OBJECT(found)); - -        if (iter > 0 && result[iter - 1] != '_') result[iter++] = '_'; - -        assert(has_phys_addr(addr) || has_virt_addr(addr)); - -        /* TODO : use_phy_instead_of_virt */ -        if (has_virt_addr(addr)) -            vmpa2_virt_to_string(addr, MDS_UNDEFINED, last_sfx, NULL); -        else -            vmpa2_phys_to_string(addr, MDS_UNDEFINED, last_sfx, NULL); - -        strcpy(&result[iter], last_sfx); - -    } - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : format = informations chargées à consulter.                  *  *                label  = étiquette à retrouver lors des recherches.          *  *                symbol = éventuel symbole trouvé à déréfenrencer. [OUT]      *  *                                                                             * diff --git a/src/format/format.h b/src/format/format.h index 372b3b0..a9152ba 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -132,9 +132,6 @@ bool g_binary_format_add_symbol(GBinFormat *, GBinSymbol *);  /* Retire un symbole de la collection du format binaire. */  void g_binary_format_remove_symbol(GBinFormat *, GBinSymbol *); -/* Construit une désignation pour chaîne de caractères. */ -char *create_string_label(GBinFormat *, const vmpa2t *, size_t); -  /* Recherche le symbole correspondant à une étiquette. */  bool g_binary_format_find_symbol_by_label(GBinFormat *, const char *, GBinSymbol **); diff --git a/src/format/strsym.c b/src/format/strsym.c new file mode 100644 index 0000000..b709b93 --- /dev/null +++ b/src/format/strsym.c @@ -0,0 +1,474 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * strsym.c - gestion des chaînes dans un binaire + * + * Copyright (C) 2018 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide 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. + * + *  Chrysalide 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 Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "strsym.h" + + +#include <assert.h> +#include <ctype.h> +#include <malloc.h> +#include <string.h> + + +#include "symbol-int.h" +#include "../common/alloc.h" + + + +/* ----------------------- VITRINE POUR CHAINES DE CARACTERES ----------------------- */ + + +/* Symbole pour chaîne de caractères (instance) */ +struct _GStrSymbol +{ +    GBinSymbol parent;                      /* A laisser en premier        */ + +    StringEncodingType encoding;            /* Encodage de la chaîne liée  */ + +    union +    { +        GBinContent *content;               /* Conteneur d'origine         */ +        char *utf8;                         /* Données utilisables         */ + +    }; + +    bool has_content;                       /* Choix dans l'union          */ + +}; + +/* Symbole pour chaîne de caractères (classe) */ +struct _GStrSymbolClass +{ +    GBinSymbolClass parent;                 /* A laisser en premier        */ + +}; + + +/* Initialise la classe des chaînes de caractères. */ +static void g_string_symbol_class_init(GStrSymbolClass *); + +/* Initialise une instance de chaîne de caractères. */ +static void g_string_symbol_init(GStrSymbol *); + +/* Supprime toutes les références externes. */ +static void g_string_symbol_dispose(GStrSymbol *); + +/* Procède à la libération totale de la mémoire. */ +static void g_string_symbol_finalize(GStrSymbol *); + + + +/* ---------------------------------------------------------------------------------- */ +/*                         VITRINE POUR CHAINES DE CARACTERES                         */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour un symbole d'exécutable. */ +/* +G_DEFINE_TYPE_WITH_CODE(GStrSymbol, g_string_symbol, G_TYPE_OBJECT, +                        G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_string_symbol_interface_init)); +*/ +G_DEFINE_TYPE(GStrSymbol, g_string_symbol, G_TYPE_BIN_SYMBOL); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des chaînes de caractères.              * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_string_symbol_class_init(GStrSymbolClass *klass) +{ +    GObjectClass *object;                   /* Autre version de la classe  */ + +    object = G_OBJECT_CLASS(klass); + +    object->dispose = (GObjectFinalizeFunc/* ! */)g_string_symbol_dispose; +    object->finalize = (GObjectFinalizeFunc)g_string_symbol_finalize; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : symbol = instance à initialiser.                             * +*                                                                             * +*  Description : Initialise une instance de chaîne de caractères.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_string_symbol_init(GStrSymbol *symbol) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : symbol = instance d'objet GLib à traiter.                    * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_string_symbol_dispose(GStrSymbol *symbol) +{ +    if (symbol->has_content) +        g_object_unref(G_OBJECT(symbol->content)); + +    G_OBJECT_CLASS(g_string_symbol_parent_class)->dispose(G_OBJECT(symbol)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : symbol = instance d'objet GLib à traiter.                    * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_string_symbol_finalize(GStrSymbol *symbol) +{ +    G_OBJECT_CLASS(g_string_symbol_parent_class)->finalize(G_OBJECT(symbol)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format   = format binaire reconnu.                           * +*                range    = espace couvert par le nouveau symbole.            * +*                encoding = encodage de la chaîne de caractères à représenter.* +*                                                                             * +*  Description : Crée un nouveau symbole pour chaîne de caractères.           * +*                                                                             * +*  Retour      : Adresse de l'instance mise en place ou NULL en cas d'échec.  * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GBinSymbol *g_string_symbol_new_read_only(GBinFormat *format, const mrange_t *range, StringEncodingType encoding) +{ +    GStrSymbol *result;                     /* Nouveau symbole à renvoyer  */ +    GBinSymbol *parent;                     /* Type d'instance parent      */ +    vmpa2t pos;                             /* Tête de lecture modifiable  */ +    phys_t length;                          /* Taille de la chaîne         */ +    const char *base;                       /* Contenu complet et original */ + +    result = g_object_new(G_TYPE_STR_SYMBOL, NULL); + +    parent = G_BIN_SYMBOL(result); + +    g_binary_symbol_set_range(parent, range); +    g_binary_symbol_set_target_type(parent, STP_RO_STRING); + +    result->encoding = encoding; + +    result->content = g_binary_format_get_content(format); +    result->has_content = true; + +    switch (encoding) +    { +        case SET_ASCII: +            break; + +        case SET_UTF_8: +        case SET_MUTF_8: + +            copy_vmpa(&pos, get_mrange_addr(range)); +            length = get_mrange_length(range); + +            base = (const char *)g_binary_content_get_raw_access(result->content, &pos, length); + +            if (!g_utf8_validate(base, -1, NULL)) +                result->encoding = SET_ASCII; + +            break; + +        case SET_GUESS: + +            copy_vmpa(&pos, get_mrange_addr(range)); +            length = get_mrange_length(range); + +            base = (const char *)g_binary_content_get_raw_access(result->content, &pos, length); + +            if (g_str_is_ascii(base)) +                result->encoding = SET_ASCII; + +            else if (g_utf8_validate(base, -1, NULL)) +                result->encoding = SET_UTF_8; + +            else +                result->encoding = SET_ASCII; + +            break; + +    } + +    return G_BIN_SYMBOL(result); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : symbol = symbole à venir consulter.                          * +*                                                                             * +*  Description : Fournit l'encodage d'une chaîne de caractères.               * +*                                                                             * +*  Retour      : Type d'encodage utilisé.                                     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +StringEncodingType g_string_symbol_get_encoding(const GStrSymbol *symbol) +{ +    StringEncodingType result;              /* Type à retourner            */ + +    result = symbol->encoding; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : symbol = chaîne de caractères à consulter.                   * +*                format = informations chargées à consulter.                  * +*                                                                             * +*  Description : Construit une désignation pour chaîne de caractères.         * +*                                                                             * +*  Retour      : Bilan de l'opération de mise en place.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_string_symbol_build_label(GStrSymbol *symbol, GBinFormat *format) +{ +    const mrange_t *range;                  /* Couverture du symbole       */ +    vmpa2t pos;                             /* Tête de lecture modifiable  */ +    phys_t length;                          /* Taille de la chaîne         */ +    const char *base;                       /* Contenu complet et original */ +    size_t allocated;                       /* Taille réservée             */ +    char *label;                            /* Etiquette à constituer      */ +    size_t cur;                             /* Point d'écriture courant    */ +    unsigned int wc;                        /* Nombre de mots rencontrés   */ +    size_t i;                               /* Boucle de parcours #1       */ +    char *iter;                             /* Boucle de parcours #2       */ +    gunichar c;                             /* Caractère unicode           */ +    gchar *converted;                       /* Caractère converti          */ +    glong size;                             /* Taille du caractère         */ +    bool empty;                             /* Base de l'étiquette vide ?  */ +    GBinSymbol *found;                      /* Symbole similaire trouvé    */ +    VMPA_BUFFER(last_sfx);                  /* Dernier suffixe à intégrer  */ + +    /* Base de décision */ + +    range = g_binary_symbol_get_range(G_BIN_SYMBOL(symbol)); + +    copy_vmpa(&pos, get_mrange_addr(range)); + +    switch (g_binary_symbol_get_target_type(G_BIN_SYMBOL(symbol))) +    { +        case STP_RO_STRING: +            length = get_mrange_length(range); +            base = (const char *)g_binary_content_get_raw_access(symbol->content, &pos, length); +            break; + +        case STP_DYN_STRING: +            base = symbol->utf8; +            length = strlen((char *)base); +            break; + +        default: +            assert(false); +            base = NULL; +            break; + +    } + +    if (base == NULL) +        return false; + +    /* Phase de constitution */ + +    allocated = length + 5 + VMPA_MAX_LEN + 1; +    label = (char *)malloc(allocated * sizeof(char)); + +    cur = 0; + +    wc = 0; + +    /** +     * Version simple et rapide. +     */ +    if (symbol->encoding == SET_ASCII || g_str_is_ascii(base)) +    { +        for (i = 0; i < length; i++) +        { +            if (isalnum(base[i])) label[cur++] = tolower(base[i]); + +            else if (cur > 0) +            { +                if (label[cur - 1] != '_') wc++; + +                if (wc == 3) break; + +                if (label[cur - 1] != '_') label[cur++] = '_'; + +            } + +        } + +    } + +    /** +     * Version complète. +     */ +    else +    { +        for (iter = g_utf8_offset_to_pointer(base, 0); +             iter != NULL; +             iter = g_utf8_find_next_char(iter, NULL)) +        { +            c = g_utf8_get_char_validated(iter, -1); + +            /** +             * Si le caractère n'est pas valide (chaîne chiffrée ?)... +             */ +            if (c == (gunichar)-1 || c == (gunichar)-2) +                break; + +            if (c == '\0') +                break; + +            else if (g_unichar_isalnum(c)) +            { +                c = g_unichar_tolower(c); + +                converted = g_ucs4_to_utf8(&c, 1, NULL, &size, NULL); + +                label = ensure_allocation_size(label, &allocated, cur + size); + +                memcpy(label + cur, converted, size); + +                g_free(converted); + +                cur += size; + +            } + +            else if (cur > 0) +            { +                if (label[cur - 1] != '_') wc++; + +                if (wc == 3) break; + +                if (label[cur - 1] != '_') +                { +                    label = ensure_allocation_size(label, &allocated, cur + 1); +                    label[cur++] = '_'; +                } + +            } + +        } + +    } + +    empty = (cur == 0); + +    if (!empty && label[cur - 1] != '_') +    { +        label = ensure_allocation_size(label, &allocated, cur + 1); +        label[cur++] = '_'; +    } + +    label = ensure_allocation_size(label, &allocated, cur + 4); + +    strcpy(label + cur, "str"); +    cur += 3; + +    /* Détermination du suffixe suffisant */ + +    found = NULL; + +    if (empty || g_binary_format_find_symbol_by_label(format, label, &found)) +    { +        if (found != NULL) +            g_object_unref(G_OBJECT(found)); + +        if (label[cur - 1] != '_') +        { +            label = ensure_allocation_size(label, &allocated, cur + 1); +            label[cur++] = '_'; +        } + +        copy_vmpa(&pos, get_mrange_addr(range)); + +        assert(has_phys_addr(&pos) || has_virt_addr(&pos)); + +        if (has_virt_addr(&pos)) +            vmpa2_virt_to_string(&pos, MDS_UNDEFINED, last_sfx, NULL); +        else +            vmpa2_phys_to_string(&pos, MDS_UNDEFINED, last_sfx, NULL); + +        label = ensure_allocation_size(label, &allocated, cur + strlen(last_sfx) + 1); + +        strcpy(label + cur, last_sfx); + +    } + +    /* Application */ + +    g_binary_symbol_set_alt_label(G_BIN_SYMBOL(symbol), label); + +    free(label); + +    return true; + +} diff --git a/src/format/strsym.h b/src/format/strsym.h new file mode 100644 index 0000000..e827e6a --- /dev/null +++ b/src/format/strsym.h @@ -0,0 +1,80 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * strsym.h - prototypes pour la gestion des chaînes dans un binaire + * + * Copyright (C) 2018 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide 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. + * + *  Chrysalide 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 Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _FORMAT_STRSYM_H +#define _FORMAT_STRSYM_H + + +#include <glib-object.h> + + +#include "format.h" +#include "symbol.h" + + + +/* ----------------------- VITRINE POUR CHAINES DE CARACTERES ----------------------- */ + + +/* Types de chaînes */ +typedef enum _StringEncodingType +{ +    SET_ASCII,                              /* Format brut                 */ +    SET_UTF_8,                              /* Format UTF-8                */ +    SET_MUTF_8,                             /* Format UTF-8 modifié        */ + +    SET_GUESS,                              /* Détection automatique       */ + +} StringEncodingType; + + +#define G_TYPE_STR_SYMBOL               g_string_symbol_get_type() +#define G_STR_SYMBOL(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_string_symbol_get_type(), GStrSymbol)) +#define G_IS_STR_SYMBOL(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_string_symbol_get_type())) +#define G_STR_SYMBOL_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_STR_SYMBOL, GStrSymbolClass)) +#define G_IS_STR_SYMBOL_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_STR_SYMBOL)) +#define G_STR_SYMBOL_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_STR_SYMBOL, GStrSymbolClass)) + + +/*/* Symbole pour chaîne de caractères (instance) */ +typedef struct _GStrSymbol GStrSymbol; + +/* Symbole pour chaîne de caractères (classe) */ +typedef struct _GStrSymbolClass GStrSymbolClass; + + +/* Indique le type défini pour un symbole d'exécutable. */ +GType g_string_symbol_get_type(void); + +/* Crée un nouveau symbole pour chaîne de caractères. */ +GBinSymbol *g_string_symbol_new_read_only(GBinFormat *, const mrange_t *, StringEncodingType); + +/* Fournit l'encodage d'une chaîne de caractères. */ +StringEncodingType g_string_symbol_get_encoding(const GStrSymbol *); + +/* Construit une désignation pour chaîne de caractères. */ +bool g_string_symbol_build_label(GStrSymbol *, GBinFormat *); + + + +#endif  /* _FORMAT_STRSYM_H */ diff --git a/src/format/symbol.h b/src/format/symbol.h index 13747d4..577a6a0 100644 --- a/src/format/symbol.h +++ b/src/format/symbol.h @@ -43,8 +43,8 @@ typedef enum _SymbolType      STP_CODE_LABEL,                         /* Renvoi au sein de code      */      STP_OBJECT,                             /* Objet quelconque            */      STP_ENTRY_POINT,                        /* Morceau de code en entrée   */ -    STP_STRING,                             /* Chaîne de caractères        */ -    STP_RO_STRING,                          /* Chaîne de caractères        */ +    STP_RO_STRING,                          /* Chaîne d'origine            */ +    STP_DYN_STRING,                         /* Chaîne créée ex-nihilo      */      STP_COUNT @@ -57,6 +57,7 @@ typedef enum _SymbolStatus      SSS_INTERNAL,                           /* Visibilité nulle            */      SSS_EXPORTED,                           /* Disponibilité extérieure    */      SSS_IMPORTED,                           /* Besoin interne              */ +    SSS_DYNAMIC,                            /* Création durant l'analyse   */      SSS_COUNT  | 
