栈溢出

时间:2024-10-28 01:39:15编辑:流行君

栈溢出原理

栈溢出指的是程序向栈中某个变量中写入的字节数超过了这个变量本身所申请的字节数,因而导致与其相邻的栈中的变量的值被改变。这种问题是一种特定的缓冲区溢出漏洞,类似的还有堆溢出,bss 段溢出等溢出方式。栈溢出漏洞轻则可以使程序崩溃,重则可以使攻击者控制程序执行流程。此外,我们也不难发现,发生栈溢出的基本前提是. 最典型的栈溢出利用是覆盖程序的返回地址为攻击者所控制的地址,当然 需要确保这个地址所在的段具有可执行权限 。 这个程序的主要目的读取一个字符串,并将其输出。 我们希望可以控制程序执行 success 函数。 因为 gets 是一个非常危险的函数,它从不检查输入字符串的长度,以回车判断输入是否结束. gcc编译指令中, -m32 指的是生成32位程序, -fno-stack-protector 指的是不开启堆栈溢出保护,即不生成 canary。 -no-pie 避免加载基址被打乱. 2.IDA反编译 字符串s距离ebp的长度为0x14,所以栈结构s是 [外链图片转存失败(img-zPyIZk71-1564741311529)(../images/2018-12-10-16-30-04.png)] 而且我们可以可以获得 success 函数的返回地址为 08049192 所以我们输入的字符串就是 0x14*'a'+'bbbb'+success_addr .14个 a 覆盖了字符串数组,4个 b 覆盖ebp的地址,然后将 success 的地址覆盖到返回地址上. 通过交互成功实现了栈溢出

堆栈溢出一般是由什么原因导致的?

递归过程的局部变量过多、递归深度过大,是造成系统栈溢出的原因,特别是递归列循环时肯定会发生系统栈溢出。递归堆栈溢出的解决方案是尾部递归优化。事实上,尾部递归和循环具有相同的效果,所以可以把循环看作是一个特殊的尾部递归函数。尾部递归,当函数返回时调用自身,并且返回语句不能包含表达式。通过这种方式,编译器或解释器可以优化尾部递归,这样递归本身无论被调用多少次,都只占用一个堆栈帧,而不会出现堆栈溢出。扩展资料:针对堆栈溢出可能造成的计算机安全问题,通常有以下这些防范措施:1、强制代码遵循正确的规则。2、使操作系统无法执行缓冲区,从而防止攻击者植入攻击代码。但是,由于攻击者不必求助于嵌入代码,而且Linux使用可执行的堆栈属性来发出信号和在线重用GCC,这种方法仍然有一些弱点。3、利用编译器的边界检查实现缓冲区保护。这种方法使缓冲区溢出不可能发生,完全消除了缓冲区溢出的威胁,但是代价很高,比如性能较低。4、对程序指针完整性进行检查,该方法可以防止绝大多数的缓冲区溢出攻击。这意味着在程序使用指针之前检查指针的内容是否已更改。

如何解决栈溢出

解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。尾递归,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。扩展资料针对堆栈溢出可能造成的计算机安全问题,通常有以下这些防范措施:1、强制按照正确的规则写代码。2、通过操作系统使得缓冲区不可执行,从而阻止攻击者植入攻击代码。但由于攻击者并不一定要通过植入代码来实现攻击,同时linux在信号传递和GCC的在线重用都使用了可执行堆栈的属性,因此该方法依然有一定弱点。3、利用编译器的边界检查来实现缓冲区的保护。该方法使得缓冲区溢出不可能出现,完全消除了缓冲区溢出的威胁,但代价较大,如性能速度变慢。4、程序指针完整性检查,该方法能阻止绝大多数缓冲区溢出攻击。该方法就是说在程序使用指针之前,检查指针的内容是否发生了变化。参考资料来源:百度百科-堆栈溢出参考资料来源:百度百科-栈溢出

上一篇:春夜喜雨的作者

下一篇:没有了