解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。
尾递归,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。
扩展资料
针对堆栈溢出可能造成的计算机安全问题,通常有以下这些防范措施:
1、强制按照正确的规则写代码。
2、通过 *** 作系统使得缓冲区不可执行,从而阻止攻击者植入攻击代码。但由于攻击者并不一定要通过植入代码来实现攻击,同时linux在信号传递和GCC的在线重用都使用了可执行堆栈的属性,因此该方法依然有一定弱点。
3、利用编译器的边界检查来实现缓冲区的保护。该方法使得缓冲区溢出不可能出现,完全消除了缓冲区溢出的威胁,但代价较大,如性能速度变慢。
4、程序指针完整性检查,该方法能阻止绝大多数缓冲区溢出攻击。该方法就是说在程序使用指针之前,检查指针的内容是否发生了变化。
参考资料来源:百度百科-堆栈溢出
参考资料来源:百度百科-栈溢出
栈溢出漏洞是由于使用了不安全的函数,如 C 中的 scanf, strcpy等,通过构造特定的数据使得栈溢出,从而导致程序的执行流程被控制。
要分析栈溢出漏洞,我们要先了解函数栈帧的结构。
在 C 函数中,每个函数都有一个栈帧,它用来保存这个函数的参数、局部变量、返回地址等信息,是系统栈的一部分。
假设有这样一个函数:
void foo(char *arg1, char *arg2) { int temp = 0char buffer[4]strcpy(buffer, arg1)}
这个函数的栈帧是这样的:
ESP 称为栈顶指针,用来指示当前栈帧的顶部
EBP 称为栈基址指针,用来指示当前栈帧的底部
在调用这个函数时,压栈的顺序为:
由于局部变量 buffer 的长度是 4 个字节,而在使用 strcpy 函数的时候并没有判断参数 arg1 的长度,因此,当传入的 arg1 的长度大于 4 个字节时,多出的字节将会依次覆盖掉局部变量 temp、调用者的 EBP、返回地址等。
通过精心构造 arg1 的值,就可以将返回地址覆盖为任意想要的值,以便于跳到 shellcode
可以将 shellcode 保存在 buffer 中,并将返回地址覆盖为 buffer 的起始地址,如图:
<br />
此外,我们可以采取相对移位的方法,如图:
在很多情况下,要精确定位 buffer 的起始位置是很难的,我们可以采用增大 “落点” 的面积的方式来增加命中的几率,具体做法是使用 nop 填充 buffer,如果落点在 nop,那么系统会一直往下执行直到遇到 shellcode
如果函数返回地址的偏移按 DWORD 不定,可以用一片连续的跳转指令地址来覆盖函数返回地址,如图:
在函数返回时,esp 总是指向返回地址的下一个位置,所以,我们可以通过覆盖多一些栈帧,将 shellcode 写到返回地址之后的位置,并通过跳板指令重新回到栈中,如图:
那么,到哪儿去找跳板指令呢?在早期的 Windows 版本的动态链接库中,存在大量的 jmp esp 指令,而这些库在内存中的地址是相对固定的,如Win2000、XP、Win2003 的 0x7ffa4512
<br />
参考资料:
x86函数调用堆栈的 *** 作
《0day安全 软件漏洞分析技术》
什么是栈溢出和堆溢出?所谓溢出广义上就是超出范围,整数就有溢出,比如8字节无符号整数是0到255
0 - 1就是下溢 255 + 1就是上溢
说正题
int f(int x)
{
int a[10]
a[唬1] = x
}
这个就是栈溢出,x被写到了不应该写的地方。在特定编译模式下,这个x的内容就会覆盖f原来的返回地址。也就是原本应该返回到调用位置的f函数,返回到了x指向的位置。一般情况下程序会就此崩溃。但是如果x被有意指向一段恶意代码,这段恶意代码就会被执行。
堆溢出相对比较复杂,因为各种环境堆的实现都不完全相同。但是程序管理堆必须有额外的数据来标记堆的各种信息。堆内存如果发生上面那样的赋值的话就有可能破坏堆的逻辑结构。进而修改原本无法访问的数据。
int f(char *s, int n)
{
char a[10]
memcpy(a, s, n)
...
}
这个是栈溢出比较真实一点的例子,如果传入的数据长度大于10就会造成溢出,进而改变f的返回地址。只要事先在特定地址写入恶意代码,代码就会被执行。
堆溢出执行恶意代码的一种情况是通过过长的数据破坏堆结构,使下次申请能得到保存某些特定函数指针的位置,然后进行修改。
栈和堆溢出的一个共性就是第三方可以完全依靠提供特定数据实现代码级别的入侵。玩游戏的话可能知道PSP3000的破解,利用的就是PSP系统显示tiff文件时候的一个溢出漏洞。tiff文件内包含一段入侵代码,载入tiff文件的时候这段代码也会被载入,只不过这个时候各奔不可能被执行。但是tiff中的一部分数据是超长的,并且超长的部分包含了入侵代码的位置。当系统读取这部分数据的时候入侵代码就会被执行。
堆栈溢出是什么意思
堆栈溢出就是不顾堆栈中分配的局部数据块大小,向该数据块写入了过多的数据,导致数据越界,结果覆盖了老的堆栈数礌。 或者解释为 在长字符串中嵌入一段代码,并将过程的返回地址覆盖为这段代码的地址,这样当过程返回时,程序就转而开始执行这段自编的代码了。
电脑屏幕上出现(堆栈溢出、位置:第37行)是什么意思
zhidao.baidu/...iST4BK
人家有人有详细解答
堆栈溢出一般是由什么原因导致的?
一般情况下,是读写数据超出来申的内存的范围。
堆栈溢出一般会报段错误
电脑跳出窗口显示堆栈溢出 第一行 是什么意思
常言所说的堆栈溢出,就是指栈溢出。使用 malloc()函数是动态分配内存堆区的空间,一般的程序如没用这个,就不存在堆溢出。栈溢出: 栈空间是预设的,它通常用于存放临时变量,如果你在函数内部定义一个局部变量,空间超出了设置的栈空间大小,就会溢出。不仅如此,如果函数嵌套太多,也会发生栈溢出,因为函数没有结束前,函数占用的变量也不被释放,占用了栈空间。解决办法:恰当的设置栈空间大小。分析代码,评估在哪个环节,使用的临时变量字节数最大,所设置的栈空间必须大于此。也可以将大的变量在全局进行定义,它就不占用栈区空间
请问:堆栈溢出是什么意思?怎么处理?
堆栈溢出就是不顾堆栈中分配的局骸数据块大小,向该数据块写入了过多的数据,导致数据越界,结果覆盖了老的堆栈数据。就是字写多了!
堆栈溢出是什么意思
*** 作系统在内存里分配给你这个程序进程的内存块满足不你的程序的请求了
1001 递归太深;堆栈溢出是什么意思
1001 递归是反复调用,用空间换时间,如果你递归次数太多,内存开销太大了,所以会报错 不ac这个题似乎不用递归就能做啊
堆栈溢出一般是由什么原因导致的?
没有回收垃圾资源。
堆栈溢出一般是由什么原因导致的
申请的内存不够,已经把申请的内存用完了,但还是一直往里放数据。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)