由于编程错误,我们会出现分段错误。但作为一个必要的工具,我们尝试了同样的事情,但内核检测到它破坏了堆栈。内核究竟是如何看待差异的?
简而言之,没有。分段错误是指内核能够检测到无效的内存访问,然后终止进程。内核无法检测到一些无效的内存访问,堆栈溢出就是建立在这些访问之上的。然而,编译器可以检测到堆栈溢出,并且是最新版本的gcc(4.1+),该版本具有内置的防堆栈破坏攻击保护。基本上,在堆栈帧之间的堆栈上放置一个"金丝雀"值。有一些检查可以确保金丝雀仍然具有正确的值;如果没有(因为它被覆盖了,而且覆盖器无法猜测正确的值),那么堆栈粉碎保护例程就会执行。有关详细信息,请参阅:http://en.wikipedia.org/wiki/Buffer_overflow_protection#GCC_Stack-Smashing_Protector_.28ProPolice.29和http://wiki.osdev.org/GCC_Stack_Smashing_Protector
您可以使用"-fno堆栈保护器"禁用gcc保护,有关更多信息,请参阅:堆栈粉碎代码不适用于Linux内核2.6.38.7…请帮助
相反,分段错误只是程序中任何地方发生的无效内存访问,这意味着内核检测到对不在程序允许内存区域内的内存的访问。AFAIK这是使用x86段和虚拟内存的组合进行检查的。内核/操作系统没有真正的方法来知道访问是在原始程序代码中还是在某种程度上被利用了;无论哪种方式,程序都试图访问它无法访问的内存,因此它被强制终止。
Isnt分段错误与砸碎堆栈相同?
否,分段故障是指操作系统检测到无效内存访问并终止进程。破坏堆栈是指覆盖(返回)堆栈上的地址的行为,通常是通过溢出本地声明的数组。
当你(作为攻击者)破坏堆栈时,你的目标是让进程执行你选择的代码。你想避免分段错误,因为它们会扼杀你试图接管的过程。
由于编程错误,我们会出现分段错误。
是的,有些错误会导致分段错误。其他错误没有任何作用,或者只是导致错误的结果(例如攻击者成功利用缓冲区溢出并使程序运行完全不同的代码)。
但作为一个必要的工具,我们尝试了同样的事情,但内核检测到它破坏了堆栈。
我不知道你刚才说了什么,但内核没有检测到"破坏堆栈"。
内核究竟是如何看待差异的?
什么区别?