栈溢出分析

栈溢出

栈是从高地址向低地址方向增涨,堆的方向相反。

在一次函数调用中,栈中将被依次压入:参数,返回地址,EBP。如果函数有局部变量,接下来,就在栈中开辟相应的空间以构造变量。

在C语言程序中,参数的压栈顺序是反向的。比如func(a,b,c)。在参数入栈的时候,是:先压c,再压b,最后a。在取参数的时候,由于栈的先入后 出,先取栈顶的a,再取b,最后取c。

C语言是不作栈溢出检查,如下代码可以正常编译运行。

#include<stdio.h>
main(){
     char buf[2];
     printf ( "enter a string shorter than 2.\n" );
     scanf ( "%s" ,buf);
     printf ( "buf=%s\n" ,buf);
}

如果函数局部变量发生栈溢出,就会依次覆盖重写EBP(4个字节)、返回地址(4个字节)、函数参数。函数的“返回地址”被重写是非常危险的,因为“返回地址”可能指向了一段恶意代码而我们却毫无察觉。

下面的代码中funcA的局部变量发生栈溢出,使得funcA的返回地址成为funcB的入口地址。不过幸好在运行的时候发现了这种行为,报告了“segmentation fault”。

#include <stdio.h>
#include <string.h>
 
#define BUFLENGTH 2
 
void funcA( char * str)
{
     char buf[BUFLENGTH];
     strcpy (buf,str);    //危险,可能造成栈溢出
     printf ( "strlen(buf)=%d\tbuf=%s\n" , strlen (buf),buf);
     printf ( "不安全的代码被调用\n" );
}
 
//下面的函数是恶意代码
void funcB()
{
     printf ( "恶意代码被调用\n" );
}
 
void main()
{
     //以不安全的方式调用函数funcA
     char bufNasty[BUFLENGTH+8];
     memset (bufNasty, 'A' , sizeof (bufNasty));
     int *ptr=( int *)&bufNasty[BUFLENGTH+4];
     *ptr=0x65850408;
     funcA(bufNasty);
}

当然如何知道funcB的地址是0x65850408呢?可以使用反汇编工具查看:

objdump  -x  attack

也可以在使用gdb时通过在funcB处设置断点看到funcB的地址。

gdb>b  funcB

原文来自:博客园(华夏35度)http://www.cnblogs.com/zhangchaoyang作者:Orisun
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值