/* OpenIDA - Outil d'analyse de fichiers binaires * elf-int.c - structures internes du format ELF * * Copyright (C) 2009 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 . */ #include "elf-int.h" /****************************************************************************** * * * Paramètres : format = informations chargées à consulter. * * pos = position de début de lecture. [OUT] * * header = structure lue à retourner. [OUT] * * * * Description : Procède à la lecture d'une en-tête de programme ELF. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool read_elf_program_header(const GElfFormat *format, off_t *pos, elf_phdr *header) { bool result; /* Bilan à retourner */ const bin_t *content; /* Contenu binaire à lire */ off_t length; /* Taille totale du contenu */ content = G_BIN_FORMAT(format)->content; length = G_BIN_FORMAT(format)->length; if (format->is_32b) { result = read_u32(&header->phdr32.p_type, content, pos, length, format->endian); result &= read_u32(&header->phdr32.p_offset, content, pos, length, format->endian); result &= read_u32(&header->phdr32.p_vaddr, content, pos, length, format->endian); result &= read_u32(&header->phdr32.p_paddr, content, pos, length, format->endian); result &= read_u32(&header->phdr32.p_filesz, content, pos, length, format->endian); result &= read_u32(&header->phdr32.p_memsz, content, pos, length, format->endian); result &= read_u32(&header->phdr32.p_flags, content, pos, length, format->endian); result &= read_u32(&header->phdr32.p_align, content, pos, length, format->endian); } else { result = read_u32(&header->phdr64.p_type, content, pos, length, format->endian); result &= read_u32(&header->phdr64.p_flags, content, pos, length, format->endian); result &= read_u64(&header->phdr64.p_offset, content, pos, length, format->endian); result &= read_u64(&header->phdr64.p_vaddr, content, pos, length, format->endian); result &= read_u64(&header->phdr64.p_paddr, content, pos, length, format->endian); result &= read_u64(&header->phdr64.p_filesz, content, pos, length, format->endian); result &= read_u64(&header->phdr64.p_memsz, content, pos, length, format->endian); result &= read_u64(&header->phdr64.p_align, content, pos, length, format->endian); } return result; } /****************************************************************************** * * * Paramètres : format = informations chargées à consulter. * * pos = position de la tête de lecture. * * section = section lue. [OUT] * * * * Description : Procède à la lecture d'une en-tête de section ELF. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool read_elf_section_header(const GElfFormat *format, off_t pos, elf_shdr *section) { bool result; /* Bilan à retourner */ const bin_t *content; /* Contenu binaire à lire */ off_t length; /* Taille totale du contenu */ elf32_shdr *shdr32; /* Version 32 bits */ elf64_shdr *shdr64; /* Version 32 bits */ result = true; content = G_BIN_FORMAT(format)->content; length = G_BIN_FORMAT(format)->length; if (format->is_32b) { shdr32 = §ion->shdr32; result = read_u32(&shdr32->sh_name, content, &pos, length, format->endian); result &= read_u32(&shdr32->sh_type, content, &pos, length, format->endian); result &= read_u32(&shdr32->sh_flags, content, &pos, length, format->endian); result &= read_u32(&shdr32->sh_addr, content, &pos, length, format->endian); result &= read_u32(&shdr32->sh_offset, content, &pos, length, format->endian); result &= read_u32(&shdr32->sh_size, content, &pos, length, format->endian); result &= read_u32(&shdr32->sh_link, content, &pos, length, format->endian); result &= read_u32(&shdr32->sh_info, content, &pos, length, format->endian); result &= read_u32(&shdr32->sh_addralign, content, &pos, length, format->endian); result &= read_u32(&shdr32->sh_entsize, content, &pos, length, format->endian); } else { shdr64 = §ion->shdr64; result = read_u32(&shdr64->sh_name, content, &pos, length, format->endian); result &= read_u32(&shdr64->sh_type, content, &pos, length, format->endian); result &= read_u64(&shdr64->sh_flags, content, &pos, length, format->endian); result &= read_u64(&shdr64->sh_addr, content, &pos, length, format->endian); result &= read_u64(&shdr64->sh_offset, content, &pos, length, format->endian); result &= read_u64(&shdr64->sh_size, content, &pos, length, format->endian); result &= read_u32(&shdr64->sh_link, content, &pos, length, format->endian); result &= read_u32(&shdr64->sh_info, content, &pos, length, format->endian); result &= read_u64(&shdr64->sh_addralign, content, &pos, length, format->endian); result &= read_u64(&shdr64->sh_entsize, content, &pos, length, format->endian); } return result; } /****************************************************************************** * * * Paramètres : format = informations chargées à consulter. * * pos = position de début de lecture. [OUT] * * sym = structure lue à retourner. [OUT] * * * * Description : Procède à la lecture d'un symbole ELF. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool read_elf_symbol(const GElfFormat *format, off_t *pos, elf_sym *sym) { bool result; /* Bilan à retourner */ const bin_t *content; /* Contenu binaire à lire */ off_t length; /* Taille totale du contenu */ content = G_BIN_FORMAT(format)->content; length = G_BIN_FORMAT(format)->length; if (format->is_32b) { result = read_u32(&sym->sym32.st_name, content, pos, length, format->endian); result &= read_u32(&sym->sym32.st_value, content, pos, length, format->endian); result &= read_u32(&sym->sym32.st_size, content, pos, length, format->endian); result &= read_u8(&sym->sym32.st_info, content, pos, length, format->endian); result &= read_u8(&sym->sym32.st_other, content, pos, length, format->endian); result &= read_u16(&sym->sym32.st_shndx, content, pos, length, format->endian); } else { result = read_u32(&sym->sym64.st_name, content, pos, length, format->endian); result &= read_u8(&sym->sym64.st_info, content, pos, length, format->endian); result &= read_u8(&sym->sym64.st_other, content, pos, length, format->endian); result &= read_u16(&sym->sym64.st_shndx, content, pos, length, format->endian); result &= read_u64(&sym->sym64.st_value, content, pos, length, format->endian); result &= read_u64(&sym->sym64.st_size, content, pos, length, format->endian); } return result; } /****************************************************************************** * * * Paramètres : format = informations chargées à consulter. * * pos = position de début de lecture. [OUT] * * reloc = structure lue à retourner. [OUT] * * * * Description : Procède à la lecture d'une relocalisation ELF. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool read_elf_relocation(const GElfFormat *format, off_t *pos, elf_rel *reloc) { bool result; /* Bilan à retourner */ const bin_t *content; /* Contenu binaire à lire */ off_t length; /* Taille totale du contenu */ content = G_BIN_FORMAT(format)->content; length = G_BIN_FORMAT(format)->length; if (format->is_32b) { result = read_u32(&reloc->rel32.r_offset, content, pos, length, format->endian); result &= read_u32(&reloc->rel32.r_info, content, pos, length, format->endian); } else { result = read_u64(&reloc->rel64.r_offset, content, pos, length, format->endian); result &= read_u64(&reloc->rel64.r_info, content, pos, length, format->endian); } return result; }