#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<