1,检查变量是否被改写
通过变量前后各插入一个字长的缓冲带(32bit的字长是4byte,64bit的字长是8byte),并且这个缓冲区均用0xCC填充(即 汇编指令的int 3)。
检查时机1:当对变量进行访问时,会检查这两个缓冲带。
检查时机2:函数返回时,进行栈检查。
只要缓冲带有任何一个字节不是0xCC,那就是变量被改写了。
2,char buff[100]溢出
首先按照普通变量的方式,在这个buff首位加上一段缓冲区(缓冲区具体大小由编译器决定),接着还是用0xCC填充。
并对这个buff的地址、大小、变量名,插入到一个错误检查链表。在函数返回时,会对这个链表进行检查。主要检查的还是这个buff的两侧缓冲带是否均被0xCC填充。
3,栈指针(EBP),栈顶(ESP)
有几种方式会导致EBP和ESP被改写:
第一种:如果通过溢出攻击的方式,会函数返回时的返回地址在栈上被改写。这就可能间接导致栈在函数进入前和退出后的关键状态不一致(EBP、ESP、前一栈帧的函数返回地址不正确等)。
第二种:栈出现与其增长的反方向溢出时,如栈是向上增长的,如果出现下溢时,可能会出现EBP指向的栈空间内容被改写,进而导致函数返回时ESP和EBP之前存储值不一致。
因此需要做一个安全cookie,这个cookie本质是一个随机数和ebp异或得到的。当要进行校验时,再异或一次就可以得到原先的ebp的值。
在vc8里面cookie有两个,一个是esp或ebp 和 随机数 异或得到的,另一个是 esp或ebp 和随机数的取反异或得到的。
4,对esp的针对性检查
函数返回时和ebp指向的帧地址进行比较。