#ifndef __ELFREADER_H #define __ELFREADER_H #include #include #include #include #include "debug.h" #include "assert.h" #define SWP16(X) (((X)&0x00FF)<<8)|(((X)&0xFF00)>>8) #define SWP32(X) ((((X)&0x00FF)<<24)|(((X)&0xFF00)<<8)|(((X)&0xFF0000)>>8)|(((X)&0xFF000000)>>24)) #define ELF_TYPE_UNKNOWN 0 #define ELF_TYPE_32 1 #define ELF_TYPE_64 2 /* if you add header on Intel(LE) on MIPS(be) arch then you going to have troubles. Lets prepare for this troubles */ #define ELF_ENONE 0 #define ELF_LLSB 1 #define ELF_LMSB 2 #define ELF_MLSB 3 #define ELF_MMSB 4 typedef struct Elf_Ident { unsigned char ident[EI_NIDENT]; } Elf_Ident; /* ++++++++++++++++++++++++++++++++++++ + Type + ELF32 + ELF64 + ++++++++++++++++++++++++++++++++++++ +Half + uint16_t + uint16_t + +Word + uint32_t + uint32_t + +Sword + int32_t + int32_t + +Xword + uint64_t + uint64_t + +Sxword + int64_t + int64_t + +Addr + uint32_t + uint64_t + +Off + uint32_t + uint64_t + +Section + uint16_t + uint16_t + +Versym + uint16_t + uint16_t + ++++++++++++++++++++++++++++++++++++ */ typedef struct Elf_Ehdr { int type; /* to distinguish 32 or its 64 bits */ int byteorder; /* generic elf header information */ uint16_t e_type; uint16_t e_machine; uint32_t e_version; uint64_t e_entry; uint64_t e_phoff; uint64_t e_shoff; uint32_t e_flags; uint16_t e_ehsize; uint16_t e_phentsize; uint16_t e_phnum; uint16_t e_shentsize; uint16_t e_shnum; uint16_t e_shstrndx; } Elf_Ehdr; typedef struct Elf_Phdr { int type; uint32_t offset; /* Offset in file */ int byteorder; /* generic progeam heaer information */ uint32_t p_type; /* Segment type */ uint64_t p_offset; /* Segment file offset */ uint64_t p_vaddr; /* Segment virtual address */ uint64_t p_paddr; /* Segment physical address */ uint32_t p_filesz; /* Segment size in file */ uint32_t p_memsz; /* Segment size in memory */ uint32_t p_flags; /* Segment flags */ uint32_t p_align; /* Segment alignment */ } Elf_Phdr; typedef struct Elf_Shdr { int type; uint32_t offset; /* Offset inside file */ int byteorder; /* generic section header information */ uint32_t sh_name; /* Section name (string tbl index) */ uint32_t sh_type; /* Section type */ uint64_t sh_flags; /* Section flags */ uint64_t sh_addr; /* Section virtual addr at execution */ uint64_t sh_offset; /* Section file offset */ uint64_t sh_size; /* Section size in bytes */ uint32_t sh_link; /* Link to another section */ uint32_t sh_info; /* Additional section information */ uint64_t sh_addralign; /* Section alignment */ uint64_t sh_entsize; } Elf_Shdr; typedef struct Elf_Shdr_strtab { long offset; int sz_tab; uint8_t *strtab; } Elf_Shdr_strtab; Elf_Ident* elf_ident( FILE *f ); int ident_check( Elf_Ident *ident ); void ident_info( Elf_Ident *ident ); /* All headers can have different types or different offsets inside structure should we write each function 2 times for 32/64? or just one generic function and type convos in between? */ /* ehdr := mapping ehdr32 */ int elf_ehdr_32( Elf_Ehdr *ehdr, Elf32_Ehdr *ehdr32, int byteorder ); /* ehdr := mapping ehdr64 */ int elf_ehdr_64( Elf_Ehdr *ehdr, Elf64_Ehdr *ehdr64, int byteorder ); /* ehdr32 := mapping ehdr */ int elf_32_ehdr( Elf32_Ehdr *ehdr32, Elf_Ehdr *ehdr ); /* ehdr64 := mapping ehdr */ int elf_64_ehdr( Elf64_Ehdr *ehdr64, Elf_Ehdr *ehdr ); int elf_ehdr32_bele( Elf32_Ehdr *ehdr32 ); int elf_ehdr32_lebe( Elf32_Ehdr *ehdr32 ); int elf_ehdr2mem( Elf_Ident *ident, Elf_Ehdr *ehdr, uint8_t *buf, int size ); Elf_Ehdr* elf_header( FILE *f, Elf_Ident *ident, int sysorder ); void header_info( Elf_Ehdr *ehdr ); int elf_phdr_32( Elf_Phdr *phdr, Elf32_Phdr *phdr32 ); int elf_phdr_64( Elf_Phdr *phdr, Elf64_Phdr *phdr64 ); int elf_32_phdr( Elf32_Phdr *phdr32, Elf_Phdr *phdr ); int elf_64_phdr( Elf64_Phdr *phdr64, Elf_Phdr *phdr ); Elf_Phdr* elf_phdr( FILE *f, Elf_Ehdr *ehdr ); int elf_shdr_32( Elf_Shdr *shdr, Elf32_Shdr *shdr32 ); int elf_shdr_64( Elf_Shdr *shdr, Elf64_Shdr *shdr64 ); int elf_32_shdr( Elf32_Shdr *shdr32, Elf_Shdr *shdr ); int elf_64_shdr( Elf64_Shdr *shdr64, Elf_Shdr *shdr ); int elf_shdr64_lebe( Elf64_Shdr *shdr64 ); int elf_shdr32_lebe( Elf32_Shdr *shdr32 ); int elf_shdr2mem( Elf_Shdr *shdr, uint8_t *buf, int size, int offset ); Elf_Shdr** elf_shdr( FILE *f, Elf_Ehdr *ehdr ); void section_info( Elf_Shdr* shdr, Elf_Shdr_strtab *strtab ); /* Search for strtab section */ Elf_Shdr_strtab* strtab_search( FILE *f, Elf_Shdr **shdr ); unsigned char* strtab_name( Elf_Shdr_strtab *strtab, long offset ); #endif