怎么了?得到()

use*_*108 2 c

让我们考虑这两行:

char input[1];
gets(input);
Run Code Online (Sandbox Code Playgroud)

假设输入是"测试".printf("%s \n",输入)=>"test"但是如果我使用调试器,我看到输入[0] ='t'没有输入[1] ......究竟发生了什么?

dwc*_*dwc 10

这是缓冲区溢出,fyi.为了好玩,添加char untouched[20];char input[1];也打印untouched.不要使用gets(),使用fgets()或其他与边界检查.

调试器没有显示,input[1]因为没有这样的东西.您的char input[1];声明分配长度为1的数组,而不是从0到1的数组.


Tom*_*Tom 7

gets(s)从stdin读取一行到s指向的缓冲区,直到终止换行符或EOF,它替换为'\ 0'.不执行缓冲区溢出检查

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

执行gets时,输入被写入s指向的缓冲区.然后它添加一个\ 0.只有't'在输入缓冲区内.其余的,位于堆栈上的连续内存中.printf打印"test",因为它可以从s开始读取到第一个\ 0.但是"est\0"在缓冲区之外.

 ------
|  t  |  input - Debugger only sees this position.
 ------
|  e  |  Memory you are stepping onto. Trouble if it doesn´t belong to your proc.   
|  s  | 
|  t  |
|  \0 |
------
Run Code Online (Sandbox Code Playgroud)

当你调试它时,输入只指向一个char,所以你可以看到.

重要的是要看一下"不检查缓冲区溢出是否已执行".这意味着如果为输入分配了内存,则获取函数并不在意.它将从您指示的点开始复制所有内容.如果您不小心,那么您的输入可以进入重要信息.在某些最糟糕的情况下,这将是您的函数的返回地址(您使用获取的地方)."只是犯"这个错误的人会说"wtf正在进行中".故意这样做的人会将您的返回地址指向特定部分,并执行位于那里的代码.

有关缓冲区溢出的更多信息