显然,导致堆栈溢出并获得 Segmentation fault
的一种明显方法是递归地将堆栈帧推到彼此之上,直到崩溃。我想知道是否可以在不压入新的堆栈帧的情况下发生堆栈溢出。
从经验上讲,创建足够大的数组也可能导致堆栈溢出,但还有其他可能的情况吗?
显然,导致堆栈溢出并获得 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
函数族,不同之处在于它通过调整堆栈指针来分配堆栈内存。
$ ulimit -s
8192
$
那么
int main(void)
{
volatile char bla[8192 * 1024 + 16] = {0};
}
执行时很可能发生段错误。
volatile
关键字。如果您使用printf
打印所有元素的for
循环,则不需要volatile
限定符,因为编译器无法将其优化掉。 - ouah如果您正在使用Windows SDK / VS进行开发,请滥用alloca()
或_alloca()
:
alloca()
函数在调用者的堆栈帧中分配大小为size字节的空间。
请注意,_alloca()
现已弃用,推荐使用_malloca()
。
从根本上讲,“堆栈”只是一些内存,当ESP / EBP超出此内存的边界时,就会发生堆栈溢出。
您可以通过多种方式实现此目标:
int x[10000000];
__asm mov esp, 0x0
int x; memset(&x, 0, 10000000);
还有无数其他方法...