Introduction

Cette page sert de base simple et réutilisable pour construire toutes les autres pages de ta présentation.

Exploration d'un binaire

Commencons par créer un code simple qui nous servira de base d'analyse

// data_bss.c
int global_uninitialised;
int global_initialised = 3;
 
void ma_fonction() {
    static int static_local = 6;
}
 
int main() {
    ma_fonction();
    return 0;
}
                                        

On peut compiler ce code et commencer à explorer le binaire.

$ gcc data_bss.c -o data_bss
$
                                        

size

La commande size nous permet de connaitre la taille de chacune des sections de notre binaire.

On peut compiler ce code et commencer à explorer le binaire.

$ size data_bss
   text    data     bss     dec     hex filename
   1273     536       8    1817     719 data_bss
                                        

readelf

readelf nous permet d'avoir énormément d'information sur un binaire sans avoir besoin de l'executé.
les arguments que nous allons montrer ici sont :

  • -h : Affiche l'en-tête ELF du programme
  • -S : Affiche les en-tête de section
  • -d : Affiche les dépendances dynamiques
  • -s : Affiche les symboles du binaire

$ readelf -h data_bss
En-tête ELF:
  Magique:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Classe:                            ELF64
  Données:                          complément à 2, système à octets de poids faible d'abord (little endian)
  Version:                           1 (actuelle)
  OS/ABI:                            UNIX - System V
  Version ABI:                       0
  Type:                              DYN (fichier exécutable indépendant de la position)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Adresse du point d'entrée:         0x1040
  Début des en-têtes de programme :  64 (octets dans le fichier)
  Début des en-têtes de section :    14080 (octets dans le fichier)
  Fanions:                           0x0
  Taille de cet en-tête:             64 (octets)
  Taille de l'en-tête du programme:  56 (octets)
  Nombre d'en-tête du programme:     14
  Taille des en-têtes de section:    64 (octets)
  Nombre d'en-têtes de section:      30
  Table d'index des chaînes d'en-tête de section: 29
                                        
$ readelf -S data_bss
Il y a 30 en-têtes de section, débutant à l'adresse de décalage 0x3700 :

En-têtes de section :
  [Nr] Nom               Type             Adresse           Décalage
       Taille            TaillEntrée      Fanion Lien  Info  Alignement
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .note.gnu.pr[...] NOTE             0000000000000350  00000350
       0000000000000020  0000000000000000   A       0     0     8
  [ 2] .note.gnu.bu[...] NOTE             0000000000000370  00000370
       0000000000000024  0000000000000000   A       0     0     4
  [ 3] .interp           PROGBITS         0000000000000394  00000394
       000000000000001c  0000000000000000   A       0     0     1
  [ 4] .gnu.hash         GNU_HASH         00000000000003b0  000003b0
       0000000000000024  0000000000000000   A       5     0     8
  [ 5] .dynsym           DYNSYM           00000000000003d8  000003d8
       0000000000000090  0000000000000018   A       6     1     8
  [ 6] .dynstr           STRTAB           0000000000000468  00000468
       0000000000000088  0000000000000000   A       0     0     1
  [ 7] .gnu.version      VERSYM           00000000000004f0  000004f0
       000000000000000c  0000000000000002   A       5     0     2
  [ 8] .gnu.version_r    VERNEED          0000000000000500  00000500
       0000000000000030  0000000000000000   A       6     1     8
  [ 9] .rela.dyn         RELA             0000000000000530  00000530
       00000000000000c0  0000000000000018   A       5     0     8
  [10] .init             PROGBITS         0000000000001000  00001000
       0000000000000017  0000000000000000  AX       0     0     4
  [11] .plt              PROGBITS         0000000000001020  00001020
       0000000000000010  0000000000000010  AX       0     0     16
  [12] .plt.got          PROGBITS         0000000000001030  00001030
       0000000000000008  0000000000000008  AX       0     0     8
  [13] .text             PROGBITS         0000000000001040  00001040
       0000000000000105  0000000000000000  AX       0     0     16
  [14] .fini             PROGBITS         0000000000001148  00001148
       0000000000000009  0000000000000000  AX       0     0     4
  [15] .rodata           PROGBITS         0000000000002000  00002000
       0000000000000004  0000000000000004  AM       0     0     4
  [16] .eh_frame_hdr     PROGBITS         0000000000002004  00002004
       0000000000000034  0000000000000000   A       0     0     4
  [17] .eh_frame         PROGBITS         0000000000002038  00002038
       00000000000000cc  0000000000000000   A       0     0     8
  [18] .note.ABI-tag     NOTE             0000000000002104  00002104
       0000000000000020  0000000000000000   A       0     0     4
  [19] .init_array       INIT_ARRAY       0000000000003e00  00002e00
       0000000000000008  0000000000000008  WA       0     0     8
  [20] .fini_array       FINI_ARRAY       0000000000003e08  00002e08
       0000000000000008  0000000000000008  WA       0     0     8
  [21] .dynamic          DYNAMIC          0000000000003e10  00002e10
       00000000000001b0  0000000000000010  WA       6     0     8
  [22] .got              PROGBITS         0000000000003fc0  00002fc0
       0000000000000028  0000000000000008  WA       0     0     8
  [23] .got.plt          PROGBITS         0000000000003fe8  00002fe8
       0000000000000018  0000000000000008  WA       0     0     8
  [24] .data             PROGBITS         0000000000004000  00003000
       0000000000000018  0000000000000000  WA       0     0     8
  [25] .bss              NOBITS           0000000000004018  00003018
       0000000000000008  0000000000000000  WA       0     0     4
  [26] .comment          PROGBITS         0000000000000000  00003018
       000000000000001f  0000000000000001  MS       0     0     1
  [27] .symtab           SYMTAB           0000000000000000  00003038
       00000000000003a8  0000000000000018          28    19     8
  [28] .strtab           STRTAB           0000000000000000  000033e0
       0000000000000210  0000000000000000           0     0     1
  [29] .shstrtab         STRTAB           0000000000000000  000035f0
       0000000000000110  0000000000000000           0     0     1
