# ELF Tricks {% hint style="success" %} Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks * Check the [**plans d'abonnement**](https://github.com/sponsors/carlospolop)! * **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** nous sur **Twitter** 🐩 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Partagez des astuces de hacking en soumettant des PRs aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dĂ©pĂŽts github.
{% endhint %} ## Program Headers Ils dĂ©crivent au chargeur comment charger l'ELF en mĂ©moire : ```bash readelf -lW lnstat Elf file type is DYN (Position-Independent Executable file) Entry point 0x1c00 There are 9 program headers, starting at offset 64 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x000040 0x0000000000000040 0x0000000000000040 0x0001f8 0x0001f8 R 0x8 INTERP 0x000238 0x0000000000000238 0x0000000000000238 0x00001b 0x00001b R 0x1 [Requesting program interpreter: /lib/ld-linux-aarch64.so.1] LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x003f7c 0x003f7c R E 0x10000 LOAD 0x00fc48 0x000000000001fc48 0x000000000001fc48 0x000528 0x001190 RW 0x10000 DYNAMIC 0x00fc58 0x000000000001fc58 0x000000000001fc58 0x000200 0x000200 RW 0x8 NOTE 0x000254 0x0000000000000254 0x0000000000000254 0x0000e0 0x0000e0 R 0x4 GNU_EH_FRAME 0x003610 0x0000000000003610 0x0000000000003610 0x0001b4 0x0001b4 R 0x4 GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10 GNU_RELRO 0x00fc48 0x000000000001fc48 0x000000000001fc48 0x0003b8 0x0003b8 R 0x1 Section to Segment mapping: Segment Sections... 00 01 .interp 02 .interp .note.gnu.build-id .note.ABI-tag .note.package .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 03 .init_array .fini_array .dynamic .got .data .bss 04 .dynamic 05 .note.gnu.build-id .note.ABI-tag .note.package 06 .eh_frame_hdr 07 08 .init_array .fini_array .dynamic .got ``` Le programme prĂ©cĂ©dent a **9 en-tĂȘtes de programme**, ensuite, le **mappage de segment** indique dans quel en-tĂȘte de programme (de 00 Ă  08) **chaque section est situĂ©e**. ### PHDR - En-tĂȘte de programme Contient les tables d'en-tĂȘtes de programme et les mĂ©tadonnĂ©es elles-mĂȘmes. ### INTERP Indique le chemin du chargeur Ă  utiliser pour charger le binaire en mĂ©moire. ### LOAD Ces en-tĂȘtes sont utilisĂ©s pour indiquer **comment charger un binaire en mĂ©moire.**\ Chaque en-tĂȘte **LOAD** indique une rĂ©gion de **mĂ©moire** (taille, permissions et alignement) et indique les octets du binaire ELF **Ă  copier lĂ -dedans**. Par exemple, le second a une taille de 0x1190, devrait ĂȘtre situĂ© Ă  0x1fc48 avec des permissions de lecture et d'Ă©criture et sera rempli avec 0x528 Ă  partir de l'offset 0xfc48 (il ne remplit pas tout l'espace rĂ©servĂ©). Cette mĂ©moire contiendra les sections `.init_array .fini_array .dynamic .got .data .bss`. ### DYNAMIC Cet en-tĂȘte aide Ă  lier les programmes Ă  leurs dĂ©pendances de bibliothĂšque et Ă  appliquer des relocations. VĂ©rifiez la section **`.dynamic`**. ### NOTE Cela stocke des informations de mĂ©tadonnĂ©es sur le binaire. ### GNU\_EH\_FRAME DĂ©finit l'emplacement des tables de dĂ©pliage de pile, utilisĂ©es par les dĂ©bogueurs et les fonctions d'exĂ©cution des exceptions C++. ### GNU\_STACK Contient la configuration de la dĂ©fense contre l'exĂ©cution de la pile. Si activĂ©, le binaire ne pourra pas exĂ©cuter de code depuis la pile. ### GNU\_RELRO Indique la configuration RELRO (Relocation Read-Only) du binaire. Cette protection marquera comme en lecture seule certaines sections de la mĂ©moire (comme le `GOT` ou les tables `init` et `fini`) aprĂšs que le programme a Ă©tĂ© chargĂ© et avant qu'il ne commence Ă  s'exĂ©cuter. Dans l'exemple prĂ©cĂ©dent, il copie 0x3b8 octets Ă  0x1fc48 en lecture seule affectant les sections `.init_array .fini_array .dynamic .got .data .bss`. Notez que RELRO peut ĂȘtre partiel ou complet, la version partielle ne protĂšge pas la section **`.plt.got`**, qui est utilisĂ©e pour **lazy binding** et a besoin de cet espace mĂ©moire pour avoir **des permissions d'Ă©criture** afin d'Ă©crire l'adresse des bibliothĂšques la premiĂšre fois que leur emplacement est recherchĂ©. ### TLS DĂ©finit une table d'entrĂ©es TLS, qui stocke des informations sur les variables locales aux threads. ## En-tĂȘtes de section Les en-tĂȘtes de section donnent une vue plus dĂ©taillĂ©e du binaire ELF. ``` objdump lnstat -h lnstat: file format elf64-littleaarch64 Sections: Idx Name Size VMA LMA File off Algn 0 .interp 0000001b 0000000000000238 0000000000000238 00000238 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .note.gnu.build-id 00000024 0000000000000254 0000000000000254 00000254 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 2 .note.ABI-tag 00000020 0000000000000278 0000000000000278 00000278 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .note.package 0000009c 0000000000000298 0000000000000298 00000298 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .gnu.hash 0000001c 0000000000000338 0000000000000338 00000338 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 5 .dynsym 00000498 0000000000000358 0000000000000358 00000358 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 6 .dynstr 000001fe 00000000000007f0 00000000000007f0 000007f0 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 7 .gnu.version 00000062 00000000000009ee 00000000000009ee 000009ee 2**1 CONTENTS, ALLOC, LOAD, READONLY, DATA 8 .gnu.version_r 00000050 0000000000000a50 0000000000000a50 00000a50 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 9 .rela.dyn 00000228 0000000000000aa0 0000000000000aa0 00000aa0 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 10 .rela.plt 000003c0 0000000000000cc8 0000000000000cc8 00000cc8 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 11 .init 00000018 0000000000001088 0000000000001088 00001088 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 12 .plt 000002a0 00000000000010a0 00000000000010a0 000010a0 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 13 .text 00001c34 0000000000001340 0000000000001340 00001340 2**6 CONTENTS, ALLOC, LOAD, READONLY, CODE 14 .fini 00000014 0000000000002f74 0000000000002f74 00002f74 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 15 .rodata 00000686 0000000000002f88 0000000000002f88 00002f88 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 16 .eh_frame_hdr 000001b4 0000000000003610 0000000000003610 00003610 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 17 .eh_frame 000007b4 00000000000037c8 00000000000037c8 000037c8 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 18 .init_array 00000008 000000000001fc48 000000000001fc48 0000fc48 2**3 CONTENTS, ALLOC, LOAD, DATA 19 .fini_array 00000008 000000000001fc50 000000000001fc50 0000fc50 2**3 CONTENTS, ALLOC, LOAD, DATA 20 .dynamic 00000200 000000000001fc58 000000000001fc58 0000fc58 2**3 CONTENTS, ALLOC, LOAD, DATA 21 .got 000001a8 000000000001fe58 000000000001fe58 0000fe58 2**3 CONTENTS, ALLOC, LOAD, DATA 22 .data 00000170 0000000000020000 0000000000020000 00010000 2**3 CONTENTS, ALLOC, LOAD, DATA 23 .bss 00000c68 0000000000020170 0000000000020170 00010170 2**3 ALLOC 24 .gnu_debugaltlink 00000049 0000000000000000 0000000000000000 00010170 2**0 CONTENTS, READONLY 25 .gnu_debuglink 00000034 0000000000000000 0000000000000000 000101bc 2**2 CONTENTS, READONLY ``` It also indicates the location, offset, permissions but also the **type of data** it section has. ### Meta Sections * **String table**: Il contient toutes les chaĂźnes nĂ©cessaires au fichier ELF (mais pas celles rĂ©ellement utilisĂ©es par le programme). Par exemple, il contient des noms de sections comme `.text` ou `.data`. Et si `.text` est Ă  l'offset 45 dans la table des chaĂźnes, il utilisera le numĂ©ro **45** dans le champ **name**. * Afin de trouver oĂč se trouve la table des chaĂźnes, l'ELF contient un pointeur vers la table des chaĂźnes. * **Symbol table**: Il contient des informations sur les symboles comme le nom (offset dans la table des chaĂźnes), l'adresse, la taille et plus de mĂ©tadonnĂ©es sur le symbole. ### Main Sections * **`.text`**: L'instruction du programme Ă  exĂ©cuter. * **`.data`**: Variables globales avec une valeur dĂ©finie dans le programme. * **`.bss`**: Variables globales laissĂ©es non initialisĂ©es (ou initialisĂ©es Ă  zĂ©ro). Les variables ici sont automatiquement initialisĂ©es Ă  zĂ©ro, empĂȘchant ainsi l'ajout de zĂ©ros inutiles au binaire. * **`.rodata`**: Variables globales constantes (section en lecture seule). * **`.tdata`** et **`.tbss`**: Comme .data et .bss lorsque des variables locales Ă  un thread sont utilisĂ©es (`__thread_local` en C++ ou `__thread` en C). * **`.dynamic`**: Voir ci-dessous. ## Symbols Symbols est un emplacement nommĂ© dans le programme qui pourrait ĂȘtre une fonction, un objet de donnĂ©es global, des variables locales Ă  un thread... ``` readelf -s lnstat Symbol table '.dynsym' contains 49 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000001088 0 SECTION LOCAL DEFAULT 12 .init 2: 0000000000020000 0 SECTION LOCAL DEFAULT 23 .data 3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strtok@GLIBC_2.17 (2) 4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND s[...]@GLIBC_2.17 (2) 5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strlen@GLIBC_2.17 (2) 6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fputs@GLIBC_2.17 (2) 7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND exit@GLIBC_2.17 (2) 8: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _[...]@GLIBC_2.34 (3) 9: 0000000000000000 0 FUNC GLOBAL DEFAULT UND perror@GLIBC_2.17 (2) 10: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...] 11: 0000000000000000 0 FUNC WEAK DEFAULT UND _[...]@GLIBC_2.17 (2) 12: 0000000000000000 0 FUNC GLOBAL DEFAULT UND putc@GLIBC_2.17 (2) [...] ``` Chaque entrĂ©e de symbole contient : * **Nom** * **Attributs de liaison** (faible, local ou global) : Un symbole local ne peut ĂȘtre accĂ©dĂ© que par le programme lui-mĂȘme, tandis que les symboles globaux sont partagĂ©s en dehors du programme. Un objet faible est par exemple une fonction qui peut ĂȘtre remplacĂ©e par une autre. * **Type** : NOTYPE (aucun type spĂ©cifiĂ©), OBJECT (variable de donnĂ©es globale), FUNC (fonction), SECTION (section), FILE (fichier de code source pour les dĂ©bogueurs), TLS (variable locale au thread), GNU\_IFUNC (fonction indirecte pour la relocation) * **Index de section** oĂč il est situĂ© * **Valeur** (adresse en mĂ©moire) * **Taille** ## Section dynamique ``` readelf -d lnstat Dynamic section at offset 0xfc58 contains 28 entries: Tag Type Name/Value 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 0x0000000000000001 (NEEDED) Shared library: [ld-linux-aarch64.so.1] 0x000000000000000c (INIT) 0x1088 0x000000000000000d (FINI) 0x2f74 0x0000000000000019 (INIT_ARRAY) 0x1fc48 0x000000000000001b (INIT_ARRAYSZ) 8 (bytes) 0x000000000000001a (FINI_ARRAY) 0x1fc50 0x000000000000001c (FINI_ARRAYSZ) 8 (bytes) 0x000000006ffffef5 (GNU_HASH) 0x338 0x0000000000000005 (STRTAB) 0x7f0 0x0000000000000006 (SYMTAB) 0x358 0x000000000000000a (STRSZ) 510 (bytes) 0x000000000000000b (SYMENT) 24 (bytes) 0x0000000000000015 (DEBUG) 0x0 0x0000000000000003 (PLTGOT) 0x1fe58 0x0000000000000002 (PLTRELSZ) 960 (bytes) 0x0000000000000014 (PLTREL) RELA 0x0000000000000017 (JMPREL) 0xcc8 0x0000000000000007 (RELA) 0xaa0 0x0000000000000008 (RELASZ) 552 (bytes) 0x0000000000000009 (RELAENT) 24 (bytes) 0x000000000000001e (FLAGS) BIND_NOW 0x000000006ffffffb (FLAGS_1) Flags: NOW PIE 0x000000006ffffffe (VERNEED) 0xa50 0x000000006fffffff (VERNEEDNUM) 2 0x000000006ffffff0 (VERSYM) 0x9ee 0x000000006ffffff9 (RELACOUNT) 15 0x0000000000000000 (NULL) 0x0 ``` Le rĂ©pertoire NEEDED indique que le programme **doit charger la bibliothĂšque mentionnĂ©e** pour continuer. Le rĂ©pertoire NEEDED se complĂšte une fois que la **bibliothĂšque partagĂ©e est entiĂšrement opĂ©rationnelle et prĂȘte** Ă  ĂȘtre utilisĂ©e. ## Relocations Le chargeur doit Ă©galement relocaliser les dĂ©pendances aprĂšs les avoir chargĂ©es. Ces relocalisations sont indiquĂ©es dans la table de relocalisation dans les formats REL ou RELA et le nombre de relocalisations est donnĂ© dans les sections dynamiques RELSZ ou RELASZ. ``` readelf -r lnstat Relocation section '.rela.dyn' at offset 0xaa0 contains 23 entries: Offset Info Type Sym. Value Sym. Name + Addend 00000001fc48 000000000403 R_AARCH64_RELATIV 1d10 00000001fc50 000000000403 R_AARCH64_RELATIV 1cc0 00000001fff0 000000000403 R_AARCH64_RELATIV 1340 000000020008 000000000403 R_AARCH64_RELATIV 20008 000000020010 000000000403 R_AARCH64_RELATIV 3330 000000020030 000000000403 R_AARCH64_RELATIV 3338 000000020050 000000000403 R_AARCH64_RELATIV 3340 000000020070 000000000403 R_AARCH64_RELATIV 3348 000000020090 000000000403 R_AARCH64_RELATIV 3350 0000000200b0 000000000403 R_AARCH64_RELATIV 3358 0000000200d0 000000000403 R_AARCH64_RELATIV 3360 0000000200f0 000000000403 R_AARCH64_RELATIV 3370 000000020110 000000000403 R_AARCH64_RELATIV 3378 000000020130 000000000403 R_AARCH64_RELATIV 3380 000000020150 000000000403 R_AARCH64_RELATIV 3388 00000001ffb8 000a00000401 R_AARCH64_GLOB_DA 0000000000000000 _ITM_deregisterTM[...] + 0 00000001ffc0 000b00000401 R_AARCH64_GLOB_DA 0000000000000000 __cxa_finalize@GLIBC_2.17 + 0 00000001ffc8 000f00000401 R_AARCH64_GLOB_DA 0000000000000000 stderr@GLIBC_2.17 + 0 00000001ffd0 001000000401 R_AARCH64_GLOB_DA 0000000000000000 optarg@GLIBC_2.17 + 0 00000001ffd8 001400000401 R_AARCH64_GLOB_DA 0000000000000000 stdout@GLIBC_2.17 + 0 00000001ffe0 001e00000401 R_AARCH64_GLOB_DA 0000000000000000 __gmon_start__ + 0 00000001ffe8 001f00000401 R_AARCH64_GLOB_DA 0000000000000000 __stack_chk_guard@GLIBC_2.17 + 0 00000001fff8 002e00000401 R_AARCH64_GLOB_DA 0000000000000000 _ITM_registerTMCl[...] + 0 Relocation section '.rela.plt' at offset 0xcc8 contains 40 entries: Offset Info Type Sym. Value Sym. Name + Addend 00000001fe70 000300000402 R_AARCH64_JUMP_SL 0000000000000000 strtok@GLIBC_2.17 + 0 00000001fe78 000400000402 R_AARCH64_JUMP_SL 0000000000000000 strtoul@GLIBC_2.17 + 0 00000001fe80 000500000402 R_AARCH64_JUMP_SL 0000000000000000 strlen@GLIBC_2.17 + 0 00000001fe88 000600000402 R_AARCH64_JUMP_SL 0000000000000000 fputs@GLIBC_2.17 + 0 00000001fe90 000700000402 R_AARCH64_JUMP_SL 0000000000000000 exit@GLIBC_2.17 + 0 00000001fe98 000800000402 R_AARCH64_JUMP_SL 0000000000000000 __libc_start_main@GLIBC_2.34 + 0 00000001fea0 000900000402 R_AARCH64_JUMP_SL 0000000000000000 perror@GLIBC_2.17 + 0 00000001fea8 000b00000402 R_AARCH64_JUMP_SL 0000000000000000 __cxa_finalize@GLIBC_2.17 + 0 00000001feb0 000c00000402 R_AARCH64_JUMP_SL 0000000000000000 putc@GLIBC_2.17 + 0 00000001feb8 000d00000402 R_AARCH64_JUMP_SL 0000000000000000 opendir@GLIBC_2.17 + 0 00000001fec0 000e00000402 R_AARCH64_JUMP_SL 0000000000000000 fputc@GLIBC_2.17 + 0 00000001fec8 001100000402 R_AARCH64_JUMP_SL 0000000000000000 snprintf@GLIBC_2.17 + 0 00000001fed0 001200000402 R_AARCH64_JUMP_SL 0000000000000000 __snprintf_chk@GLIBC_2.17 + 0 00000001fed8 001300000402 R_AARCH64_JUMP_SL 0000000000000000 malloc@GLIBC_2.17 + 0 00000001fee0 001500000402 R_AARCH64_JUMP_SL 0000000000000000 gettimeofday@GLIBC_2.17 + 0 00000001fee8 001600000402 R_AARCH64_JUMP_SL 0000000000000000 sleep@GLIBC_2.17 + 0 00000001fef0 001700000402 R_AARCH64_JUMP_SL 0000000000000000 __vfprintf_chk@GLIBC_2.17 + 0 00000001fef8 001800000402 R_AARCH64_JUMP_SL 0000000000000000 calloc@GLIBC_2.17 + 0 00000001ff00 001900000402 R_AARCH64_JUMP_SL 0000000000000000 rewind@GLIBC_2.17 + 0 00000001ff08 001a00000402 R_AARCH64_JUMP_SL 0000000000000000 strdup@GLIBC_2.17 + 0 00000001ff10 001b00000402 R_AARCH64_JUMP_SL 0000000000000000 closedir@GLIBC_2.17 + 0 00000001ff18 001c00000402 R_AARCH64_JUMP_SL 0000000000000000 __stack_chk_fail@GLIBC_2.17 + 0 00000001ff20 001d00000402 R_AARCH64_JUMP_SL 0000000000000000 strrchr@GLIBC_2.17 + 0 00000001ff28 001e00000402 R_AARCH64_JUMP_SL 0000000000000000 __gmon_start__ + 0 00000001ff30 002000000402 R_AARCH64_JUMP_SL 0000000000000000 abort@GLIBC_2.17 + 0 00000001ff38 002100000402 R_AARCH64_JUMP_SL 0000000000000000 feof@GLIBC_2.17 + 0 00000001ff40 002200000402 R_AARCH64_JUMP_SL 0000000000000000 getopt_long@GLIBC_2.17 + 0 00000001ff48 002300000402 R_AARCH64_JUMP_SL 0000000000000000 __fprintf_chk@GLIBC_2.17 + 0 00000001ff50 002400000402 R_AARCH64_JUMP_SL 0000000000000000 strcmp@GLIBC_2.17 + 0 00000001ff58 002500000402 R_AARCH64_JUMP_SL 0000000000000000 free@GLIBC_2.17 + 0 00000001ff60 002600000402 R_AARCH64_JUMP_SL 0000000000000000 readdir64@GLIBC_2.17 + 0 00000001ff68 002700000402 R_AARCH64_JUMP_SL 0000000000000000 strndup@GLIBC_2.17 + 0 00000001ff70 002800000402 R_AARCH64_JUMP_SL 0000000000000000 strchr@GLIBC_2.17 + 0 00000001ff78 002900000402 R_AARCH64_JUMP_SL 0000000000000000 fwrite@GLIBC_2.17 + 0 00000001ff80 002a00000402 R_AARCH64_JUMP_SL 0000000000000000 fflush@GLIBC_2.17 + 0 00000001ff88 002b00000402 R_AARCH64_JUMP_SL 0000000000000000 fopen64@GLIBC_2.17 + 0 00000001ff90 002c00000402 R_AARCH64_JUMP_SL 0000000000000000 __isoc99_sscanf@GLIBC_2.17 + 0 00000001ff98 002d00000402 R_AARCH64_JUMP_SL 0000000000000000 strncpy@GLIBC_2.17 + 0 00000001ffa0 002f00000402 R_AARCH64_JUMP_SL 0000000000000000 __assert_fail@GLIBC_2.17 + 0 00000001ffa8 003000000402 R_AARCH64_JUMP_SL 0000000000000000 fgets@GLIBC_2.17 + 0 ``` ### Relocalisations Statique Si le **programme est chargĂ© Ă  un endroit diffĂ©rent** de l'adresse prĂ©fĂ©rĂ©e (gĂ©nĂ©ralement 0x400000) parce que l'adresse est dĂ©jĂ  utilisĂ©e ou Ă  cause de **ASLR** ou pour toute autre raison, une relocalisation statique **corrige les pointeurs** qui avaient des valeurs s'attendant Ă  ce que le binaire soit chargĂ© Ă  l'adresse prĂ©fĂ©rĂ©e. Par exemple, toute section de type `R_AARCH64_RELATIV` devrait avoir modifiĂ© l'adresse au biais de relocalisation plus la valeur d'addend. ### Relocalisations Dynamiques et GOT La relocalisation pourrait Ă©galement rĂ©fĂ©rencer un symbole externe (comme une fonction d'une dĂ©pendance). Comme la fonction malloc de libC. Ensuite, le chargeur, en chargeant libC Ă  une adresse, vĂ©rifie oĂč la fonction malloc est chargĂ©e, il Ă©crira cette adresse dans la table GOT (Global Offset Table) (indiquĂ©e dans la table de relocalisation) oĂč l'adresse de malloc devrait ĂȘtre spĂ©cifiĂ©e. ### Table de Liaison de ProcĂ©dure La section PLT permet d'effectuer un liaison paresseuse, ce qui signifie que la rĂ©solution de l'emplacement d'une fonction sera effectuĂ©e la premiĂšre fois qu'elle est accĂ©dĂ©e. Ainsi, lorsqu'un programme appelle malloc, il appelle en rĂ©alitĂ© l'emplacement correspondant de `malloc` dans le PLT (`malloc@plt`). La premiĂšre fois qu'il est appelĂ©, il rĂ©sout l'adresse de `malloc` et la stocke, donc la prochaine fois que `malloc` est appelĂ©, cette adresse est utilisĂ©e au lieu du code PLT. ## Initialisation du Programme AprĂšs que le programme a Ă©tĂ© chargĂ©, il est temps pour lui de s'exĂ©cuter. Cependant, le premier code qui est exĂ©cutĂ© **n'est pas toujours la fonction `main`**. Cela est dĂ» au fait que, par exemple, en C++, si une **variable globale est un objet d'une classe**, cet objet doit ĂȘtre **initialisĂ©** **avant** que main ne s'exĂ©cute, comme dans : ```cpp #include // g++ autoinit.cpp -o autoinit class AutoInit { public: AutoInit() { printf("Hello AutoInit!\n"); } ~AutoInit() { printf("Goodbye AutoInit!\n"); } }; AutoInit autoInit; int main() { printf("Main\n"); return 0; } ``` Notez que ces variables globales se trouvent dans `.data` ou `.bss`, mais dans les listes `__CTOR_LIST__` et `__DTOR_LIST__`, les objets Ă  initialiser et Ă  dĂ©truire sont stockĂ©s afin de les suivre. À partir du code C, il est possible d'obtenir le mĂȘme rĂ©sultat en utilisant les extensions GNU : ```c __attributte__((constructor)) //Add a constructor to execute before __attributte__((destructor)) //Add to the destructor list ``` D'un point de vue du compilateur, pour exĂ©cuter ces actions avant et aprĂšs l'exĂ©cution de la fonction `main`, il est possible de crĂ©er une fonction `init` et une fonction `fini` qui seraient rĂ©fĂ©rencĂ©es dans la section dynamique comme **`INIT`** et **`FIN`**. et sont placĂ©es dans les sections `init` et `fini` de l'ELF. L'autre option, comme mentionnĂ©, est de rĂ©fĂ©rencer les listes **`__CTOR_LIST__`** et **`__DTOR_LIST__`** dans les entrĂ©es **`INIT_ARRAY`** et **`FINI_ARRAY`** dans la section dynamique et la longueur de celles-ci est indiquĂ©e par **`INIT_ARRAYSZ`** et **`FINI_ARRAYSZ`**. Chaque entrĂ©e est un pointeur de fonction qui sera appelĂ© sans arguments. De plus, il est Ă©galement possible d'avoir un **`PREINIT_ARRAY`** avec des **pointeurs** qui seront exĂ©cutĂ©s **avant** les pointeurs **`INIT_ARRAY`**. ### Ordre d'initialisation 1. Le programme est chargĂ© en mĂ©moire, les variables globales statiques sont initialisĂ©es dans **`.data`** et celles non initialisĂ©es sont mises Ă  zĂ©ro dans **`.bss`**. 2. Toutes les **dĂ©pendances** pour le programme ou les bibliothĂšques sont **initialisĂ©es** et le **lien dynamique** est exĂ©cutĂ©. 3. Les fonctions **`PREINIT_ARRAY`** sont exĂ©cutĂ©es. 4. Les fonctions **`INIT_ARRAY`** sont exĂ©cutĂ©es. 5. S'il y a une entrĂ©e **`INIT`**, elle est appelĂ©e. 6. Si c'est une bibliothĂšque, dlopen se termine ici, si c'est un programme, il est temps d'appeler le **vrai point d'entrĂ©e** (fonction `main`). ## Stockage Local par Fil (TLS) Ils sont dĂ©finis en utilisant le mot-clĂ© **`__thread_local`** en C++ ou l'extension GNU **`__thread`**. Chaque fil maintiendra un emplacement unique pour cette variable, donc seul le fil peut accĂ©der Ă  sa variable. Lorsque cela est utilisĂ©, les sections **`.tdata`** et **`.tbss`** sont utilisĂ©es dans l'ELF. Qui sont comme `.data` (initialisĂ©) et `.bss` (non initialisĂ©) mais pour le TLS. Chaque variable aura une entrĂ©e dans l'en-tĂȘte TLS spĂ©cifiant la taille et l'offset TLS, qui est l'offset qu'elle utilisera dans la zone de donnĂ©es locale du fil. Le `__TLS_MODULE_BASE` est un symbole utilisĂ© pour faire rĂ©fĂ©rence Ă  l'adresse de base du stockage local par fil et pointe vers la zone en mĂ©moire qui contient toutes les donnĂ©es locales au fil d'un module. {% hint style="success" %} Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)! * **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐩 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %}