From f94a0dcba4dfd31f511a286f95197ee3610edb21 Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Mon, 22 Apr 2024 20:42:58 -0500 Subject: [PATCH] Finished writing the code to parse out the ELF header into a structure. --- elf_header.c | 107 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 86 insertions(+), 21 deletions(-) diff --git a/elf_header.c b/elf_header.c index a854a03..a4a826e 100644 --- a/elf_header.c +++ b/elf_header.c @@ -11,6 +11,11 @@ #define ELF_BYTE_ORDER_LSB 1 #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 { EI_MAG0 = 0, //Magic number position zero - three. @@ -24,10 +29,6 @@ typedef enum EIdent EI_ABIVERSION = ELF_OSABI_VERSION_IDENT_INDEX, 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 { @@ -39,6 +40,12 @@ struct elf_header { uint64_t ProgramHeaderOffset; uint64_t SectionHeaderOffset; 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); @@ -61,17 +68,60 @@ struct elf_header* ParseObjectFile(const char* bytes, size_t count) { 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; - } + 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; + uint64_t halfSize = ELF64_HALF_SIZE;//header->Identitication[EI_CLASS] == ELF_CLASS_TYPE32 ? ELF64_HALF_SIZE / 2 : ELF64_HALF_SIZE; + size_t cursor = ELF_IDENTITIFCATION_MAX_SIZE; + + memcpy(&header->FileType, &bytes[cursor], halfSize); //e_type + + cursor += halfSize; + + 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]) { @@ -94,16 +144,31 @@ struct elf_header* ParseObjectFile(const char* bytes, size_t count) { printf("OS ABI: %s\n", buffer); - GetELFMachineTypeText(bytes[EI_MACHINE], buffer); + GetELFMachineTypeText((ELFMachine)header->ISA, 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; } @@ -121,7 +186,7 @@ void ELFPrintMagic(const struct elf_header* header) { for(int i = 0; i < ELF_IDENTITIFCATION_MAX_SIZE; i++) { - printf("%02X ", header->Identitication[i]); + printf("%02x ", header->Identitication[i]); } printf("\n");