How read ELF header in C?

c elf
19,670

Solution 1

Depending on the platform, a header file already defining this structure might be available. For instance you can try to include elf.h if you're running linux:

#include <elf.h>
#include <stdio.h>
#include <string.h>

#if defined(__LP64__)
#define ElfW(type) Elf64_ ## type
#else
#define ElfW(type) Elf32_ ## type
#endif

void read_elf_header(const char* elfFile) {
  // Either Elf64_Ehdr or Elf32_Ehdr depending on architecture.
  ElfW(Ehdr) header;

  FILE* file = fopen(elfFile, "rb");
  if(file) {
    // read the header
    fread(&header, sizeof(header), 1, file);

    // check so its really an elf file
    if (memcmp(header.e_ident, ELFMAG, SELFMAG) == 0) {
       // this is a valid elf file
    }

    // finally close the file
    fclose(file);
  }
}

If you system does not already include the elf.h you can check how the elf header is structured here. Then you can create a struct to hold your data and simply read it like this:

typedef struct {
  uint8     e_ident[16];         /* Magic number and other info */
  uint16    e_type;              /* Object file type */
  uint16    e_machine;           /* Architecture */
  uint32    e_version;           /* Object file version */
  uint64    e_entry;             /* Entry point virtual address */
  uint64    e_phoff;             /* Program header table file offset */
  uint64    e_shoff;             /* Section header table file offset */
  uint32    e_flags;             /* Processor-specific flags */
  uint16    e_ehsize;            /* ELF header size in bytes */
  uint16    e_phentsize;         /* Program header table entry size */
  uint16    e_phnum;             /* Program header table entry count */
  uint16    e_shentsize;         /* Section header table entry size */
  uint16    e_shnum;             /* Section header table entry count */
  uint16    e_shstrndx;          /* Section header string table index */
} Elf64Hdr;

void read_elf_header(const char* elfFile, const char* outputFile) {
  struct Elf64Hdr header;

  FILE* file = fopen(elfFile, "rb");
  if(file) {
    // read the header
    fread(&header, 1, sizeof(header), file);

    // check so its really an elf file
    if(header.e_type == 0x7f &&
       header.e_ident[1] == 'E' &&
       header.e_ident[2] == 'L' &&
       header.e_ident[3] == 'F') {

       // write the header to the output file
       FILE* fout = fopen(outputFile, "wb");
       if(fout) {
         fwrite(&header, 1, sizeof(header), fout);
         fclose(fout);
       }
     }

    // finally close the file
    fclose(file);
  }
}

Solution 2

  1. Include elf.h
  2. Open and Stat elf file
  3. Map file
  4. Typecast map address to Elf64_Ehdr and read
Share:
19,670
David
Author by

David

Updated on July 24, 2022

Comments

  • David
    David almost 2 years

    How to open the file and copy the info into another file. I just need to copy the magic number and version. void read_header(FILE *file, File *file2);

  • user253751
    user253751 over 8 years
    Note: your platform may define this structure in a header file already, so you don't need to copy it. But I don't remember what it's called or which header.
  • Alexandro de Oliveira
    Alexandro de Oliveira over 6 years
    You don't need to open the file to call stat on it.
  • demon36
    demon36 about 5 years
    can better use ElfW(Ehdr) instead of Elf64_Ehdr or Elf32_Ehdr