Skip to content

Instantly share code, notes, and snippets.

@aaronyoo
Created December 31, 2018 04:27
Show Gist options
  • Save aaronyoo/0fa4eb2cfff41a476670274330038e39 to your computer and use it in GitHub Desktop.
Save aaronyoo/0fa4eb2cfff41a476670274330038e39 to your computer and use it in GitHub Desktop.
Simple elf parser.
#include <stdint.h>
#include <stdlib.h>
#include <elf.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
void readElfHeader(Elf64_Ehdr *ehdr);
int main(int argc, char **argv) {
if (argc != 2) {
printf("Incorrect number of arguments\n");
exit(0);
}
/* Open the file */
FILE *fp = fopen(argv[1], "rb");
if (fp == NULL) {
perror("fopen");
exit(-1);
}
/* Get the size of the file */
fseek(fp, 0L, SEEK_END);
long int file_size = ftell(fp);
rewind(fp);
/* Map the entire binary into memory for quick random access */
uint8_t *addr = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fileno(fp), 0);
if (addr == MAP_FAILED) {
perror("mmap");
exit(-1);
}
/* Assign ELF Header, program header table, and section header table */
Elf64_Ehdr *ehdr = (Elf64_Ehdr *)(addr);
Elf64_Phdr *phdr = (Elf64_Phdr *)(addr + ehdr->e_phoff);
Elf64_Shdr *shdr = (Elf64_Shdr *)(addr + ehdr->e_shoff);
/* Make sure it is a valid ELF Binary by checking magic numbers */
if (ehdr->e_ident[0] != 0x7f ||
ehdr->e_ident[1] != 'E' ||
ehdr->e_ident[2] != 'L' ||
ehdr->e_ident[3] != 'F') {
printf("File is not an ELF Binary\n");
exit(-1);
}
/* Make sure it is an executable ELF file */
if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) {
printf("%d\n", ehdr->e_type);
printf("ELF file is not executable\n");
exit(-1);
}
/* Extract Information from the ELF Header */
readElfHeader(ehdr);
/* Get the string table */
uint8_t *string_table = &addr[shdr[ehdr->e_shstrndx].sh_offset];
/* Print Section Header Table */
printf("Section Headers:\n");
printf("\tName : Offset\n");
for (int i = 0; i < ehdr->e_shnum; i++) {
printf("\t%s : 0x%lx\n", &string_table[shdr[i].sh_name], shdr[i].sh_offset);
}
printf("\n");
/* Print Program Header Table */
printf("Program Headers:\n");
printf("\tType : Offset : Virtual Address\n");
for (int i = 0; i < ehdr->e_phnum; i++) {
printf("\t%d : 0x%lx : 0x%lx\n", phdr[i].p_type, phdr[i].p_offset, phdr[i].p_vaddr);
}
printf("\n");
}
/*
* Extract information from the ELF Header:
* Magic Bytes
* Entry Point Address
* Start of Program Headers (offset)void readSectionHeaders(Elf64_Shdr *shdr, Elf64_Shdr *string_table)
* Start of Section Headers (address)
* Size of ELF Header
* Number of Program Headers
* Number of Section Headers
*/
void readElfHeader(Elf64_Ehdr *ehdr) {
printf("ELF Header (%d bytes):\n", ehdr->e_ehsize);
/* Print Magic Bytes */
printf("\tMagic:\t");
for (int i = 0; i < 16; i++) {
printf("%02x ", *(((uint8_t *) ehdr) + i));
}
printf("\n");
/* Print Entry Point Address */
printf("\tEntry Point:\t%lx\n", ehdr->e_entry);
/* Print Start of Program Headers */
printf("\tStart of Program Headers:\t%ld (bytes into file)\n",
ehdr->e_phoff);
/* Print Start of Section Headers */
printf("\tStart of Section Headers:\t%ld (bytes into file)\n",
ehdr->e_shoff);
/* Print Size of Program Headers */
printf("\tSize of Program Headers:\t%d (bytes)\n", ehdr->e_phentsize);
/* Print Number of Program Headers */
printf("\tNumber of Program Headers:\t%d\n", ehdr->e_phnum);
/* Print Size of Section Headers */
printf("\tSize of Section Headers:\t%d (bytes)\n", ehdr->e_shentsize);
/* Print Number of Section Headers */
printf("\tNumber of Section Headers:\t%d\n", ehdr->e_shnum);
printf("\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment