#include "elf_header.h" #include #include #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; }