c语言栈溢出破解密码
#include<bits/stdc++.h>
using namespace std;
#define PASSWORD "1234567"
int check(char * password)
{
int valid_flag = 0;
char buffer[8];
valid_flag=strcmp(password, PASSWORD);
strcpy(buffer, password);
return valid_flag;
}
int main()
{
char inputstr[20];
for(int i=0;i!=3;i++)
{
printf("input password:");
scanf("%s", inputstr);
if(check(inputstr)==0)
{
printf("ok\n");
}
else
{
printf("no\n");
}
}
return 0;
}
运行结果:
input password:zzzzzzzz
ok
input password:
8个z比PASSWORD大,所以strcmp会返回1(0000 0000 0000 0000 0000 0000 0000 0001).
strcpy函数的实现是:
while(*t++=*s++);
所以会将s字符串直到\0的内容都传给t。
我们又可以看到我们需要利用buffer越界,将valid_flag给覆盖为0,但是键盘输入不能输入\0,并且strcpy遇到\0就会停止,只会在字符串最后留下一个\0,所以要利用这仅有的一个\0将1(0000 0000 0000 0000 0000 0000 0000 0001)中的1覆盖掉,所以要传入8个字符,让最后一个\0越界覆盖1,这个位置太巧妙了。
内存排放位置,验证代码:
#include<bits/stdc++.h>
using namespace std;
union A
{
int _int;
char _str[4];
};
int main()
{
A a;
// 1 -> (00000000 00000000 00000000 00000001)
// str -> (str[3] str[2] str[1] str[0])
a._int=1;
a._str[0]='\0';
printf("%d\n", a._int);
a._str[1]=1;
printf("%d\n", a._int);
return 0;
}
运行结果:
0
256