summaryrefslogtreecommitdiff
path: root/src/format/elf/strings.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/format/elf/strings.c')
-rw-r--r--src/format/elf/strings.c161
1 files changed, 76 insertions, 85 deletions
diff --git a/src/format/elf/strings.c b/src/format/elf/strings.c
index 2bcd911..157d3b5 100644
--- a/src/format/elf/strings.c
+++ b/src/format/elf/strings.c
@@ -27,6 +27,7 @@
#include <ctype.h>
#include <malloc.h>
#include <string.h>
+#include <sys/param.h>
#include "elf-int.h"
@@ -35,7 +36,7 @@
/* Enregistre toutes les chaînes de caractères trouvées. */
-bool parse_elf_string_data(elf_format *, const off_t, const off_t, uint64_t);
+bool parse_elf_string_data(GElfFormat *, off_t, off_t, vmpa_t);
@@ -51,63 +52,81 @@ bool parse_elf_string_data(elf_format *, const off_t, const off_t, uint64_t);
* *
******************************************************************************/
-bool find_all_elf_strings(elf_format *format)
+bool find_all_elf_strings(GElfFormat *format)
{
+ bool got_string; /* Indique un remplissage */
off_t str_start; /* Début de section */
off_t str_size; /* Taille de section */
- uint64_t str_vaddr; /* Adresse virtuelle associée */
- Elf_Shdr *sections; /* Groupe de sections trouvées */
+ vmpa_t str_addr; /* Adresse virtuelle associée */
+ elf_shdr *sections; /* Groupe de sections trouvées */
size_t count; /* Quantité de données */
- size_t i; /* Boucle de parcours */
- off_t offset; /* Position physique */
- Elf_Phdr phdr; /* En-tête de programme ELF */
+ size_t i; /* Boucle de parcours #1 */
+ off_t length; /* Taille totale du contenu */
+ off_t iter; /* Boucle de parcours #2 */
+ elf_phdr phdr; /* En-tête de programme ELF */
+
+ got_string = false;
/* Données en lecture seule */
- if (find_elf_section_content_by_name(format, ".rodata", &str_start, &str_size, &str_vaddr))
- parse_elf_string_data(format, str_start, str_size, str_vaddr);
+ if (find_elf_section_content_by_name(format, ".rodata", &str_start, &str_size, &str_addr))
+ got_string |= parse_elf_string_data(format, str_start, str_size, str_addr);
else
{
- find_elf_section_by_type(format, SHT_PROGBITS, &sections, &count);
+ if (find_elf_sections_by_type(format, SHT_PROGBITS, &sections, &count))
+ {
+ for (i = 0; i < count; i++)
+ if (ELF_SHDR(format, sections[i], sh_flags) == SHF_ALLOC
+ || (ELF_SHDR(format, sections[i], sh_flags) & SHF_STRINGS))
+ {
+ get_elf_section_content(format, &sections[i], &str_start, &str_size, &str_addr);
+ got_string |= parse_elf_string_data(format, str_start, str_size, str_addr);
+ }
- for (i = 0; i < count; i++)
- if (ELF_SHDR(format, &sections[i], sh_flags) == SHF_ALLOC
- || (ELF_SHDR(format, &sections[i], sh_flags) & SHF_STRINGS))
- {
- get_elf_section_content(format, &sections[i], &str_start, &str_size, &str_vaddr);
- parse_elf_string_data(format, str_start, str_size, str_vaddr);
- }
+ free(sections);
+
+ }
}
/* Chaîne de caractères déclarées */
- find_elf_section_by_type(format, SHT_STRTAB, &sections, &count);
-
- for (i = 0; i < count; i++)
+ if (find_elf_sections_by_type(format, SHT_STRTAB, &sections, &count))
{
- get_elf_section_content(format, &sections[i], &str_start, &str_size, &str_vaddr);
- parse_elf_string_data(format, str_start, str_size, str_vaddr);
+ for (i = 0; i < count; i++)
+ {
+ get_elf_section_content(format, &sections[i], &str_start, &str_size, &str_addr);
+ got_string |= parse_elf_string_data(format, str_start, str_size, str_addr);
+ }
+
+ free(sections);
+
}
/* En désespoir de cause, on se rabbat sur les parties de programme directement */
- if (format->str_count == 0 && format->header.e_shnum == 0 /* FIXME : cond. à garder ? */)
- for (i = 0; i < format->header.e_phnum; i++)
- {
- offset = format->header.e_phoff + format->header.e_phentsize * i;
- if ((offset + format->header.e_phentsize) >= EXE_FORMAT(format)->length) continue;
+ if (!got_string)
+ {
+ length = G_BIN_FORMAT(format)->length;
+ length = MIN(length, format->header.e_phnum * ELF_SIZEOF_PHDR(format));
- memcpy(&phdr, &EXE_FORMAT(format)->content[offset], format->header.e_phentsize);
+ for (iter = ELF_OFF(format, format->header.e_phoff); iter < length; )
+ {
+ if (!read_elf_program_header(format, &iter, &phdr))
+ continue;
- if (ELF_PHDR(format, &phdr, p_flags) & PF_R && !(ELF_PHDR(format, &phdr, p_flags) & PF_X))
- parse_elf_string_data(format, ELF_PHDR(format, &phdr, p_offset),
- ELF_PHDR(format, &phdr, p_filesz),
- ELF_PHDR(format, &phdr, p_vaddr));
+ if (ELF_PHDR(format, phdr, p_flags) & PF_R
+ && !(ELF_PHDR(format, phdr, p_flags) & PF_X))
+ parse_elf_string_data(format,
+ ELF_PHDR(format, phdr, p_offset),
+ ELF_PHDR(format, phdr, p_filesz),
+ ELF_PHDR(format, phdr, p_vaddr));
}
+ }
+
return true;
}
@@ -115,77 +134,49 @@ bool find_all_elf_strings(elf_format *format)
/******************************************************************************
* *
-* Paramètres : format = description de l'exécutable à compléter. *
-* start = début de la zone à parcourir. *
-* size = taille de l'espace à parcourir. *
-* vaddress = adresse virtuelle du début de la section. *
+* Paramètres : format = description de l'exécutable à compléter. *
+* start = début de la zone à parcourir. *
+* size = taille de l'espace à parcourir. *
+* address = adresse virtuelle du début de la section. *
* *
* Description : Enregistre toutes les chaînes de caractères trouvées. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : true si des chaînes ont été ajoutées, false sinon. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool parse_elf_string_data(elf_format *format, const off_t start, const off_t size, uint64_t vaddress)
+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 */
off_t i; /* Boucle de parcours */
off_t end; /* Position de fin de chaîne */
+ GBinSymbol *symbol; /* Nouveau symbole construit */
- if (vaddress == 0) return false;
-
- for (i = start; i < (start + size); i++)
- if (isprint(EXE_FORMAT(format)->content[i]))
- {
- for (end = i + 1; end < (start + size); end++)
- if (!isprint(EXE_FORMAT(format)->content[end])) break;
-
- format->strings = (elf_string *)realloc(format->strings, ++format->str_count * sizeof(elf_string));
-
- format->strings[format->str_count - 1].value = strndup((const char *)&EXE_FORMAT(format)->content[i], end - i);
- format->strings[format->str_count - 1].len = end - i;
- format->strings[format->str_count - 1].address = vaddress + i - start;
-
- i = end;
-
- }
+ if (address == 0) return false;
- return true;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = informations chargées à consulter. *
-* label = étiquette allouée du symbole si trouvé. [OUT] *
-* vaddres = adresse à cibler, puis décallage final. [OUT] *
-* *
-* Description : Recherche une chaîne correspondant à une adresse. *
-* *
-* Retour : true si l'opération a été un succès, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ result = false;
-bool resolve_elf_strings(const elf_format *format, char **label, vmpa_t *address)
-{
- bool result; /* Bilan de recherche remonté */
- size_t real_start; /* Début de chaîne effective */
- size_t i; /* Boucle de parcours */
+ content = G_BIN_FORMAT(format)->content;
+ length = G_BIN_FORMAT(format)->length;
- result = false;
+ length = MIN(length, start + size);
- for (i = 0; i < format->str_count && !result; i++)
- if (format->strings[i].address <= *address
- && *address < (format->strings[i].address + format->strings[i].len))
+ for (i = start; i < length; i++)
+ if (isprint(content[i]))
{
- real_start = *address - format->strings[i].address;
- *label = strndup(&format->strings[i].value[real_start],
- format->strings[i].len - real_start);
+ 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));
+ g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
+
+ i = end;
result = true;
}