在微软vs系列开发工具,可以开启 “Security Check” 选项,检查栈溢出,在gcc编译器应该也有类似的功能。
栈的结构
栈空间的起止位置由ebp和esp寄存器,栈上存有当前函数的参数,返回地址,函数的局部变量。每次调用函数,都会向栈中依次压入参数,返回地址,进入函数后,会预留出函数使用的局部变量的大小。
栈溢出的危害
最大的危害会破坏函数的返回地址,“精心的破坏”会让你的函数跳入一个攻击者制定的函数,也就是新闻里常说的“执行任意代码”。
防范
vs的Security Check和GCC的堆栈保护机制差不多,都是在返回地址和局部变量插入一个哨兵,由编译器自动插入代码,在函数开始时赋值一个特殊的值,函数退出时检查这个值是否被改变,如果改变了就是栈被破坏了。
GCC中的堆栈保护机制
gcc 4.9新加入的参数 -fstack-protector-strong
编译器会自动调整局部变量在内存中的顺序,使char数组排在靠近返回地址。