Utilisation d'un système de tag des objets elf

download Utilisation d'un système de tag des objets elf

If you can't read please download the document

Transcript of Utilisation d'un système de tag des objets elf

Diamond_editions

Mise en place d'un systme de tag sur les objets ELFThierry GAYETLors de l'inspection d'un objet ELF (binaire, librairie dynamiques, ), il peut tre intressant de connatre les lments qui sont entrs dans la phase de gnration (version du noyau, version du compilateur, version des binutils, tag SVN ou GIT, ). Ces lments peuvent servir remonter l'origine d'un bug et donc aider aux investigations.1. Les objets binaire ELF sous LinuxELF (Executable and Linkable Format, format excutable et liable ; anciennement Executable and Linking Format) est un format de fichier binaire utilis pour l'enregistrement de code compil (objets, excutables, bibliothques de fonctions). Il a t dvelopp par lUSL (Unix System Laboratories) pour remplacer les anciens formats a.out et COFF qui avaient atteint leurs limites. Aujourd'hui, ce format est utilis dans la plupart des systmes d'exploitation de type Unix (GNU/Linux, Solaris, IRIX, System V, BSD), l'exception de Mac OS X.

Chaque fichier ELF est constitu d'une en-tte ELF, suivi par les donnes du fichier. Les donnes de fichier peuvent inclure:Un tableau d'en-tte de programme, dcrivant zro ou plusieurs segments;

Un tableau d'en-tte de section, dcrivant zro ou plusieurs sections;

Les donnes rfrences par des entres dans la table d'en-tte du programme ou le tableau d'en-tte de la section;

Les segments contiennent des informations qui sont ncessaires l'excution d'excution du fichier, tandis que les sections contiennent des donnes importantes pour la liaison et la relocalisation. Chaque octet dans le fichier entier est pris par une section la fois, mais il peut y avoir octets orphelins qui ne sont pas couverts par une section. Dans le cas normal d'un excutable UNIX une ou plusieurs sections sont enferms dans un segment.

