通过导致缓冲区溢出,我们可以覆盖保存标志值0的内存,因此即使是错误的密码也会破坏代码..
这将如何在内部发生?有人可以请详细解释..这会在记忆中实际发生吗?
#include<stdio.h>
int main(int argc, char *argv[])
{
int flag = 0;
char passwd[10];
memset(passwd,0,sizeof(passwd));
strcpy(passwd, argv[1]);
if(0 == strcmp("LinuxGeek", passwd))
{
flag = 1;
}
if(flag)
{
printf("\n Password cracked \n");
}
else
{
printf("\n Incorrect passwd \n");
}
return 0;
}
答案 0 :(得分:6)
请记住,从理论的角度来看,如果存储在passwd
中的字符串溢出,它会调用未定义的行为,结果是不可预测的。
实际上,在许多将局部变量存储在堆栈中的现代平台上,如果编译器将flag
置于高于passwd
缓冲区的位置,它可能会溢出{{1调用。
即。你的堆栈看起来像这样:
strcpy
如果您向| ... |
+------------+
| flag | / \
+------------+ |
| passwd[10] | | increasing addresses
| ... |
写入的字节超过10个字节,passwd
只需写入strcpy
。
请注意,行为因编译器到编译器,平台到平台而异。这个解释涵盖了常见系统上发生的事情,但是知道理论上可以建立一个不使用堆栈的平台,所以这个解释不适用。
答案 1 :(得分:3)
C中的局部变量通常在堆栈上分配。堆栈往往在内存中向下增长,因此“flag”的存储将在为“passwd”分配的存储之后立即生效。
strcpy不检查正在复制的数据量是否会溢出正在复制数据的缓冲区。所以,假设argv [1]完全是11个字符,这就是将要发生的事情:
因此,标志将为非零。
确切的行为因编译器而异 - 但这是典型的情况。
使用strncpy来避免这种情况。