2009-05-13 4 views
2

Considérons ces deux lignes:Que se passe-t-il? gets()

char input[1]; 
gets(input); 

Disons que l'entrée est "test". printf ("% s \ n", entrée) => "test" mais si j'utilise le débogueur je vois l'entrée [0] = 't' aucune entrée [1] ... Que se passe-t-il exactement?

+3

Je sens un dépassement de tampon. – Tom

+0

Vraiment GRANDE odeur! – mmmmmmmm

Répondre

2

Vous débordez votre tampon, c'est ce qui se passe. Vous écrivez à la mémoire qui n'est pas à vous et qui a de la chance.

10

C'est un buffer overflow, fyi. Pour le plaisir ajouter char untouched[20]; après char input[1]; et aussi imprimer untouched. N'utilisez pas gets(), utilisez fgets() ou autre chose avec vérification des limites.

Le débogueur ne montre pas input[1] car il n'existe pas. Votre déclaration char input[1]; alloue un tableau de longueur 1, pas un tableau de 0 à 1.

2

Ce.

char input[1]; 

réserve que la valeur d'un caractère de la mémoire, mais vous mettez cinq caractères dans

Le débogueur sait que vous n'avez qu'un seul personnage et vous montrera ce qu'il sait.

Le programme en cours va éclabousser la chaîne sur la mémoire adjacente à input et se bloquer ou s'en tirer avec. Dans votre cas, vous vous en sortez.

0

Vous déclarez un tableau avec la taille fixe '1'. L'index du premier élément du tableau est toujours '0'. C'est pourquoi l'entrée [0] contient le caractère 't'.

EDIT - Le reste est stocké quelque part en dehors du tampon (BufferOverFlow).

1

Un caractère char [] de longueur n a la dernière entrée stockée dans la position n-1. Ainsi,

char input[1]; 

signifie une seule donnée de type char stockées dans l'entrée de gamme, la position 0.

(sous la direction de fournir des éclaircissements -. Première formulation était trop mauvaise)

7

gets (s) lit une ligne de stdin dans le tampon pointé par s jusqu'à soit une nouvelle ligne de fin soit EOF, qu'elle remplace par '\ 0'. Aucune vérification pour dépassement de la mémoire tampon est réalisée

http://linux.die.net/man/3/gets

Lorsque vous exécutez obtient, est entrée dans le tampon pointé par s. Ensuite, il ajoute un \ 0. Seul le 't' est à l'intérieur du tampon d'entrée. Le reste, est situé sur la mémoire contiguë sur la pile. Print0 imprime "test", car c'est ce qu'il peut lire à partir de s jusqu'à la première \ 0. Mais les "est \ 0" sont en dehors du tampon. Lorsque vous le déboguez, l'entrée ne pointe que vers un seul caractère, c'est tout ce que vous pouvez voir.

Il est important de jeter un coup d'œil sur le "Aucune vérification du dépassement de tampon n'est effectuée". Cela signifie que la fonction ne se soucie pas vraiment si vous avez alloué de la mémoire pour votre entrée. Il va commencer à tout copier à partir du point que vous indiquez. Si vous ne faites pas attention, votre contribution peut passer sur des informations importantes. Dans le pire des cas, ce sera l'adresse de retour pour votre fonction (où vous utilisez get). Quelqu'un qui "fait juste" cette erreur, dira "wtf se passe". Quelqu'un qui le fait intentionnellement, pointera votre adresse de retour à une partie spécifique, et exécuter du code situé là.

More on Buffer Overflow.

Questions connexes