Architecture du format ELF.2. Quelques commandes pour jouer avec ELFQu'il soit ELF32 (x86 32 bits) ou ELF64 (x86 - 64 bits), la commande file donne la carte d'identit d'un objet sous linux:$ file ./myBinElfmyBinElf: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x8070f79e36c1d0b20889559eaa5a3c91efaabb8c, not stripped$ file /lib/libcryptsetup.so.4.0.0libcryptsetup.so.4.0.0: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, BuildID[sha1]=0x134928597054b3e93f142dd94c2179ff56e0fc55, strippedReadELF est un programme utile pour extraire les lments de l'entte ELF:$ readelf -h ./myBinElfELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 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: 0x8048310 Start of program headers: 52 (bytes into file) Start of section headers: 4400 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 8 Size of section headers: 40 (bytes) Number of section headers: 29 Section header string table index: 26Quelques explications sont les bienvenue:
Nous pouvons remarques quelques donnes au dbut:7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00Ces quatre premier octets reprsentent le nombre magique permettant d'identifier le type du fichier:7f 45 4c 46Les octets suivant reprsentent des meta-donnes du fichier comme la version, la taille, le type d'encodage des donnes: Data: 2's complement, little endian Type: EXEC (Executable file)Cela spcifie si le ELF est excutable. Un fichier ELF peur tre relogeable, un objet partage, un core file ou un fichier spcifique un processeur. Par exemple, un driver dynamique est relogeable de part son point d'entre. Entry point address: 0x8048310Le point d'entre de l'excutable est _start().Readelf permet galement de lister des sections:$ readelf -S ./myBinElfThere are 30 section headers, starting at offset 0x1148:

Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .interp PROGBITS 08048154 000154 000013 00 A 0 0 1 [ 2] .note.ABI-tag NOTE 08048168 000168 000020 00 A 0 0 4 [ 3] .note.gnu.build-i NOTE 08048188 000188 000024 00 A 0 0 4 [ 4] .gnu.hash GNU_HASH 080481ac 0001ac 000020 04 A 5 0 4 [ 5] .dynsym DYNSYM 080481cc 0001cc 000080 10 A 6 1 4 [ 6] .dynstr STRTAB 0804824c 00024c 000077 00 A 0 0 1 [ 7] .gnu.version VERSYM 080482c4 0002c4 000010 02 A 5 0 2 [ 8] .gnu.version_r VERNEED 080482d4 0002d4 000030 00 A 6 1 4 [ 9] .rel.dyn REL 08048304 000304 000008 08 A 5 0 4 [10] .rel.plt REL 0804830c 00030c 000030 08 A 5 12 4 [11] .init PROGBITS 0804833c 00033c 00002e 00 AX 0 0 4 [12] .plt PROGBITS 08048370 000370 000070 04 AX 0 0 16 [13] .text PROGBITS 080483e0 0003e0 00020c 00 AX 0 0 16 [14] .fini PROGBITS 080485ec 0005ec 00001a 00 AX 0 0 4 [15] .rodata PROGBITS 08048608 000608 000042 00 A 0 0 4 [16] .eh_frame_hdr PROGBITS 0804864c 00064c 000044 00 A 0 0 4 [17] .eh_frame PROGBITS 08048690 000690 000104 00 A 0 0 4 [18] .ctors PROGBITS 08049f14 000f14 000008 00 WA 0 0 4 [19] .dtors PROGBITS 08049f1c 000f1c 000008 00 WA 0 0 4 [20] .jcr PROGBITS 08049f24 000f24 000004 00 WA 0 0 4 [21] .dynamic DYNAMIC 08049f28 000f28 0000c8 08 WA 6 0 4 [22] .got PROGBITS 08049ff0 000ff0 000004 04 WA 0 0 4 [23] .got.plt PROGBITS 08049ff4 000ff4 000024 04 WA 0 0 4 [24] .data PROGBITS 0804a018 001018 000008 00 WA 0 0 4 [25] .bss NOBITS 0804a020 001020 000008 00 WA 0 0 4 [26] .comment PROGBITS 00000000 001020 00002a 01 MS 0 0 1 [27] .shstrtab STRTAB 00000000 00104a 0000fc 00 0 0 1 [28] .symtab SYMTAB 00000000 0015f8 000460 10 29 45 4 [29] .strtab STRTAB 00000000 001a58 000259 00 0 0 1Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings) I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific)Ainsi que les segments:$ readelf --segments ./myBinElf

Elf file type is EXEC (Executable file)Entry point 0x80483e0There are 9 program headers, starting at offset 52

Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x000034 0x08048034 0x08048034 0x00120 0x00120 R E 0x4 INTERP 0x000154 0x08048154 0x08048154 0x00013 0x00013 R 0x1 [Requesting program interpreter: /lib/ld-linux.so.2] LOAD 0x000000 0x08048000 0x08048000 0x00794 0x00794 R E 0x1000 LOAD 0x000f14 0x08049f14 0x08049f14 0x0010c 0x00114 RW 0x1000 DYNAMIC 0x000f28 0x08049f28 0x08049f28 0x000c8 0x000c8 RW 0x4 NOTE 0x000168 0x08048168 0x08048168 0x00044 0x00044 R 0x4 GNU_EH_FRAME 0x00064c 0x0804864c 0x0804864c 0x00044 0x00044 R 0x4 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 GNU_RELRO 0x000f14 0x08049f14 0x08049f14 0x000ec 0x000ec R 0x1

Section to Segment mapping: Segment Sections... 00 01 .interp 02 .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 03 .ctors .dtors .jcr .dynamic .got .got.plt .data .bss 04 .dynamic 05 .note.ABI-tag .note.gnu.build-id 06 .eh_frame_hdr 07 08 .ctors .dtors .jcr .dynamic .got 3. Le systme de TAG:En s'appuyant sur ce format dont tous les objets binaires (programmes, librairies dynamiques, ) utilisent, il est possible de rajouter une section personnalise ce format dynamique.

Il est donc possible de rajouter dans cette section un ensemble de donnes cohrent qui rsumerait la chane de gnration d'un binaire. En effet, il peut cela peut tre utile de faon a reproduire un bug dans le but de le rsoudre.

