0
点赞
收藏
分享

微信扫一扫

缓冲区溢出(栈溢出)

落花时节又逢君to 2022-04-15 阅读 89

栈溢出(缓冲区溢出)

堆栈:

​ 堆栈是一个特定的存储器或寄存器,其本质就是存储数据的内存。在实际应用中,堆栈会用于存储临时变函数调用、中断切换时保存和恢复现场数据

在这里插入图片描述

​ 如图所示,堆栈就是内存中的某一片区域,每一个堆栈的内存单元都有唯一一个物理地址,且内存单元的大小都统一是4个字节大小。

​ 栈溢出就是发生在这样一个存储区域中。在了解了发生溢出的环境之后,了解溢出就相当于了解了一半了,另一半原因与使用的call指令有关。

Call指令:

​ call指令通常用于调用函数。用下面的例子理解。

cpu执行的程序

在这里插入图片描述

对应的堆栈变化

在这里插入图片描述

​ 之后cpu就会在堆栈中开辟出一段存储空间用于调用函数、存储临时变量。这里不细说。

函数调用时对堆栈的使用(图中用CCCCCCCC填充的内存单元就是缓冲区,存放局部变量就是在这里)

在这里插入图片描述

函数调用完后对堆栈的处理

在这里插入图片描述

​ 讲完call的特点和函数调用,现在就把栈溢出所需了解的知识点都知道了。

栈溢出(缓冲区溢出):

​ 在了解完堆栈结构和call指令后,我们可以清楚的知道如果我们在调用一个函数时传入一个数据,如果这个数据大小超过我们所分配的缓冲区大小,那么就会造成缓冲区溢出。

堆栈图可以帮助我们更好的理解溢出的发生。

在这里插入图片描述

​ 图中左边的堆栈可以看到给我们所分配的存储局部变量的位置是[ebp-14h]至[ebp-4]这个范围中,但是当我们输入的数据超过这个范围之后,多余的数据就被安排到了[ebp-adr]这个堆栈单元中了。[ebp-adr]这个单元中存放的是我们的返回地址(call语句的下一条语句的地址)。

缓冲区溢出的危害

​ 缓冲区溢出最基本的影响就是会造成系统报错,更大的危害是利用缓冲区溢出执行非程序本身的操作。

缓冲区的利用方法

  • 普通的数据传入:通过传入大量的数据造成溢出。(就像上面的图)
  • 数组越界:通过往超过数组空间大小的位置传入数据,可以指定修改堆栈中的数据。
#include "stdafx.h"//版本:vc 6.0

void HelloWorld(){
	printf("HelloWorld");
	getchar();
}

void Fun(){
	int arr[5]={1,2,3,4,5};
	arr[6]=(int)HelloWorld;
}

int main(int argc, char* argv[])
{
	Fun();
	return 0;
}

​ 这串代码就是用到了数组越界的方法。我们声明的数组大小为五,所以在堆栈中分配的五个堆栈内存单元,但是我们向下标为六的数组空间中存入我们Hello World函数的地址,这就造成了越界。

在这里插入图片描述

​ 当程序开始开始通过返回地址返回时,就会跳转到Hello World函数处,而Hello World函数并没有返回到主函数的返回地址,所以就会造成报错。

防止缓冲区溢出的方法—GS

在这里插入图片描述

​ 防止缓冲区溢出和数组越界的方法还有很多,以上也仅是缓冲区溢出的基本知识。

举报

相关推荐

0 条评论