1 引言
缓冲区溢出是C/C++语言种常见的一种攻击手段,主要是利用了C/C++语言中缺少对数组边界的检查机制。典型的一段代码如下所示:
#include <stdio.h>
#include <string.h>
#define N 256
#define n 16
void foo(char *str){
char buf[n];
buf[0] = 'a';
strcpy(buf, str);
return;
}
int main(){
int idx;
char str1[N];
char str2[n];
for(idx=0; idx<N; idx++)
str1[idx] = 'b';
foo(str1);
return 0;
}
库函数strcpy负责把字符串str复制到buf中,但是因为缺乏字符串边界检查,而buf的长度为16,str的长度为256,把str的内容复制到buf中,必然会覆盖栈中某些数据,其中就有可能把函数的返回地址覆盖了。下图中是x86运行时候的栈帧结构虚线之上表示前一个栈的栈帧,虚线下面表示当前栈的栈帧。堆栈的生长方向通常是向下增长(地址减少),而堆栈中数组的增长方向是向上增长。所以当向buff中写入越界的数据时,会首先覆盖帧指针,然后覆盖返回地址。攻击者就能够通过利用此种攻击,改变程序的返回地址,把程序返回到一段恶意的代码区域,从而进行攻击活动,包括非法获得某些权限、窃取信息等。