Académique Documents
Professionnel Documents
Culture Documents
Cette série de billets vous montrera comment désamorcer une bombe binaire.
Qu'est-ce qu'une bombe binaire ?
J'ai trouvé ce type de bombe sur le site web de l'excellent livre "Computer
Systems : A Programmer's Perspective".
Les outils de base nécessaires pour désamorcer une telle bombe sont les suivants
gdb et objdump . gdb est un débogueur que nous utiliserons pour inspecter le
programme pendant que nous l'exécutons. objdump est un outil permettant de
désassembler les fichiers objets afin de voir les instructions réelles que l'ordinateur
exécute.
Cette série n'est pas destinée à être un tutoriel sur gdb , en particulier parce que
c'était la première fois que je l'utilisais.
$ ls -l total 36
-rwxr-xr-x 1 carlos carlos 26406 Jun 9 15:41bombe
-rw-r--r-- 1 carlos carlos 4069 Jun 9 15:41 bombe.c
En regardant bomb.c , nous voyons un tas de commentaires et la façon dont tout est
configuré.
http://webcache.googleusercontent.com/search?q=cache:NPuQo5CSngAJ:blog.carlosgaldino.com/2015/11/12/defusing-a-binary-bomb-with-gdb-part-1.html+&... 1/7
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 2 - carlosgaldino
En regardant bomb.c , nous voyons un tas de commentaires et la façon dont tout est
configuré.
http://webcache.googleusercontent.com/search?q=cache:NPuQo5CSngAJ:blog.carlosgaldino.com/2015/11/12/defusing-a-binary-bomb-with-gdb-part-2.html+&... 1/7
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 1 - carlosgaldino
Vous pouvez passer un fichier en argument pour éviter de taper à chaque fois l'entrée
correcte pour des phases déjà désamorcées.
Ensuite, nous devons jeter un coup d'œil à l'exécutable de la bombe , qui est une donnée
binaire, de sorte que nous ne verrons rien d'intéressant si nous l'ouvrons à l'aide de
$EDITOR . C'est pourquoi nous avons besoin d'objdump pour désassembler cet
exécutable.
Si nous examinons les premières lignes de ce nouveau fichier, nous constatons ce qui
suit :
0000000000400ac0 <_init> :
400ac0 : 48 83 éc 08 sous $0x8,%rsp
400ac4 : e8 f3 01 00 00 callq 400cbc <call_gmon_start>
400ac9 : 48 83 c4 08 ajouter $0x8,%rsp
400acd : c3 retq
Voici à quoi ressemble un fichier ELF lorsqu'il est désassemblé. Examinons donc la
fonction principale :
0000000000400da0 <main> :
http://webcache.googleusercontent.com/search?q=cache:NPuQo5CSngAJ:blog.carlosgaldino.com/2015/11/12/defusing-a-binary-bomb-with-gdb-part-1.html+&... 3/7
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 1 - carlosgaldino
http://webcache.googleusercontent.com/search?q=cache:NPuQo5CSngAJ:blog.carlosgaldino.com/2015/11/12/defusing-a-binary-bomb-with-gdb-part-1.html+&... 4/7
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 1 - carlosgaldino
400dd6 : 75 41 jne mov 400e19 <main+0x79>
400dd8 : 48 8b 4b 08 0x8(%rbx),%rcx
400ddc : 48 8b 13 déplacer (%rbx),%rdx
400ddf : be b6 22 40 00 déplacer $0x4022b6,%esi
400de4 : bf 01 00 00 00 déplacer $0x1,%edi
400de9 : e8 12 fe ff ff callq 400c00 <__printf_chk@plt>
400dee : bf 08 00 00 00 déplacer $0x8,%edi
400df3 : e8 28 fe ff ff callq 400c20 <exit@plt>
400df8 : 48 8b 16 déplacer (%rsi),%rdx
400dfb : be d3 22 40 00 déplacer $0x4022d3,%esi
400e00 : bf 01 00 00 00 déplacer $0x1,%edi
400e05 : b8 00 00 00 00 déplacer $0x0,%eax
400e0a : e8 f1 fd ff ff callq 400c00 <__printf_chk@plt>
400e0f : bf 08 00 00 00 déplacer $0x8,%edi
400e14 : e8 07 fe ff ff callq 400c20 <exit@plt>
400e19 : e8 84 05 00 00 callq 4013a2 <initialisation_bombe>
400e1e : bf 38 23 40 00 déplacer $0x402338,%edi
400e23 : e8 e8 fc ff ff callq 400b10 <puts@plt>
400e28 : bf 78 23 40 00 déplacer $0x402378,%edi
400e2d : e8 de fc ff ff callq 400b10 <puts@plt>
400e32 : e8 67 06 00 00 callq 40149e <read_line>
400e37 : 48 89 c7 déplacer %rax,%rdi
400e3a : e8 a1 00 00 00 callq 400ee0 <phase_1>
400e3f : e8 80 07 00 00 callq 4015c4 <phase_defused>
Je n'ai pas collé l'ensemble de la fonction car elle est suffisamment importante et nous
ne sommes pas encore concernés par les autres phases.
http://webcache.googleusercontent.com/search?q=cache:NPuQo5CSngAJ:blog.carlosgaldino.com/2015/11/12/defusing-a-binary-bomb-with-gdb-part-1.html+&... 5/7
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 1 - carlosgaldino
Cette ligne indique que la fonction initialize_bomb doit être appelée. La ligne
correspondante dans le fichier C est la suivante :
/* Faire toutes sortes de choses secrètes qui rendent la bombe plus difficile à désamorcer.
*/
initialize_bomb() ;
00000000004013a2 <initialize_bomb>:
4013a2 : 48 83 ec 08 sous $0x8,%rsp
4013a6 : êtr a0 12 40 00 déplacer $0x4012a0,%esi
4013ab : e bf 02 00 00 00 déplacer 0x2,%edi
4013b0 : e8 db f7 ff ff callq 400b90 <signal@plt>
4013b5 : 48 83 c4 08 ajouter $0x8,%rsp
4013b9 : c3 retq
L'inspection des valeurs ne révèle rien d'intéressant. Passons à autre chose. Les
quelques lignes qui suivent initialize_bomb dans la fonction principale correspondent aux
lignes suivantes dans le fichier C :
printf("Bienvenue dans ma petite bombe diabolique. Vous avez 6 phases avec \N") ;
printf("qui s'est fait exploser. Bonne journée!\N") ;
/* Hmm... Six phases doivent être plus sûres qu'une seule phase ! */
input = read_line() ; /* Obtenir une entrée */
phase_1(input) ; /* Exécuter la phase */
Ils impriment donc les messages et lisent les entrées. Il est alors temps de désamorcer la
première phase.
Là encore, la fonction phase_1 située à 0x400ee0 est appelée. Voyons ce qu'il en est
0000000000400ee0 <phase_1> :
400ee0 : 48 83 ec 08 sous $0x8,%rsp
http://webcache.googleusercontent.com/search?q=cache:NPuQo5CSngAJ:blog.carlosgaldino.com/2015/11/12/defusing-a-binary-bomb-with-gdb-part-1.html+&... 6/7
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 1 - carlosgaldino
Remarquez qu'à 0x400ee4 , la valeur 0x402400 est copiée dans le registre esi . Le
registre esi est généralement utilisé comme registre pour le deuxième argument d'une
fonction qui sera appelée ultérieurement. Dans notre cas, cette fonction est appelée
juste après l'instruction mov . On peut alors se demander où se trouve le premier
argument. Le premier argument est généralement placé dans le registre edi qui, dans
ce cas, sera la chaîne de caractères que nous avons fournie en entrée. Si vous jetez un
coup d'œil à la fonction principale , vous verrez :
La valeur de retour (stockée dans rax ) de la fonction read_line a été placée dans le
registre rdi ( edi est un registre de 32 bits et rdi est le registre équivalent de 64 bits) et
sera utilisée comme premier argument pour la fonction qui sera appelée ensuite et
qui, dans ce cas, est phase_1 . Et c'est exactement ce que fait le code C :
/* Hmm... Six phases doivent être plus sûres qu'une seule phase ! */ input = read_line() ; /* Obtenir une
entrée */
phase_1(input) ; /* Exécuter la phase */
Ok, revenons à la fonction phase_1 . Nous savons maintenant quels sont les
arguments donnés à strings_not_equal et, après avoir exécuté cette fonction, il y a un
test pour vérifier le résultat :
http://webcache.googleusercontent.com/search?q=cache:NPuQo5CSngAJ:blog.carlosgaldino.com/2015/11/12/defusing-a-binary-bomb-with-gdb-part-1.html+&... 7/7
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 1 - carlosgaldino
L'instruction de test effectue une opération ET bit à bit entre ses opérandes et place
les drapeaux appropriés dans le registre eflags . L'instruction je est une instruction de
saut conditionnel qui saute à l'emplacement spécifié uniquement si la comparaison
précédente a mis le ZF (Zero Flag) à 1 dans le registre eflags.
Ainsi, l'instruction test ne mettra ZF à 1 que lorsque nous aurons 0 dans eax , ce qui ne
se produit que lorsque strings_not_equal renvoie 0 . ( L'examen de strings_not_equal
ne révèle rien d'intéressant, c'est exactement ce que l'on attend d'une fonction
portant un tel nom. Il renvoie 1 si les deux arguments ne sont pas égaux et 0 sinon ).
Si les chaînes ne sont pas égales, le saut conditionnel n'est pas effectué et la ligne
suivante est exécutée, ce qui fait exploser la bombe. Si les chaînes sont égales, nous
sautons à 0x400eef7 et retournons à la page principale :
Ok, nous savons maintenant que la première phase nous demande de fournir une
chaîne que nous ne connaissons pas. Comment allons-nous découvrir de quelle
chaîne il s'agit ? Nous devons commencer à exécuter le programme. Mais dans ce cas,
au lieu de l'exécuter comme vous le faites habituellement avec d'autres programmes,
nous allons l'exécuter avec gdb. gdb nous aidera à inspecter les valeurs et à trouver ce
qu'est cette mystérieuse chaîne de caractères.
$ gdb bomb
La ligne ci-dessus démarre gdb avec le programme de la bombe qui lui est attaché afin
que nous puissions exécuter la bombe et inspecter les valeurs, définir des points
d'arrêt, etc. Dans ce cas, nous avons déjà effectué la majeure partie du travail en
examinant uniquement le code d'assemblage et le code d'identification.
http://webcache.googleusercontent.com/search?q=cache:NPuQo5CSngAJ:blog.carlosgaldino.com/2015/11/12/defusing-a-binary-bomb-with-gdb-part-1.html+&... 6/7
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 1 - carlosgaldino
nous savons que la chaîne mystérieuse se trouve à l'adresse 0x402400 (alors qu'elle a
été chargée dans le registre esi à l'adresse 0x400ee4 ). Pour voir quelle est sa valeur,
nous pouvons simplement demander à gdb d'imprimer la valeur à l'adresse souhaitée
et de la traiter comme une séquence de caractères :
(gdb) exécuter
Démarrage du programme : /home/carlos/Downloads/bomb/bomb
Bienvenue dans ma petite bombe diabolique. Vous disposez de 6 phases pour vous faire exploser. Bonne
journée !
En entrant dans la chaîne complète, nous verrons que la phase 1 a été désamorcée :
Les relations frontalières avec le Canada n'ont jamais été aussi bonnes.
Phase 1 désamorcée. Que diriez-vous de la prochaine ?
http://webcache.googleusercontent.com/search?q=cache:NPuQo5CSngAJ:blog.carlosgaldino.com/2015/11/12/defusing-a-binary-bomb-with-gdb-part-1.html+&... 9/7
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 2 - carlosgaldino
Ce billet fait partie d'une série où je montre comment désamorcer une bombe
binaire en lisant le code assembleur et en utilisant gdb . Vous pouvez lire la
première partie si vous ne l'avez pas encore fait.
Après avoir désamorcé la première phase , nous avons été mis au défi de désamorcer
la suivante :
Les relations frontalières avec le Canada n'ont jamais été aussi bonnes.
Phase 1 désamorcée. Que diriez-vous de la prochaine ?
Comme nous pouvons le voir (à 0x400e53 ), il place notre entrée dans le registre rdi
pour qu'elle soit utilisée comme premier argument de la phase_2 qui sera appelée par
l'instruction suivante. Tout comme on pourrait imaginer que le code C réel le fait :
http://webcache.googleusercontent.com/search?q=cache:0AQyhw4TGq4J:blog.carlosgaldino.com/2015/11/19/defusing-a-binary-bomb-with-gdb-part-2.html+&... 1/6
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 2 - carlosgaldino
phase_defused() ;
http://webcache.googleusercontent.com/search?q=cache:0AQyhw4TGq4J:blog.carlosgaldino.com/2015/11/19/defusing-a-binary-bomb-with-gdb-part-2.html+&... 2/6
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 2 - carlosgaldino
0000000000400efc <phase_2> :
400efc 55 pousser %rbp
400efd 53 pousser %rbx
400efe 48 83 ec 28 sous 0x28,%rsp
400f02 48 89 e6 déplacer %rsp,%rsi
400f05 e8 52 05 00 00 callq 40145c <read_six_numbers>
400f0a 83 3c 24 01 cmpl $0x1,(%rsp)
400f0e 74 20 je 400f30 <phase_2+0x34>
400f10 e8 25 05 00 00 callq 40143a <explode_bomb>
400f15 eb 19 jmp 400f30 <phase_2+0x34>
400f17 8b 43 fc déplacer -0x4(%rbx),%eax
400f1a 01 c0 ajouter %eax,%eax
400f1c 39 03 cmp %eax,(%rbx)
400f1e 74 05 je 400f25 <phase_2+0x29>
400f20 e8 15 05 00 00 callq 40143a <explode_bomb>
400f25 48 83 c3 04 ajouter $0x4,%rbx
400f29 48 39 eb cmp %rbp,%rbx
400f2c 75 e9 jne 400f17 <phase_2+0x1b>
400f2e eb 0c jmp 400f3c <phase_2+0x40>
400f30 48 8d 5c 24 04 lea 0x4(%rsp),%rbx
400f35 48 8d 6c 24 18 lea 0x18(%rsp),%rbp
400f3a eb db jmp 400f17 <phase_2+0x1b>
400f3c 48 83 c4 28 ajouter 0x28,%rsp
400f40 5b pop %rbx
400f41 5d pop %rbp
400f42 c3 retq
D'emblée, nous constatons que cette phase attend de nous que nous entrions six chiffres
:
000000000040145c <read_six_numbers>:
40145c : 48 83 ec 18 sous 0x18,%rsp
401460: 48 89 f2 déplac %rsi,%rdx
401463: 48 8d 4e 04 er lea 0x4(%rsi),%rcx
401467: 48 8d 46 14 lea 0x14(%rsi),%rax
40146b : 48 89 44 24 08 déplac %rax,0x8(%rsp)
401470: 48 8d 46 10 er lea 0x10(%rsi),%rax
401474: 48 89 04 24 déplac %rax,(%rsp)
er
http://webcache.googleusercontent.com/search?q=cache:0AQyhw4TGq4J:blog.carlosgaldino.com/2015/11/19/defusing-a-binary-bomb-with-gdb-part-2.html+&... 3/6
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 2 - carlosgaldino
#include <stdio.h>
En suivant la même idée que celle utilisée pour la phase 1, nous pouvons confirmer
que cette fonction fait exactement ce que son nom suggère. En 0x401480 , quelque
chose est stocké dans esi pour être utilisé comme second argument de sscanf qui,
comme nous l'avons vu plus haut, est le format attendu pour notre entrée.
Ensuite, sur gdb , nous pouvons imprimer la valeur comme nous l'avons fait pour la
phase_1 :
read_six_numbers vérifie alors si nous avons tapé au moins six nombres, si c'est le cas il
http://webcache.googleusercontent.com/search?q=cache:0AQyhw4TGq4J:blog.carlosgaldino.com/2015/11/19/defusing-a-binary-bomb-with-gdb-part-2.html+&... 4/6
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 2 - carlosgaldino
De retour à la fonction phase_2 , nous constatons que notre premier nombre doit être 1 (
comparaison à 0x400f0a ), sinon la bombe explosera immédiatement :
Après avoir confirmé que notre premier nombre était 1, il passe à 0x400f30 :
400f30 : 48 8d 5c 24 04 0x4(%rsp),%rbx
400f35 : 48 8d 6c 24 18 lea lea 0x18(%rsp),%rbp
400f3a : eb db jmp 400f17 <phase_2+0x1b>
En 0x400f30 , l'adresse du numéro suivant est stockée dans rbx et en 0x400f35, rbp reçoit
l'adresse juste après l'adresse du dernier numéro analysé par sscanf lors de
read_six_numbers .
(gdb) p $rsp+0x18
$2 = (void *) 0x7fffffddd8
(gdb) p $rsp
$3 = (void *) 0x7fffffddc0
Si l'on considère uniquement l'octet de poids faible : 0xd8 - 0xc0 = 0x18 . Ce qui
correspond à la décimale 24 . Chaque int prend quatre octets, de sorte que la structure
de la mémoire ressemble à l'image ci-dessous, ce qui explique pourquoi rbp retient
l'adresse après le sixième chiffre :
http://webcache.googleusercontent.com/search?q=cache:0AQyhw4TGq4J:blog.carlosgaldino.com/2015/11/19/defusing-a-binary-bomb-with-gdb-part-2.html+&... 5/6
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 2 - carlosgaldino
p 0kco
Quai Oxc ? Ou.cc OkaH
Lk
HG+ OLVE BYTES
x, x xni Xs
AE : Ok'FFFFFFFDD
<6
A 0x400f17 , le nombre précédent est copié dans eax , puis l'instruction suivante
duplique cette valeur dans eax , qui est ensuite comparée à notre deuxième
nombre. S'ils sont égaux, la fonction poursuivra son exécution à 0x400f25 , sinon
vous savez quoi.
La vérification des nombres, le déplacement des pointeurs vers l'avant, les sauts en
avant et en arrière suggèrent que nous avons affaire à une boucle. En supposant
que p est un pointeur sur le premier nombre, la boucle de la phase_2 pourrait
ressembler à ce qui suit :
http://webcache.googleusercontent.com/search?q=cache:0AQyhw4TGq4J:blog.carlosgaldino.com/2015/11/19/defusing-a-binary-bomb-with-gdb-part-2.html+&... 6/6
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 2 - carlosgaldino
si (*x != précédent * 2)
explode_bomb() ;
}
Très bien, nous avons maintenant une idée de ce que devraient être les cinq
prochains chiffres. Ils doivent être le double du nombre précédent. Si nous
commençons à 1, le suivant est 2, le suivant est 4 et ainsi de suite. Cela vous
rappelle quelque chose, n'est-ce pas ? Notre entrée doit être les six premières
puissances de 2 :
• 20 = 1
• 21 = 2
• 22 = 4
• 23 = 8
• 24 = 16
• 25 = 32
Après avoir saisi les six chiffres, nous constatons que nous avons désamorcé la
deuxième phase :
http://webcache.googleusercontent.com/search?q=cache:0AQyhw4TGq4J:blog.carlosgaldino.com/2015/11/19/defusing-a-binary-bomb-with-gdb-part-2.html+&... 7/6
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 3 - carlosgaldino
Ce billet fait partie d'une série où je montre comment désamorcer une bombe
binaire en lisant du code assembleur et en utilisant gdb . Vous pouvez lire les
autres parties si vous ne l'avez pas encore fait.
Selon le processus habituel, après avoir désamorcé la deuxième phase, nous avons
été invités à désamorcer la troisième :
Bienvenue dans ma petite bombe diabolique. Vous disposez de 6 phases pour vous faire exploser.
Bonne journée !
Les relations frontalières avec le Canada n'ont jamais été aussi bonnes.
Phase 1 désamorcée. Que diriez-vous de la prochaine ?
1 2 4 8 16 32
C'est le numéro 2. Continuez !
0000000000400f43 <phase_3> :
400f43 : 4883 ec 18 sous 0x18,%rsp
400f47 : 48 8d 4c 24 0c lea 0xc(%rsp),%rcx
400f4c : 48 8d 54 24 08 lea 0x8(%rsp),%rdx
400f51 : êtr cf 25 40 00 déplac $0x4025cf,%esi
400f56 : e b8 00 00 00 00 er déplac 0x0,%eax
er
http://webcache.googleusercontent.com/search?q=cache:T7QwiqsqtVEJ:blog.carlosgaldino.com/2015/14/03/defusing-a-binary-bomb-with-gdb-part-3.html+&cd... 6/6
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 3 - carlosgaldino
400f5b e8 90 fc ff ff callq 400bf0 <__isoc99_sscanf@pl
t>
400f60 83 f8 01 cmp $0x1,%eax
400f63 7f 05 jg 400f6a <phase_3+0x27>
400f65 e8 d0 04 00 00 callq 40143a <explode_bomb>
400f6a 83 7c 24 08 07 cmpl 0x7,0x8(%rsp)
400f6f 77 3c ja 400fad <phase_3+0x6a>
400f71 8b 44 24 08 déplacer 0x8(%rsp),%eax
400f75 ff 24 c5 70 24 40 00 jmpq *0x402470(,%rax,8)
400f7c b8 cf 00 00 00 déplacer 0xcf,%eax
400f81 eb 3b jmp 400fbe <phase_3+0x7b>
400f83 b8 c3 02 00 00 déplacer $0x2c3,%eax
400f88 eb 34 jmp 400fbe <phase_3+0x7b>
400f8a b8 00 01 00 00 déplacer 0x100,%eax
400f8f eb 2d jmp 400fbe <phase_3+0x7b>
400f91 b8 85 01 00 00 déplacer $0x185,%eax
400f96 eb 26 jmp 400fbe <phase_3+0x7b>
400f98 b8 ce 00 00 00 déplacer 0xce,%eax
400f9d eb 1f jmp 400fbe <phase_3+0x7b>
400f9f b8 aa 02 00 00 déplacer 0x2aa,%eax
400fa4 eb 18 jmp 400fbe <phase_3+0x7b>
400fa6 b8 47 01 00 00 déplacer $0x147,%eax
400fab eb 11 jmp 400fbe <phase_3+0x7b>
400fad e8 88 04 00 00 callq 40143a <explode_bomb>
400fb2 b8 00 00 00 00 déplacer 0x0,%eax
400fb7 eb 05 jmp 400fbe <phase_3+0x7b>
400fb9 b8 37 01 00 00 déplacer $0x137,%eax
400fbe 3b 44 24 0c cmp 0xc(%rsp),%eax
400fc2 74 05 je 400fc9 <phase_3+0x86>
400fc4 e8 71 04 00 00 callq 40143a <explode_bomb>
400fc9 48 83 c4 18 ajouter 0x18,%rsp
400fcd c3 retq
A 0x400f51 , nous voyons qu'une valeur est stockée sur esi , eax est initialisé et
sscanf est appelé.
Si vous ne vous souvenez pas de la phase précédente, sscanf est une fonction qui
analyse les données d'entrée en fonction d'un format donné en argument. Ce
format doit être celui qui est stocké dans l'esi.
Nous devons donc introduire 2 nombres entiers. Cela peut également être
confirmé par les instructions suivantes qui comparent si nous avons saisi plus d'un
nombre entier à
http://webcache.googleusercontent.com/search?q=cache:T7QwiqsqtVEJ:blog.carlosgaldino.com/2015/15/03/defusing-a-binary-bomb-with-gdb-part-3.html+&cd... 6/6
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 3 - carlosgaldino
Vous vous demandez peut-être comment sscanf a obtenu son premier argument,
qui est la chaîne de caractères utilisée comme source pour l'analyse des valeurs
souhaitées. Comme expliqué dans les articles précédents, le premier argument des
fonctions est généralement placé dans le registre rdi et n'importe quelle instruction
peut interagir avec n'importe quel registre, de la même manière que vous
interagissez avec une variable globale dans un programme. Si vous regardez à
0x400e6f dans la fonction principale , la chaîne que nous entrons comme entrée
pour la phase_3 est copiée dans rdi pour être ensuite utilisée comme premier
argument de sscanf :
http://webcache.googleusercontent.com/search?q=cache:T7QwiqsqtVEJ:blog.carlosgaldino.com/2015/16/03/defusing-a-binary-bomb-with-gdb-part-3.html+&cd... 6/6
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 3 - carlosgaldino
La première instruction ci-dessus copiera le premier entier dans eax et, lors de la
deuxième instruction, sautera à un emplacement basé sur cet entier. Imaginons
que nous ayons saisi 0 comme premier nombre entier. Dans ce cas, le programme
sautera à l'adresse stockée à 0x402470 . La règle de calcul de l'adresse est la
suivante :
*(%rax * 8 + 0x402470)
Cette opération stocke 0xcf (décimale 207) sur eax et saute ensuite à 0x400fbe qui
effectue ce qui suit :
400fbe : 3b 44 24 0c 0xc(%rsp),%eax
400fc2 : 74 05 cmp je 400fc9 <phase_3+0x86>
400fc4 : e8 71 04 00 00 callq 40143a <explode_bomb>
400fc9 : 48 83 c4 18 ajouter 0x18,%rsp
400fcd : c3 retq
0 207
À mi-chemin !
C'est donc tout ! C'est assez simple, non ? Mais qu'en est-il de toutes les autres
http://webcache.googleusercontent.com/search?q=cache:T7QwiqsqtVEJ:blog.carlosgaldino.com/2015/17/03/defusing-a-binary-bomb-with-gdb-part-3.html+&cd... 6/6
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 3 - carlosgaldino
http://webcache.googleusercontent.com/search?q=cache:T7QwiqsqtVEJ:blog.carlosgaldino.com/2015/18/03/defusing-a-binary-bomb-with-gdb-part-3.html+&cd... 6/6
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 3 - carlosgaldino
Notes
http://webcache.googleusercontent.com/search?q=cache:T7QwiqsqtVEJ:blog.carlosgaldino.com/2015/12/03/defusing-a-binary-bomb-with-gdb-part-3.html+&cd... 6/6
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 4 - carlosgaldino
Ce billet fait partie d'une série où je montre comment désamorcer une bombe
binaire en lisant le code assembleur et en utilisant gdb . Vous pouvez lire la
première partie si vous ne l'avez pas encore fait.
000000000040100c <phase_4> :
40100c : 48 83 ec 18
401010: 48 8d 4c 24 0c sub lea 0x18,%rsp
401015: 48 8d 54 24 08 be cf 25 40 lea 0xc(%rsp),%rcx
40101a : 00 b8 00 00 00 00 mov 0x8(%rsp),%rdx $0x4025cf,%esi
40101f : mov 0x0,%eax
401024:
e8 c7 fb ff ff callq 400bf0 <__isoc99_sscanf@pl
t>
401029: 83 f8 02 cmp $0x2,%eax
40102c : 75 07 jne 401035 <phase_4+0x29>
40102e : 83 7c 24 08 0e cmpl $0xe,0x8(%rsp)
401033: 76 05 jbe 40103a <phase_4+0x2e>
401035: e8 00 04 00 00 callq 40143a <explode_bomb>
40103a : ba 0e 00 00 00 déplacer $0xe,%edx
40103f : êtr 00 00 00 00 déplacer $0x0,%esi
401044: e 8b 7c 24 08 déplacer 0x8(%rsp),%edi
401048: e8 81 ff ff ff callq 400fce <func4>
40104d : 85 c0 test %eax,%eax
40104f : 75 07 jne 401058 <phase_4+0x4c>
401051: 83 7c 24 0c 00 cmpl 0x0,0xc(%rsp)
401056: 74 05 je 40105d <phase_4+0x51>
401058: e8 dd 03 00 00 callq 40143a <explode_bomb>
40105d : 48 83 c4 18 ajouter 0x18,%rsp
401061: c3 retq
Tout comme pour la phase 3 , nous pouvons constater que cette phase attend deux
http://webcache.googleusercontent.com/search?q=cache:POrmVxSy8kgJ:blog.carlosgaldino.com/2016/04/25/defusing-a-binary-bomb-with-gdb-part-4.html+&c... 1/7
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 4 - carlosgaldino
En 0x401029 , nous pouvons également confirmer que si nous entrons plus de deux
entiers, le code passe à 0x401035 qui appelle explode_bomb :
401029: 83 f8 02 cmp$0x2,%eax
40102c : 75 07 jne 401035 <phase_4+0x29>
Quels sont donc les chiffres exacts à saisir ? Il doit s'agir d'un nombre inférieur à 15
:
cmpl compare 0xe qui est 14 au premier entier1 que nous avons entré pour cette
phase. Ensuite, jbe ("jump below or equal") évitera de faire exploser la bombe si la
valeur est inférieure ou égale à 14.
Ensuite, nous pouvons voir qu'une certaine configuration est effectuée avant
d'appeler une nouvelle fonction, func4 :
edi est généralement utilisé comme registre pour contenir le premier argument,
esi le deuxième et edx le troisième. Le premier argument est le premier nombre que
nous avons fourni, les deuxième et troisième sont respectivement 0 et 14 .
http://webcache.googleusercontent.com/search?q=cache:POrmVxSy8kgJ:blog.carlosgaldino.com/2016/04/25/defusing-a-binary-bomb-with-gdb-part-4.html+&c... 2/7
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 4 - carlosgaldino
0000000000400fce
400fce : <func4>
48 83 éc: 08 sous $0x8,%rsp
400fd2 : 89 d0 déplace %edx,%eax
400fd4 : 29 f0 r sous %esi,%eax
400fd6 : 89 c1 déplace %eax,%ecx
400fd8 : c1 e9 1f r shr $0x1f,%ecx
400fdb : 01 c8 ajouter %ecx,%eax
400fdd : d1 f8 sar %eax
400fdf : 8d 0c 30 lea (%rax,%rsi,1),%ecx
400fe2 : 39 f9 cmp %edi,%ecx
400fe4 : 7e 0c jle 400ff2 <func4+0x24>
400fe6 : 8d 51 ff lea -0x1(%rcx),%edx
400fe9 : e8 e0 ff ff ff callq 400fce <func4>
400fee : 01 c0 ajouter %eax,%eax
400ff0 : eb 15 jmp 401007 <func4+0x39>
400ff2 : b8 00 00 00 00 déplace $0x0,%eax
400ff7 : 39 f9 r cmp %edi,%ecx
400ff9 : 7d 0c jge 401007 <func4+0x39>
400ffb : 8d 71 01 lea 0x1(%rcx),%esi
400ffe : e8 cb ff ff ff callq 400fce <func4>
401003: 8d 44 00 01 lea 0x1(%rax,%rax,1),%eax
401007: 48 83 c4 08 ajouter $0x8,%rsp
40100b : c3 retq
func4(a, b, y - 1) ;
Après l'avoir appelé, vous pouvez voir que 0x400fee double le résultat de cette
invocation "interne" ( eax contient la valeur de retour de cette exécution) et saute
ensuite à 0x401007 qui nettoie le cadre de la pile pour cette invocation. Le résultat
http://webcache.googleusercontent.com/search?q=cache:POrmVxSy8kgJ:blog.carlosgaldino.com/2016/04/25/defusing-a-binary-bomb-with-gdb-part-4.html+&c... 3/7
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 4 - carlosgaldino
return 2 * func4(a, b, y - 1) ;
func4(a, y + 1, c) ;
Après le retour de cet appel récursif, la valeur de retour est fixée à 0x401003 en
utilisant le résultat de l'appel récursif, ce qui donne le résultat suivant :
return 2 * func4(a, y + 1, c) + 1 ;
Avec tout ce contexte, nous pouvons maintenant essayer de deviner ce qui se passe
exactement avec cette fonction :
if (y <= a) {
if (y >= a) { return 0 ;
} else {
return 2 * func4(a, y + 1, c) + 1 ;
}
} else {
return 2 * func4(a, b, y - 1) ;
Nous pouvons alors voir que func4 sera appelé par la clause else de la première
clause
si :
return 2 * func4(1, 0, 7 - 1) ;
func4(1, 0, 6) { int x = 6 - 0 ;
int y = 6 >> 31 ; x = 6 + 0 ;
x = 6 >> 1 ;
y=3+0;
}
retour 2 * func4(1, 0, 3 - 1) ;
func4(1, 0, 2) { int x = 2 - 0 ;
int y = 2 >> 31 ;
x=2+0;
x = 2 >> 1 ;
y=1+0;
}
Cette fois-ci, y == 1 , donc les deux branches if seront prises et 0 sera renvoyé de
cette invocation récursive. Rappelez-vous que nous avons invoqué cette fonction
deux fois, de sorte que le résultat final sera :
http://webcache.googleusercontent.com/search?q=cache:POrmVxSy8kgJ:blog.carlosgaldino.com/2016/04/25/defusing-a-binary-bomb-with-gdb-part-4.html+&c... 5/7
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 4 - carlosgaldino
return func4(1, 0, 14) ;
return 2 * func4(1, 0, 6) ;
return 2 * func4(1, 0, 2) ;
retour 0 ;
10
Vous l'avez donc compris. Essayez celui-ci.
Un autre aspect intéressant de cette phase est la manière dont le compilateur gère
les résultats des appels récursifs. Comme eax est un registre, les résultats de
chaque invocation récursive seront disponibles pour le cadre de pile qui l'a
invoquée et peuvent ensuite être simplement renvoyés sans sauvegarder le résultat
http://webcache.googleusercontent.com/search?q=cache:POrmVxSy8kgJ:blog.carlosgaldino.com/2016/04/25/defusing-a-binary-bomb-with-gdb-part-4.html+&c... 6/7
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 4 - carlosgaldino
à un autre endroit. Vous voyez également qu'après avoir rappelé func4 , rien ne
gère les variables locales x et y, ce qui explique qu'elles soient également stockées
dans des registres au lieu d'être sauvegardées à l'intérieur de chaque trame de pile.
Un exercice laissé au lecteur est d'essayer de trouver les autres solutions possibles
pour cette phase, y compris une entrée qui n'appelle même pas func4
récursivement. Essayez également de voir quels sont les nombres invalides pour
cette phase et le résultat que renvoie func4 lorsque ces nombres sont utilisés.
Notes
http://webcache.googleusercontent.com/search?q=cache:POrmVxSy8kgJ:blog.carlosgaldino.com/2016/04/25/defusing-a-binary-bomb-with-gdb-part-4.html+&c... 7/7
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 5 - carlosgaldino
Ce billet fait partie d'une série où je montre comment désamorcer une bombe
binaire en lisant le code assembleur et en utilisant gdb . Vous pouvez lire la
première partie si vous ne l'avez pas encore fait.
0000000000401062 <phase_5> :
401062: 53 pousser %rbx
401063: 48 83 ec 20 sous 0x20,%rsp
401067: 48 89 fb déplacer %rdi,%rbx
40106a : 64 48 8b 04 25 28 00 déplacer %fs:0x28,%rax
401071: 00 00
401073: 48 89 44 24 18 déplacer %rax,0x18(%rsp)
401078: 31 c0 xor %eax,%eax
40107a : e8 9c 02 00 00 callq 40131b <longueur_de_chaîne>
40107f : 83 f8 06 cmp $0x6,%eax
401082: 74 4e je 4010d2 <phase_5+0x70>
401084: e8 b1 03 00 00 callq 40143a <explode_bomb>
401089: eb 47 jmp 4010d2 <phase_5+0x70>
40108b : 0f b6 0c 03 movzbl (%rbx,%rax,1),%ecx
40108f : 88 0c 24 déplacer %cl,(%rsp)
401092: 48 8b 14 24 déplacer (%rsp),%rdx
401096: 83 e2 0f et $0xf,%edx
401099: 0f b6 92 b0 24 40 00 movzbl 0x4024b0(%rdx),%edx
4010a0 : 88 54 04 10 déplacer %dl,0x10(%rsp,%rax,1)
4010a4 : 48 83 c0 01 ajouter $0x1,%rax
http://webcache.googleusercontent.com/search?q=cache:r7Vvh9Ci4SUJ:blog.carlosgaldino.com/2016/04/28/defusing-a-binary-bomb-with-gdb-part-5.html+&cd... 1/5
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 5 - carlosgaldino
Les premières lignes configurent la pile pour cette fonction et, à 0x40106a , le
protecteur de pile1 est mis en place.
En 0x40108b , le premier octet de la chaîne d'entrée est copié dans ecx . Remarquez
qu'au début de cette fonction, la chaîne d'entrée stockée sur rdi a été copiée sur rbx
à 0x401067 . L'instruction à 0x40108b utilise à la fois rbx et rax , mais comme rax a
une valeur de 0, l'adresse des données utilisée comme source sera uniquement
l'adresse stockée sur rbx. Nous pouvons le confirmer avec :
http://webcache.googleusercontent.com/search?q=cache:r7Vvh9Ci4SUJ:blog.carlosgaldino.com/2016/04/28/defusing-a-binary-bomb-with-gdb-part-5.html+&cd... 2/5
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 5 - carlosgaldino
(gdb) i r $ecx
ecx 0x69 105
Ensuite, dans les deux instructions suivantes, cet octet est copié dans rdx et, dans
0x401096 , un ET bit à bit est effectué par rapport à cet octet. La valeur après l'ET
bit à bit est ensuite utilisée comme décalage pour copier une valeur d'un
emplacement quelconque vers le même registre edx sur 0x401099 . Cette même
valeur d'un octet est ensuite stockée dans une variable locale à 0x4010a0 .
L'instruction suivante incrémente rax qui est ensuite vérifié par l'instruction
suivante pour voir si ce processus a été exécuté pour tous les caractères de notre
entrée. Si le processus n'a pas été exécuté pour tous les caractères, il saute à
nouveau à 0x40108b pour lire le caractère suivant et répéter les étapes ci-dessus.
À la fin de ce processus, une variable locale contiendra une nouvelle chaîne créée
en utilisant nos caractères d'entrée comme décalage vers une chaîne mystérieuse.
Si le processus a été exécuté pour tous les caractères, il prépare les arguments pour
l'appel de fonction suivant, qui commence à 0x4010ae . La nouvelle chaîne dont
nous parlons servira d'argument à la fonction strings_not_equal que nous avons déjà
vue dans cette série. L'autre chaîne à laquelle la nôtre sera comparée est située à
0x40245e , comme vous pouvez le voir à 0x4010b3 .
Après avoir appelé strings_not_equal , le résultat sera testé à 0x4010c2 et s'il est égal,
le code sautera à la fin de la phase_5 à 0x4010d9 qui vérifiera que la pile n'a pas été
corrompue et retournera. Si les cordes sont différentes, vous savez ce qui va se
passer.
http://webcache.googleusercontent.com/search?q=cache:r7Vvh9Ci4SUJ:blog.carlosgaldino.com/2016/04/28/defusing-a-binary-bomb-with-gdb-part-5.html+&cd... 3/5
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 5 - carlosgaldino
doit produire.
Il ne nous reste plus qu'à examiner la chaîne intermédiaire pour voir quels sont les
décalages que nous devons saisir pour que la chaîne finale soit composée d'éléments
volants.
lettre comp
ensati
f 0x9
l 0xf
y
0xe
e 0x5
r 0x6
s 0x7
compe caractères
nsation possibles
0x9 )9IYiy
http://webcache.googleusercontent.com/search?q=cache:r7Vvh9Ci4SUJ:blog.carlosgaldino.com/2016/04/28/defusing-a-binary-bomb-with-gdb-part-5.html+&cd... 4/5
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 5 - carlosgaldino
0xf / ? O _ o DEL
0xe N^n~
0x5 0x6 0x7
Notes
1. https://en.wikipedia.org/wiki/Buffer_overflow_protection
http://webcache.googleusercontent.com/search?q=cache:r7Vvh9Ci4SUJ:blog.carlosgaldino.com/2016/04/28/defusing-a-binary-bomb-with-gdb-part-5.html+&cd... 5/5
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 6 - carlosgaldino
Ce billet fait partie d'une série où je montre comment désamorcer une bombe
binaire en lisant le code assembleur et en utilisant gdb . Vous pouvez lire la
première partie si vous ne l'avez pas encore fait.
Nous voici arrivés à la dernière phase. C'est la phase la plus intéressante jusqu'à
présent. Le code de la phase_6 est le suivant :
00000000004010f4 <phase_6> :
4010f4 41 56 pousser %r14
4010f6 41 55 pousser %r13
4010f8 41 54 pousser %r12
4010fa 55 pousser %rbp
4010fb 53 pousser %rbx
4010fc 48 83 ec 50 sous $0x50,%rsp
401100 49 89 e5 déplacer %rsp,%r13
401103 48 89 e6 déplacer %rsp,%rsi
401106 e8 51 03 00 00 callq 40145c <read_six_numbers>
40110b 49 89 e6 déplacer %rsp,%r14
40110e 41 bc 00 00 00 00 déplacer $0x0,%r12d
401114 4c 89 ed déplacer %r13,%rbp
401117 41 8b 45 00 déplacer 0x0(%r13),%eax
40111b 83 e8 01 sous $0x1,%eax
40111e 83 f8 05 cmp $0x5,%eax
401121 76 05 jbe 401128 <phase_6+0x34>
401123 e8 12 03 00 00 callq 40143a <explode_bomb>
401128 41 83 c4 01 ajouter $0x1,%r12d
40112c 41 83 fc 06 cmp $0x6,%r12d
401130 74 21 je 401153 <phase_6+0x5f>
401132 44 89 e3 déplacer %r12d,%ebx
401135 48 63 c3 movslq %ebx,%rax
401138 8b 04 84 déplacer (%rsp,%rax,4),%eax
40113b 39 45 00 cmp %eax,0x0(%rbp)
40113e 75 05 jne 401145 <phase_6+0x51>
401140 e8 f5 02 00 00 callq 40143a <explode_bomb>
401145 83 c3 01 ajouter $0x1,%ebx
http://webcache.googleusercontent.com/search?q=cache:1K1SsGLv47UJ:blog.carlosgaldino.com/2016/05/19/defusing-a-binary-bomb-with-gdb-part-6.html+... 1/15
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 6 - carlosgaldino
http://webcache.googleusercontent.com/search?q=cache:1K1SsGLv47UJ:blog.carlosgaldino.com/2016/05/19/defusing-a-binary-bomb-with-gdb-part-6.html+... 2/15
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 6 - carlosgaldino
http://webcache.googleusercontent.com/search?q=cache:1K1SsGLv47UJ:blog.carlosgaldino.com/2016/05/19/defusing-a-binary-bomb-with-gdb-part-6.html+... 3/15
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 6 - carlosgaldino
4011f5 : 75 e8 jne 4011df <phase_6+0xeb>
4011f7 : 48 83 c4 50 ajouter $0x50,%rsp
4011fb : 5b pop %rbx
4011fc : 5d pop %rbp
4011fd : 41 5c pop %r12
4011 et 41 5d pop %r13
suivants :
401201: 41 5e pop %r14
401203: c3 retq
Elle est plus longue que les autres phases et semble plus compliquée. Nous allons
donc la diviser en plusieurs parties afin d'expliquer le rôle de chacune d'entre elles.
La première partie que nous pouvons examiner est celle où la fonction s'initialise.
Il commence par enregistrer certaines valeurs de registres, car elles seront utilisées
comme variables locales dans cette fonction, puis il fait de la place pour d'autres
variables locales et lit l'entrée qui sera utilisée pour désamorcer la phase. À
0x401106 , nous pouvons voir que l'entrée de cette phase doit être composée de six
nombres :
Après avoir lu les six nombres et placé le premier sur rsp , le code copie l'adresse
pointant vers le premier dans r14 , puis il configure d'autres variables et enfin, sur
0x40111e , il vérifie si le premier nombre que nous avons fourni est inférieur ou
égal à 6. Comment cela s'est-il produit ?
rsi est utilisé pour contenir le deuxième argument d'un appel de fonction et avant
d'appeler read_six_numbers (à 0x401103 ), l'adresse de rsp a été copiée dans rsi.
http://webcache.googleusercontent.com/search?q=cache:1K1SsGLv47UJ:blog.carlosgaldino.com/2016/05/19/defusing-a-binary-bomb-with-gdb-part-6.html+... 4/15
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 6 - carlosgaldino
à utiliser par read_six_numbers . C'est là que nos nombres ont été stockés, dans un
tableau qui commence à l'adresse de rsi . Cette même adresse est également
stockée sur rsp et r13 . Nous pouvons consulter les registres pour voir de quelle
adresse il s'agit :
Après le retour de read_six_numbers , cette même adresse est stockée sur r14 à
0x40110b et à 0x40114 , elle est également stockée sur rbp.
Ensuite, à 0x401117 , la valeur stockée à l'adresse r13 , notre premier nombre, est
copiée dans eax et le code vérifie ensuite si elle est inférieure ou égale à 6 .
Maintenant que nous avons compris comment le chèque a été effectué, passons à
la partie suivante :
Rappelez-vous qu'à la ligne 0x40110e , le registre r12d a stocké la valeur 0. Les trois
premières lignes servent donc uniquement à vérifier si le code a déjà effectué 6
itérations. Continuons à 0x401132 où la nouvelle valeur de r12d (qui est 1 pour la
première itération) est copiée dans ebx qui est ensuite copiée dans rax par
extension de signe d'un double mot (4 octets) à un quadruple mot (8 octets)
puisque ebx est un registre de 32 bits tandis que rax est un registre de 64 bits.
Ensuite, le numéro suivant que nous avons saisi est comparé au premier. Le
deuxième nombre est copié dans eax par cette instruction :
http://webcache.googleusercontent.com/search?q=cache:1K1SsGLv47UJ:blog.carlosgaldino.com/2016/05/19/defusing-a-binary-bomb-with-gdb-part-6.html+... 5/15
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 6 - carlosgaldino
La valeur stockée à cette adresse est alors copiée dans eax . Pour la première
itération, il s'agit de notre deuxième numéro d'entrée.
Ensuite, notre deuxième valeur (sur eax ) est comparée à la première pour voir si
elles ne sont pas égales et passer à la partie suivante :
Les trois premières lignes vérifieront si nous avons effectué cette vérification pour
les six nombres, ce qui signifie que nous ne pouvons pas saisir de nombres répétés.
Ensuite, à 0x40114d , r13 est modifié pour contenir l'adresse du deuxième numéro
d'entrée en ajoutant 4 octets ( sizeof(int) ) à l'adresse que r13 stocke actuellement. Il
retourne ensuite à 0x401114 pour effectuer les mêmes vérifications avec les autres
numéros que nous avons fournis.
Continuons à voir quelles sont les autres caractéristiques que ces nombres doivent
avoir.
http://webcache.googleusercontent.com/search?q=cache:1K1SsGLv47UJ:blog.carlosgaldino.com/2016/05/19/defusing-a-binary-bomb-with-gdb-part-6.html+... 6/15
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 6 - carlosgaldino
401153 : 48 8d 74 24 18 lea 0x18(%rsp),%rsi
401158 : 4c 89 f0 déplacer %r14,%rax
40115b : b9 07 00 00 00 déplac $0x7,%ecx
401160: 89 ca er déplac %ecx,%edx
401162: 2b 10 er sous (%rax),%edx
401164: 89 10 déplac %edx,(%rax)
401166: 48 83 c0 04 er ajouter $0x4,%rax
40116a : 48 39 f0 cmp %rsi,%rax
40116d : 75 f1 jne 401160 <phase_6+0x6c>
40116f : be 00 00 00 00 déplac $0x0,%esi
401174: eb 21 er jmp 401197 <phase_6+0xa3>
La première ligne de cette partie définit simplement l'adresse qui signifie que nous
avons itéré sur les six nombres. Le premier nombre est stocké à l'adresse détenue
par rsp et le sixième nombre sera stocké à $rsp + 0x14 (adresse de départ + décalage
de 5 int ).
r14 contient également l'adresse du premier nombre, qui sera copiée dans rax à
0x401158 pour être utilisée dans cette itération. Ensuite, sur les deux lignes
suivantes, ecx et edx stockent la valeur 7 . Après la configuration, l'itération
proprement dite commencera par la soustraction de edx de la valeur stockée à
l'adresse rax (notre premier nombre dans la première itération). À 0x401164 , le
résultat de cette soustraction remplacera la valeur de rax , puis à 0x401166 , le code
passera au prochain int que nous avons fourni, comparera à 0x40116d si nous
avons itéré sur les six nombres et reviendra à 0x401160 si ce n'est pas le cas, sinon
sortira de la boucle et poursuivra l'exécution à 0x401197 .
Simulons ce qui se passe après l'exécution de cette boucle. Supposons que nous
ayons saisi 1 2 3 4 5 6 comme numéros d'entrée pour cette phase. Après avoir itéré
dans cette boucle, notre tableau aura les nouvelles valeurs suivantes : 6 5 4 3 2 1 .
La boucle modifie simplement tous les nombres du tableau pour qu'ils soient
abs(n-7) .
Après avoir quitté la boucle, nous continuons à 0x401197 , ce qui nous amène à la
partie suivante de cette phase :
Si le nombre actuel sur ecx est inférieur ou égal à 1, le code sautera à 0x401183 ,
sinon il sautera à 0x401176 .
déplac
401176: 48 8b 52 08 er 0x8(%rdx),%rdx
40117a : 83 c0 01 ajouter $0x1,%eax
40117d : 39 c8 cmp %ecx,%eax
40117f : 75 f5 jne 401176 <phase_6+0x82>
401181: eb 05 jmp 401188 <phase_6+0x94>
Remarquez qu'avant de sauter à 0x401176 , l'adresse 0x6032d0 a été stockée sur edx
. Ensuite, la valeur stockée après les 8 premiers octets de cette adresse sera copiée
dans rdx sur 0x401176 . Après cette opération, eax sera incrémenté et comparé à
http://webcache.googleusercontent.com/search?q=cache:1K1SsGLv47UJ:blog.carlosgaldino.com/2016/05/19/defusing-a-binary-bomb-with-gdb-part-6.html+... 8/15
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 6 - carlosgaldino
Les valeurs de ecx et eax ne correspondent qu'après six itérations : dans notre
exemple, ecx commence par 6 et eax par 1 . Dans ce cas, avant de sauter à
0x401188 , rdx aura la valeur stockée dans $rdx + 0x48 (six fois en ajoutant 0x8 à
l'adresse initiale et en copiant la valeur de la nouvelle adresse dans rdx ).
À cette ligne, l'adresse détenue par rdx sera copiée à l'adresse résultant de :
$rsi*0x2 + $rsp + 0x20 . rsi est l'index de l'itération en cours :
Ensuite, rsi est incrémenté de 4 ( sizeof(int) ) et comparé à 0x18 pour voir si nous
avons itéré sur les six nombres. Si ce n'est pas le cas, à 0x401197 , ecx obtient le
numéro suivant de notre tableau et l'itération suivante commence.
Maintenant que nous savons en quoi consiste cette itération, voyons ce que
contient exactement l'adresse initiale de rdx :
(gdb) x 0x6032d0
0x6032d0 <node1> : 0x0000014c
http://webcache.googleusercontent.com/search?q=cache:1K1SsGLv47UJ:blog.carlosgaldino.com/2016/05/19/defusing-a-binary-bomb-with-gdb-part-6.html+... 9/15
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 6 - carlosgaldino
Huh, node1 , un nom intéressant, n'est-ce pas ? Voyons ce que cette adresse plus 8
octets nous réservent :
(gdb) x 0x6032d0+0x8
0x6032d8 <node1+8> : 0x006032e0
(gdb) x 0x6032e0
0x6032e0 <node2> : 0x000000a8
Aha ! Cela ressemble à une liste chaînée. Pour voir l'adresse du nœud3 :
(gdb) x 0x6032e0+0x8
0x6032e8 <node2+8> : 0x006032f0
(gdb) x *(0x6032e0+0x8)
0x6032f0 <node3> : 0x0000039c
Nous avons une liste chaînée qui contient une valeur int , l'identifiant du nœud et
le pointeur vers le nœud suivant, quelque chose comme ce qui suit :
struct node {
int x ;
int i ;
struct node *next;
};
Ainsi, lorsque le code saute à 0x401188 , rdx aura l'adresse de la valeur stockée par
node6 puisque notre tableau est 6 5 4 3 2 1 et qu'il est passé par
(gdb) i r rdx
rdx 0x603320 6304544
(gdb) x 0x6032d0+0x48
http://webcache.googleusercontent.com/search?q=cache:1K1SsGLv47UJ:blog.carlosgaldino.com/2016/05/19/defusing-a-binary-bomb-with-gdb-part-6.html+... 10/15
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 6 - carlosgaldino
0x603318 <node5+8> : 0x00603320
(gdb) x $rdx
0x603320 <node6> : 0x000001bb
L'adresse rdx , qui contient la valeur 0x1bb , sera placée en première position d'un
nouveau tableau commençant à $rsp + 0x20 . Puisque ce code itère sur les six
nombres, après avoir exécuté cette partie pour tous les nombres, ce nouveau
tableau stockera en fait les adresses contenant les valeurs que le nœud
correspondant stocke, sur la base de notre tableau d'entrée transformé.
Voyons quelles sont les valeurs stockées par chaque nœud et leurs adresses. Nous
commençons par définir une commande pour imprimer les valeurs des nœuds et
passer au nœud suivant :
définir plist
set var $n = $arg0
while $n
printf "node%d (%p) : value = %#.3x, next=%p\n", *($n+0x4), $n, *$n,
*($n+0x8)
set var $n = *($n+0x8)
fin
fin
http://webcache.googleusercontent.com/search?q=cache:1K1SsGLv47UJ:blog.carlosgaldino.com/2016/05/19/defusing-a-binary-bomb-with-gdb-part-6.html+... 11/15
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 6 - carlosgaldino
Après avoir créé ce nouveau tableau, le code poursuit son exécution à 0x4011ab ,
qui est la partie suivante :
http://webcache.googleusercontent.com/search?q=cache:1K1SsGLv47UJ:blog.carlosgaldino.com/2016/05/19/defusing-a-binary-bomb-with-gdb-part-6.html+... 12/15
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 6 - carlosgaldino
(gdb) i r rcx rdx
rcx 0x603320 6304544
rdx 0x603310 6304528
$rcx + 0x8 est l'adresse qui contient le pointeur sur l'élément suivant de la liste et,
après l'exécution de 0x4011c0 , il pointera sur la valeur stockée par rdx :
(gdb) x $rcx+0x8
0x603328 <node6+8> : 0x0000000000603310
Ensuite, à 0x4011c4 , la valeur suivante du nouveau tableau est placée dans rax
pour l'itération suivante, qui est comparée à rsi dans la ligne suivante, et le
processus se répète. À la fin de cette opération, le pointeur suivant de chaque nœud
sera modifié en fonction des valeurs du nouveau tableau. Comme nous l'avons vu
ci-dessus, le nouveau tableau contient les valeurs suivantes :
Ces valeurs correspondent au nœud6 nœud5 nœud4 nœud3 nœud2 nœud1 . Après
l'itération ci-dessus, les pointeurs seront donc modifiés pour refléter cet ordre.
Nous pouvons le confirmer avec notre commande plist après avoir exécuté
l'instruction sur 0x4011d2 :
Avec la saisie initiale de 1 2 3 4 5 6 , le code a inversé la liste. Notez que j'ai utilisé
l'adresse du nœud 6 comme adresse de départ de la liste car c'est l'ordre du tableau
situé à $rsp + 0x20 . Remarquez également qu'à 0x4011d2 , le pointeur suivant de la
dernière itération reçoit la valeur NULL et, dans notre cas, il s'agit de node1->next .
http://webcache.googleusercontent.com/search?q=cache:1K1SsGLv47UJ:blog.carlosgaldino.com/2016/05/19/defusing-a-binary-bomb-with-gdb-part-6.html+... 13/15
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 6 - carlosgaldino
4011da : bd 05 00 00 00 déplacer $0x5,%ebp
4011df : 48 8b 43 08 déplacer 0x8(%rbx),%rax
4011e3 : 8b 00 déplacer (%rax),%eax
4011e5 : 39 03 cmp %eax,(%rbx)
4011e7 : 7d 05 jge 4011ee <phase_6+0xfa>
4011e9 : e8 4c 02 00 00 callq 40143a <explode_bomb>
4011ee : 48 8b 5b 08 déplacer 0x8(%rbx),%rbx
4011f2 : 83 ed 01 sous $0x1,%ebp
4011f5 : 75 e8 jne 4011df <phase_6+0xeb>
Cette itération vérifie donc que la valeur x du nœud actuel est supérieure ou égale à
la valeur x suivante pour tous les nœuds de la liste. Si ce n'est pas le cas, la bombe
explose, comme on peut le voir à 0x4011e9 .
Maintenant que nous avons vu tout ce que fait cette fonction, nous savons que nos
nombres d'entrée sont utilisés pour trier la liste chaînée dans l'ordre
décroissant.
N'oubliez pas qu'avant d'être utilisé pour réorganiser la liste, chaque nombre
d'entrée sera transformé en abs(n-7) .
x
nœud # x (déc)
(hexagone
1 0x14c 332
2 0x0a8 168
http://webcache.googleusercontent.com/search?q=cache:1K1SsGLv47UJ:blog.carlosgaldino.com/2016/05/19/defusing-a-binary-bomb-with-gdb-part-6.html+... 14/15
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 6 - carlosgaldino
3
0x39c 924
4
0x2b3 691
5
0x1dd 477
6 0x1bb 443
Les valeurs de x pour la liste finale doivent être dans l'ordre suivant :
924 -> 691 -> 477 -> 443 -> 332 -> 168
nœud3 -> nœud4 -> nœud5 -> nœud6 -> nœud1 -> nœud2
432165
Félicitations ! Vous avez désamorcé la bombe !
input = read_line () ;
phase_6(input) ;
phase_defused() ;
retour 0;
http://webcache.googleusercontent.com/search?q=cache:1K1SsGLv47UJ:blog.carlosgaldino.com/2016/05/19/defusing-a-binary-bomb-with-gdb-part-6.html+... 15/15
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 7 - carlosgaldino
Ce billet fait partie d'une série où je montre comment désamorcer une bombe
binaire en lisant le code assembleur et en utilisant gdb . Vous pouvez lire la
première partie si vous ne l'avez pas encore fait.
Dans le dernier message , la bombe a été désamorcée mais il y avait quelque chose
de bizarre dans le fichier C. C'est la fin de la fonction principale :
input = read_line () ;
phase_6(input) ;
phase_defused() ;
retour 0;
Et j'ai laissé un indice dans le dernier message à propos d'un appel à une fonction
secret_phase à partir de phase_defused .
phase_defused est une fonction qui est appelée à chaque fois qu'une phase est
désamorcée :
00000000004015c4 <phase_defused>:
4015c4 : 48 83 ec 78 sous 0x78,%rsp
4015c8 : 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
4015cf : 00 00
http://webcache.googleusercontent.com/search?q=cache:aW_YFEmXe2cJ:blog.carlosgaldino.com/2016/05/24/defusing-a-binary-bomb-with-gdb-part-7.html+... 2/11
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 7 - carlosgaldino
4015d1 : 48 89 44 24 68 %rax,0x68(%rsp)
4015d6 : 31 c0 mov xor %eax,%eax
4015d8 : 83 3d 81 21 20 00 06 cmpl $0x6,0x202181(%rip)
# 603760 <nombre_d'entr chaînes>
4015df : ées_ 75 5e jne 40163f <phase_defused+0x7b
>
4015e1 : 4c 8d 44 24 10 lea 0x10(%rsp),%r8
4015e6 : 48 8d 4c 24 0c lea 0xc(%rsp),%rcx
4015eb : 48 8d 54 24 08 lea 0x8(%rsp),%rdx
4015f0 : être 19 26 40 00 déplace $0x402619,%esi
4015f5 : bf 70 38 60 00 r déplace $0x603870,%edi
4015fa : e8 f1 f5 ff ff r callq 400bf0 <__isoc99_sscanf@pl
t>
4015 et 83 f8 03 cmp $0x3,%eax
suivants
401602: : 75 31 jne 401635 <phase_defused+0x71
>
401604: être 22 26 40 00 déplace $0x402622,%esi
401609: 48 8d 7c 24 10 r lea 0x10(%rsp),%rdi
40160e : e8 25 fd ff ff callq 401338 <strings_not_equal>
401613: 85 c0 test %eax,%eax
401615: 75 1e jne 401635 <phase_defused+0x71
>
401617: bf f8 24 40 00 déplace $0x4024f8,%edi
40161c : e8 ef f4 ff ff r callq 400b10 <puts@plt>
401621: bf 20 25 40 00 déplace $0x402520,%edi
401626: e8 e5 f4 ff ff r callq 400b10 <puts@plt>
40162b : b8 00 00 00 00 déplace $0x0,%eax
401630: e8 0d fc ff ff r callq 401242 <secret_phase>
401635: bf 58 25 40 00 déplace $0x402558,%edi
40163a : e8 d1 f4 ff ff r callq 400b10 <puts@plt>
40163f : 48 8b 44 24 68 déplace 0x68(%rsp),%rax
401644: 64 48 33 04 25 28 00 r xor %fs:0x28,%rax
40164b : 00 00
40164d : 74 05 je 401654 <phase_defused+0x90
>
40164f : e8 dc f4 ff ff callq 400b30 <__stack_chk_fail@p
lt>
401654: 48 83 c4 78 ajouter 0x78,%rsp
401658: c3 retq
401659: 90 nop
40165a : 90 nop
40165b : 90 nop
40165c : 90 nop
40165d : 90 nop
40165e : 90 nop
40165f : 90 nop
Les premières lignes jusqu'à 0x4015d8 servent à définir le protecteur de pile1 puis à
sauvegarder rax avant de le mettre à 0 à 0x4015d6 . Puis, à 0x4015d8 , on trouve
http://webcache.googleusercontent.com/search?q=cache:aW_YFEmXe2cJ:blog.carlosgaldino.com/2016/05/24/defusing-a-binary-bomb-with-gdb-part-7.html+... 2/11
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 7 - carlosgaldino
compare si nous avons déjà parcouru les six phases en regardant le nombre de
chaînes d'entrée. Cette comparaison ne sera vraie qu'après avoir désamorcé les six
phases, donc avant le dernier message, le code sautait toujours à 0x40163f qui
restaurait la valeur de rax et vérifiait le protecteur de pile avant de revenir.
Maintenant que la sixième phase a été désamorcée, le code continue sur 0x4015e1 .
Dans les trois lignes suivantes, les registres r8 , rcx et rdx stockent les adresses des
variables locales, puis à 0x4015f0 et 0x4015f5 , esi et edi reçoivent deux adresses.
Examinons-les pour voir ce que contient chaque adresse :
edi et esi sont tous deux utilisés pour contenir respectivement le premier et le
deuxième argument. Dans ce cas, la seule chose que les deux registres peuvent
stocker est une adresse pointant vers strings2.
La valeur 1 0 sur l'edi vous semble familière ? Il devrait, car c'est la réponse à la
quatrième phase.
sscanf est ensuite utilisé pour analyser à nouveau l'entrée de la quatrième phase,
mais avec un format différent : une chaîne de caractères est attendue après la
deuxième valeur. Vous pouvez voir qu'à 0x4015ff , s'il ne voit pas 3 valeurs, il saute
à 0x401635 qui imprimera le message suivant et retournera :
0000000000401242 <secret_phase>:
401242: 53 pousser %rbx
401243: e8 56 02 00 00 callq 40149e <read_line>
401248: ba 0a 00 00 00 déplacer 0xa,%edx
40124d : êtr 00 00 00 00 déplacer $0x0,%esi
401252: e 48 89 c7 déplacer %rax,%rdi
401255: e8 76 f9 ff ff callq 400bd0 <strtol@plt>
40125a : 48 89 c3 déplacer %rax,%rbx
40125d : 8d 40 ff lea -0x1(%rax),%eax
401260: 3d e8 03 00 00 cmp $0x3e8,%eax
401265: 76 05 jbe 40126c <secret_phase+0x2a>
401267: e8 ce 01 00 00 callq 40143a <explode_bomb>
40126c : 89 de déplacer %ebx,%esi
40126e : bf f0 30 60 00 déplacer $0x6030f0,%edi
401273: e8 8c ff ff ff callq 401204 <fun7>
401278: 83 f8 02 cmp $0x2,%eax
40127b : 74 05 je 401282 <secret_phase+0x40>
40127d : e8 b8 01 00 00 callq 40143a <explode_bomb>
401282: bf 38 24 40 00 déplacer $0x402438,%edi
401287: e8 84 f8 ff ff callq 400b10 <puts@plt>
40128c : e8 33 03 00 00 callq 4015c4 <phase_defused>
401291: 5b pop %rbx
401292: c3 retq
401293: 90 nop
401294: 90 nop
401295: 90 nop
401296: 90 nop
401297: 90 nop
401298: 90 nop
http://webcache.googleusercontent.com/search?q=cache:aW_YFEmXe2cJ:blog.carlosgaldino.com/2016/05/24/defusing-a-binary-bomb-with-gdb-part-7.html+... 2/11
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 7 - carlosgaldino
401299: 90 nop
40129a : 90 nop
40129b : 90 nop
40129c : 90 nop
40129d : 90 nop
40129e : 90 nop
40129f : 90 nop
Après avoir lu l'entrée de cette phase secrète sur 0x401243 , edx stockera la valeur
10 , esi stockera NULL et rdi stockera l'entrée que nous avons donnée. Puis strtol 3
sera appelé à 0x401255 et, à en juger par les valeurs des registres, cela signifie que
notre entrée sera convertie en un nombre en base 10. Ensuite, à 0x40125a , le
nombre déjà converti sera stocké sur rbx . En 0x40125d , la valeur sera modifiée en
soustrayant 1 et placée à nouveau sur eax . Puis une comparaison avec 0x3e8 qui
est 1000 en base 10. Si notre entrée est inférieure à 1000 , le code sautera à
0x40126c pour continuer et si ce n'est pas le cas, la bombe explosera.
À 0x40126c , notre valeur est placée sur esi et edi reçoit une adresse. Les deux
valeurs seront utilisées dans la fonction suivante fun7 qui est appelée à 0x401273 .
Le résultat que fun7 doit renvoyer est 2 comme vous pouvez le voir sur 0x401278 .
Avant d'examiner fun7 , regardons ce que contient l'adresse reçue par edi et utilisée
comme premier argument de fun7 :
(gdb) x 0x6030f0
0x6030f0 <n1> : 0x00000024
Hmm, n1 . Ce nom ne donne aucun indice sur ce que c'est exactement. Voyons
donc ce qu'il en est de fun7 :
0000000000401204 <fun7> :
401204: 48 83 éc 08 sous $0x8,%rsp
401208: 48 85 ff test %rdi,%rdi
40120b : 74 2b je 401238 <fun7+0x34>
40120d : 8b 17 déplace (%rdi),%edx
40120f : 39 f2 r cmp %esi,%edx
401211: 7e 0d jle 401220 <fun7+0x1c>
401213: 48 8b 7f 08 déplace 0x8(%rdi),%rdi
401217: e8 e8 ff ff ff r callq 401204 <fun7>
40121c : 01 c0 ajouter %eax,%eax
40121e : eb 1d jmp 40123d <fun7+0x39>
401220: b8 00 00 00 00 déplace 0x0,%eax
r
http://webcache.googleusercontent.com/search?q=cache:aW_YFEmXe2cJ:blog.carlosgaldino.com/2016/05/24/defusing-a-binary-bomb-with-gdb-part-7.html+... 2/11
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 7 - carlosgaldino
401225: 39 f2 cmp %esi,%edx
401227: 74 14 je 40123d <fun7+0x39>
401229: 48 8b 7f 10 déplace 0x10(%rdi),%rdi
40122d : e8 d2 ff ff ff r callq 401204 <fun7>
401232: 8d 44 00 01 lea 0x1(%rax,%rax,1),%eax
401236: eb 05 jmp 40123d <fun7+0x39>
401238: b8 ff ff ff ff déplace $0xffffffff,%eax
40123d : 48 83 c4 08 r ajouter $0x8,%rsp
401241: c3 retq
Elle vérifie d'abord si rdi est NULL ( 0x0 ) et si c'est le cas, la fonction renvoie la
valeur -1 ( 0xffffffff à 0x401238 ). Si ce n'est pas le cas, la valeur stockée dans
l'adresse stockée par rdi sera placée sur edx et comparée (sur 0x40120f ) à notre
nombre d'entrée. Si la valeur sur edx est inférieure ou égale à notre nombre, le
code va à 0x401220 , sinon il continue à 0x401213. Continuons sur 0x401213 puis
revenons pour voir ce qui se passe dans l'autre branche.
En 0x401213, rdi stocke ce qui se trouve 8 octets après l'adresse déjà présente sur
rdi et appelle à nouveau fun7 .
Dans l'autre branche, lorsque le nombre sur edx est inférieur ou égal à notre
nombre, le code va à 0x401220 qui met eax à 0, compare ce qui est sur edx avec
notre nombre et s'ils sont égaux, il va à 0x40123d qui renvoie. Si les nombres sont
différents, l'instruction à 0x401229 changera rdi pour stocker ce qui se trouve 16
octets après l'adresse actuelle, puis appellera fun7 comme le fait l'autre branche.
Dans chaque branche, rdi est modifié pour contenir la nouvelle adresse située 8 ou
16 octets après son adresse actuelle. La première chose que contient rdi est un
nombre, les deux autres sont des pointeurs, il pourrait donc s'agir d'un arbre
binaire:
struct node { int data ; struct node *left; struct node *right;
};
Le nœud racine, situé à l'adresse initiale avec laquelle fun7 est appelé, est le suivant
:
(gdb) x 0x6030f0
0x6030f0 <n1> : 0x00000024
(gdb) x 0x6030f0+0x8
http://webcache.googleusercontent.com/search?q=cache:aW_YFEmXe2cJ:blog.carlosgaldino.com/2016/05/24/defusing-a-binary-bomb-with-gdb-part-7.html+... 2/11
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 7 - carlosgaldino
0x6030f8 <n1+8> : 0x00603110
(gdb) x 0x6030f0+0x10
0x603100 <n1+16> : 0x00603130
Après avoir suivi les pointeurs de nœuds, nous pouvons voir que la structure de
l'arbre est la suivante :
Nous savons comment l'arbre est structuré, mais nous ne savons pas ce que nous
devons faire pour obtenir la bonne réponse. secret_phase appelle fun7 et s'attend à
ce qu'il renvoie la valeur 2 :
Voyons donc ce que fun7 nous renvoie. Nous savons qu'il s'agit d'une fonction
récursive. Voyons quel est le cas de base, qui est en fait double :
http://webcache.googleusercontent.com/search?q=cache:aW_YFEmXe2cJ:blog.carlosgaldino.com/2016/05/24/defusing-a-binary-bomb-with-gdb-part-7.html+... 2/11
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 7 - carlosgaldino
401208 : 48 85 ff %rdi,%rdi
test je
40120b : 74 2b 401238 <fun7+0x34>
Et.. :
Les deux montrent que la fonction revient lorsque nous avons atteint un pointeur
NULL (premier cas) ou si le nombre que nous avons donné est égal à celui du
nœud actuel (deuxième cas).
Mais dans le premier cas, le code saute à 0x401238 , ce qui fixe la valeur de retour à
-1 :
401238 : b8 ff ff ff ff ff mov
$0xffffffff,%eax
40123d : 48 83 c4 08 add
$0x8,%rsp
401241 : c3 retq
dépla
401220 : b8 00 00 00 00 cer $0x0,%eax
401225 : 39 f2 cmp %esi,%edx
401227: 74 14 je 40123d <fun7+0x39>
Ainsi, si nous fournissons un nombre qui n'est pas présent dans l'arbre, le code
atteindra un pointeur NULL et renverra -1 et si notre nombre est présent, il
renverra 0.
Nous devons maintenant examiner chaque appel récursif à fun7 et voir ce que
l'appel en cours fera avec le résultat de l'appel interne. Voyons ce qui se passe
après le retour de l'appel interne de fun7 :
C'est le cas lorsque notre nombre est plus petit que la valeur actuelle du nœud. Il
double simplement la valeur de retour (à 0x40121c ) et saute à 0x40123d pour revenir.
Dans l'autre branche, lorsque notre nombre est supérieur ou égal à la valeur du nœud
actuel, il passe à 0x401220 :
Ici, si les valeurs sont égales, la fonction renverra 0 comme nous l'avons vu
précédemment, mais si elles sont différentes, fun7 sera appelé à nouveau et la valeur
de retour de l'appel interne sera doublée comme dans l'autre branche, mais dans ce
cas, elle sera également augmentée de 1 :
Bien que lea signifie load effective address, cette instruction est souvent utilisée
pour des opérations arithmétiques.4 et c'est exactement le cas ici. L'instruction ci-
dessus signifie :
Simplifier :
eax = 2*rax + 1
http://webcache.googleusercontent.com/search?q=cache:aW_YFEmXe2cJ:blog.carlosgaldino.com/2016/05/24/defusing-a-binary-bomb-with-gdb-part-7.html+... 9/11
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 7 - carlosgaldino
Une option consiste à visiter 0x8 et 0x16 . En remplaçant les adresses des nœuds par
les données réelles dont ils disposent, nous obtiendrions les appels suivants à fun7 :
http://webcache.googleusercontent.com/search?q=cache:aW_YFEmXe2cJ:blog.carlosgaldino.com/2016/05/24/defusing-a-binary-bomb-with-gdb-part-7.html+... 2/11
5/29/2016 Désamorcer une bombe binaire avec gdb - Partie 7 - carlosgaldino
Il existe une autre réponse possible pour cette phase, mais le lecteur est invité à la
trouver.
Notes
2. https://en.wikipedia.org/wiki/Buffer_overflow_protection
4. Si vous souhaitez en savoir plus sur lea , sa différence avec mov , comment et
pourquoi les opérations arithmétiques peuvent être effectuées avec lea , vous
pouvez commencer par lire la page suivante :
https://en.wikibooks.org/wiki/X86_Assembly/Data_Transfer#Load_Effe
ctive_Address
http://webcache.googleusercontent.com/search?q=cache:aW_YFEmXe2cJ:blog.carlosgaldino.com/2016/05/24/defusing-a-binary-bomb-with-gdb-part-7.html+... 2/11