Le donnes inclure sont libre, mais pourrait tre: version de la toolchain (gcc, ld, );

version de la glibc;

version des sources du noyau;

version des binutils (ar, strip, ranlib, );

date et heure du build;

tag du systme de gestion de versions utilis (SVN, Mercurial, Git, );

...

Cela pourrait tre rsum avec un identifiant du build si sauvegarde de la carte identit des build en base de donnes;4. Gnration et pose d'un TAG avec objcopyUn tag est simplement un fichier texte dans lequel on crit des donnes importantes. Il peut donc tre personnalis souhait:$ touch ./myTag$ echo "TOOLCHAIN = " $(TOOLCHAIN_VERSION) GCC v$ (GCC_VERSION) >> ./myTag $ echo "TARGET = " $(TARGET_ID) >> ./myTag$ echo "BUILT = " $(shell date +"%Y/%m/%d %H:%M: %S") on $(BUILD_HOST) $(BUILD_KIND) >> ./myTagPour faire simple, nous allons utiliser un tag avec juste une salutation:echo "bonjour Thierry" > ./mytagAvant d'appliquer un TAG dans les sections du header ELF, il peut tre ncessaire par scurit de supprimer un ancien TAG similaire:

$ objcopy --remove-section MYTAG ./myBinElf

Ensuite, nous pouvons ajouter notre TAG au binaire:$ objcopy --add-section MYTAG=./myTag --set-section-flags MYTAG=contents ./myBinElf

On peut vrifier que le tag est bien prsent:$ readelf -all ./myBinElf | grep MYTAG [27] MYTAG PROGBITS 00000000 00104a 000010 00 W 0 0 15. Extraction du TAG avec objcopyMaintenant nous avons besoin d'extraire ce TAG pour pouvoir connatre sont contenu. Nous allons utilise l'outil objcopy et dd pour ce faire. De faon, simplifier l'extraction, je propose un petit script shell extractTAG.sh:IN_F=$1OUT_F=$2SECTION=$3

objdump -h $IN_F | grep $SECTION | awk '{print "dd if='$IN_F' of='$OUT_F' bs=1 count=$[0x" $3 "] skip=$[0x" $6 "]"}' | bash

Une fois le script rendu excutable avec un chmod +x, son utilisant se fait de la faon suivante:./extractTAG.sh ./myBinElf MYTAG_dump.txt MYTAG16+0enregistrements lus16+0enregistrements crits16octets (16 B) copis, 4,2532e-05s, 376 kB/s$ cat ./MYTAG_dump.txt bonjour ThierryNous retrouvons donc bien notre salutation d'origine.6. ConclusionNous avons vu la faon de poser un tag dans dans une nouvelle section ELF d'un binaire. De mme, nous avons galement vu comme procd son extraction.

Gnralis, un systme de build, cela pourrait permettre de suivre la gnration d'un binaire et aussi de remont aux contexte de gnration en se basant sur les donnes inclus dans cette section.7. Lienshttp://manpagesfr.free.fr/man/man5/elf.5.html

http://pwet.fr/man/linux/formats/elf

http://elftoolchain.sourceforge.net/for-review/libelf-by-example-20100111.pdf

http://developers.sun.com/solaris/articles/elf.html

http://docs.oracle.com/cd/E19082-01/819-0690/chapter6-43405/index.html

http://www.skyfree.org/linux/references/ELF_Format.pdf

http://www.linuxjournal.com/article/1059

http://unixhelp.ed.ac.uk/CGI/man-cgi?objcopy+1

http://mylinuxbook.com/readelf-command/

http://www.bottomupcs.com/elf.html

http://www.ensta-paristech.fr/~diam/dev/online/elf-howto-1996_07_14/ELF-HOWTO.html#toc

http://fr.slideshare.net/varunmahajan06/gnu-linux-programstructure

http://linuxgazette.berlios.de/issue84/hawk.html

http://asm.sourceforge.net/articles/startup.html

http://stackoverflow.com/questions/13908276/loading-elf-file-in-c-in-user-space

http://linux.die.net/man/1/file

http://linux.die.net/man/1/readelf

http://linux.die.net/man/1/objdump