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/e_elf.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/e_elf.c')
-rw-r--r-- | src/format/elf/e_elf.c | 604 |
1 files changed, 0 insertions, 604 deletions
diff --git a/src/format/elf/e_elf.c b/src/format/elf/e_elf.c deleted file mode 100644 index a91e279..0000000 --- a/src/format/elf/e_elf.c +++ /dev/null @@ -1,604 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * e_elf.c - support du format 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 "e_elf.h" - - -#include <malloc.h> -#include <string.h> - - -#include "elf-int.h" -#include "section.h" -#include "strings.h" -#include "symbol.h" -#include "../../panel/log.h" -#include "../../common/extstr.h" - - - - -#define _(str) str - - - - -/* Indique le type d'architecture visée par le format. */ -FormatTargetMachine get_elf_target_machine(const elf_format *); - - - -/* Fournit l'adresse mémoire du point d'entrée du programme. */ -uint64_t get_elf_entry_point(const elf_format *); - - - - - -/* Récupère tous les éléments identifiées dans le binaire. */ -size_t get_elf_resolved_items(const elf_format *, char ***, ResolvedType **, uint64_t **); - - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à parcourir. * -* length = taille du contenu en question. * -* * -* Description : Indique si le format peut être pris en charge ici. * -* * -* Retour : true si la réponse est positive, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool elf_is_matching(const uint8_t *content, off_t length) -{ - bool result; /* Bilan à faire connaître */ - - result = false; - - if (length >= 4) - result = (strncmp((const char *)content, "\x7f\x45\x4c\x46" /* .ELF */, 4) == 0); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : content = contenu binaire à parcourir. * -* length = taille du contenu en question. * -* * -* Description : Prend en charge un nouvel ELF. * -* * -* Retour : Adresse de la structure mise en place ou NULL en cas d'échec.* -* * -* Remarques : - * -* * -******************************************************************************/ - -elf_format *load_elf(const uint8_t *content, off_t length) -{ - elf_format *result; /* Structure à retourner */ - bool test; /* Bilan d'une initialisation */ - - - Elf32_Half i; - Elf32_Phdr phdr; - - size_t count; - - - result = (elf_format *)calloc(1, sizeof(elf_format)); - - EXE_FORMAT(result)->content = content; - EXE_FORMAT(result)->length = length; - - EXE_FORMAT(result)->get_target_machine = (get_target_machine_fc)get_elf_target_machine; - EXE_FORMAT(result)->get_entry_point = (get_entry_point_fc)get_elf_entry_point; - EXE_FORMAT(result)->get_def_parts = (get_def_parts_fc)get_elf_default_code_parts; - EXE_FORMAT(result)->find_section = (find_section_fc)find_elf_section_content_by_name; - EXE_FORMAT(result)->get_symbols = (get_symbols_fc)get_elf_symbols; - EXE_FORMAT(result)->get_resolved = (get_resolved_fc)get_elf_resolved_items; - EXE_FORMAT(result)->resolve_symbol = (resolve_symbol_fc)resolve_elf_symbol; - EXE_FORMAT(result)->get_all_routines = (get_all_routines_fc)get_all_elf_routines; - - memcpy(&result->header, content, sizeof(Elf32_Ehdr)); - - - /* TODO : endian */ - - - /* Vérification des tailles d'entrée de table */ - switch (result->header.e_ident[EI_CLASS]) - { - case ELFCLASS32: - - if (result->header.e_phentsize != sizeof(Elf32_Phdr)) - { - log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed !"), - result->header.e_phentsize); - result->header.e_phentsize = sizeof(Elf32_Phdr); - } - - if (result->header.e_shentsize != sizeof(Elf32_Shdr)) - { - log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed !"), - result->header.e_shentsize); - result->header.e_shentsize = sizeof(Elf32_Shdr); - } - - break; - - case ELFCLASS64: - - if (result->header.e_phentsize != sizeof(Elf64_Phdr)) - { - log_variadic_message(LMT_BAD_BINARY, _("Corrupted program header size (%hu); fixed !"), - result->header.e_phentsize); - result->header.e_phentsize = sizeof(Elf64_Phdr); - } - - if (result->header.e_shentsize != sizeof(Elf64_Shdr)) - { - log_variadic_message(LMT_BAD_BINARY, _("Corrupted section header size (%hu); fixed !"), - result->header.e_shentsize); - result->header.e_shentsize = sizeof(Elf64_Shdr); - } - - break; - - default: - log_variadic_message(LMT_BAD_BINARY, ("Invalid ELF class '%hhu'"), - result->header.e_ident[EI_CLASS]); - break; - - } - - - /* FIXME : à améliorer */ - if ((result->header.e_shnum * result->header.e_shentsize) >= length) - { - log_variadic_message(LMT_BAD_BINARY, ("Suspicious section table (bigger than the binary !) ; reset !")); - result->header.e_shnum = 0; - } - - - result->is_32b = (result->header.e_ident[EI_CLASS] == ELFCLASS32); - - - for (i = 0; i < result->header.e_phnum; i++) - { - - memcpy(&phdr, &content[result->header.e_phoff + i * result->header.e_phentsize], result->header.e_phentsize); - - - printf(" seg [0x%08x] :: %d -> %d\n", phdr.p_type, phdr.p_offset, phdr.p_filesz); - - - } - - - test = read_elf_section_names(result); - - printf("section names ok ? %d\n", test); - - test = find_all_elf_strings(result); - - printf("strings ok ? %d\n", test); - - test = load_elf_symbols(result); - - printf("symbols ok ? %d\n", test); - - - - return result; - - lelf: - - /* TODO */ - - return NULL; - -} - - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* * -* Description : Indique le type d'architecture visée par le format. * -* * -* Retour : Identifiant de l'architecture ciblée par le format. * -* * -* Remarques : - * -* * -******************************************************************************/ - -FormatTargetMachine get_elf_target_machine(const elf_format *format) -{ - FormatTargetMachine result; /* Identifiant à retourner */ - - switch (format->header.e_machine) - { - case EM_MIPS: - result = FTM_MIPS; - break; - - case EM_386: - result = FTM_386; - break; - - default: - /* FIXME */ - break; - - } - - return result; - -} - - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* * -* Description : Fournit l'adresse mémoire du point d'entrée du programme. * -* * -* Retour : Adresse de mémoire. * -* * -* Remarques : - * -* * -******************************************************************************/ - -uint64_t get_elf_entry_point(const elf_format *format) -{ - return format->header.e_entry; - -} - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* count = quantité de zones listées. [OUT] * -* * -* Description : Fournit les références aux zones de code à analyser. * -* * -* Retour : Zones de code à analyser. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bin_part **get_elf_default_code_parts(const elf_format *format, size_t *count) -{ - bin_part **result; /* Tableau à retourner */ - bin_part *part; /* Partie à intégrer à la liste*/ - off_t offset; /* Position physique */ - off_t size; /* Taille de la partie */ - uint64_t voffset; /* Adresse virtuelle éventuelle*/ - int i; /* Boucle de parcours */ - Elf_Shdr shdr; /* En-tête de section ELF */ - Elf_Phdr phdr; /* En-tête de programme ELF */ - - result = NULL; - *count = 0; - - if (format->sec_size > 0) - { - if (find_elf_section_content_by_name(format, ".plt", &offset, &size, &voffset)) - { - part = create_bin_part(); - - set_bin_part_name(part, ".plt"); - set_bin_part_values(part, offset, size, voffset); - - result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *)); - result[*count - 1] = part; - - } - - if (find_elf_section_content_by_name(format, ".MIPS.stubs", &offset, &size, &voffset)) - { - part = create_bin_part(); - - set_bin_part_name(part, ".MIPS.stubs"); - set_bin_part_values(part, offset, size, voffset); - - result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *)); - result[*count - 1] = part; - - } - - if (find_elf_section_content_by_name(format, ".init", &offset, &size, &voffset)) - { - part = create_bin_part(); - - set_bin_part_name(part, ".init"); - set_bin_part_values(part, offset, size, voffset); - - result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *)); - result[*count - 1] = part; - - } - - if (find_elf_section_content_by_name(format, ".text", &offset, &size, &voffset)) - { - part = create_bin_part(); - - set_bin_part_name(part, ".text"); - set_bin_part_values(part, offset, size, voffset); - - result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *)); - result[*count - 1] = part; - - } - - if (find_elf_section_content_by_name(format, ".fini", &offset, &size, &voffset)) - { - part = create_bin_part(); - - set_bin_part_name(part, ".fini"); - set_bin_part_values(part, offset, size, voffset); - - result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *)); - result[*count - 1] = part; - - } - - } - - /* Si aucune section n'a été trouvée... */ - - if (*count == 0) - for (i = 0; i < format->header.e_shnum; i++) - { - offset = format->header.e_shoff + format->header.e_shentsize * i; - if ((offset + format->header.e_shentsize) >= EXE_FORMAT(format)->length) continue; - - memcpy(&shdr, &EXE_FORMAT(format)->content[offset], format->header.e_shentsize); - - if (ELF_SHDR(format, &shdr, sh_flags) & SHF_EXECINSTR) - { - part = create_bin_part(); - - /* TODO : nom */ - - set_bin_part_values(part, ELF_SHDR(format, &shdr, sh_offset), - ELF_SHDR(format, &shdr, sh_size), - ELF_SHDR(format, &shdr, sh_addr)); - - result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *)); - result[*count - 1] = part; - - } - - } - - /* En désespoir de cause, on se rabbat sur les parties de programme directement */ - - if (*count == 0) - 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; - - memcpy(&phdr, &EXE_FORMAT(format)->content[offset], format->header.e_phentsize); - - if (ELF_PHDR(format, &phdr, p_flags) & PF_X) - { - part = create_bin_part(); - - /* TODO : nom */ - - set_bin_part_values(part, ELF_PHDR(format, &phdr, p_offset), - ELF_PHDR(format, &phdr, p_filesz), - ELF_PHDR(format, &phdr, p_vaddr)); - - result = (bin_part **)realloc(result, ++(*count) * sizeof(bin_part *)); - result[*count - 1] = part; - - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* labels = liste des commentaires à insérer. [OUT] * -* types = type des symboles listés. [OUT] * -* offsets = liste des indices des commentaires. [OUT] * -* * -* Description : Récupère tous les symboles présents dans le contenu binaire. * -* * -* Retour : Nombre d'éléments mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -size_t get_elf_symbols(const elf_format *format, char ***labels, SymbolType **types, uint64_t **offsets) -{ - size_t result; /* Quantité à retourner */ - size_t i; /* Boucle de parcours */ - - result = format->sym_count; - - *labels = (char **)calloc(result, sizeof(char *)); - *types = (SymbolType *)calloc(result, sizeof(SymbolType)); - *offsets = (uint64_t *)calloc(result, sizeof(uint64_t)); - - for (i = 0; i < format->sym_count; i++) - { - (*labels)[i] = strdup(format->symbols[i].name); - (*types)[i] = STP_SECTION; - (*offsets)[i] = format->symbols[i].address; - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* labels = liste des commentaires à insérer. [OUT] * -* types = type des symboles listés. [OUT] * -* offsets = liste des indices des commentaires. [OUT] * -* * -* Description : Récupère tous les éléments identifiées dans le binaire. * -* * -* Retour : Nombre d'éléments mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -size_t get_elf_resolved_items(const elf_format *format, char ***labels, ResolvedType **types, uint64_t **offsets) -{ - size_t result; /* Quantité à retourner */ - size_t i; /* Boucle de parcours */ - size_t start; /* Point de départ du tour */ - - result = format->sym_count + format->str_count; - - *labels = (char **)calloc(result, sizeof(char *)); - *types = (SymbolType *)calloc(result, sizeof(SymbolType)); - *offsets = (uint64_t *)calloc(result, sizeof(uint64_t)); - - for (i = 0; i < format->sym_count; i++) - { - (*labels)[i] = strdup(format->symbols[i].name); - (*types)[i] = RTP_SECTION; - (*offsets)[i] = format->symbols[i].address; - } - - start = format->sym_count; - - for (i = 0; i < format->str_count; i++) - { - (*labels)[start + i] = strndup(format->strings[i].value, format->strings[i].len); - (*types)[start + i] = RTP_STRING; - (*offsets)[start + i] = format->strings[i].address; - - (*labels)[start + i] = escape_crlf((*labels)[start + i]); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* label = étiquette du symbole si trouvé. [OUT] * -* type = type du symbole trouvé. [OUT] * -* address = adresse à cibler, puis décallage final. [OUT] * -* * -* Description : Recherche le symbole correspondant à une adresse. * -* * -* Retour : true si l'opération a été un succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool resolve_elf_symbol(const elf_format *format, char **label, SymbolType *type, vmpa_t *address) -{ - bool result; /* Bilan à retourner */ - size_t best_index; /* Meilleur symbole trouvé */ - vmpa_t best_addr; /* Meilleure adresse trouvée */ - vmpa_t addr; /* Adresse de routine */ - size_t i; /* Boucle de parcours */ - - if (resolve_elf_strings(format, label, address)) - { - *type = STP_STRING; - return true; - } - - best_index = format->routines_count; /* Pour GCC */ - best_addr = UINT64_MAX; /* FIXME */ - - for (i = 0; i < format->routines_count; i++) - { - addr = g_binary_routine_get_address(format->routines[i]); - - if (addr <= *address && (*address - addr) < best_addr) - { - best_index = i; - best_addr = *address - addr; - } - - } - - result = (best_addr != UINT64_MAX); - - if (result) - { - *label = strdup(g_binary_routine_get_name(format->routines[best_index])); - *type = STP_SECTION; - *address -= g_binary_routine_get_address(format->routines[best_index]); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* count = taille du tableau créé. [OUT] * -* * -* Description : Fournit le prototype de toutes les routines détectées. * -* * -* Retour : Tableau créé ou NULL si aucun symbole de routine trouvé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GBinRoutine **get_all_elf_routines(const elf_format *format, size_t *count) -{ - *count = format->routines_count; - - return format->routines; - -} |