如何在不推送新堆栈帧的情况下溢出堆栈?

时间:2012-04-11 09:06:49

标签: c segmentation-fault stack-overflow

导致堆栈溢出并获得Segmentation fault的一种显而易见的方法是递归地将堆栈帧推到彼此之上,直到它激增。我想知道堆栈溢出是否可能在没有推送新堆栈帧的情况下发生。

创建一个足够大的数组也可以从经验,但任何其他可能的场景吗?

4 个答案:

答案 0 :(得分:3)

C99使用可调整大小的数组,您可以使用它并将其大小调整为较大的数组。但是,这个可调整大小的数组是使用alloca实现的。以下是 UNIX env

中的示例代码
#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函数族中,除了它通过调整堆栈指针在堆栈上分配内存。

答案 1 :(得分:1)

如果您在Windows SDK / VS上进行开发,请滥用alloca()_alloca()

  

alloca()函数在堆栈帧中分配空间的大小字节   呼叫者。

注意{I}现已弃用_alloca()

答案 2 :(得分:1)

从根本上说,“堆栈”只是一些内存,而堆栈溢出是ESP / EBP超出此内存的范围。

您可以通过多种方式实现这一目标:

  1. 创建一个巨大的堆栈分配数组,该数组大于剩余堆栈空间的大小:int x[10000000];
  2. 直接设置ESP:__asm mov esp, 0x0
  3. 损坏堆栈,以便当前函数展开时,ESP / EBP将设置为垃圾:int x; memset(&x, 0, 10000000);
  4. 无数其他方式......

答案 3 :(得分:1)

通过声明并使用大于堆栈大小的数组:

$ ulimit -s
8192
$

然后

int main(void)
{
    volatile char bla[8192 * 1024 + 16] = {0};
}

在执行时可能会出现段错误。