/* Chrysalide - Outil d'analyse de fichiers binaires * program.c - gestion des en-têtes de programme d'un ELF * * Copyright (C) 2010-2017 Cyrille Bagard * * This file is part of Chrysalide. * * Chrysalide 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. * * Chrysalide 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 "program.h" #include "elf-int.h" /****************************************************************************** * * * Paramètres : p_type = type associé à un en-tête de programme. * * * * Description : Fournit la description humaine d'un type de segment ELF. * * * * Retour : Désignation prête à emploi. * * * * Remarques : - * * * ******************************************************************************/ const char *get_elf_program_type_desc(uint32_t p_type) { const char *result; /* Description à renvoyer */ #define MAKE_STRING_FROM_PT(pt) case pt: result = #pt; break; switch(p_type) { MAKE_STRING_FROM_PT(PT_NULL); MAKE_STRING_FROM_PT(PT_LOAD); MAKE_STRING_FROM_PT(PT_DYNAMIC); MAKE_STRING_FROM_PT(PT_INTERP); MAKE_STRING_FROM_PT(PT_NOTE); MAKE_STRING_FROM_PT(PT_SHLIB); MAKE_STRING_FROM_PT(PT_PHDR); MAKE_STRING_FROM_PT(PT_TLS); MAKE_STRING_FROM_PT(PT_NUM); MAKE_STRING_FROM_PT(PT_LOOS); MAKE_STRING_FROM_PT(PT_GNU_EH_FRAME); MAKE_STRING_FROM_PT(PT_GNU_STACK); MAKE_STRING_FROM_PT(PT_GNU_RELRO); MAKE_STRING_FROM_PT(PT_LOSUNW); MAKE_STRING_FROM_PT(PT_SUNWSTACK); MAKE_STRING_FROM_PT(PT_HIOS); MAKE_STRING_FROM_PT(PT_LOPROC); MAKE_STRING_FROM_PT(PT_HIPROC); default: result = "PT_???"; break; } return result; } /****************************************************************************** * * * Paramètres : format = description de l'exécutable à consulter. * * index = indice de la section recherchée. * * program = ensemble d'informations à faire remonter. [OUT] * * * * Description : Recherche un programme donné au sein de binaire par indice. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool find_elf_program_by_index(const GElfFormat *format, uint16_t index, elf_phdr *program) { off_t offset; /* Emplacement à venir lire */ if (index >= ELF_HDR(format, format->header, e_phnum)) return false; offset = ELF_HDR(format, format->header, e_phoff) + ELF_HDR(format, format->header, e_phentsize) * index; return read_elf_program_header(format, offset, program); } /****************************************************************************** * * * Paramètres : format = description de l'exécutable à consulter. * * off = position physique à retrouver. * * pos = position correspondante. [OUT] * * * * Description : Fournit l'emplacement correspondant à une position physique. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool translate_offset_into_vmpa_using_elf_programs(const GElfFormat *format, phys_t off, vmpa2t *pos) { bool result; /* Bilan à retourner */ uint16_t i; /* Boucle de parcours */ elf_phdr program; /* Programme à analyser */ virt_t addr; /* Adresse virtuelle calculée */ result = false; for (i = 0; i < ELF_HDR(format, format->header, e_phnum) && !result; i++) { find_elf_program_by_index(format, i, &program); if (ELF_PHDR(format, program, p_offset) <= off && off < (ELF_PHDR(format, program, p_offset) + ELF_PHDR(format, program, p_filesz))) { addr = ELF_PHDR(format, program, p_vaddr) + ELF_PHDR(format, program, p_offset) - off; init_vmpa(pos, off, addr); result = true; } } return result; } /****************************************************************************** * * * Paramètres : format = description de l'exécutable à consulter. * * addr = adresse virtuelle à retrouver. * * pos = position correspondante. [OUT] * * * * Description : Fournit l'emplacement correspondant à une adresse virtuelle. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool translate_address_into_vmpa_using_elf_programs(const GElfFormat *format, virt_t addr, vmpa2t *pos) { bool result; /* Bilan à retourner */ uint16_t i; /* Boucle de parcours */ elf_phdr program; /* Programme à analyser */ phys_t off; /* Position physique calculée */ result = false; for (i = 0; i < ELF_HDR(format, format->header, e_phnum) && !result; i++) { find_elf_program_by_index(format, i, &program); if (ELF_PHDR(format, program, p_vaddr) <= addr && addr < (ELF_PHDR(format, program, p_vaddr) + ELF_PHDR(format, program, p_filesz))) { off = ELF_PHDR(format, program, p_offset) + addr - ELF_PHDR(format, program, p_vaddr); init_vmpa(pos, off, addr); result = true; } } return result; }