From cd956221a807e4c1961e17602d5ca641b93a937a Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 22 Mar 2017 18:58:36 +0100 Subject: Ensured all string symbols referenced by instructions get a label. --- ChangeLog | 14 ++++++++++++++ src/arch/target.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/format/elf/strings.c | 18 ++++++++---------- src/format/format.c | 12 ++++++++++-- src/format/format.h | 2 +- 5 files changed, 76 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index b8cd12c..94c99d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +17-03-22 Cyrille Bagard + + * src/arch/target.c: + Ensure all string symbols referenced by instructions get a label. + + * src/format/elf/strings.c: + Avoid to allocate memory for reading binary content which can be read + directly. + + * src/format/format.c: + * src/format/format.h: + Use the internal format content instead of a provided one when creating + labels. + 17-03-21 Cyrille Bagard * src/glibext/gbufferline.c: diff --git a/src/arch/target.c b/src/arch/target.c index 63ae295..3632b76 100644 --- a/src/arch/target.c +++ b/src/arch/target.c @@ -24,6 +24,7 @@ #include "target.h" +#include #include #include #include @@ -305,12 +306,54 @@ void g_target_operand_get_addr(const GTargetOperand *operand, vmpa2t *addr) bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool strict) { 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 */ if (operand->symbol != NULL) g_object_unref(G_OBJECT(operand->symbol)); result = g_binary_format_resolve_symbol(format, &operand->addr, strict, &operand->symbol, &operand->diff); + /** + * Si plusieurs chaînes se suivent, la seconde et les suivantes bénéficient + * d'une étiquette si et seulement si elles sont détachées des précédentes + * par un octet nul. + * + * S'il y a juste un retour à la ligne ("\n"), alors aucune séparation n'est + * considérée, et le bloc de chaînes est uniforme. + * + * Aussi, si une référence renvoie vers une ligne de ce bloc, alors on + * attribue à cette ligne une étiquette propre. + */ + + if (result && operand->diff == 0) + { + symbol = operand->symbol; + + stype = g_binary_symbol_get_target_type(symbol); + + if (stype == STP_STRING || stype == STP_RO_STRING) + { + if (g_binary_symbol_get_label(symbol) == NULL) + { + range = g_binary_symbol_get_range(symbol); + + assert(cmp_vmpa(&operand->addr, get_mrange_addr(range)) == 0); + + label = create_string_label(format, get_mrange_addr(range), get_mrange_length(range)); + + g_binary_symbol_set_alt_label(symbol, label); + + free(label); + + } + + } + + } + return result; } diff --git a/src/format/elf/strings.c b/src/format/elf/strings.c index 755163e..9bcb87f 100644 --- a/src/format/elf/strings.c +++ b/src/format/elf/strings.c @@ -152,7 +152,7 @@ bool parse_elf_string_data(GElfFormat *format, phys_t start, phys_t size, virt_t { bool result; /* Bilan à faire remonter */ GBinContent *content; /* Contenu binaire à lire */ - char *data; /* Données copiées à traiter */ + const bin_t *data; /* Contenu complet et original */ vmpa2t pos; /* Tête de lecture */ bool cut; /* Séparation nette ? */ off_t i; /* Boucle de parcours */ @@ -161,7 +161,8 @@ bool parse_elf_string_data(GElfFormat *format, phys_t start, phys_t size, virt_t GBinSymbol *symbol; /* Symbole à intégrer */ char *label; /* Désignation de la chaîne */ - if (address == 0) return false; + if (address == 0) + return false; result = false; @@ -169,11 +170,11 @@ bool parse_elf_string_data(GElfFormat *format, phys_t start, phys_t size, virt_t content = g_binary_format_get_content(G_BIN_FORMAT(format)); - data = (char *)malloc(size * sizeof(char)); - init_vmpa(&pos, start, address); - if (!g_binary_content_read_raw(content, &pos, size, (bin_t *)data)) + data = g_binary_content_get_raw_access(content, &pos, size); + + if (data == NULL) goto pesd_error; /* Boucle de parcours */ @@ -194,8 +195,7 @@ bool parse_elf_string_data(GElfFormat *format, phys_t start, phys_t size, virt_t init_vmpa(&pos, start + i, address + i); - instr = g_raw_instruction_new_array(G_BIN_FORMAT(format)->content, MDS_8_BITS, - end - i, &pos, format->endian); + instr = g_raw_instruction_new_array(content, MDS_8_BITS, end - i, &pos, format->endian); g_raw_instruction_mark_as_string(G_RAW_INSTRUCTION(instr), true); @@ -207,7 +207,7 @@ bool parse_elf_string_data(GElfFormat *format, phys_t start, phys_t size, virt_t { init_vmpa(&pos, start + i, address + i); - label = create_string_label(G_BIN_FORMAT(format), &pos, &data[i], end - i); + label = create_string_label(G_BIN_FORMAT(format), &pos, end - i); g_binary_symbol_set_alt_label(symbol, label); @@ -229,8 +229,6 @@ bool parse_elf_string_data(GElfFormat *format, phys_t start, phys_t size, virt_t g_object_unref(G_OBJECT(content)); - free(data); - return result; } diff --git a/src/format/format.c b/src/format/format.c index 327b28e..978a3d2 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -546,7 +546,6 @@ 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. * @@ -557,9 +556,11 @@ GBinSymbol **g_binary_format_get_symbols(const GBinFormat *format, size_t *count * * ******************************************************************************/ -char *create_string_label(GBinFormat *format, const vmpa2t *addr, const char *base, size_t length) +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 */ @@ -567,6 +568,13 @@ char *create_string_label(GBinFormat *format, const vmpa2t *addr, const char *ba 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; diff --git a/src/format/format.h b/src/format/format.h index d97f542..c2ef895 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -77,7 +77,7 @@ void g_binary_format_remove_symbol(GBinFormat *, GBinSymbol *); 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); +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 **); -- cgit v0.11.2-87-g4458