在微软vs系列开发工具,可以开启 “Security Check” 选项,检查栈溢出,在gcc编译器应该也有类似的功能。

栈的结构

栈空间的起止位置由ebp和esp寄存器,栈上存有当前函数的参数,返回地址,函数的局部变量。每次调用函数,都会向栈中依次压入参数,返回地址,进入函数后,会预留出函数使用的局部变量的大小。

栈溢出的危害

最大的危害会破坏函数的返回地址,“精心的破坏”会让你的函数跳入一个攻击者制定的函数,也就是新闻里常说的“执行任意代码”。

防范

vs的Security Check和GCC的堆栈保护机制差不多,都是在返回地址和局部变量插入一个哨兵,由编译器自动插入代码,在函数开始时赋值一个特殊的值,函数退出时检查这个值是否被改变,如果改变了就是栈被破坏了。

GCC中的堆栈保护机制

gcc 4.9新加入的参数 -fstack-protector-strong

编译器会自动调整局部变量在内存中的顺序,使char数组排在靠近返回地址。