GS保护检测栈溢出,在函数调用时向栈帧中压入一个额外的随机DWORD,就是常见的逆向代码中的Security Cookie.
Security Cookie 位于EBP之前,系统还将在.data的内存区域中存放一个Security Cookie的副本。
系统比较栈帧中原先存放的Security Cookie和.data中的副本的值是否一致。来判定栈是否被破坏。
当检测到栈中发生溢出时,系统将进入异常处理流程。函数不会被正常返回。ret指令也不会被执行。系统以.data节的第一个双字节作为原始Cookie,所用的函数Cookie都是通过此DWORD生成,程序每次运行时原始Cookie都不同,在栈帧初始化后系统用EBP异或原始Cookie,作为当前函数的COokie.增加不同的函数Cookie随机性。函数返回前在异或回去。
若统一将函数都GS保护,GS操作将大大影响系统性能,因此在设计时部分情况不会用GS,因此对绕过GS就有了可乘之机。
下面几种情况编译器不会应用GS.
1.函数不包含缓冲区。
2.函数被定义为具有变量参数列表。
3.函数使用无保护的关键字标记。
4.函数第一个语句中包含内嵌汇编代码。
5.缓冲区不是8字节类型且大小不大于4个字节。
Visual Studio 2005后加入变量重排技术。编译时将局部变量类型对变量在栈帧中毒的位置进行调整。将字符串变量移动到栈帧的高地址。防止在字符串溢出对其他局部变量的破环。同时将指针参数和字符串参数复制到内存中低地址。防止函数参数被破坏。
程序员可对特殊的不符合GS保护条件的函数添加GS保护。通过#pragram strict_gs_check(on)添加Security Cookie.
#pragram strict_gs_check(on)//为此函数强制启用GS
int sometingFunc(char * str)
{
char arry[4]; //缓冲区太小。
strcpy(arry,str);
return 1;
}
vs2017中的启用编译器启用GS保护。