c stack smashing détecté
J'ai créé un fichier qui affiche " Hello, world autant de fois que l'utilisateur veut donner de l'entrée.
#include <stdio.h>
#include <string.h>
int main() {
char message[10];
int count, i;
strcpy(message, "Hello, world!");
printf("Repeat how many times? ");
scanf("%d", &count);
for(i=0; i < count; i++)
printf("%3d - %s\n", i, message);
}
Quel que soit le nombre entré il en résulte toujours dans une pile "smash". Voici le programme, quelqu'un peut-il venir à une conclusion, pourquoi il fait cela? Ici, c'est le "traceback" qui se produit après que la pile smash est détecté:
sean@blue:~/programming$ ./a.out
Repeat how many times? 12
0 - Hello, world!
1 - Hello, world!
2 - Hello, world!
3 - Hello, world!
4 - Hello, world!
5 - Hello, world!
6 - Hello, world!
7 - Hello, world!
8 - Hello, world!
9 - Hello, world!
10 - Hello, world!
11 - Hello, world!
*** stack smashing detected ***: ./a.out terminated
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x45)[0x1f8c75]
/lib/i386-linux-gnu/libc.so.6(+0xe8c27)[0x1f8c27]
./a.out[0x8048524]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x129113]
./a.out[0x80483f1]
======= Memory map: ========
00110000-00288000 r-xp 00000000 08:01 1577912 /lib/i386-linux-gnu/libc-2.13.so
00288000-0028a000 r--p 00178000 08:01 1577912 /lib/i386-linux-gnu/libc-2.13.so
0028a000-0028b000 rw-p 0017a000 08:01 1577912 /lib/i386-linux-gnu/libc-2.13.so
0028b000-0028e000 rw-p 00000000 00:00 0
0036b000-0036c000 r-xp 00000000 00:00 0 [vdso]
00454000-00470000 r-xp 00000000 08:01 1573818 /lib/i386-linux-gnu/libgcc_s.so.1
00470000-00471000 r--p 0001b000 08:01 1573818 /lib/i386-linux-gnu/libgcc_s.so.1
00471000-00472000 rw-p 0001c000 08:01 1573818 /lib/i386-linux-gnu/libgcc_s.so.1
00e7e000-00e9c000 r-xp 00000000 08:01 1573924 /lib/i386-linux-gnu/ld-2.13.so
00e9c000-00e9d000 r--p 0001d000 08:01 1573924 /lib/i386-linux-gnu/ld-2.13.so
00e9d000-00e9e000 rw-p 0001e000 08:01 1573924 /lib/i386-linux-gnu/ld-2.13.so
08048000-08049000 r-xp 00000000 00:14 3801591 /home/sean/programming/a.out
08049000-0804a000 r--p 00000000 00:14 3801591 /home/sean/programming/a.out
0804a000-0804b000 rw-p 00001000 00:14 3801591 /home/sean/programming/a.out
08a9e000-08abf000 rw-p 00000000 00:00 0 [heap]
b77e8000-b77e9000 rw-p 00000000 00:00 0
b77fc000-b7800000 rw-p 00000000 00:00 0
bff87000-bffa8000 rw-p 00000000 00:00 0 [stack]
Aborted
Vous trouverez peut-être utile d'activer les avertissements sur n'importe quel compilateur que vous utilisez. Par exemple, lorsque je l'ai utilisé avec gcc -Wall, il produit à la fois "avertissement: le contrôle a atteint sa fin de non-void function" et "appel à l' __builtin___strcpy_chk sera toujours la destination de débordement de la mémoire tampon", ce qui indique clairement quel est le problème.
OriginalL'auteur bigl | 2012-03-15
Vous devez vous connecter pour publier un commentaire.
Parce que
"Hello, world!"
est de plus de 10 caractères...OriginalL'auteur Oliver Charlesworth
message
ne peut contenir de 10 octets. Vous copiez la chaîne de caractères "Hello World!", qui est de 13 octets (si vous compter le caractère nul) et vous allez vous retrouver écraser et d'endommager la pile protecteur de cookie.Le cookie est un hasard octet inséré par le compilateur pour vous assurer que vous bloquer si l'adresse de retour est modifié sur la pile, de la prévention de débordement de tampon potentiel à exploiter.
Si vous êtes à la compilation avec gcc, à l'expérience, essayez d'ajouter
-fno-stack-protector
commutateur à votre compilation de déclaration et d'essayer de nouveau. Le programme sera probablement planter (mais pas avec un message d'erreur comme ça) et sera vulnérable à débordement de la mémoire tampon exploits.Oh, j'en ai oublié la virgule. Vis d'elle. C'est d'accord. Je ne vais pas éditer le post pour celle-ci 🙂
OriginalL'auteur Mehrdad Afshari
Votre message tableau est composé de 10 caractères (de 0 à 9), mais si vous comptez
"Hello, World!"
(sans les guillemets), il est de 13 caractères. En tant que tel, vous êtes l'écrasement de la mémoire qui ne fait pas partie de votre groupe.De référence,
strcpy()
,strcat()
et la plupart des autres C-les fonctions de chaîne ne cochez pas la longueur de la matrice, ils supposent que vous avez donné assez d'espace pour travailler avec.Ainsi, vous aurez besoin de donner à votre message de la matrice de plus d'espace. Mais combien de plus? assez pour s'adapter "Bonjour, monde!" PLUS un pour les nuls-caractère de terminaison
'\0'
, qui détermine la fin de la chaîne. de sorte que vous aurez besoin de déclarer un tableau de 14 caractères.Pour un peu plus d'explication en profondeur sur la façon de travailler avec de la ficelle et le null-personnage, je suggère cette page. Alors que c'est une page C++ il recouvre la substance qui est commun à la fois pour C et C++ (C++ est basé sur C)
Aussi, comme Pearsonartphoto dit, vous pouvez simplement déclarer votre tableau comme
Cependant, si c'est pour l'école ou un uni affectation, assurez-vous que vous avez appris à le faire de cette façon, parce que parfois vous pouvez être déduits des marques 'de se précipiter en avant'. L'idée de ce genre de questions est d'enseigner à l'funementals, et COMMENT et POURQUOI certaines choses fonctionnent, ils peuvent ne pas être le plus facile ou le plus efficace de faire les choses (le type de pile-smash vous êtes l'obtention est toujours à l'origine des problèmes dans les principaux systèmes aujourd'hui parce que les programmeurs oubliez pas de vérifier la taille, etc).
OriginalL'auteur Robotnik
Votre
message
tableau doit être au moins un caractère de plus que la chaîne que vous copiez-y (rappelez-vous, vous devez maintenir la implicites'\0'
terminateur null).OriginalL'auteur John Carter
Comme il a été dit, Bonjour tout le Monde! est trop long. Beaucoup plus facile serait de faire ce qui suit
Qui sera à la bonne taille automatiquement.
Oups... C'est ce que je reçois pour l'utilisation de trop nombreux langages de programmation en même temps...
OriginalL'auteur PearsonArtPhoto
J'ai eu ce problème lorsque j'ai défini une structure de cette façon:
Cela ne donne pas d'AVERTISSEMENT, mais dans mon cas, a provoqué un écrasement de la pile d'erreur.
J'ai résolu en remplaçant ce avec
OriginalL'auteur Giovanni Giomini Figliozzi