找回密码
 注册
X系列官方授权正版
搜索
查看: 2181|回复: 1

什么叫缓冲区溢出

[复制链接]
发表于 2007-8-22 23:56:52 | 显示全部楼层 |阅读模式
缓冲区溢出
缓冲区是内存中存放数据的地方。在程序试图将数据放到计算机内存中的某一位置,但没有足够空间时会发生缓冲区溢出。

缓冲区是程序运行时计算机内存中的一个连续的块,它保存了给定类型的数据。问题随着动态分配变量而出现。为了不用太多的内存,一个有动态分配变量的程序在程序运行时才决定给他们分配多少内存。如果程序在动态分配缓冲区放入太多的数据会有什么现象?它溢出了,漏到了别的地方。一个缓冲区溢出应用程序使用这个溢出的数据将汇编语言代码放到计算机的内存中,通常是产生root权限的地方。单单的缓冲区溢出,并不会产生安全问题。只有将溢出送到能够以root权限运行命令的区域才行。这样,一个缓冲区利用程序将能运行的指令放在了有root权限的内存中,从而一旦运行这些指令,就是以root权限控制了计算机。总结一下上面的描述。缓冲区溢出指的是一种系统攻击的手段,通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其它指令,以达到攻击的目的。据统计,通过缓冲区溢出进行的攻击占所有系统攻击总数的80%以上。造成缓冲区溢出的原因是程序中没有仔细检查用户输入的参数。例如下面程序:

example0.c
-----------------------------------------------------------
void function(char *str) {
char buffer[16];

strcpy(buffer,str);
}
-----------------------------------------------------------

上面的strcpy()将直接把str中的内容copy到buffer中。这样只要str的长度大于16,就会造成buffer的溢出,使程序运行出错。存在象strcpy这样的问题的标准函数还有strcat(),sprintf(),vsprintf(),gets(),scanf(),以及在循环内的getc(),fgetc(),getchar()等。在C语言中,静态变量是分配在数据段中的,动态变量是分配在堆栈段的。缓冲区溢出是利用堆栈段的溢出的。一个程序在内存中通常分为程序段,数据端和堆栈三部分。程序段里放着程序的机器码和只读数据,这个段通常是只读,对它的写操作是非法的。数据段放的是程序中的静态数据。动态数据则通过堆栈来存放。在内存中,它们的位置如下:


/――――――――\ 内存低端
|程序段|
|―――――――――|
|数据段|
|―――――――――|
|堆栈|
\―――――――――/内存高端

堆栈是内存中的一个连续的块。一个叫堆栈指针的寄存器(SP)指向堆栈的栈顶。堆栈的底部是一个固定地址。堆栈有一个特点就是,后进先出。也就是说,后放入的数据第一个取出。它支持两个操作,PUSH和POP。PUSH是将数据放到栈的顶端,POP是将栈顶的数据取出。在高级语言中,程序函数调用和函数中的临时变量都用到堆栈。参数的传递和返回值是也用到了堆栈。通常对局部变量的引用是通过给出它们对SP的偏移量来实现的。另外还有一个基址指针(FP,在Intel芯片中是BP),许多编译器实际上是用它来引用本地变量和参数的。通常,参数的相对FP的偏移是正的,局部变量是负的。当程序中发生函数调用时,计算机做如下操作:首先把参数压入堆栈;然后保存指令寄存器(IP)中的内容,做为返回地址(RET);第三个放入堆栈的是基址寄存器(FP);然后把当前的栈指针(SP)拷贝到FP,做为新的基地址;最后为本地变量留出一定空间,把SP减去适当的数值。

下面举个例子:
example1.c:
------------------------------------------------------------
void function(int a, int b, int c) {
char buffer1[5];
char buffer2[10];
}

void main() {
function(1,2,3);
}
-----------------------------------------------------------

为了理解程序是怎样调用函数function()的,使用-S选项,在Linux下,用gcc进行编译,产生汇编代码输出:

$ gcc -S -o example1.s example1.c

看看输出文件中调用函数的那部分:

pushl $3
pushl $2
pushl $1
call function

这就将3个参数压到堆栈里了,并调用function()。指令call会将指令指针IP压入堆栈。在返回时,RET要用到这个保存的IP。在函数中,第一要做的事是进行一些必要的处理。每个函数都必须有这些过程:


pushl %ebp
movl %esp,%ebp
subl $20,%esp

