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



导致堆栈溢出并获得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 超出此内存的范围。

您可以通过多种方式实现此目的:

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

还有无数其他方式...

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

$ ulimit -s
8192
$

然后

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

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

相关内容

  • 没有找到相关文章

最新更新