diff options
Diffstat (limited to 'src/format')
-rw-r--r-- | src/format/elf/strings.c | 80 | ||||
-rw-r--r-- | src/format/format.c | 84 | ||||
-rw-r--r-- | src/format/format.h | 3 | ||||
-rw-r--r-- | src/format/symbol.c | 15 | ||||
-rw-r--r-- | src/format/symbol.h | 15 |
5 files changed, 181 insertions, 16 deletions
diff --git a/src/format/elf/strings.c b/src/format/elf/strings.c index 09bd442..f2c5dd3 100644 --- a/src/format/elf/strings.c +++ b/src/format/elf/strings.c @@ -32,6 +32,7 @@ #include "elf-int.h" #include "section.h" +#include "../../arch/raw.h" @@ -141,7 +142,7 @@ bool find_all_elf_strings(GElfFormat *format) * * * Description : Enregistre toutes les chaînes de caractères trouvées. * * * -* Retour : true si des chaînes ont été ajoutées, false sinon. * +* Retour : true si des chaînes ont été ajoutées sans erreur, ou false. * * * * Remarques : - * * * @@ -150,36 +151,83 @@ bool find_all_elf_strings(GElfFormat *format) bool parse_elf_string_data(GElfFormat *format, off_t start, off_t size, vmpa_t address) { bool result; /* Bilan à faire remonter */ - const bin_t *content; /* Contenu binaire à lire */ - off_t length; /* Taille totale du contenu */ + GBinContent *content; /* Contenu binaire à lire */ + char *data; /* Données copiées à traiter */ + vmpa2t pos; /* Tête de lecture */ + bool cut; /* Séparation nette ? */ off_t i; /* Boucle de parcours */ off_t end; /* Position de fin de chaîne */ - GBinSymbol *symbol; /* Nouveau symbole construit */ + GArchInstruction *instr; /* Instruction décodée */ + GBinSymbol *symbol; /* Symbole à intégrer */ + char *label; /* Désignation de la chaîne */ if (address == 0) return false; result = false; - content = G_BIN_FORMAT(format)->content; - length = G_BIN_FORMAT(format)->length; + /* Préparation des accès */ + + content = g_binary_format_get_conten_(G_BIN_FORMAT(format)); + + data = (char *)malloc(size * sizeof(char)); + + init_vmpa(&pos, start, address); + + if (!g_binary_content_get_raw(content, &pos, size, (bin_t *)data)) + goto pesd_error; + + /* Boucle de parcours */ - length = MIN(length, start + size); + cut = true; - for (i = start; i < length; i++) - if (isprint(content[i])) + for (i = 0; i < size; i++) + if (isprint(data[i])) { - for (end = i + 1; end < length; end++) - if (!isprint(content[end])) break; - - symbol = g_binary_symbol_new(STP_STRING, NULL, address + i - start); - g_binary_symbol_set_alt_name(symbol, strndup((const char *)&content[i], end - i)); + for (end = i + 1; end < size; end++) + if (!isprint(data[end])) break; + + if (isspace(data[end]) && (end + 1) < size) + end++; + + if (data[end] == '\0' && (end + 1) < size) + end++; + + init_vmpa(&pos, start + i, address + i); + + instr = g_raw_instruction_new_array(G_BIN_FORMAT(format)->conten_, MDS_8_BITS, + end - i, &pos, format->endian); + + g_raw_instruction_mark_as_string(G_RAW_INSTRUCTION(instr), true); - ///// reactiver g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol); + ADD_STR_AS_SYM(format, symbol, instr); - i = end; + /* Jointure avec la chaîne précédente ? */ + + if (cut) + { + init_vmpa(&pos, start + i, address + i); + + label = create_string_label(G_BIN_FORMAT(format), &pos, &data[i], end - i); + + g_binary_symbol_set_label(symbol, label); + + free(label); + + } + + /* Conclusion */ + + cut = (data[end - 1] == '\0'); + + i = end - 1; result = true; } + else cut = true; + + pesd_error: + + free(data); return result; diff --git a/src/format/format.c b/src/format/format.c index 6b63556..2808b67 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -24,6 +24,8 @@ #include "format.h" +#include <assert.h> +#include <ctype.h> #include <malloc.h> #include <string.h> @@ -224,6 +226,88 @@ GBinSymbol **g_binary_format_get_symbols(const GBinFormat *format, size_t *count /****************************************************************************** * * * Paramètres : format = informations chargées à consulter. * +* addr = adresse liée à la chaîne à traiter. * +* base = contenu complet et original d'une chaîne. * +* 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, const char *base, size_t length) +{ + char *result; /* Nouvelle chaîne à retourner */ + 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 */ + + 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 e23b4bd..38418b3 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -70,6 +70,9 @@ void g_binary_format_add_symbol(GBinFormat *, GBinSymbol *); /* Fournit la liste de tous les symboles détectés. */ GBinSymbol **g_binary_format_get_symbols(const GBinFormat *, size_t *); +/* Construit une désignation pour chaîne de caractères. */ +char *create_string_label(GBinFormat *, const vmpa2t *, const char *, size_t); + /* Recherche le symbole correspondant à une étiquette. */ bool g_binary_format_find_symbol_by_label(const GBinFormat *, const char *, GBinSymbol **); diff --git a/src/format/symbol.c b/src/format/symbol.c index 7817d5f..8ab76b6 100644 --- a/src/format/symbol.c +++ b/src/format/symbol.c @@ -41,6 +41,8 @@ struct _GBinSymbol char *alt; /* Nom alternatif */ + char *tmp_label; /* REMME */ + union { GArchInstruction *instr; /* Instruction correspondante */ @@ -255,6 +257,13 @@ vmpa_t g_binary_symbol_get_address(const GBinSymbol *symbol) +void g_binary_symbol_set_label(GBinSymbol *symbol, const char *lbl) +{ + symbol->tmp_label = strdup(lbl); + +} + + /****************************************************************************** * * * Paramètres : symbol = symbole à venir consulter. * @@ -273,6 +282,12 @@ const char *g_binary_symbol_get_label(const GBinSymbol *symbol) result = NULL; + + /* TODO : utiliser des types pour les instructions */ + if (symbol->tmp_label != NULL) + return symbol->tmp_label; + + switch (symbol->type) { case STP_ROUTINE: diff --git a/src/format/symbol.h b/src/format/symbol.h index e123898..c3e53cc 100644 --- a/src/format/symbol.h +++ b/src/format/symbol.h @@ -79,6 +79,12 @@ const char *g_binary_symbol_to_string(const GBinSymbol *); /* Fournit l'adresse associée à un symbole. */ vmpa_t g_binary_symbol_get_address(const GBinSymbol *); /////////////////// + + +void g_binary_symbol_set_label(GBinSymbol *symbol, const char *lbl); + + + /* Fournit un étiquette pour viser un symbole. */ const char *g_binary_symbol_get_label(const GBinSymbol *); @@ -133,6 +139,15 @@ GDbComment *g_binary_symbol_get_comment(const GBinSymbol *); } \ while (0) +#define ADD_STR_AS_SYM(_fmt, _sym, _ins) \ + do \ + { \ + _sym = g_binary_symbol_new(STP_DATA, NULL, 0); \ + g_binary_symbol_attach_instruction(_sym, _ins); \ + g_binary_format_add_symbol(G_BIN_FORMAT(_fmt), _sym); \ + } \ + while (0) + #endif /* _FORMAT_SYMBOL_H */ |