diff options
author | FreeArtMan <dos21h@gmail.com> | 2016-07-06 19:25:42 +0100 |
---|---|---|
committer | FreeArtMan <dos21h@gmail.com> | 2016-07-06 19:25:42 +0100 |
commit | 885658f5475b4ab35254b86ce0507790807299b6 (patch) | |
tree | fb4e53b809c9881fb42e36835b6e1c7824a4a581 | |
download | libelf-885658f5475b4ab35254b86ce0507790807299b6.tar.gz libelf-885658f5475b4ab35254b86ce0507790807299b6.zip |
Initial libelf commit
-rw-r--r-- | elfreader.c | 727 | ||||
-rw-r--r-- | elfreader.h | 158 |
2 files changed, 885 insertions, 0 deletions
diff --git a/elfreader.c b/elfreader.c new file mode 100644 index 0000000..b514da3 --- /dev/null +++ b/elfreader.c @@ -0,0 +1,727 @@ +#include "elfreader.h" + + +/******************************************************************************/ +Elf_Ident* elf_ident( FILE *f ) +{ + Elf_Ident *ret = NULL; + size_t read_bytes = 0; + + if ( f == NULL ) + { + return NULL; + } + + ret = malloc( sizeof(Elf_Ident) ); + if ( ret == NULL ) + { + return NULL; + } + + fseek( f, 0, SEEK_SET ); + read_bytes = fread( ret->ident, 1, EI_NIDENT, f ); + if ( read_bytes != EI_NIDENT ) + { + free( ret ); + return NULL; + } + + return ret; +} + + +/******************************************************************************/ +int ident_check( Elf_Ident *ident ) +{ + int ret=0; + /* check if its elf file */ + if ( (ident->ident[EI_MAG0] != ELFMAG0) || + (ident->ident[EI_MAG1] != ELFMAG1) || + (ident->ident[EI_MAG2] != ELFMAG2) || + (ident->ident[EI_MAG3] != ELFMAG3) ) + { + printf("Elf header magic is wrong\n"); + ret = -1; + } + + /* check file class */ + switch ( ident->ident[EI_CLASS] ) + { + case ELFCLASS32: + case ELFCLASS64: + break; + default: + printf("EI_CLASS not supported\n"); + return -1; + } + + return ret; +} + + +/******************************************************************************/ +void ident_info( Elf_Ident *ident ) +{ + printf("ELF IDENT:\n"); + printf("ELFCLASS :0x%02x\n", ident->ident[EI_CLASS]); + printf("ELFDATA :0x%02x\n", ident->ident[EI_DATA]); +} + + +/******************************************************************************/ +int elf_ehdr_32( Elf_Ehdr *ehdr, Elf32_Ehdr *ehdr32, int byteorder ) +{ + if ( byteorder == ELF_MLSB ) + { + /* working with MIPS on INTEL */ + elf_ehdr32_bele( ehdr32 ); + /* input was in MSB output now in LSB */ + } else if ( (byteorder == ELF_MMSB) || (byteorder == ELF_LLSB) ) + { + /* no need to do something */ + } else + { + /* is someone compile stuff on MIPS for Intel or so? */ + ERROR("Not yet implemented\n"); + /* Should be ok for now */ + exit(0); + } + + ehdr->e_type = ehdr32->e_type; + ehdr->e_machine = ehdr32->e_machine; + ehdr->e_version = ehdr32->e_version; + ehdr->e_entry = ehdr32->e_entry; + ehdr->e_phoff = ehdr32->e_phoff; + ehdr->e_shoff = ehdr32->e_shoff; + ehdr->e_flags = ehdr32->e_flags; + ehdr->e_ehsize = ehdr32->e_ehsize; + ehdr->e_phentsize = ehdr32->e_phentsize; + ehdr->e_phnum = ehdr32->e_phnum; + ehdr->e_shentsize = ehdr32->e_shentsize; + ehdr->e_shnum = ehdr32->e_shnum; + ehdr->e_shstrndx = ehdr32->e_shstrndx; + + return 0; +} + + +/******************************************************************************/ +int elf_ehdr_64( Elf_Ehdr *ehdr, Elf64_Ehdr *ehdr64, int byteorder ) +{ + ENL(); + + ehdr->e_type = ehdr64->e_type; + ehdr->e_machine = ehdr64->e_machine; + ehdr->e_version = ehdr64->e_version; + ehdr->e_entry = ehdr64->e_entry; + ehdr->e_phoff = ehdr64->e_phoff; + ehdr->e_shoff = ehdr64->e_shoff; + ehdr->e_flags = ehdr64->e_flags; + ehdr->e_ehsize = ehdr64->e_ehsize; + ehdr->e_phentsize = ehdr64->e_phentsize; + ehdr->e_phnum = ehdr64->e_phnum; + ehdr->e_shentsize = ehdr64->e_shentsize; + ehdr->e_shnum = ehdr64->e_shnum; + ehdr->e_shstrndx = ehdr64->e_shstrndx; + + return 0; +} + + +/******************************************************************************/ +int elf_32_ehdr( Elf32_Ehdr *ehdr32, Elf_Ehdr *ehdr ) +{ + + ehdr32->e_type = ehdr->e_type; + ehdr32->e_machine = ehdr->e_machine; + ehdr32->e_version = ehdr->e_version; + ehdr32->e_entry = ehdr->e_entry; + ehdr32->e_phoff = ehdr->e_phoff; + ehdr32->e_shoff = ehdr->e_shoff; + ehdr32->e_flags = ehdr->e_flags; + ehdr32->e_ehsize = ehdr->e_ehsize; + ehdr32->e_phentsize = ehdr->e_phentsize; + ehdr32->e_phnum = ehdr->e_phnum; + ehdr32->e_shentsize = ehdr->e_shentsize; + ehdr32->e_shnum = ehdr->e_shnum; + ehdr32->e_shstrndx = ehdr->e_shstrndx; + + if ( ehdr->byteorder == ELF_MLSB ) + { + elf_ehdr32_bele( ehdr32 ); + } else if ( (ehdr->byteorder == ELF_MMSB) || + ( ehdr->byteorder == ELF_LLSB)) + { + /* No need to do anything */ + } else + { + ERROR("Note implemtented\n"); + } + + + return 0; +} + + +/******************************************************************************/ +int elf_64_ehdr( Elf64_Ehdr *ehdr64, Elf_Ehdr *ehdr ) +{ + ehdr64->e_type = ehdr->e_type; + ehdr64->e_machine = ehdr->e_machine; + ehdr64->e_version = ehdr->e_version; + ehdr64->e_entry = ehdr->e_entry; + ehdr64->e_phoff = ehdr->e_phoff; + ehdr64->e_shoff = ehdr->e_shoff; + ehdr64->e_flags = ehdr->e_flags; + ehdr64->e_ehsize = ehdr->e_ehsize; + ehdr64->e_phentsize = ehdr->e_phentsize; + ehdr64->e_phnum = ehdr->e_phnum; + ehdr64->e_shentsize = ehdr->e_shentsize; + ehdr64->e_shnum = ehdr->e_shnum; + ehdr64->e_shstrndx = ehdr->e_shstrndx; + + return 0; +} + +/******************************************************************************/ +int elf_ehdr32_bele( Elf32_Ehdr *ehdr32 ) +{ + int ret = 0; + + ehdr32->e_type = SWP16(ehdr32->e_type); + ehdr32->e_machine = SWP16(ehdr32->e_machine); + ehdr32->e_version = SWP32(ehdr32->e_version); + ehdr32->e_entry = SWP32(ehdr32->e_entry); + ehdr32->e_phoff = SWP32(ehdr32->e_phoff ); + ehdr32->e_shoff = SWP32(ehdr32->e_shoff); + ehdr32->e_flags = SWP32(ehdr32->e_flags); + ehdr32->e_ehsize = SWP16(ehdr32->e_ehsize); + ehdr32->e_phentsize = SWP16(ehdr32->e_phentsize); + ehdr32->e_phnum = SWP16(ehdr32->e_phnum); + ehdr32->e_shentsize = SWP16(ehdr32->e_shentsize); + ehdr32->e_shnum = SWP16(ehdr32->e_shnum); + ehdr32->e_shstrndx = SWP16(ehdr32->e_shstrndx); + + return ret; +} + +/******************************************************************************/ +int elf_ehdr32_lebe( Elf32_Ehdr *ehdr32 ) +{ + int ret = 0; + uint16_t u16; + + PNL(); + /* + ehdr32->e_type = SWP16(ehdr32->e_type); + ehdr32->e_machine = SWP16(ehdr32->e_machine); + ehdr32->e_version = SWP32(ehdr32->e_version); + ehdr32->e_entry = SWP32(ehdr32->e_entry); + ehdr32->e_phoff = SWP32(ehdr32->e_phoff ); + ehdr32->e_shoff = SWP32(ehdr32->e_shoff); + ehdr32->e_flags = SWP32(ehdr32->e_flags); + ehdr32->e_ehsize = SWP16(ehdr32->e_ehsize); + ehdr32->e_phentsize = SWP16(ehdr32->e_phentsize); + ehdr32->e_phnum = SWP16(ehdr32->e_phnum); + ehdr32->e_shentsize = SWP16(ehdr32->e_shentsize); + ehdr32->e_shnum = SWP16(ehdr32->e_shnum); + ehdr32->e_shstrndx = SWP16(ehdr32->e_shstrndx); + */ + return ret; +} + + +/******************************************************************************/ +int elf_ehdr2mem( Elf_Ident *ident, Elf_Ehdr *ehdr, uint8_t *buf, int size ) +{ + int ret = 0; + + int i,j; + uint8_t *head = NULL; + int sz_head = -1; + + if ( ehdr->type == ELF_TYPE_32 ) + { + sz_head = sizeof(Elf32_Ehdr); + head = malloc( sz_head ); + elf_32_ehdr( (Elf32_Ehdr *)head, ehdr ); + } else if ( ehdr->type == ELF_TYPE_64 ) + { + sz_head = sizeof(Elf64_Ehdr); + head = malloc( sz_head ); + elf_64_ehdr( (Elf64_Ehdr *)head, ehdr ); + } else + { + printf("Unknown ELF header type\n"); + return -1; + } + + memcpy( head, ident->ident, EI_NIDENT); + + for (i=0,j=0; (i<size)&&(j<sz_head); i++,j++ ) + { + buf[i] = head[j]; + } + + return ret; +} + + +/******************************************************************************/ +Elf_Ehdr* elf_header( FILE *f, Elf_Ident *ident, int sysorder ) +{ + Elf_Ehdr *ret = NULL; + uint8_t *buf = NULL; + int sz_buf = -1; + int class = ELF_TYPE_UNKNOWN; + int byteorder = ELF_ENONE; + + + /* check elf header class */ + switch ( ident->ident[EI_CLASS] ) + { + case ELFCLASS32: + class = ELF_TYPE_32; + sz_buf = sizeof(Elf32_Ehdr); + break; + case ELFCLASS64: + class = ELF_TYPE_64; + sz_buf = sizeof(Elf64_Ehdr); + break; + default: + printf("Unknown ELFCLASS class\n"); + } + + /* check file endianess */ + switch ( ident->ident[EI_DATA] ) + { + case ELFDATA2LSB: + if ( sysorder == __ORDER_LITTLE_ENDIAN__ ) + { + byteorder = ELF_LLSB; + } else if ( sysorder == __ORDER_BIG_ENDIAN__ ) + { + byteorder = ELF_LMSB; + } else + { + ENL(); + } + break; + case ELFDATA2MSB: + if ( sysorder == __ORDER_LITTLE_ENDIAN__ ) + { + byteorder = ELF_MLSB; + } else if ( sysorder == __ORDER_BIG_ENDIAN__ ) + { + byteorder = ELF_MMSB; + } else + { + ENL(); + } + break; + case ELFDATANONE: + default: + printf("Unknown\n"); + } + + /* create buffer for elf header */ + buf = malloc( sz_buf ); + if ( buf == NULL ) + { + printf("alloc NULL\n"); + return NULL; + } + fseek( f, 0, SEEK_SET ); + if ( fread( buf, 1, sz_buf, f) != sz_buf ) + { + free( buf ); + printf("Cannot read ELF header\n"); + return NULL; + } + + //dont chk mmalc =P + ret = malloc( sizeof(Elf_Ehdr) ); + if ( class == ELF_TYPE_32 ) + { + PNL(); + elf_ehdr_32( ret, (Elf32_Ehdr *)buf, byteorder ); + ret->type = ELF_TYPE_32; + ret->byteorder = byteorder; + } else if ( class == ELF_TYPE_64 ) + { + PNL(); + elf_ehdr_64( ret, (Elf64_Ehdr *)buf, byteorder ); + ret->type = ELF_TYPE_64; + ret->byteorder = byteorder; + } else + { + printf("Unknown elf class\n"); + return NULL; + } + + return ret; +} + +/******************************************************************************/ +void header_info( Elf_Ehdr *ehdr ) +{ + printf("ELF EXCUTABLE HEADER\n"); + printf("TYPE : 0x%04x\n", ehdr->e_type ); + printf("ENTRY : 0x%08x\n", ehdr->e_entry ); + printf("PHOFF : 0x%04x\n", ehdr->e_phoff ); + printf("SHOFF : 0x%04x\n", ehdr->e_shoff ); + printf("EHSIZE : 0x%04x(%u bytes)\n", ehdr->e_ehsize, ehdr->e_ehsize ); + printf("PHENTSIZE : 0x%04x(%u bytes)\n", ehdr->e_phentsize, ehdr->e_phentsize ); + printf("PHNUM : 0x%04x(%u bytes)\n", ehdr->e_phnum, ehdr->e_phnum ); + printf("SHENTSIZE : 0x%04x(%u bytes)\n", ehdr->e_shentsize, ehdr->e_shentsize ); + printf("SHNUM : 0x%04x(%u bytes)\n", ehdr->e_shnum, ehdr->e_shnum ); +} + +/******************************************************************************/ +int elf_phdr_32( Elf_Phdr *phdr, Elf32_Phdr *phdr32 ) +{ + return -1; +} + + +/******************************************************************************/ +int elf_phdr_64( Elf_Phdr *phdr, Elf64_Phdr *phdr64 ) +{ + return -1; +} + + +/******************************************************************************/ +int elf_32_phdr( Elf32_Phdr *phdr32, Elf_Phdr *phdr ) +{ + return -1; +} + + +/******************************************************************************/ +int elf_64_phdr( Elf64_Phdr *phdr64, Elf_Phdr *phdr ) +{ + return -1; +} + + +/******************************************************************************/ +Elf_Phdr* elf_phdr( FILE *f, Elf_Ehdr *ehdr ) +{ + Elf_Phdr *ret = NULL; + + return ret; +} + + +/******************************************************************************/ +int elf_shdr_32( Elf_Shdr *shdr, Elf32_Shdr *shdr32 ) +{ + shdr->sh_name = shdr32->sh_name; + shdr->sh_type = shdr32->sh_type; + shdr->sh_flags = shdr32->sh_flags; + shdr->sh_addr = shdr32->sh_addr; + shdr->sh_offset = shdr32->sh_offset; + shdr->sh_size = shdr32->sh_size; + shdr->sh_link = shdr32->sh_link; + shdr->sh_info = shdr32->sh_info; + shdr->sh_addralign = shdr32->sh_addralign; + shdr->sh_entsize = shdr32->sh_entsize; + + return 0; +} + + +/******************************************************************************/ +int elf_shdr_64( Elf_Shdr *shdr, Elf64_Shdr *shdr64 ) +{ + shdr->sh_name = shdr64->sh_name; + shdr->sh_type = shdr64->sh_type; + shdr->sh_flags = shdr64->sh_flags; + shdr->sh_addr = shdr64->sh_addr; + shdr->sh_offset = shdr64->sh_offset; + shdr->sh_size = shdr64->sh_size; + shdr->sh_link = shdr64->sh_link; + shdr->sh_info = shdr64->sh_info; + shdr->sh_addralign = shdr64->sh_addralign; + shdr->sh_entsize = shdr64->sh_entsize; + + return 0; +} + + +/******************************************************************************/ +int elf_32_shdr( Elf32_Shdr *shdr32, Elf_Shdr *shdr ) +{ + shdr32->sh_name = shdr->sh_name; + shdr32->sh_type = shdr->sh_type; + shdr32->sh_flags = shdr->sh_flags; + shdr32->sh_addr = shdr->sh_addr; + shdr32->sh_offset = shdr->sh_offset; + shdr32->sh_size = shdr->sh_size; + shdr32->sh_link = shdr->sh_link; + shdr32->sh_info = shdr->sh_info; + shdr32->sh_addralign = shdr->sh_addralign; + shdr32->sh_entsize = shdr->sh_entsize; + + return 0; +} + + +/******************************************************************************/ +int elf_64_shdr( Elf64_Shdr *shdr64, Elf_Shdr *shdr ) +{ + shdr64->sh_name = shdr->sh_name; + shdr64->sh_type = shdr->sh_type; + shdr64->sh_flags = shdr->sh_flags; + shdr64->sh_addr = shdr->sh_addr; + shdr64->sh_offset = shdr->sh_offset; + shdr64->sh_size = shdr->sh_size; + shdr64->sh_link = shdr->sh_link; + shdr64->sh_info = shdr->sh_info; + shdr64->sh_addralign = shdr->sh_addralign; + shdr64->sh_entsize = shdr->sh_entsize; + + return 0; +} + + +/******************************************************************************/ +int elf_shdr64_lebe( Elf64_Shdr *shdr64 ) +{ + int ret = 0; + + ERROR("Not implemented\n"); + + return ret; +} + + +/******************************************************************************/ +int elf_shdr32_lebe( Elf32_Shdr *shdr32 ) +{ + int ret = 0; + + shdr32->sh_name = SWP32(shdr32->sh_name); + shdr32->sh_type = SWP32(shdr32->sh_type); + shdr32->sh_flags = SWP32(shdr32->sh_flags); + shdr32->sh_addr = SWP32(shdr32->sh_addr); + shdr32->sh_offset = SWP32(shdr32->sh_offset); + shdr32->sh_size = SWP32(shdr32->sh_size); + shdr32->sh_link = SWP32(shdr32->sh_link); + shdr32->sh_info = SWP32(shdr32->sh_info); + shdr32->sh_addralign = SWP32(shdr32->sh_addralign); + shdr32->sh_entsize = SWP32(shdr32->sh_entsize); + + return ret; +} + + +/******************************************************************************/ +int elf_shdr2mem( Elf_Shdr *shdr, uint8_t *buf, int size, int offset ) +{ + int ret = 0; + + int i,j; + uint8_t *sec_head = NULL; + int sz_sec_head = -1; + + if ( shdr->type == ELF_TYPE_32 ) + { + sz_sec_head = sizeof(Elf32_Shdr); + sec_head = malloc(sz_sec_head); + elf_32_shdr( (Elf32_Shdr *)sec_head, shdr ); + if (shdr->byteorder == ELF_MLSB) + { + elf_shdr32_lebe( (Elf32_Shdr *)sec_head ); + } else if ( (shdr->byteorder == ELF_MMSB) || + (shdr->byteorder == ELF_LLSB) ) + { + + } else + { + ENL(); + } + } else if ( shdr->type == ELF_TYPE_64 ) + { + sz_sec_head = sizeof(Elf64_Shdr); + sec_head = malloc( sz_sec_head ); + elf_64_shdr( (Elf64_Shdr *)sec_head, shdr ); + if (shdr->byteorder == ELF_MLSB) + { + elf_shdr64_lebe( (Elf64_Shdr *)sec_head ); + } else if ( (shdr->byteorder == ELF_MMSB) || + (shdr->byteorder == ELF_LLSB) ) + { + + } else + { + ENL(); + } + } else + { + printf("Unknown type\n"); + return -1; + } + + for (i=offset,j=0; (j<sz_sec_head)&&(i<size); i++,j++) + { + buf[i] = sec_head[j]; + } + + return ret; +} + +/******************************************************************************/ +Elf_Shdr** elf_shdr( FILE *f, Elf_Ehdr *ehdr ) +{ + Elf_Shdr **ret = NULL; + Elf_Shdr *sh = NULL; + uint8_t **buf = NULL; + int sz_buf = -1; + int sh_num = -1; + int i = 0; + + /* Binary probably sstriped */ + if (ehdr->e_shoff == 0) + { + printf("No section headers\n"); + return NULL; + } + + + /* set section header size according of file class */ + switch ( ehdr->type ) + { + case ELF_TYPE_32: + sz_buf = sizeof(Elf32_Shdr); + break; + case ELF_TYPE_64: + sz_buf = sizeof(Elf64_Shdr); + break; + default: + printf("Unknown ELFCLASS\n"); + return NULL; + } + + /* Read/convert data accroding to elf class */ + sh_num = ehdr->e_shnum; + ret = malloc( sizeof(Elf_Shdr*)*(sh_num+1)); + memset( ret, 0, sizeof(Elf_Shdr*)*(sh_num+1) ); // last value should be null + + buf = malloc( sz_buf ); //no check =P + fseek( f, ehdr->e_shoff, SEEK_SET ); + for (i=0; i<sh_num; i++) + { + if ( fread( buf, 1, sz_buf, f ) != sz_buf ) + { + free( buf ); + printf("Cannot read section headers\n"); + return NULL; + } + + sh = malloc(sizeof(Elf_Shdr)); + memset( sh, 0, sizeof(Elf_Shdr)); + switch (ehdr->type) + { + case ELF_TYPE_32: + elf_shdr_32( sh, (Elf32_Shdr *)buf ); + break; + case ELF_TYPE_64: + elf_shdr_64( sh, (Elf64_Shdr *)buf ); + break; + default: + printf("Unknown class/ unknown state\n"); + return NULL; + } + + /* Remember section header type */ + sh->type = ehdr->type; + + ret[i] = sh; + } + + return ret; +} + + +void section_info( Elf_Shdr* shdr, Elf_Shdr_strtab *strtab ) +{ + printf("ELF SECTION HEADER:\n"); + if ( strtab != NULL ) + { + char *s = NULL; + s = strtab_name( strtab, shdr->sh_name); + if ( s != NULL ) + { + printf("NAME :%s\n", s); + //free( s ); + //s = NULL; + } + } + printf("TYPE : 0x%02x\n", shdr->sh_type); + printf("OFFSET: 0x%08x\n", shdr->sh_offset); + printf("SIZE : 0x%08x\n", shdr->sh_size); +} + +Elf_Shdr_strtab* strtab_search( FILE *f, Elf_Shdr **shdr ) +{ + Elf_Shdr_strtab *ret = NULL; + Elf_Shdr *iter = NULL; + + if ( shdr == NULL ) + { + return NULL; + } + + iter = shdr[0]; + while ( iter != NULL ) + { + if ( iter->sh_type == SHT_STRTAB ) + { + ret = malloc( sizeof(Elf_Shdr_strtab) ); + ret->offset = iter->sh_offset; + ret->sz_tab = iter->sh_size; + ret->strtab = malloc(ret->sz_tab); + fseek( f, ret->offset, SEEK_SET ); + if ( fread( ret->strtab, 1, ret->sz_tab, f ) != ret->sz_tab ) + { + free( ret->strtab ); + free( ret ); + printf("Cannot read strtab\n"); + return NULL; + } + return ret; + } + iter++; + } + + return ret; +} + +/* no need to free return value */ +unsigned char* strtab_name( Elf_Shdr_strtab *strtab, long offset ) +{ + unsigned char *ret = NULL; + + if ( strtab == NULL ) + { + return NULL; + } + + if ( offset > strtab->sz_tab ) + { + printf("strtab offset > then header size\n"); + return NULL; + } + + if ( offset < 0 ) + { + printf("strtab offset <0\n"); + return NULL; + } + + ret = &strtab->strtab[offset]; + + return ret; +}
\ No newline at end of file diff --git a/elfreader.h b/elfreader.h new file mode 100644 index 0000000..50e08a7 --- /dev/null +++ b/elfreader.h @@ -0,0 +1,158 @@ +#ifndef __ELFREADER_H +#define __ELFREADER_H + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <elf.h> + +#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
\ No newline at end of file |