Started to break out the parsing of the file's bytes into seperate files.
This commit is contained in:
+125
@@ -0,0 +1,125 @@
|
||||
#include "elf_header.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ELF_IDENTITIFCATION_MAX_SIZE 16
|
||||
#define ELF_CLASS_TYPE32 1
|
||||
#define ELF_CLASS_TYPE64 2
|
||||
|
||||
#define ELF_BYTE_ORDER_LSB 1
|
||||
#define ELF_BYTE_ORDER_MSB 2
|
||||
|
||||
typedef enum EIdent
|
||||
{
|
||||
EI_MAG0 = 0, //Magic number position zero - three.
|
||||
EI_MAG1 = 1,
|
||||
EI_MAG2 = 2,
|
||||
EI_MAG3 = 3,
|
||||
EI_CLASS = 4,
|
||||
EI_DATA = 5,
|
||||
EI_HEADER_VERSION = 6,
|
||||
EI_OSABI = 7,
|
||||
EI_ABIVERSION = 8,
|
||||
EI_PAD = 9,
|
||||
EI_NIDENT = ELF_IDENTITIFCATION_MAX_SIZE - 1, //End of reserved 16 bytes for the header.
|
||||
EI_TYPE = EI_NIDENT + 1,
|
||||
EI_MACHINE = EI_TYPE + 2,
|
||||
EI_OBJECT_FILE_VERSION = EI_MACHINE + 2,
|
||||
EI_ENTRY_ADDRESS_POINT = EI_OBJECT_FILE_VERSION + 4
|
||||
} ELFIdentOffsets;
|
||||
|
||||
struct elf_header {
|
||||
unsigned char Identitication[ELF_IDENTITIFCATION_MAX_SIZE];
|
||||
uint32_t FileType;
|
||||
uint32_t ISA;
|
||||
uint32_t ELFVersion;
|
||||
uint64_t EntryAddress;
|
||||
uint64_t ProgramHeaderOffset;
|
||||
uint64_t SectionHeaderOffset;
|
||||
uint32_t Flags;
|
||||
};
|
||||
|
||||
struct elf_header* CreateELFHeader(void);
|
||||
int ELFMagicNumberValid(const unsigned char* ident);
|
||||
void ELFPrintMagic(const struct elf_header* header);
|
||||
|
||||
struct elf_header* ParseObjectFile(const char* bytes, size_t count) {
|
||||
if (count < 0x40) return NULL;
|
||||
|
||||
struct elf_header* header = CreateELFHeader();
|
||||
|
||||
memcpy(header, bytes, ELF_IDENTITIFCATION_MAX_SIZE);
|
||||
|
||||
if (!ELFMagicNumberValid(header->Identitication))
|
||||
{
|
||||
fprintf(stderr, "Failed to find ELF magic number in file header.\n");
|
||||
ELFPrintMagic(header);
|
||||
printf("\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch(bytes[EI_CLASS])
|
||||
{
|
||||
case ELF_CLASS_TYPE32:
|
||||
memcpy(&header->EntryAddress, &bytes[EI_ENTRY_ADDRESS_POINT], sizeof(int32_t));
|
||||
break;
|
||||
case ELF_CLASS_TYPE64:
|
||||
memcpy(&header->EntryAddress, &bytes[EI_ENTRY_ADDRESS_POINT], sizeof(int64_t));
|
||||
break;
|
||||
default:
|
||||
header->EntryAddress = -1;
|
||||
}
|
||||
|
||||
switch(bytes[EI_DATA])
|
||||
{
|
||||
case ELF_BYTE_ORDER_LSB:
|
||||
printf("Data: 2's complement, little endian.\n");
|
||||
break;
|
||||
case ELF_BYTE_ORDER_MSB:
|
||||
printf("Data: 2's complement, big endian.\n");
|
||||
break;
|
||||
default:
|
||||
printf("Data: Unknown byte order\n");
|
||||
}
|
||||
|
||||
// int64_t entryAddress;
|
||||
|
||||
// memcpy(&entryAddress, &bytes[EI_ENTRY_ADDRESS_POINT], sizeof(int64_t));
|
||||
|
||||
// printf("Entry point address: %#06lx\n", entryAddress);
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
int ELFMagicNumberValid(const unsigned char* ident) {
|
||||
char magic[5] = { ident[EI_MAG0], ident[EI_MAG1], ident[EI_MAG2], ident[EI_MAG3], '\0' };
|
||||
|
||||
return strcmp(magic, "\x7f""ELF") == 0;
|
||||
}
|
||||
|
||||
void ELFPrintMagic(const struct elf_header* header) {
|
||||
if (!header) return;
|
||||
|
||||
printf("Magic: ");
|
||||
|
||||
for(int i = 0; i < ELF_IDENTITIFCATION_MAX_SIZE; i++)
|
||||
{
|
||||
printf("%02X ", header->Identitication[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
struct elf_header* CreateELFHeader(void) {
|
||||
struct elf_header* header = calloc(sizeof(struct elf_header), 1);
|
||||
|
||||
if (!header)
|
||||
{
|
||||
fprintf(stderr, "Failed to calloc\n");
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
Reference in New Issue
Block a user