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
文章目录