From 8c84aa2e41305fd388b7dac49f29ae17ee0554fb Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 3 Aug 2018 00:25:15 +0200 Subject: Introduced symbols dedicated to strings. --- plugins/dex/pool.c | 12 +- plugins/elf/strings.c | 13 +- plugins/pychrysalide/format/symbol.c | 3 +- plugins/readelf/strtab.c | 16 +- src/arch/target.c | 20 +- src/common/Makefile.am | 1 + src/common/alloc.c | 60 +++++ src/common/alloc.h | 37 +++ src/format/Makefile.am | 1 + src/format/format.c | 91 ------- src/format/format.h | 3 - src/format/strsym.c | 474 +++++++++++++++++++++++++++++++++++ src/format/strsym.h | 80 ++++++ src/format/symbol.h | 5 +- src/gui/panels/strings.c | 16 +- 15 files changed, 680 insertions(+), 152 deletions(-) create mode 100644 src/common/alloc.c create mode 100644 src/common/alloc.h create mode 100644 src/format/strsym.c create mode 100644 src/format/strsym.h diff --git a/plugins/dex/pool.c b/plugins/dex/pool.c index 75841df..d95f519 100644 --- a/plugins/dex/pool.c +++ b/plugins/dex/pool.c @@ -31,6 +31,7 @@ #include #include #include +#include #include @@ -205,9 +206,8 @@ GBinSymbol *get_string_symbol_from_dex_pool(GDexFormat *format, uint32_t index) uint32_t count; /* Nombre d'éléments présents */ mrange_t range; /* Emplacement de la chaîne */ const char *string; /* Chaîne de caractères liée */ - GBinSymbol *new; /* Nouveau symbol créé */ GBinFormat *base; /* Autre version du format */ - char *label; /* Désignation de la chaîne */ + GBinSymbol *new; /* Nouveau symbol créé */ bool inserted; /* Bilan d'une insertion */ result = NULL; @@ -222,15 +222,11 @@ GBinSymbol *get_string_symbol_from_dex_pool(GDexFormat *format, uint32_t index) string = get_string_from_dex_pool(format, index, &range); if (string == NULL) goto gssfdp_error; - new = g_binary_symbol_new(&range, STP_RO_STRING); - base = G_BIN_FORMAT(format); - label = create_string_label(base, get_mrange_addr(&range), get_mrange_length(&range)); - - g_binary_symbol_set_alt_label(new, label); + new = g_string_symbol_new_read_only(base, &range, SET_MUTF_8); - free(label); + g_string_symbol_build_label(G_STR_SYMBOL(new), base); g_object_ref(G_OBJECT(new)); inserted = g_binary_format_add_symbol(base, new); diff --git a/plugins/elf/strings.c b/plugins/elf/strings.c index a14b389..4d6b5c8 100644 --- a/plugins/elf/strings.c +++ b/plugins/elf/strings.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "elf-int.h" @@ -285,7 +286,6 @@ static bool do_elf_string_loading(GElfLoading *loading, GElfFormat *format, phys const mrange_t *range; /* Espace occupé par une chaîne*/ GBinSymbol *symbol; /* Symbole à intégrer */ bool cut; /* Coupure par étiquette ? */ - char *label; /* Désignation de la chaîne */ result = false; @@ -355,7 +355,7 @@ static bool do_elf_string_loading(GElfLoading *loading, GElfFormat *format, phys { range = g_arch_instruction_get_range(instr); - symbol = g_binary_symbol_new(range, STP_RO_STRING); + symbol = g_string_symbol_new_read_only(base, range, SET_GUESS); g_binary_format_add_symbol(base, symbol); /* Jointure avec la chaîne précédente ? */ @@ -366,14 +366,7 @@ static bool do_elf_string_loading(GElfLoading *loading, GElfFormat *format, phys cut = (data[*iter - offset - 1] == '\0'); if (cut) - { - label = create_string_label(base, get_mrange_addr(range), end - *iter); - - g_binary_symbol_set_alt_label(symbol, label); - - free(label); - - } + g_string_symbol_build_label(G_STR_SYMBOL(symbol), base); } diff --git a/plugins/pychrysalide/format/symbol.c b/plugins/pychrysalide/format/symbol.c index 7dcb0eb..d6298d4 100644 --- a/plugins/pychrysalide/format/symbol.c +++ b/plugins/pychrysalide/format/symbol.c @@ -342,13 +342,14 @@ static bool py_binary_symbol_define_constants(PyTypeObject *obj_type) result &= PyDict_AddIntMacro(obj_type, STP_CODE_LABEL); result &= PyDict_AddIntMacro(obj_type, STP_OBJECT); result &= PyDict_AddIntMacro(obj_type, STP_ENTRY_POINT); - result &= PyDict_AddIntMacro(obj_type, STP_STRING); result &= PyDict_AddIntMacro(obj_type, STP_RO_STRING); + result &= PyDict_AddIntMacro(obj_type, STP_DYN_STRING); result &= PyDict_AddIntMacro(obj_type, STP_COUNT); result &= PyDict_AddIntMacro(obj_type, SSS_INTERNAL); result &= PyDict_AddIntMacro(obj_type, SSS_EXPORTED); result &= PyDict_AddIntMacro(obj_type, SSS_IMPORTED); + result &= PyDict_AddIntMacro(obj_type, SSS_DYNAMIC); return result; diff --git a/plugins/readelf/strtab.c b/plugins/readelf/strtab.c index e8d0f45..3cbe353 100644 --- a/plugins/readelf/strtab.c +++ b/plugins/readelf/strtab.c @@ -29,6 +29,7 @@ #include +#include #include @@ -67,7 +68,6 @@ static void parse_elf_string_table(GElfFormat *format, GPreloadInfo *info, const bool inserted; /* Bilan d'une insertion */ const mrange_t *irange; /* Espace occupé par une chaîne*/ GBinSymbol *symbol; /* Symbole à intégrer */ - char *label; /* Désignation de la chaîne */ length = get_mrange_length(range); @@ -112,23 +112,13 @@ static void parse_elf_string_table(GElfFormat *format, GPreloadInfo *info, const { irange = g_arch_instruction_get_range(instr); - symbol = g_binary_symbol_new(irange, STP_RO_STRING); + symbol = g_string_symbol_new_read_only(base, irange, SET_GUESS); g_binary_format_add_symbol(base, symbol); /* Jointure avec la chaîne précédente ? */ if (cut) - { - copy_vmpa(&pos, get_mrange_addr(range)); - advance_vmpa(&pos, i); - - label = create_string_label(base, get_mrange_addr(irange), end - i); - - g_binary_symbol_set_alt_label(symbol, label); - - free(label); - - } + g_string_symbol_build_label(G_STR_SYMBOL(symbol), base); } diff --git a/src/arch/target.c b/src/arch/target.c index bdae746..a2e1f34 100644 --- a/src/arch/target.c +++ b/src/arch/target.c @@ -37,6 +37,7 @@ #include "../analysis/routine.h" #include "../common/extstr.h" #include "../format/format.h" +#include "../format/strsym.h" #include "../glibext/gbinarycursor.h" @@ -422,8 +423,8 @@ static char *g_target_operand_build_tooltip(const GTargetOperand *operand, const result = g_binary_routine_build_tooltip(G_BIN_ROUTINE(operand->symbol), binary); break; - case STP_STRING: case STP_RO_STRING: + case STP_DYN_STRING: srange = g_binary_symbol_get_range(operand->symbol); @@ -499,9 +500,10 @@ bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool { bool result; /* Bilan à retourner */ GBinSymbol *symbol; /* Facilités d'accès au symbole*/ - SymbolType stype; /* Type de symbole trouvé */ - const mrange_t *range; /* Couverture du symbole */ char *label; /* Désignation de la chaîne */ +#ifndef NDEBUG + const mrange_t *range; /* Couverture du symbole */ +#endif if (operand->symbol != NULL) g_object_unref(G_OBJECT(operand->symbol)); @@ -528,9 +530,7 @@ bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool { symbol = operand->symbol; - stype = g_binary_symbol_get_target_type(symbol); - - if (stype == STP_STRING || stype == STP_RO_STRING) + if (G_IS_STR_SYMBOL(symbol)) { label = g_binary_symbol_get_label(symbol); @@ -539,15 +539,13 @@ bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool else { +#ifndef NDEBUG range = g_binary_symbol_get_range(symbol); assert(cmp_vmpa(&operand->addr, get_mrange_addr(range)) == 0); +#endif - label = create_string_label(format, get_mrange_addr(range), get_mrange_length(range)); - - g_binary_symbol_set_alt_label(symbol, label); - - free(label); + g_string_symbol_build_label(G_STR_SYMBOL(symbol), format); } diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 7a13aa8..3fabc73 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -2,6 +2,7 @@ noinst_LTLIBRARIES = libcommon.la libcommon_la_SOURCES = \ + alloc.h alloc.c \ array.h array.c \ asm.h asm.c \ bconst.h \ diff --git a/src/common/alloc.c b/src/common/alloc.c new file mode 100644 index 0000000..70f2f01 --- /dev/null +++ b/src/common/alloc.c @@ -0,0 +1,60 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * alloc.c - gestion particulière des allocations + * + * 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 . + */ + + +#include "alloc.h" + + +#include + + + +/****************************************************************************** +* * +* Paramètres : ptr = pointeur à traiter. * +* allocated = taille actuellement allouée. [OUT] * +* needed = taille finale nécessaire. * +* * +* Description : Assure qu'une zone de mémoire allouée a la taille requise. * +* * +* Retour : Pointeur à utiliser avec assurance. * +* * +* Remarques : - * +* * +******************************************************************************/ + +void *ensure_allocation_size(void *ptr, size_t *allocated, size_t needed) +{ + void *result; /* Pointeur à renvoyer */ + + if (needed < *allocated) + result = ptr; + + else + { + *allocated = needed; + result = realloc(ptr, needed); + } + + return result; + +} diff --git a/src/common/alloc.h b/src/common/alloc.h new file mode 100644 index 0000000..5dd564e --- /dev/null +++ b/src/common/alloc.h @@ -0,0 +1,37 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * alloc.h - prototypes pour une gestion particulière des allocations + * + * 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 . + */ + + +#ifndef _COMMON_ALLOC_H +#define _COMMON_ALLOC_H + + +#include + + + +/* Assure qu'une zone de mémoire allouée a la taille requise. */ +void *ensure_allocation_size(void *, size_t *, size_t); + + + +#endif /* _COMMON_ALLOC_H */ 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 -#include #include #include @@ -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 . + */ + + +#include "strsym.h" + + +#include +#include +#include +#include + + +#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 . + */ + + +#ifndef _FORMAT_STRSYM_H +#define _FORMAT_STRSYM_H + + +#include + + +#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 diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c index 6e9324f..895a1b9 100644 --- a/src/gui/panels/strings.c +++ b/src/gui/panels/strings.c @@ -39,6 +39,7 @@ #include "../../core/params.h" #include "../../core/queue.h" #include "../../format/format.h" +#include "../../format/strsym.h" #include "../../format/symiter.h" #include "../../gtkext/easygtk.h" #include "../../gtkext/gtkdisplaypanel.h" @@ -766,7 +767,7 @@ static void reload_strings_for_new_list_view(const GStringsPanel *panel, GtkStat symbol != NULL; symbol = get_symbol_iterator_next(siter)) { - if (g_binary_symbol_get_target_type(symbol) != STP_RO_STRING) + if (!G_IS_STR_SYMBOL(symbol)) goto rsfnlv_next; range = g_binary_symbol_get_range(symbol); @@ -1378,21 +1379,10 @@ static bool is_string_name_matching(const strings_update_data *data, GtkTreeMode { bool result; /* Bilan à retourner */ GBinSymbol *symbol; /* Symbole manipulé */ -#ifndef NDEBUG - SymbolType type; /* Type associé au symbole */ -#endif char *label; /* Etiquette à analyser */ gtk_tree_model_get(model, iter, STC_SYMBOL, &symbol, -1); - assert(symbol != NULL); - -#ifndef NDEBUG - - type = g_binary_symbol_get_target_type(symbol); - - assert(type == STP_RO_STRING); - -#endif + assert(G_IS_STR_SYMBOL(symbol)); label = g_binary_symbol_get_label(symbol); -- cgit v0.11.2-87-g4458