导致堆栈溢出并获得Segmentation fault
的一个明显方法是递归地将堆栈帧推到彼此之上,直到它蓬勃发展。我想知道是否会发生堆栈溢出,甚至不推送新的堆栈帧。
根据经验,创建一个足够大的数组也可以做到这一点,但还有其他可能的情况吗?
C99 使用可调整大小的数组,您可以使用该数组并将其大小调整为更大的数组。但是,这个可调整大小的数组是使用 alloca
实现的。下面是 UNIX 环境中的示例代码:
#include <stdio.h>
#include <alloca.h>
#include <stdlib.h>
#include <stdbool.h>
int
main()
{
while (true)
{
void *p = alloca(32UL);
printf("new memory allocated at %p n", p);
}
exit(EXIT_SUCCESS);
}
您的输出将如下所示
new memory allocated at 0xbf800a60
new memory allocated at 0xbf800a30
new memory allocated at 0xbf800a00
new memory allocated at 0xbf8009d0
new memory allocated at 0xbf8009a0
[1] 3977 segmentation fault ./a.out
alloca
属于malloc
系列函数,只不过它通过调整堆栈指针在堆栈上分配内存。
>滥用alloca()
或_alloca()
,如果你在Windows SDK/VS上开发:
alloca() 函数在 访客。
注意 _alloca()
现在已弃用,取而代之的是 _malloca()
。
从根本上说,"堆栈"只是一些内存,而堆栈溢出是指 ESP/EBP 超出此内存的范围。
您可以通过多种方式实现此目的:
- 创建一个大于剩余堆栈空间大小的巨大堆栈分配数组:
int x[10000000];
- 直接设置 ESP:
__asm mov esp, 0x0
- 损坏堆栈,因此当当前函数展开时,ESP/EBP 将被设置为垃圾:
int x; memset(&x, 0, 10000000);
还有无数其他方式...
通过声明和使用大于堆栈大小的数组:
$ ulimit -s
8192
$
然后
int main(void)
{
volatile char bla[8192 * 1024 + 16] = {0};
}
在执行时可能会出现段错误。