vendredi 4 octobre 2013

En tête ELF

Les fichiers exécutables sous linux sont  format ELF. Le format est décrit sur wikipedia (ELF). Par exemple, le 5e octet définit l'architecture du binaire. Si cet octet vaut 1, c'est du 32 bits, s'il vaut 2, c'est du 64 bits. L'archi est défini au 19e octet. Jouons un peu avec un hello world:
$ cat hello.c
#include <stdio.h>

int main(void) {
    printf("Hello World\n");
    return 0;
}
$ make hello
cc     hello.c   -o hello
$ hexdump -C hello | head -2

00000000  7f 45 4c 46 01 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 03 00 01 00 00 00  20 83 04 08 34 00 00 00  |........ ...4...|
$ file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, BuildID[sha1]=0x0b170e8da236317529906c11be894759a87a8cc3, not stripped
$


On peut "transformer" ce binaire en 64bits avec un coup de hexedit:
$ hexdump -C hello | head -2
00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 3e 00 01 00 00 00  20 83 04 08 34 00 00 00  |..>..... ...4...|

$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), corrupted program header size, corrupted section header size


Et voilà, un beau binaire 64 bits :)

File râle un peu car le 64 bit va chercher ailleurs les infos de taille de programme et de header. On peut les calculer d'ailleurs.

En vert le 32 bit pour le start of program headers et section headers. En souligné pour le 64 bit. (Il faut décaler de 4 octets car il y a l'entry point sur 64 bits avant)
$ hexdump -C hello | head -4
00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 3e 00 01 00 00 00  20 83 04 08 34 00 00 00  |..>..... ...4...|
00000020  a8 07 00 00 00 00 00 00  34 00 20 00 08 00 28 00  |........4. ...(.|
00000030  1f 00 1c 00 06 00 00 00  34 00 00 00 34 80 04 08  |........4...4...|

Ce qui représente une taille de section headers de 0x0028000800200034 soit 11259033430261812 octets (!!). Ca se confirme avec un coup de readelf:
$ readelf -h hello
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x3408048320
  Start of program headers:          1960 (bytes into file)
  Start of section headers:          11259033430261812 (bytes into file)
  Flags:                             0x1c001f
  Size of this header:               6 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         52
  Size of section headers:           0 (bytes)
  Number of section headers:         32820
  Section header string table index: 2052
$


Mitsurugi

Aucun commentaire:

Publier un commentaire