summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-03-03 23:51:04 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-03-03 23:51:04 (GMT)
commitdc9e68505c4cc7ad208e63dbc7d0e0e8f582d0d9 (patch)
tree1e597f7d2ab5a8bb2f3c106a4a14b05f481c4efe /src
parent4724b73c5161140222cab3c61bb5b3d0c8dde360 (diff)
Loaded and displayed found strings in ELF.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@481 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src')
-rw-r--r--src/arch/arm/v7/post.c8
-rw-r--r--src/arch/raw.c132
-rw-r--r--src/arch/raw.h6
-rw-r--r--src/format/elf/strings.c80
-rw-r--r--src/format/format.c84
-rw-r--r--src/format/format.h3
-rw-r--r--src/format/symbol.c15
-rw-r--r--src/format/symbol.h15
8 files changed, 321 insertions, 22 deletions
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 <assert.h>
+#include <ctype.h>
#include <string.h>
@@ -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 <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 */