summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--elfreader.c727
-rw-r--r--elfreader.h158
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