Finished writing the code to parse out the ELF header into a structure.

This commit is contained in:
2024-04-22 20:42:58 -05:00
parent 34f2956922
commit f94a0dcba4
+86 -21
View File
@@ -11,6 +11,11 @@
#define ELF_BYTE_ORDER_LSB 1 #define ELF_BYTE_ORDER_LSB 1
#define ELF_BYTE_ORDER_MSB 2 #define ELF_BYTE_ORDER_MSB 2
#define ELF64_ADDR_SIZE sizeof(uint64_t)
#define ELF64_OFFSET_SIZE ELF64_ADDR_SIZE
#define ELF64_WORD_SIZE ELF64_ADDR_SIZE / 2
#define ELF64_HALF_SIZE ELF64_WORD_SIZE / 2
typedef enum EIdent typedef enum EIdent
{ {
EI_MAG0 = 0, //Magic number position zero - three. EI_MAG0 = 0, //Magic number position zero - three.
@@ -24,10 +29,6 @@ typedef enum EIdent
EI_ABIVERSION = ELF_OSABI_VERSION_IDENT_INDEX, EI_ABIVERSION = ELF_OSABI_VERSION_IDENT_INDEX,
EI_PAD = 9, EI_PAD = 9,
EI_NIDENT = ELF_IDENTITIFCATION_MAX_SIZE - 1, //End of reserved 16 bytes for the header. 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; } ELFIdentOffsets;
struct elf_header { struct elf_header {
@@ -39,6 +40,12 @@ struct elf_header {
uint64_t ProgramHeaderOffset; uint64_t ProgramHeaderOffset;
uint64_t SectionHeaderOffset; uint64_t SectionHeaderOffset;
uint32_t Flags; uint32_t Flags;
uint16_t HeaderSize;
uint16_t ProgramHeaderEntrySize;
uint16_t ProgramHeaderEntryCount;
uint16_t SectionHeaderEntrySize;
uint16_t SectionHeaderEntryCount;
uint16_t SectionNamesIndex;
}; };
struct elf_header* CreateELFHeader(void); struct elf_header* CreateELFHeader(void);
@@ -61,17 +68,60 @@ struct elf_header* ParseObjectFile(const char* bytes, size_t count) {
return NULL; return NULL;
} }
switch(bytes[EI_CLASS]) uint64_t offsetSize = header->Identitication[EI_CLASS] == ELF_CLASS_TYPE32 ? ELF64_OFFSET_SIZE / 2 : ELF64_OFFSET_SIZE;
{ uint64_t wordSize = ELF64_WORD_SIZE;//header->Identitication[EI_CLASS] == ELF_CLASS_TYPE32 ? ELF64_WORD_SIZE / 2 : ELF64_WORD_SIZE;
case ELF_CLASS_TYPE32: uint64_t halfSize = ELF64_HALF_SIZE;//header->Identitication[EI_CLASS] == ELF_CLASS_TYPE32 ? ELF64_HALF_SIZE / 2 : ELF64_HALF_SIZE;
memcpy(&header->EntryAddress, &bytes[EI_ENTRY_ADDRESS_POINT], sizeof(int32_t)); size_t cursor = ELF_IDENTITIFCATION_MAX_SIZE;
break;
case ELF_CLASS_TYPE64: memcpy(&header->FileType, &bytes[cursor], halfSize); //e_type
memcpy(&header->EntryAddress, &bytes[EI_ENTRY_ADDRESS_POINT], sizeof(int64_t));
break; cursor += halfSize;
default:
header->EntryAddress = -1; memcpy(&header->ISA, &bytes[cursor], halfSize); //e_machine
}
cursor += halfSize;
memcpy(&header->ELFVersion, &bytes[cursor], wordSize); //e_version
cursor += wordSize;
memcpy(&header->EntryAddress, &bytes[cursor], offsetSize); //e_entry
cursor += offsetSize;
memcpy(&header->ProgramHeaderOffset, &bytes[cursor], offsetSize); //e_phoff
cursor += offsetSize;
memcpy(&header->SectionHeaderOffset, &bytes[cursor], offsetSize); //e_shoff
cursor += offsetSize;
memcpy(&header->Flags, &bytes[cursor], wordSize); //e_flags
cursor += wordSize;
memcpy(&header->HeaderSize, &bytes[cursor], halfSize); //e_ehsize
cursor += halfSize;
memcpy(&header->ProgramHeaderEntrySize, &bytes[cursor], halfSize); //e_phentsize
cursor += halfSize;
memcpy(&header->ProgramHeaderEntryCount, &bytes[cursor], halfSize); //e_phnum
cursor += halfSize;
memcpy(&header->SectionHeaderEntrySize, &bytes[cursor], halfSize); //e_shentsize
cursor += halfSize;
memcpy(&header->SectionHeaderEntryCount, &bytes[cursor], halfSize); //e_shnum
cursor += halfSize;
memcpy(&header->SectionNamesIndex, &bytes[cursor], halfSize); //e_shstrndx
switch(bytes[EI_DATA]) switch(bytes[EI_DATA])
{ {
@@ -94,16 +144,31 @@ struct elf_header* ParseObjectFile(const char* bytes, size_t count) {
printf("OS ABI: %s\n", buffer); printf("OS ABI: %s\n", buffer);
GetELFMachineTypeText(bytes[EI_MACHINE], buffer); GetELFMachineTypeText((ELFMachine)header->ISA, buffer);
printf("Machine type: %s\n", buffer); printf("Machine type: %s\n", buffer);
printf("Machine: %d\n", bytes[EI_MACHINE]);
// int64_t entryAddress; printf("Object File Version: %#02x\n", header->ELFVersion);
// memcpy(&entryAddress, &bytes[EI_ENTRY_ADDRESS_POINT], sizeof(int64_t)); printf("Entry point address: %#06lx\n", header->EntryAddress);
// printf("Entry point address: %#06lx\n", entryAddress); printf("Program Header Offset: %ld bytes\n", header->ProgramHeaderOffset);
printf("Section Header Offset: %ld bytes\n", header->SectionHeaderOffset);
printf("Flags: %#04x\n", header->Flags);
printf("Size of Header: %d bytes\n", header->HeaderSize);
printf("Size of Program Headers: %d bytes\n", header->ProgramHeaderEntrySize);
printf("Number of Programer Headers: %d\n", header->ProgramHeaderEntryCount);
printf("Size of Section Header: %d bytes\n", header->SectionHeaderEntrySize);
printf("Number of Section Headers: %d\n", header->SectionHeaderEntryCount);
printf("Section Header string table index: %d\n", header->SectionNamesIndex);
return header; return header;
} }
@@ -121,7 +186,7 @@ void ELFPrintMagic(const struct elf_header* header) {
for(int i = 0; i < ELF_IDENTITIFCATION_MAX_SIZE; i++) for(int i = 0; i < ELF_IDENTITIFCATION_MAX_SIZE; i++)
{ {
printf("%02X ", header->Identitication[i]); printf("%02x ", header->Identitication[i]);
} }
printf("\n"); printf("\n");