Clé des fanions :
  W (écriture), A (allocation), X (exécution), M (fusion), S (chaînes), I (info),
  L (ordre des liens), O (traitement supplémentaire par l'OS requis), G (groupe),
  T (TLS), C (compressé), x (inconnu), o (spécifique à l'OS), E (exclu),
  D (mbind), l (grand), p (processor specific)
$ readelf -d data_bss

La section dynamique à l'offset 0x2e10 contient 23 entrées :
  Étiquettes Type                         Nom/Valeur
 0x0000000000000001 (NEEDED)             Bibliothèque partagée : [libc.so.6]
 0x000000000000000c (INIT)               0x1000
 0x000000000000000d (FINI)               0x1148
 0x0000000000000019 (INIT_ARRAY)         0x3e00
 0x000000000000001b (INIT_ARRAYSZ)       8 (octets)
 0x000000000000001a (FINI_ARRAY)         0x3e08
 0x000000000000001c (FINI_ARRAYSZ)       8 (octets)
 0x000000006ffffef5 (GNU_HASH)           0x3b0
 0x0000000000000005 (STRTAB)             0x468
 0x0000000000000006 (SYMTAB)             0x3d8
 0x000000000000000a (STRSZ)              136 (octets)
 0x000000000000000b (SYMENT)             24 (octets)
 0x0000000000000015 (DEBUG)              0x0
 0x0000000000000003 (PLTGOT)             0x3fe8
 0x0000000000000007 (RELA)               0x530
 0x0000000000000008 (RELASZ)             192 (octets)
 0x0000000000000009 (RELAENT)            24 (octets)
 0x000000006ffffffb (FLAGS_1)            Fanions: PIE
 0x000000006ffffffe (VERNEED)            0x500
 0x000000006fffffff (VERNEEDNUM)         1
 0x000000006ffffff0 (VERSYM)             0x4f0
 0x000000006ffffff9 (RELACOUNT)          3
 0x0000000000000000 (NULL)               0x0
$ readelf -s data_bss

La table de symboles « .dynsym » contient 6 entrées :
   Num:    Valeur         Tail Type    Lien   Vis      Ndx Nom
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _[...]@GLIBC_2.34 (2)
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterT[...]
     3: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     4: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMC[...]
     5: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND [...]@GLIBC_2.2.5 (3)

La table de symboles « .symtab » contient 39 entrées :
   Num:    Valeur         Tail Type    Lien   Vis      Ndx Nom
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS Scrt1.o
     2: 0000000000002104    32 OBJECT  LOCAL  DEFAULT   18 __abi_tag
     3: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
     4: 0000000000001070     0 FUNC    LOCAL  DEFAULT   13 deregister_tm_clones
     5: 00000000000010a0     0 FUNC    LOCAL  DEFAULT   13 register_tm_clones
     6: 00000000000010e0     0 FUNC    LOCAL  DEFAULT   13 __do_global_dtors_aux
     7: 0000000000004018     1 OBJECT  LOCAL  DEFAULT   25 completed.0
     8: 0000000000003e08     0 OBJECT  LOCAL  DEFAULT   20 __do_global_dtor[...]
     9: 0000000000001120     0 FUNC    LOCAL  DEFAULT   13 frame_dummy
    10: 0000000000003e00     0 OBJECT  LOCAL  DEFAULT   19 __frame_dummy_in[...]
    11: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS data_bss.c
    12: 0000000000004014     4 OBJECT  LOCAL  DEFAULT   24 static_local.0
    13: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    14: 0000000000002100     0 OBJECT  LOCAL  DEFAULT   17 __FRAME_END__
    15: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 
    16: 0000000000003e10     0 OBJECT  LOCAL  DEFAULT   21 _DYNAMIC
    17: 0000000000002004     0 NOTYPE  LOCAL  DEFAULT   16 __GNU_EH_FRAME_HDR
    18: 0000000000003fe8     0 OBJECT  LOCAL  DEFAULT   23 _GLOBAL_OFFSET_TABLE_
    19: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_mai[...]
    20: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterT[...]
    21: 0000000000004000     0 NOTYPE  WEAK   DEFAULT   24 data_start
    22: 0000000000004018     0 NOTYPE  GLOBAL DEFAULT   24 _edata
    23: 000000000000401c     4 OBJECT  GLOBAL DEFAULT   25 global_uninitialised
    24: 0000000000001148     0 FUNC    GLOBAL HIDDEN    14 _fini
    25: 0000000000004010     4 OBJECT  GLOBAL DEFAULT   24 global_initialised
    26: 0000000000004000     0 NOTYPE  GLOBAL DEFAULT   24 __data_start
    27: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
    28: 0000000000004008     0 OBJECT  GLOBAL HIDDEN    24 __dso_handle
    29: 0000000000002000     4 OBJECT  GLOBAL DEFAULT   15 _IO_stdin_used
    30: 0000000000004020     0 NOTYPE  GLOBAL DEFAULT   25 _end
    31: 0000000000001040    34 FUNC    GLOBAL DEFAULT   13 _start
    32: 0000000000001129     7 FUNC    GLOBAL DEFAULT   13 ma_fonction
    33: 0000000000004018     0 NOTYPE  GLOBAL DEFAULT   25 __bss_start
    34: 0000000000001130    21 FUNC    GLOBAL DEFAULT   13 main
    35: 0000000000004018     0 OBJECT  GLOBAL HIDDEN    24 __TMC_END__
    36: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMC[...]
    37: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __cxa_finalize@G[...]
    38: 0000000000001000     0 FUNC    GLOBAL HIDDEN    10 _init

objdump

La commande objdump -d nous permet de désassembler le binaire pour voir le code assembleur généré.
(/!\ les compilations avec optimisation (-O*) peuvent générer un assembleur inattendu /!\)

$ objdump -d data_bss

data_bss:     format de fichier elf64-x86-64


Déassemblage de la section .init :

0000000000001000 <_init>:
    1000:       48 83 ec 08             sub    $0x8,%rsp
    1004:       48 8b 05 c5 2f 00 00    mov    0x2fc5(%rip),%rax        # 3fd0 <__gmon_start__@Base>
    100b:       48 85 c0                test   %rax,%rax
    100e:       74 02                   je     1012 <_init+0x12>
    1010:       ff d0                   call   *%rax
    1012:       48 83 c4 08             add    $0x8,%rsp
    1016:       c3                      ret

Déassemblage de la section .plt :

0000000000001020 <.plt>:
    1020:       ff 35 ca 2f 00 00       push   0x2fca(%rip)        # 3ff0 <_GLOBAL_OFFSET_TABLE_+0x8>
    1026:       ff 25 cc 2f 00 00       jmp    *0x2fcc(%rip)        # 3ff8 <_GLOBAL_OFFSET_TABLE_+0x10>
    102c:       0f 1f 40 00             nopl   0x0(%rax)

Déassemblage de la section .plt.got :

0000000000001030 <__cxa_finalize@plt>:
    1030:       ff 25 aa 2f 00 00       jmp    *0x2faa(%rip)        # 3fe0 <__cxa_finalize@GLIBC_2.2.5>
    1036:       66 90                   xchg   %ax,%ax

Déassemblage de la section .text :

0000000000001040 <_start>:
    1040:       31 ed                   xor    %ebp,%ebp
    1042:       49 89 d1                mov    %rdx,%r9
    1045:       5e                      pop    %rsi
    1046:       48 89 e2                mov    %rsp,%rdx
    1049:       48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
    104d:       50                      push   %rax
    104e:       54                      push   %rsp
    104f:       45 31 c0                xor    %r8d,%r8d
    1052:       31 c9                   xor    %ecx,%ecx
    1054:       48 8d 3d d5 00 00 00    lea    0xd5(%rip),%rdi        # 1130 <main>
    105b:       ff 15 5f 2f 00 00       call   *0x2f5f(%rip)        # 3fc0 <__libc_start_main@GLIBC_2.34>
    1061:       f4                      hlt
    1062:       66 2e 0f 1f 84 00 00    cs nopw 0x0(%rax,%rax,1)
    1069:       00 00 00 
    106c:       0f 1f 40 00             nopl   0x0(%rax)

0000000000001070 <deregister_tm_clones>:
    1070:       48 8d 3d a1 2f 00 00    lea    0x2fa1(%rip),%rdi        # 4018 <__TMC_END__>
    1077:       48 8d 05 9a 2f 00 00    lea    0x2f9a(%rip),%rax        # 4018 <__TMC_END__>
    107e:       48 39 f8                cmp    %rdi,%rax
    1081:       74 15                   je     1098 <deregister_tm_clones+0x28>
    1083:       48 8b 05 3e 2f 00 00    mov    0x2f3e(%rip),%rax        # 3fc8 <_ITM_deregisterTMCloneTable@Base>
    108a:       48 85 c0                test   %rax,%rax
    108d:       74 09                   je     1098 <deregister_tm_clones+0x28>
    108f:       ff e0                   jmp    *%rax
    1091:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
    1098:       c3                      ret
    1099:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

00000000000010a0 <register_tm_clones>:
    10a0:       48 8d 3d 71 2f 00 00    lea    0x2f71(%rip),%rdi        # 4018 <__TMC_END__>
    10a7:       48 8d 35 6a 2f 00 00    lea    0x2f6a(%rip),%rsi        # 4018 <__TMC_END__>
    10ae:       48 29 fe                sub    %rdi,%rsi
    10b1:       48 89 f0                mov    %rsi,%rax
    10b4:       48 c1 ee 3f             shr    $0x3f,%rsi
    10b8:       48 c1 f8 03             sar    $0x3,%rax
    10bc:       48 01 c6                add    %rax,%rsi
    10bf:       48 d1 fe                sar    $1,%rsi
    10c2:       74 14                   je     10d8 <register_tm_clones+0x38>
    10c4:       48 8b 05 0d 2f 00 00    mov    0x2f0d(%rip),%rax        # 3fd8 <_ITM_registerTMCloneTable@Base>
    10cb:       48 85 c0                test   %rax,%rax
    10ce:       74 08                   je     10d8 <register_tm_clones+0x38>
    10d0:       ff e0                   jmp    *%rax
    10d2:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
    10d8:       c3                      ret
    10d9:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

00000000000010e0 <__do_global_dtors_aux>:
    10e0:       f3 0f 1e fa             endbr64
    10e4:       80 3d 2d 2f 00 00 00    cmpb   $0x0,0x2f2d(%rip)        # 4018 <__TMC_END__>
    10eb:       75 2b                   jne    1118 <__do_global_dtors_aux+0x38>
    10ed:       55                      push   %rbp
    10ee:       48 83 3d ea 2e 00 00    cmpq   $0x0,0x2eea(%rip)        # 3fe0 <__cxa_finalize@GLIBC_2.2.5>
    10f5:       00 
    10f6:       48 89 e5                mov    %rsp,%rbp
    10f9:       74 0c                   je     1107 <__do_global_dtors_aux+0x27>
    10fb:       48 8b 3d 06 2f 00 00    mov    0x2f06(%rip),%rdi        # 4008 <__dso_handle>
    1102:       e8 29 ff ff ff          call   1030 <__cxa_finalize@plt>
    1107:       e8 64 ff ff ff          call   1070 <deregister_tm_clones>
    110c:       c6 05 05 2f 00 00 01    movb   $0x1,0x2f05(%rip)        # 4018 <__TMC_END__>
    1113:       5d                      pop    %rbp
    1114:       c3                      ret
    1115:       0f 1f 00                nopl   (%rax)
    1118:       c3                      ret
    1119:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

0000000000001120 <frame_dummy>:
    1120:       f3 0f 1e fa             endbr64
    1124:       e9 77 ff ff ff          jmp    10a0 <register_tm_clones>

0000000000001129 <ma_fonction>:
    1129:       55                      push   %rbp
    112a:       48 89 e5                mov    %rsp,%rbp
    112d:       90                      nop
    112e:       5d                      pop    %rbp
    112f:       c3                      ret

0000000000001130 <main>:
    1130:       55                      push   %rbp
    1131:       48 89 e5                mov    %rsp,%rbp
    1134:       b8 00 00 00 00          mov    $0x0,%eax
    1139:       e8 eb ff ff ff          call   1129 <ma_fonction>
    113e:       b8 00 00 00 00          mov    $0x0,%eax
    1143:       5d                      pop    %rbp
    1144:       c3                      ret

Déassemblage de la section .fini :

0000000000001148 <_fini>:
    1148:       48 83 ec 08             sub    $0x8,%rsp
    114c:       48 83 c4 08             add    $0x8,%rsp
    1150:       c3                      ret