diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2009-08-09 18:12:27 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2009-08-09 18:12:27 (GMT) |
commit | 5cd25c4adfe0426520a51a76de3f77c77cfa4b8e (patch) | |
tree | 396514971fb78e81b7bb55c9cd3331d87b45ca9a /src/format/elf/strings.c | |
parent | d02deb2425d6559c357bdd00e1c0fb05f35d5fc9 (diff) |
Reorganized the way formats are handled (Java and PE got disabled, Dwarf is empty).
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@105 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format/elf/strings.c')
-rw-r--r-- | src/format/elf/strings.c | 161 |
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, §ions, &count); + if (find_elf_sections_by_type(format, SHT_PROGBITS, §ions, &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, §ions[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, §ions[i], sh_flags) == SHF_ALLOC - || (ELF_SHDR(format, §ions[i], sh_flags) & SHF_STRINGS)) - { - get_elf_section_content(format, §ions[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, §ions, &count); - - for (i = 0; i < count; i++) + if (find_elf_sections_by_type(format, SHT_STRTAB, §ions, &count)) { - get_elf_section_content(format, §ions[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, §ions[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; } |