diff options
Diffstat (limited to 'src/format/elf')
-rw-r--r-- | src/format/elf/Makefile.am | 1 | ||||
-rw-r--r-- | src/format/elf/e_elf.c | 11 | ||||
-rw-r--r-- | src/format/elf/elf-int.h | 12 | ||||
-rw-r--r-- | src/format/elf/strings.c | 145 | ||||
-rw-r--r-- | src/format/elf/strings.h | 40 |
5 files changed, 209 insertions, 0 deletions
diff --git a/src/format/elf/Makefile.am b/src/format/elf/Makefile.am index 4886115..2240a35 100644 --- a/src/format/elf/Makefile.am +++ b/src/format/elf/Makefile.am @@ -5,6 +5,7 @@ libformatelf_a_SOURCES = \ e_elf.h e_elf.c \ elf-int.h \ section.h section.c \ + strings.h strings.c \ symbol.h symbol.c libformatelf_a_CFLAGS = $(AM_CFLAGS) diff --git a/src/format/elf/e_elf.c b/src/format/elf/e_elf.c index 03b2e82..c2e49b1 100644 --- a/src/format/elf/e_elf.c +++ b/src/format/elf/e_elf.c @@ -30,6 +30,7 @@ #include "elf-int.h" #include "section.h" +#include "strings.h" #include "symbol.h" @@ -95,6 +96,10 @@ elf_format *load_elf(const uint8_t *content, off_t length) printf("ok ? %d\n", test); + test = find_all_elf_strings(result); + + printf("ok ? %d\n", test); + test = load_elf_symbols(result); printf("ok ? %d\n", test); @@ -279,6 +284,12 @@ bool resolve_elf_symbol(const elf_format *format, char **label, SymbolType *type uint64_t best_addr; /* Meilleure adresse trouvée */ size_t i; /* Boucle de parcours */ + if (resolve_elf_strings(format, label, offset)) + { + *type = STP_STRING; + return true; + } + best_addr = UINT64_MAX; for (i = 0; i < format->sym_count; i++) diff --git a/src/format/elf/elf-int.h b/src/format/elf/elf-int.h index 6e7bca1..02cc2dd 100644 --- a/src/format/elf/elf-int.h +++ b/src/format/elf/elf-int.h @@ -34,6 +34,15 @@ +/* Chaîne de caractères présente */ +typedef struct _elf_string +{ + const char *value; /* Valeur humainement lisible */ + size_t len; /* Longueur de la chaîne */ + uint64_t vaddress; /* Adresse de localisation */ + +} elf_string; + /* Symbole trouvé */ typedef struct _elf_symbol { @@ -58,6 +67,9 @@ struct _elf_format elf_symbol *symbols; /* Liste des symboles */ size_t sym_count; /* Taille de cette liste */ + elf_string *strings; /* Liste des chaînes */ + size_t str_count; /* Taille de cette liste */ + }; diff --git a/src/format/elf/strings.c b/src/format/elf/strings.c new file mode 100644 index 0000000..3d373a6 --- /dev/null +++ b/src/format/elf/strings.c @@ -0,0 +1,145 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * strings.c - recherche des chaînes contenues dans un ELF + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "strings.h" + + +#include <ctype.h> +#include <malloc.h> +#include <string.h> + + +#include "elf-int.h" +#include "section.h" + + + +/* 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); + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à analyser. * +* * +* Description : Charge en mémoire toutes les chaînes trouvées. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool find_all_elf_strings(elf_format *format) +{ + off_t str_start; /* Début de section */ + off_t str_size; /* Taille de section */ + uint64_t str_vaddr; /* Adresse virtuelle associée */ + + if (find_elf_section(format, ".rodata", &str_start, &str_size, &str_vaddr)) + parse_elf_string_data(format, str_start, str_size, str_vaddr); + + return true; + +} + + +/****************************************************************************** +* * +* 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. * +* * +* Description : Enregistre toutes les chaînes de caractères trouvées. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool parse_elf_string_data(elf_format *format, const off_t start, const off_t size, uint64_t vaddress) +{ + off_t i; /* Boucle de parcours */ + off_t end; /* Position de fin de chaîne */ + + 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 = (const char *)&EXE_FORMAT(format)->content[i]; + format->strings[format->str_count - 1].len = end - start; + format->strings[format->str_count - 1].vaddress = vaddress + i - start; + + i = end; + + } + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* label = étiquette allouée du symbole si trouvé. [OUT] * +* vaddress = 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 : - * +* * +******************************************************************************/ + +bool resolve_elf_strings(const elf_format *format, char **label, uint64_t *vaddress) +{ + bool result; /* Bilan de recherche remonté */ + size_t real_start; /* Début de chaîne effective */ + size_t i; /* Boucle de parcours */ + + result = false; + + for (i = 0; i < format->str_count && !result; i++) + if (format->strings[i].vaddress <= *vaddress + && *vaddress < (format->strings[i].vaddress + format->strings[i].len)) + { + real_start = *vaddress - format->strings[i].vaddress; + *label = strndup(&format->strings[i].value[real_start], + format->strings[i].len - real_start); + + result = true; + + } + + return result; + +} diff --git a/src/format/elf/strings.h b/src/format/elf/strings.h new file mode 100644 index 0000000..c636774 --- /dev/null +++ b/src/format/elf/strings.h @@ -0,0 +1,40 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * strings.h - prototypes pour la recherche des chaînes contenues dans un ELF + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _FORMAT_ELF_STRINGS_H +#define _FORMAT_ELF_STRINGS_H + + +#include "e_elf.h" + + + +/*Charge en mémoire toutes les chaînes trouvées. */ +bool find_all_elf_strings(elf_format *); + +/* Recherche une chaîne correspondant à une adresse. */ +bool resolve_elf_strings(const elf_format *, char **, uint64_t *); + + + +#endif /* _FORMAT_ELF_STRINGS_H */ |