From dc9e68505c4cc7ad208e63dbc7d0e0e8f582d0d9 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 3 Mar 2015 23:51:04 +0000 Subject: Loaded and displayed found strings in ELF. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@481 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 22 +++++++- src/arch/arm/v7/post.c | 8 +-- src/arch/raw.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++- src/arch/raw.h | 6 +++ src/format/elf/strings.c | 80 ++++++++++++++++++++++------ src/format/format.c | 84 ++++++++++++++++++++++++++++++ src/format/format.h | 3 ++ src/format/symbol.c | 15 ++++++ src/format/symbol.h | 15 ++++++ 9 files changed, 342 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6c31b70..ed1a6f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +15-03-04 Cyrille Bagard + + * src/arch/arm/v7/post.c: + Add some comments for variables. + + * src/arch/raw.c: + * src/arch/raw.h: + Deal with strings as raw instructions. + + * src/format/elf/strings.c: + Load and display found strings in ELF. + + * src/format/format.c: + * src/format/format.h: + Create labels for string data. + + * src/format/symbol.c: + * src/format/symbol.h: + Allow to define labels and register string symbols. + 15-02-25 Cyrille Bagard * plugins/pychrysa/gtkext/viewpanel.c: @@ -22,7 +42,7 @@ Update. * src/project.c: - Wait a little bit before being abl able to use sizes to compute the position of the entry point. + Wait before using sizes to compute the position of the entry point. 15-02-24 Cyrille Bagard diff --git a/src/arch/arm/v7/post.c b/src/arch/arm/v7/post.c index 084fc84..c7b0f64 100644 --- a/src/arch/arm/v7/post.c +++ b/src/arch/arm/v7/post.c @@ -51,7 +51,7 @@ void post_process_branch_instructions(GArchInstruction *instr, GProcContext *con uint32_t addr; /* Adresse visée par le saut */ GArchOperand *new; /* Instruction de ciblage */ vmpa2t target; - mrange_t trange; + mrange_t trange; /* Etendue du symbole à créer */ VMPA_BUFFER(loc); char name[5 + VMPA_MAX_LEN]; GBinRoutine *routine; /* Nouvelle routine trouvée */ @@ -114,7 +114,7 @@ void post_process_branch_and_link_instructions(GArchInstruction *instr, GProcCon uint32_t addr; /* Adresse visée par le saut */ GArchOperand *new; /* Instruction de ciblage */ vmpa2t target; - mrange_t trange; + mrange_t trange; /* Etendue du symbole à créer */ VMPA_BUFFER(loc); char name[5 + VMPA_MAX_LEN]; GBinRoutine *routine; /* Nouvelle routine trouvée */ @@ -177,7 +177,7 @@ void post_process_comp_and_branch_instructions(GArchInstruction *instr, GProcCon uint32_t addr; /* Adresse visée par le saut */ GArchOperand *new; /* Instruction de ciblage */ vmpa2t target; - mrange_t trange; + mrange_t trange; /* Etendue du symbole à créer */ VMPA_BUFFER(loc); char name[5 + VMPA_MAX_LEN]; GBinRoutine *routine; /* Nouvelle routine trouvée */ @@ -240,7 +240,7 @@ void post_process_ldr_instructions(GArchInstruction *instr, GProcContext *contex uint32_t addr; /* Adresse visée par le saut */ GArchOperand *new; /* Instruction de ciblage */ vmpa2t target; - mrange_t trange; + mrange_t trange; /* Etendue du symbole à créer */ VMPA_BUFFER(loc); char name[5 + VMPA_MAX_LEN]; GBinRoutine *routine; /* Nouvelle routine trouvée */ diff --git a/src/arch/raw.c b/src/arch/raw.c index 808d973..3338613 100644 --- a/src/arch/raw.c +++ b/src/arch/raw.c @@ -24,6 +24,8 @@ #include "raw.h" +#include +#include #include @@ -41,6 +43,7 @@ struct _GRawInstruction GArchInstruction parent; /* A laisser en premier */ bool is_padding; /* Bourrage à représenter ? */ + bool is_string; /* Chaîne de caractères ? */ }; @@ -370,16 +373,24 @@ static GBufferLine *g_raw_instruction_print(const GRawInstruction *instr, GCodeB GArchInstruction *base; /* Autre version de l'instance */ const char *key; /* Mot clef principal */ size_t klen; /* Taille de ce mot clef */ + char *string; /* Chaîne reconstituée */ + size_t iter; /* Tête d'écriture */ + bool first; /* Mémorise une énumération */ + size_t i; /* Boucle de parcours */ + char byte; /* Octet à afficher (ou pas) */ + bool status; /* Bilan d'une récupération */ base = G_ARCH_INSTRUCTION(instr); - if (!instr->is_padding) + if (!instr->is_padding && !instr->is_string) result = G_ARCH_INSTRUCTION_CLASS(g_raw_instruction_parent_class)->print(base, buffer, msize, content, syntax); else { result = g_code_buffer_append_new_line(buffer, &base->range); + g_buffer_line_add_flag(result, BLF_HAS_CODE); + g_buffer_line_fill_for_instr(result, msize/* TODO ! */, msize, content, base->length, true); /* Instruction proprement dite */ @@ -389,7 +400,84 @@ static GBufferLine *g_raw_instruction_print(const GRawInstruction *instr, GCodeB g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION); - g_buffer_line_insert_text(result, BLC_ASSEMBLY, "...", 3, RTT_RAW); + if (instr->is_padding) + g_buffer_line_insert_text(result, BLC_ASSEMBLY, "...", 3, RTT_RAW); + + else /*if (instr->is_string)*/ + { + string = (char *)calloc(base->operands_count + 3, sizeof(char)); + + strcpy(string, "\""); + iter = 1; + + first = true; + + for (i = 0; i < base->operands_count; i++) + { + status = g_imm_operand_get_value(G_IMM_OPERAND(base->operands[i]), MDS_8_BITS, &byte); + assert(status); + + /* Si le caractère doit apparaître en hexadécimal... */ + if (!isprint(byte)) + { + /* Si une chaîne précède */ + if (iter > 1) + { + if (!first) + { + g_buffer_line_insert_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT); + g_buffer_line_insert_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW); + } + else + first = false; + + string[iter++] = '"'; + + g_buffer_line_insert_text(result, BLC_ASSEMBLY, string, iter, RTT_STRING); + + iter = 1; + + } + + /* Impression de l'octet */ + + if (!first) + { + g_buffer_line_insert_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT); + g_buffer_line_insert_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW); + } + else + first = false; + + g_arch_operand_print(base->operands[i], result, syntax); + + } + + else + string[iter++] = byte; + + } + + /* Si une chaîne reste encore */ + if (iter > 1) + { + if (!first) + { + g_buffer_line_insert_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT); + g_buffer_line_insert_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW); + } + else + first = false; + + string[iter++] = '"'; + + g_buffer_line_insert_text(result, BLC_ASSEMBLY, string, iter, RTT_STRING); + + } + + free(string); + + } } @@ -465,3 +553,43 @@ bool g_raw_instruction_is_padding(const GRawInstruction *instr) return instr->is_padding; } + + +/****************************************************************************** +* * +* Paramètres : instr = instruction à traiter. * +* is_string = nouveau statut à associer au contenu. * +* * +* Description : Marque l'instruction comme contenant une chaîne de texte. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_raw_instruction_mark_as_string(GRawInstruction *instr, bool is_string) +{ + instr->is_string = is_string; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction à traiter. * +* is_string = nouveau statut à associer au contenu. * +* * +* Description : Indique si le contenu de l'instruction est un texte. * +* * +* Retour : Statut du contenu de l'instruction. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_raw_instruction_is_string(const GRawInstruction *instr) +{ + return instr->is_string; + +} diff --git a/src/arch/raw.h b/src/arch/raw.h index f7e1715..6712b81 100644 --- a/src/arch/raw.h +++ b/src/arch/raw.h @@ -67,6 +67,12 @@ void g_raw_instruction_mark_as_padding(GRawInstruction *, bool); /* Indique si le contenu de l'instruction est du bourrage. */ bool g_raw_instruction_is_padding(const GRawInstruction *); +/* Marque l'instruction comme contenant une chaîne de texte. */ +void g_raw_instruction_mark_as_string(GRawInstruction *, bool); + +/* Indique si le contenu de l'instruction est un texte. */ +bool g_raw_instruction_is_string(const GRawInstruction *); + #endif /* _ARCH_RAW_H */ 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 +#include #include #include @@ -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 */ -- cgit v0.11.2-87-g4458