栈中变量的存放-strcpy

函数形参和局部变量是保存在栈中的,而栈是从高地址向低地址扩展的。

#include <stdio.h> 

int main(void)
{
char s[]="123456789";
char d[]="123";
strcpy(d,s);
printf("%s,/n%s",d,s);
return 0;

}

结果输出:123456789,56789。
解析:栈是从高地址向低地址扩展的,因此先定义的局部变量的地址高,后定义的局部变量的地址低。故在内存中从低到高是如下排列的(拷贝 前):123/0123456789/0。如图1所示.
调用了strcpy后变成了:123456789/0789/0。这要从strcpy(d,s)函数的实现解 释:它将s的所有字符拷贝到d中,只到它遇到字符串结束符'/0',而对d,s是否越界没有进行检查,所以出现上面的奇怪的输出。

图1拷贝之前内存中d和s的指向情况:

图2拷贝后指针d和s在栈中的情况:


总结:在使用strcpy时一定要注意,尽量用strncpy代替。再看下面在网上找来的例子。可以帮助加深理解。

问:下面是一个简单的密码保护功能,你能在不知道密码的情况下将其破解吗?

#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; 
} 

答:破解上述加密的关键在于利用攻破strcpy()函数的漏洞。所以用户在向“passwd”缓存输入随机密码的时候并没有提前检查“passwd”的容量是否足够。所以,如果用户输入一个足够造成缓存溢出并且重写“flag”变量默认值所存在位置的内存的长“密码”,即使这个密码无法通过验证,flag验证位也变成了非零,也就可以获得被保护的数据了。例如:

$ ./psswd aaaaaaaaaaaaa 
 
Password cracked 
虽然上面的密码并不正确,但我们仍然可以通过缓存溢出绕开密码安全保护。

详细参考:http://www.csdn.net/article/2012-09-06/2809604-12-c-interview-questions


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值