/* OpenIDA - Outil d'analyse de fichiers binaires * elf_def.h - liste des structures et constantes utilisées par le 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 . */ #ifndef _FORMAT_ELF_ELF_DEF_H #define _FORMAT_ELF_ELF_DEF_H #include /* Adresses virtuelles */ typedef union _elf_addr { uint32_t addr32; /* Elf 32 bits */ uint64_t addr64; /* Elf 64 bits */ } elf_addr; /* Positions dans le fichier */ typedef union _elf_off { uint32_t off32; /* Elf 32 bits */ uint64_t off64; /* Elf 64 bits */ } elf_off; #define ELF_OFF(fmt, off) (fmt->is_32b ? (off).off32 : (off).off64) /* ---------------------------- EN-TETE DES FICHIERS ELF ---------------------------- */ #define EI_NIDENT 16 /* En-tête de fichier ELF */ typedef struct _elf_header { uint8_t e_ident[EI_NIDENT]; /* Magic number + informations */ uint16_t e_type; /* Type de fichier */ uint16_t e_machine; /* Architecture */ uint32_t e_version; /* Version du type de fichier */ elf_addr e_entry; /* Point d'entrée du programme */ elf_off e_phoff; /* Début de la table 'Program' */ elf_off e_shoff; /* Début de la table 'Section' */ uint32_t e_flags; /* Prop. spécifiques au proc. */ uint16_t e_ehsize; /* Taille de l'en-tête en oct. */ uint16_t e_phentsize; /* Taille d'une entrée Program */ uint16_t e_phnum; /* Nombre d'éléments 'Program' */ uint16_t e_shentsize; /* Taille d'une entrée Section */ uint16_t e_shnum; /* Nombre d'éléments 'Section' */ uint16_t e_shstrndx; /* Indice de la section chaînes*/ } elf_header; /* Composition du champ e_ident */ #define EI_CLASS 4 /* Indice de classe du fichier */ #define EI_DATA 5 /* Indice de l'encodage */ /* ... EI_CLASS */ #define ELFCLASSNONE 0 /* Objet invalide */ #define ELFCLASS32 1 /* Objet 32 bits */ #define ELFCLASS64 2 /* Objet 64 bits */ /* ... EI_DATA */ #define ELFDATANONE 0 /* Encodage invalide */ #define ELFDATA2LSB 1 /* Complément à 2, petit bout. */ #define ELFDATA2MSB 2 /* Complément à 2, grand bout. */ /* Valeurs possibles pour e_machine */ #define EM_NONE 0 /* Aucune machine */ #define EM_386 3 /* Intel 80386 */ #define EM_MIPS 8 /* MIPS R3000 big-endian */ #define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ /* --------------------------- EN-TETE DES PROGRAMMES ELF --------------------------- */ /* Version 32 et 64 bits */ typedef struct _elf32_phdr { uint32_t p_type; /* Type de segment */ uint32_t p_offset; /* Position dans le fichier */ uint32_t p_vaddr; /* Adresse virtuelle du segment*/ uint32_t p_paddr; /* Adresse physique du segment */ uint32_t p_filesz; /* Taille dans le fichier */ uint32_t p_memsz; /* Taille en mémoire */ uint32_t p_flags; /* Drapeaux pour le segment */ uint32_t p_align; /* Alignement du segment */ } elf32_phdr; typedef struct _elf64_phdr { uint32_t p_type; /* Type de segment */ uint32_t p_flags; /* Drapeaux pour le segment */ uint64_t p_offset; /* Position dans le fichier */ uint64_t p_vaddr; /* Adresse virtuelle du segment*/ uint64_t p_paddr; /* Adresse physique du segment */ uint64_t p_filesz; /* Taille dans le fichier */ uint64_t p_memsz; /* Taille en mémoire */ uint64_t p_align; /* Alignement du segment */ } elf64_phdr; typedef union _elf_phdr { elf32_phdr phdr32; /* Version 32 bits */ elf64_phdr phdr64; /* Version 32 bits */ } elf_phdr; #define ELF_PHDR(fmt, hdr, fld) (fmt->is_32b ? hdr.phdr32.fld : hdr.phdr64.fld) #define ELF_SIZEOF_PHDR(fmt) (fmt->is_32b ? sizeof(elf32_phdr) : sizeof(elf64_phdr)) /* Valeurs possibles pour p_flags */ #define PF_X (1 << 0) /* Le segment est exécutable */ #define PF_W (1 << 1) /* Le segment est écrasable */ #define PF_R (1 << 2) /* Le segment est lisible */ /* ---------------------------- EN-TETE DES SECTIONS ELF ---------------------------- */ /* Version 32 et 64 bits */ typedef struct _elf32_shdr { uint32_t sh_name; /* Indice du nom de la section */ uint32_t sh_type; /* Type de section */ uint32_t sh_flags; /* Drapeaux pour la section */ uint32_t sh_addr; /* Adresse virtuelle à l'exec. */ uint32_t sh_offset; /* Position dans le fichier */ uint32_t sh_size; /* Taille en octets */ uint32_t sh_link; /* Lien vers une autre section */ uint32_t sh_info; /* Infos. complémentaires */ uint32_t sh_addralign; /* Alignement de la section */ uint32_t sh_entsize; /* Eventuelle taille d'élément */ } elf32_shdr; typedef struct _elf64_shdr { uint32_t sh_name; /* Indice du nom de la section */ uint32_t sh_type; /* Type de section */ uint64_t sh_flags; /* Drapeaux pour la section */ uint64_t sh_addr; /* Adresse virtuelle à l'exec. */ uint64_t sh_offset; /* Position dans le fichier */ uint64_t sh_size; /* Taille en octets */ uint32_t sh_link; /* Lien vers une autre section */ uint32_t sh_info; /* Infos. complémentaires */ uint64_t sh_addralign; /* Alignement de la section */ uint64_t sh_entsize; /* Eventuelle taille d'élément */ } elf64_shdr; typedef union _elf_shdr { elf32_shdr shdr32; /* Version 32 bits */ elf64_shdr shdr64; /* Version 32 bits */ } elf_shdr; #define ELF_SHDR(fmt, shdr, fld) (fmt->is_32b ? (shdr).shdr32.fld : (shdr).shdr64.fld) #define ELF_SIZEOF_SHDR(fmt) (fmt->is_32b ? sizeof(elf32_shdr) : sizeof(elf64_shdr)) /* Valeurs possibles pour sh_type */ #define SHT_NULL 0 /* Entrée non utilisée */ #define SHT_PROGBITS 1 /* Données de programme */ #define SHT_SYMTAB 2 /* Table des symboles */ #define SHT_STRTAB 3 /* Table de chaînes de carac. */ #define SHT_DYNAMIC 6 /* Info. de liaison dynamique */ /* Valeurs possibles pour sh_flags */ #define SHF_ALLOC (1 << 1) /* Copie en mémoire pdt l'exec.*/ #define SHF_EXECINSTR (1 << 2) /* Section exécutable */ #define SHF_STRINGS (1 << 5) /* Contient des chaînes ('\0') */ /* ----------------------------- DONNEES POUR LE LINKER ----------------------------- */ /* Entrées de la section dynamique (version 32 et 64 bits) */ typedef struct _elf32_dyn { int32_t d_tag; /* Type de l'entrée */ union { uint32_t d_val; /* Valeur entière */ uint32_t d_ptr; /* Valeur d'adresse */ } d_un; } elf32_dyn; typedef struct _elf64_dyn { int64_t d_tag; /* Type de l'entrée */ union { uint64_t d_val; /* Valeur entière */ uint64_t d_ptr; /* Valeur d'adresse */ } d_un; } elf64_dyn; typedef union _elf_dyn { elf32_dyn dyn32; /* Version 32 bits */ elf64_dyn dyn64; /* Version 32 bits */ } elf_dyn; #define ELF_DYN(fmt, dyn, fld) (fmt->is_32b ? (dyn).dyn32.fld : (dyn).dyn64.fld) #define ELF_SIZEOF_DYN(fmt) (fmt->is_32b ? sizeof(elf32_dyn) : sizeof(elf64_dyn)) /* Valeurs possibles pour d_tag */ #define DT_SYMTAB 6 /* Table des symboles */ #define DT_JMPREL 23 /* Relocalisations PLT */ /* ---------------------------- SYMBOLES DE BINAIRES ELF ---------------------------- */ /* Elément de la table des symboles */ typedef struct _elf32_sym { uint32_t st_name; /* Indice pour le nom */ uint32_t st_value; /* Valeur du symbole */ uint32_t st_size; /* Taille du symbole */ unsigned char st_info; /* Type et infos. du symbole */ unsigned char st_other; /* Visibilité du symbole */ uint16_t st_shndx; /* Indice de la section */ } elf32_sym; typedef struct _elf64_sym { uint32_t st_name; /* Indice pour le nom */ unsigned char st_info; /* Type et infos. du symbole */ unsigned char st_other; /* Visibilité du symbole */ uint16_t st_shndx; /* Indice de la section */ uint64_t st_value; /* Valeur du symbole */ uint64_t st_size; /* Taille du symbole */ } elf64_sym; typedef union _elf_sym { elf32_sym sym32; /* Version 32 bits */ elf64_sym sym64; /* Version 64 bits */ } elf_sym; #define ELF_SYM(fmt, sb, fld) (fmt->is_32b ? sb.sym32.fld : sb.sym64.fld) #define ELF_ST_BIND(fmt, sym) (fmt->is_32b ? ELF32_ST_BIND(sym.sym32.st_info) : ELF64_ST_BIND(sym.sym64.st_info)) #define ELF_ST_TYPE(fmt, sym) (fmt->is_32b ? ELF32_ST_TYPE(sym.sym32.st_info) : ELF64_ST_TYPE(sym.sym64.st_info)) #define ELF_SIZEOF_SYM(fmt) (fmt->is_32b ? sizeof(elf32_sym) : sizeof(elf64_sym)) /* Extraction des informations de st_info */ #define ELF32_ST_BIND(val) (((unsigned char)(val)) >> 4) #define ELF32_ST_TYPE(val) ((val) & 0xf) #define ELF64_ST_BIND(val) ELF32_ST_BIND(val) #define ELF64_ST_TYPE(val) ELF32_ST_TYPE(val) /* Valeurs pour le sous-champ ST_TYPE de st_info */ #define STT_NOTYPE 0 /* Type de symbole non spécifié*/ #define STT_OBJECT 1 /* Symbole, objet de données */ #define STT_FUNC 2 /* Symbole, objet de code */ /* ------------------------- INFORMATIONS DE RELOCALISATION ------------------------- */ /* Entrée de la table de relocalisation */ typedef struct _elf32_rel { uint32_t r_offset; /* Adresse */ uint32_t r_info; /* Indice de type et symbole */ } elf32_rel; typedef struct _elf64_rel { uint64_t r_offset; /* Adresse */ uint64_t r_info; /* Indice de type et symbole */ } elf64_rel; typedef union _elf_rel { elf32_rel rel32; /* Version 32 bits */ elf64_rel rel64; /* Version 64 bits */ } elf_rel; #define ELF_REL(fmt, rl, fld) (fmt->is_32b ? rl.rel32.fld : rl.rel64.fld) #define ELF_REL_SYM(fmt, rl) (fmt->is_32b ? ELF32_R_SYM(rl.rel32.r_info) : ELF64_R_SYM(rl.rel64.r_info)) #define ELF_REL_TYPE(fmt, rl) (fmt->is_32b ? ELF32_R_TYPE(rl.rel32.r_info) : ELF64_R_TYPE(rl.rel64.r_info)) #define ELF_SIZEOF_REL(fmt) (fmt->is_32b ? sizeof(elf32_rel) : sizeof(elf64_rel)) /* Extraction des informations de r_info */ #define ELF32_R_SYM(val) ((val) >> 8) #define ELF32_R_TYPE(val) ((val) & 0xff) #define ELF64_R_SYM(val) ((val) >> 32) #define ELF64_R_TYPE(val) ((val) & 0xffffffff) /* Type de relocalisation (x86) */ #define R_386_NONE 0 /* Pas de relocalisation */ #define R_386_JMP_SLOT 7 /* Entrée PLT */ #endif /* _FORMAT_ELF_ELF_DEF_H */