Le code ci-dessous provient de l'article bien connu Smashing The Stack For Fun And Profit.Mon code de débordement ne fonctionne pas
void function(int a, int b, int c) {
char buffer1[5];
char buffer2[10];
int *ret;
ret = buffer1 + 12;
(*ret)+=8;
}
void main() {
int x;
x=0;
function(1,2,3);
x=1;
printf("%d\n",x);
}
Je pense que je dois expliquer ma cible de ce code. Le modèle de pile est ci-dessous. Le nombre en dessous du mot est le nombre d'octets de la variable dans la pile. Donc, si je veux réécrire RET pour passer l'instruction que je veux, je calcule le décalage de buffer1
à RET est 8 + 4 = 12. Depuis l'architecture est Linux x86.
buffer2 buffer1 BSP RET a b c
(12) (8) (4) (4) (4) (4) (4)
Je veux ignorer la déclaration x=1;
et laisser printf()
sortie 0
à l'écran.
Je compilez le code avec:
gcc stack2.c -g
et l'exécuter dans gdb:
gdb ./a.out
gdb me donne le résultat comme ceci:
Program received signal SIGSEGV, Segmentation fault.
main() at stack2.c:17
17 x = 1;
Je pense que Linux utilise certains mécanisme de protection contre le débordement de la pile. Peut-être que Linux stocke l'adresse RET à un autre endroit et compare l'adresse RET dans la pile avant le retour des fonctions.
Et quel est le détail du mécanisme? Comment est-ce que je devrais réécrire le code pour rendre la sortie de programme 0
? OK, le code de démontage est ci-dessous.Il vient de la sortie de gdb car je pense qu'il est plus facile à lire pour vous.Et quelqu'un peut me dire comment coller une séquence de code long? Copiez et collez un par un fait moi aussi fatigué ...
Dump of assembler code for function main:
0x08048402 <+0>: push %ebp
0x08048403 <+1>: mov %esp,%ebp
0x08048405 <+3>: sub $0x10,%esp
0x08048408 <+6>: movl $0x0,-0x4(%ebp)
0x0804840f <+13>: movl $0x3,0x8(%esp)
0x08048417 <+21>: movl $0x2,0x4(%esp)
0x0804841f <+29>: movl $0x1,(%esp)
0x08048426 <+36>: call 0x80483e4 <function>
0x0804842b <+41>: movl $0x1,-0x4(%ebp)
0x08048432 <+48>: mov $0x8048520,%eax
0x08048437 <+53>: mov -0x4(%ebp),%edx
0x0804843a <+56>: mov %edx,0x4(%esp)
0x0804843e <+60>: mov %eax,(%esp)
0x08048441 <+63>: call 0x804831c <[email protected]>
0x08048446 <+68>: mov $0x0,%eax
0x0804844b <+73>: leave
0x0804844c <+74>: ret
Dump of assembler code for function function:
0x080483e4 <+0>: push %ebp
0x080483e5 <+1>: mov %esp,%ebp
0x080483e7 <+3>: sub $0x14,%esp
0x080483ea <+6>: lea -0x9(%ebp),%eax
0x080483ed <+9>: add $0x3,%eax
0x080483f0 <+12>: mov %eax,-0x4(%ebp)
0x080483f3 <+15>: mov -0x4(%ebp),%eax
0x080483f6 <+18>: mov (%eax),%eax
0x080483f8 <+20>: lea 0x8(%eax),%edx
0x080483fb <+23>: mov -0x4(%ebp),%eax
0x080483fe <+26>: mov %edx,(%eax)
0x08048400 <+28>: leave
0x08048401 <+29>: ret
-je vérifier le code et trouver assembler une erreur au sujet de mon programme, et je dois réécrire (*ret)+=8
-(*ret)+=7
, depuis 0x08048432 <+48>
moins 0x0804842b <+41>
est 7.
Vérifiez l'assemblage généré, probablement votre fonction a été insérée. – kan
Je vous promets que la fonction n'a pas été intégrée, puisque j'ai vérifié le code d'assemblage. –
Vous supposez que 'x = 1' génère 8 octets de code d'assemblage et que la pile est disposée comme vous l'avez montré (il pourrait aussi y avoir d'autres choses). Ajouter la liste d'assemblage et la réponse deviendra vraiment évidente. – Skizz