这几条指令将EBP,基址指针放入堆栈。然后将当前SP拷贝到EBP。然后,为本地变量分配空间,并将它们的大小从SP里减掉。由于内存分配是以字为单位的,因此,这里的buffer1用了8字节(2个字,一个字4字节)。Buffer2用了12字节(3个字)。所以这里将ESP减了20。这样,现在,堆栈看起来应该是这样的。


低端内存高端内存
buffer2 buffer1 sfp ret a b c
< ------ [ ][ ][ ][ ][ ][ ][ ]
栈顶栈底

缓冲区溢出就是在一个缓冲区里写入过多的数据。那怎样利用呢,看
一下下面程序:


example2.c
-----------------------------------------------------------
void function(char *str) {
char buffer[16];

strcpy(buffer,str);
}

void main() {
char large_string[256];
int i;

for( i = 0; i < 255; i++)
large_string = 'A';

function(large_string);
}
------------------------------------------------------------

这个程序是一个经典的缓冲区溢出编码错误。函数将一个字符串不经过边界检查,拷贝到另一内存区域。当调用函数function()时,堆栈如下:

低内存端buffer sfp ret *str高内存端
< ------ [ ][ ][ ][ ]
栈顶栈底

很明显,程序执行的结果是"Segmentation fault (core dumped)"或类似的出错信息。因为从buffer开始的256个字节都将被*str的内容'A'覆盖,包括sfp, ret,甚至*str。'A'的十六进值为0x41,所以函数的返回地址变成了0x41414141, 这超出了程序的地址空间,所以出现段错误。可见,缓冲区溢出允许我们改变一个函数的返回地址。通过这种方式,可以改变程序的执行顺序。

评分

参与人数 1UCC +54 收起 理由
mike521zx + 54 有价值信息

查看全部评分

 楼主| 发表于 2007-8-22 23:57:26 | 显示全部楼层

什么是缓冲

缓冲的字面意思是减缓冲击力。除了真正的冲击力外,缓冲还有抽象的意义。凡是使某种事物的变化过程减慢或减弱进行都可以叫缓冲。比如让化学反应不那末剧烈的物质就叫缓冲剂。缓冲的程度不同,可用减缓的百分数来表达。

缓冲在各领域定义各有不同:

QoS功能主要包括:缓冲、压缩、速率/流量控制、过滤、队列、流量分类、负载均衡、邮件优化、广域文件系统优化、 应用性能分析、应用基础设施改动等。

网上看电影时,缓冲就是在你看电影时提前把一下时段内容准备好,目的是可以更流畅的观看。主要取决于CPU和内存大小,越大会反应越快。

缓冲是指在播放网络影音文件的时候,由播放器预先保存于本地硬盘临时文件夹一部分文件,以使播放更流畅。如果播放不流畅,一是与您的网速有关,另外与播放器缓冲的大小有关,您可以在播放器的工具/选项中找到。(内嵌于网页的播放器其实可以通过打开媒体播放器和REALPLAYER设置来进行),两种可能都有,尤其可能是网站采用的文件清晰度较差,有些网站采用动态技术,可以根据用户的网速来选择不同的码率,所以速度快的用户看到的效果会好一些,而网速慢的用户自然看起来较差一些。

缓冲是指把内容存放在本地,那样以前请求过的信息被再次请求时,就不会耗用WAN带宽。缓冲往往应用到网页,就网页而言,对信息(而不是事务)的请求来自远程站点。凡是在特定的LAN网段上请求网页的人,都可以跨WAN重复使用被请求过的信息。现有的几种产品有助于Web事务的缓冲。这种情况下,页面的某些部分不会变化,如页面标题和组织名称。提供这类产品的厂商包括了Chutney Technologies和 FineGround Networks(严格说来,Web浏览器早就在利用及优化缓冲机制)、Converged Access以及其他一些网络厂商。 缓冲也在开始应用于文件系统和电子邮件系统。实际上,有些较为全面的针对特定应用的缓冲(而不是普通的流量缓冲)能够集中存储和应用服务器,而不会严重影响最终用户的性能。

缓冲的引入

中断技术和通道技术的引入,提供了CPU,通道和I/O设备之间的并行操作的可能性,但由于计算机外设的发展会产生通道不足而产生的“瓶颈”现象,使并行程度受到限制,因此引入了缓冲技术。

目的:

1、改善CPU和I/O设备之间速度不匹配的情况;

2、可以减少I/O设备对CPU的中断次数及放宽对CPU的中断响应时间要求。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

Archiver|手机版|小黑屋|DeepTimes.NET 太空游戏站