diff options
Diffstat (limited to 'src/format/elf/symbol.c')
-rw-r--r-- | src/format/elf/symbol.c | 492 |
1 files changed, 0 insertions, 492 deletions
diff --git a/src/format/elf/symbol.c b/src/format/elf/symbol.c deleted file mode 100644 index 35943e9..0000000 --- a/src/format/elf/symbol.c +++ /dev/null @@ -1,492 +0,0 @@ - -/* OpenIDA - Outil d'analyse de fichiers binaires - * symbol.c - gestion des symboles d'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 "symbol.h" - - -#include <malloc.h> -#include <elf.h> -#include <stdio.h> -#include <string.h> - - -#include "elf-int.h" -#include "helper_mips.h" -#include "section.h" - - - - - -/* -------------------------- DETAIL DES SYMBOLES EXTERNES -------------------------- */ - - -/* Charge en mémoire la liste des symboles dynamiques. */ -bool load_elf_relocation_table(elf_format *, const off_t *, const off_t *, const off_t *, const off_t *, const off_t *, const off_t *); - -/* Récupère les informations d'un symbole dynamique donné. */ -char *get_elf_dynamic_symbol_info(elf_format *, const off_t *, const off_t *, const off_t *, const off_t *, const off_t *); - - - - -/* Charge en mémoire la liste humaine des symboles (32 bits). */ -bool load_elf_symbol_table_32(elf_format *, const off_t *, const off_t *, const off_t *, const off_t *); - -/* Charge en mémoire la liste humaine des symboles (64 bits). */ -bool load_elf_symbol_table_64(elf_format *, const off_t *, const off_t *, const off_t *, const off_t *); - - - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* * -* Description : Charge en mémoire la liste humaine des symboles. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_elf_symbols(elf_format *format) -{ - bool result; /* Bilan à retourner */ - Elf_Shdr *sections; /* Groupe de sections trouvées */ - size_t count; /* Quantité de données */ - size_t i; /* Boucle de parcours */ - Elf_Shdr section; /* Section trouvée ou non */ - off_t sym_start; /* Début de section */ - off_t sym_size; /* Taille de section */ - off_t str_start; /* Début de section */ - off_t str_size; /* Taille de section */ - off_t rel_start; /* Début de section */ - off_t rel_size; /* Taille de section */ - - - bool test; /* Bilan d'une recherche */ - - off_t dyn_start; /* Début de section */ - off_t dyn_size; /* Taille de section */ - - - - result = true; - - - /* Table des symboles */ - - find_elf_section_by_type(format, SHT_SYMTAB, §ions, &count); - - for (i = 0; i < count; i++) - { - /* Section ".symtab" */ - - get_elf_section_content(format, §ions[i], &sym_start, &sym_size, NULL); - - /* Section ".strtab" */ - - result &= find_elf_section_by_index(format, ELF_SHDR(format, §ions[i], sh_link), §ion); - - get_elf_section_content(format, §ion, &str_start, &str_size, NULL); - - if (result) - { - - - - result = load_elf_symbol_table_32(format, &sym_start, &sym_size, &str_start, &str_size); - - - - } - - } - - /* Relocalisations */ - - - - /* TODO : fixme ! */ - - find_elf_section_by_type(format, SHT_REL, §ions, &count); - - for (i = 0; i < count; i++) - { - /* Section ".rel.xxx" */ - - get_elf_section_content(format, §ions[i], &rel_start, &rel_size, NULL); - - /* Section ".dynsym" */ - - result &= find_elf_section_by_index(format, ELF_SHDR(format, §ions[i], sh_link), §ion); - - get_elf_section_content(format, §ion, &dyn_start, &dyn_size, NULL); - - /* Section ".dynstr" */ - - result &= find_elf_section_by_index(format, ELF_SHDR(format, §ion, sh_link), §ion); - - get_elf_section_content(format, §ion, &str_start, &str_size, NULL); - - /* Récupération (première partie) */ - if (result) - { - - result = load_elf_relocation_table(format, &rel_start, &rel_size, &dyn_start, &dyn_size, &str_start, &str_size); - - - } - - } - - free(sections); - - /* TODO : fixme ! */ - - - - - - /* Liaison dynamique (si elle existe) */ - - test = find_elf_section_by_name(format, ".dynsym", §ion); - - if (!test) - { - test = find_elf_section_by_type(format, SHT_HASH, §ions, &count); - - if (test) - test = find_elf_section_by_index(format, ELF_SHDR(format, §ions[0], sh_link), §ion); - - } - - if (test) - { - get_elf_section_content(format, §ion, &dyn_start, &dyn_size, NULL); - - result &= find_elf_section_by_index(format, ELF_SHDR(format, §ion, sh_link), §ion); - - } - - if (result) - { - get_elf_section_content(format, §ion, &str_start, &str_size, NULL); - - switch (get_elf_target_machine(format)) - { - case FTM_MIPS: - result = g_elf_format_find_mips_dynamic_symbols(format, dyn_start, dyn_size, str_start, str_size); - break; - - case FTM_386: - result = g_elf_format_find_x86_dynamic_symbols(format, dyn_start, dyn_size, str_start, str_size); - break; - - default: - break; - - } - - } - - return result; - -} - - - - - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* sym_start = début de la zone à traiter. * -* sym_size = taille de la zone à traiter. * -* str_start = début de la zone de chaîne de caractères. * -* str_size = taille de la zone de chaînes de caractères. * -* * -* Description : Charge en mémoire la liste humaine des symboles (32 bits). * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_elf_symbol_table_32(elf_format *format, const off_t *sym_start, const off_t *sym_size, const off_t *str_start, const off_t *str_size) -{ - off_t iter; /* Boucle de parcours */ - Elf32_Sym symbol; /* Symbole ELF lu */ - GBinRoutine *routine; /* Nouvelle routine trouvée */ - - if (*sym_size % sizeof(Elf32_Sym) != 0) return false; - - for (iter = *sym_start; iter < (*sym_start + *sym_size); iter += sizeof(Elf32_Sym)) - { - memcpy(&symbol, &EXE_FORMAT(format)->content[iter], sizeof(Elf32_Sym)); - - if (!(ELF32_ST_TYPE(symbol.st_info) == STT_FUNC)) continue; - - if (symbol.st_value == 0) continue; - - /* Sécurité anti-débordements */ - if (symbol.st_name >= *str_size) continue; - - /* Si le symbole possède un nom... */ - if (strlen(&EXE_FORMAT(format)->content[*str_start + symbol.st_name]) > 0) - { - routine = g_binary_routine_new(); - - g_binary_routine_set_name(routine, strdup(&EXE_FORMAT(format)->content[*str_start + symbol.st_name])); - g_binary_routine_set_address(routine, symbol.st_value); - g_binary_routine_set_size(routine, symbol.st_size); - - format->routines = (GBinRoutine **)realloc(format->routines, - ++format->routines_count * sizeof(GBinRoutine *)); - - format->routines[format->routines_count - 1] = routine; - - } - - } - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* sym_start = début de la zone à traiter. * -* sym_size = taille de la zone à traiter. * -* str_start = début de la zone de chaîne de caractères. * -* str_size = taille de la zone de chaînes de caractères. * -* * -* Description : Charge en mémoire la liste humaine des symboles (64 bits). * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_elf_symbol_table_64(elf_format *format, const off_t *sym_start, const off_t *sym_size, const off_t *str_start, const off_t *str_size) -{ - off_t iter; /* Boucle de parcours */ - Elf64_Sym symbol; /* Symbole ELF lu */ - - if (*sym_size % sizeof(Elf64_Sym) != 0) return false; - - for (iter = *sym_start; iter < (*sym_start + *sym_size); iter += sizeof(Elf64_Sym)) - { - memcpy(&symbol, &EXE_FORMAT(format)->content[iter], sizeof(Elf64_Sym)); - - if (!(ELF64_ST_TYPE(symbol.st_info) == STT_FUNC - || (ELF64_ST_TYPE(symbol.st_info) == STT_NOTYPE - && ELF64_ST_BIND(symbol.st_info) == STB_GLOBAL))) continue; - - if (symbol.st_value == 0) continue; - - /* Sécurité anti-débordements */ - if (symbol.st_name >= *str_size) continue; - - /* Si le symbole possède un nom... */ - if (strlen(&EXE_FORMAT(format)->content[*str_start + symbol.st_name]) > 0) - { - format->symbols = (elf_symbol *)realloc(format->symbols, ++format->sym_count * sizeof(elf_symbol)); - - format->symbols[format->sym_count - 1].name = &EXE_FORMAT(format)->content[*str_start + symbol.st_name]; - format->symbols[format->sym_count - 1].address = symbol.st_value; - - } - - } - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : format = informations chargées à consulter. * -* comments = liste des commentaires à insérer. [OUT] * -* offsets = liste des indices des commentaires. [OUT] * -* count = taille des listes construites. [OUT] * -* * -* Description : Récupère tous les commentaires à insérer dans le code. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void get_elf_symbol_comments(const elf_format *format, char ***comments, uint64_t **offsets, size_t *count) -{ - size_t i; /* Boucle de parcours */ - size_t len; /* Longueur d'une désignation */ - - if (format->sym_count > 0) - { - *comments = (char **)calloc(*count + format->sym_count, sizeof(char *)); - *offsets = (uint64_t *)calloc(*count + format->sym_count, sizeof(uint64_t)); - - for (i = 0; i < format->sym_count; i++) - { - len = strlen(format->symbols[i].name); - - (*comments)[i] = (char *)calloc(len + 9, sizeof(char)); - snprintf((*comments)[i], len + 9, "<%s>", format->symbols[i].name); - - (*offsets)[i] = format->symbols[i].address; - - } - - *count += format->sym_count; - - } - -} - - - - - - - - -/* ---------------------------------------------------------------------------------- */ -/* DETAIL DES SYMBOLES EXTERNES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* plt_start = début de la zone à traiter. * -* plt_size = taille de la zone à traiter. * -* dyn_start = début des informations dynamiques associées. * -* dyn_size = taille de la zone associée. * -* str_start = début de la zone de chaîne de caractères. * -* str_size = taille de la zone de chaînes de caractères. * -* * -* Description : Charge en mémoire la liste des symboles dynamiques. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_elf_relocation_table(elf_format *format, const off_t *plt_start, const off_t *plt_size, const off_t *dyn_start, const off_t *dyn_size, const off_t *str_start, const off_t *str_size) -{ - off_t iter; /* Boucle de parcours */ - Elf_Rel reloc; /* Infos de relocalisation */ - off_t index; /* Indice de la portion visée */ - char *name; /* Nom du symbole trouvé */ - - for (iter = *plt_start; iter < (*plt_start + *plt_size); iter += ELF_SIZEOF_REL(format)) - { - memcpy(&reloc, &EXE_FORMAT(format)->content[iter], ELF_SIZEOF_REL(format)); - - switch (format->header.e_machine) - { - case EM_386: - switch (ELF32_R_TYPE(ELF_REL_TYPE(format, reloc))) - { - case R_386_JMP_SLOT: - - index = ELF_REL_SYM(format, reloc); - name = get_elf_dynamic_symbol_info(format, dyn_start, dyn_size, &index, str_start, str_size); - - if (name != NULL) - { - format->relocations = (elf_symbol *)realloc(format->relocations, ++format->rel_count * sizeof(elf_symbol)); - - format->relocations[format->rel_count - 1].name = name; - format->relocations[format->rel_count - 1].address = ELF_REL(format, reloc, r_offset); - - } - - break; - - default: - printf("Relocation not supported (%lld) !\n", ELF_REL_TYPE(format, reloc)); - break; - - } - break; - - default: - printf("Machine not recognized !\n"); - return false; - break; - - } - - - } - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à compléter. * -* dyn_start = début des informations dynamiques associées. * -* dyn_size = taille de la zone associée. * -* index = indice de l'entrée à venir lire. * -* str_start = début de la zone de chaîne de caractères. * -* str_size = taille de la zone de chaînes de caractères. * -* * -* Description : Récupère les informations d'un symbole dynamique donné. * -* * -* Retour : Nom du symbole trouvé, ou NULL si erreur ou non adapté. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *get_elf_dynamic_symbol_info(elf_format *format, const off_t *dyn_start, const off_t *dyn_size, const off_t *index, const off_t *str_start, const off_t *str_size) -{ - off_t offset; /* Emplacement à venir lire */ - Elf_Sym symbol; /* Symbole aux infos visées */ - - offset = *dyn_start + *index * ELF_SIZEOF_SYM(format); - if ((offset + ELF_SIZEOF_SYM(format)) > (*dyn_start + *dyn_size)) return NULL; - - memcpy(&symbol, &EXE_FORMAT(format)->content[offset], ELF_SIZEOF_SYM(format)); - - if (ELF_SYM(format, symbol, st_name) >= *str_size) return NULL; - - return (char *)&EXE_FORMAT(format)->content[*str_start + ELF_SYM(format, symbol, st_name)]; - -} |