一.栈溢出原理背景知识
1.进程使用内存划分
代码区:二进制机器代码
数据区:存储全局变量等
堆 区:进程可在堆区动态的请求一定大小的内存,并在用完后归还堆区。动态分配和回收是堆的特点。
栈 区:动态存储函数调用关系,以保证被调用函数返回时恢复到母函数中继续执行。
2.两个与栈息息相关的寄存器ESP,EBP
ESP:栈顶指针。指向当前栈帧栈顶。
EBP:栈基址寄存器。指向当前栈帧底部(当前函数,而不是系统栈)
3.栈帧中存些什么
本函数的局部变量。、
前一个函数的栈帧(caller funcation),用来回复栈位置。
函数返回地址。以便函数返回时能够恢复到被调用前的代码区的位置。
4.函数调用大致步骤
压参数:从右向左压栈 汇编指令: push n
返回地址入栈:将当前指令
下一条指令地址压栈 push 1
代码区跳转 call 函数地址
栈帧调整:保存当前栈帧(ESP入栈) push ebp
切换栈帧 mov ebp,esp
分配栈帧 sub esp,xxxx
5.函数返回的大致步骤
返回返回值:通常将函数返回值保存在EAX中。
弹出当前栈帧,恢复上一个栈帧。具体步骤:在堆栈平衡的基础上,给ESP加上栈帧的大小,降低栈顶,回收当前栈帧的空间。 add esp,xxx
将当前栈帧底部保存的前栈帧EBP值弹入EBP pop ebp
将函数返回地址弹给EIP retn
二.栈溢出技术
1.修改邻接变量的原理
函数的局部变量在栈中是一个挨着一个排列,如果局部变量中存在数组之类的缓冲区,并且程序中还存在数组越界缺陷,那么越界的数据会破坏栈中其他数据。
参考书目:《0day安全:软件漏洞分析技术》
《逆向工程核心原理》
csdn博客