2

I was reading ELF format specification, where was told all this stuff with elf-headers, program header, sections, segments and etc. All this is referenced as structs with all kind of fields and values.

So question is, where all this go? I mean, can I watch them as structs, not as output of readelf util?

Is there any intermediate file, where all this elf-magic exist, merged into source code? Or it is just internals of compiler, and in specification structs are mentioned just for humans?)

It looks like "chicken and egg question" for me (speaking about compiled code in terms of code).

5
  • 2
    The names of structs (and fields, macros) are for human consumption. The values assigned to fields are in the ELF file, at offsets given by the struct definitions in the specification. Use any hex editor (or hexdump -C ${ELF_FILE}). If, for example, the spec calls for a Elf64_half e_ehsize at offset 48d and I see the 2 bytes 40 00 at that offset, I can see that e_ehsize (ELF64 header size) is 64 decimal (0x0040). – user4556274 Aug 24 '16 at 15:56
  • 1
    These structures describe the contents of the files created by the compiler and loader when you compile a program. – Barmar Aug 24 '16 at 20:43
  • 1
    You could use them to write your own program like readelf. – Barmar Aug 24 '16 at 20:44
  • 1
    You could look at readelf's source. On my Ubuntu 14.04.5, apt-src install readelf is where I'd start. – waltinator Aug 24 '16 at 22:46
  • 1
    teensy elf is not the only tutorial on creating a very small ELF but it is pretty good. It goes not only through the spec but also through implementation peculiarities. Making the smallest ELF possible is a great way to learn the format. – grochmal Aug 25 '16 at 1:59
1

These structures are present in the ELF files.

Let's look at the ELF header:

#define EI_NIDENT (16)

typedef struct
{
  unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
  Elf32_Half    e_type;                 /* Object file type */
  Elf32_Half    e_machine;              /* Architecture */
  Elf32_Word    e_version;              /* Object file version */
  Elf32_Addr    e_entry;                /* Entry point virtual address */
  Elf32_Off     e_phoff;                /* Program header table file offset */
  Elf32_Off     e_shoff;                /* Section header table file offset */
  Elf32_Word    e_flags;                /* Processor-specific flags */
  Elf32_Half    e_ehsize;               /* ELF header size in bytes */
  Elf32_Half    e_phentsize;            /* Program header table entry size */
  Elf32_Half    e_phnum;                /* Program header table entry count */
  Elf32_Half    e_shentsize;            /* Section header table entry size */
  Elf32_Half    e_shnum;                /* Section header table entry count */
  Elf32_Half    e_shstrndx;             /* Section header string table index */
} Elf32_Ehdr;

typedef struct
{
  unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
  Elf64_Half    e_type;                 /* Object file type */
  Elf64_Half    e_machine;              /* Architecture */
  Elf64_Word    e_version;              /* Object file version */
  Elf64_Addr    e_entry;                /* Entry point virtual address */
  Elf64_Off     e_phoff;                /* Program header table file offset */
  Elf64_Off     e_shoff;                /* Section header table file offset */
  Elf64_Word    e_flags;                /* Processor-specific flags */
  Elf64_Half    e_ehsize;               /* ELF header size in bytes */
  Elf64_Half    e_phentsize;            /* Program header table entry size */
  Elf64_Half    e_phnum;                /* Program header table entry count */
  Elf64_Half    e_shentsize;            /* Section header table entry size */
  Elf64_Half    e_shnum;                /* Section header table entry count */
  Elf64_Half    e_shstrndx;             /* Section header string table index */
} Elf64_Ehdr;

The ELF header is at the beginning of every ELF file.

What this actually means is that the first 16 bytes of ELF files are the e_ident fields on the ELF header:

  • the first byte is 0x7f;

  • the second is 'E';

  • the third is 'L';

  • the fourth is 'F';

  • the fifth is the class;

  • the sixth is the data encoding;

  • the seventh is file version;

  • the eight is the OS ABI;

  • etc.

After the e_ident field, the next 2 bytes are the e_type.

It you head /bin/bash, you will be able to see the ELF near the beginning.

Now if you take an hexdump of the beginning of an ELF file:

$ xxd /bin/bash | head
00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............
00000010: 0200 3e00 0100 0000 7005 4200 0000 0000  ..>.....p.B.....
00000020: 4000 0000 0000 0000 c0cd 0f00 0000 0000  @...............
00000030: 0000 0000 4000 3800 0900 4000 1d00 1c00  ....@.8...@.....
00000040: 0600 0000 0500 0000 4000 0000 0000 0000  ........@.......
00000050: 4000 4000 0000 0000 4000 4000 0000 0000  @.@.....@.@.....
00000060: f801 0000 0000 0000 f801 0000 0000 0000  ................
00000070: 0800 0000 0000 0000 0300 0000 0400 0000  ................
00000080: 3802 0000 0000 0000 3802 4000 0000 0000  8.......8.@.....
00000090: 3802 4000 0000 0000 1c00 0000 0000 0000  8.@.............

The first line of this hexdump are the first 16 bytes (e_ident):

  • the first byte is indeed 0x7f;

  • then comes "ELF";

  • after that comes the class 0x02 for ELFCLASS64 (ELF64);

  • then the encoding, 0x01 for ELFDATA2LSB;

  • etc.

The first two bytes of the second line are the e_type. They are encoded in LSB (because of ELFDATA2LSB) so the value is actually 0x0002 which means ET_EXEC (this is an executable file).

The next two bytes are the architecture (e_machine): 0x003e for EM_X86_64 because this is a x86_64 executable file.

You should be able to decode manually all the fields in the ELF header and you should find the same values as the ones given by readelf. From this, you can locate other ELF structures in the file such as the ElfXX_Shdr or ElfXX_Phdr and decode them based on their definition (and you should find the same infromations as the ones given by readelf).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.