越界使用数组更改eip(栈溢出)

先看源程序:

#include <stdio.h>
#include <unistd.h>

void bar(void)
{
	printf("Hello,World\n");
	_exit(0);
}

void foo(void)
{
	void *a[1];
	a[2]=(void *)bar;
}

int main()
{
	foo();
	return 0;
}
测试环境:centos32bit

输出结果:

这个程序的关键之处在于对数组a的越界处理,以前尝试从C代码角度来解释原因,一直没有得到答案。从汇编语言解释就很简单,我们直接看汇编代码:


foo函数中有一个变量a,或者说成是a[0]更合适,地址是ebp-4

这是屡一下栈中变量分布:

a[0]           a[1]          a[2]

ebp-4       ebp          ebp+4(eip)

ebp+4地址中存放的应该是main函数的return语句地址,我们却把bar函数地址替换了return语句地址,所以foo函数结束后,cpu本来要转到main中的return语句,由于foo越界访问数组更改了eip,cpu转向了bar,就出现了调用bar函数的现象。


在不同的测试环境下,可以通过修改数组a的类型,比如int;a的长度,越界的长度也要对应修改。就可以实现不走main中的return,而走bar函数。

猜你喜欢

转载自blog.csdn.net/singleyellow/article/details/78942952