GDB 错误“数组元素过多”

逆向工程 数据库 缓冲区溢出
2021-06-15 10:29:18

我试图了解非常基本的基于堆栈的缓冲区溢出我在 x86_64 Macbook Pro 上运行 Debian wheezy。

我有以下不安全的程序:

#include <stdlib.h>
#include <stdio.h>

CanNeverExecute()
{
        printf("I can never execute\n");
        exit(0);
}

GetInput()
{
        char buffer[512];

        gets(buffer);
        puts(buffer);
}

main()
{
        GetInput();

        return 0;
}

我编译-z execstack-fno-stack-protector用于我的测试。

我已经能够通过gdb启动程序,获取CanNeverExecute从未调用过函数的地址,并溢出缓冲区以用该地址替换返回地址。我被打印出来“我永远无法执行”,到目前为止,这很好。

现在我试图通过在堆栈中引入 shellcode 来利用这个缓冲区溢出。我目前正在尝试直接进入 gdb:中断GetInput函数,通过 gdb 设置缓冲区值并使用jump命令跳转到缓冲区地址

但是我在设置缓冲区时遇到了一个问题:我在gets函数之后有一个断点,我用512个a字符作为输入运行了程序

在 gdb 中,我这样做:

(gdb) p buffer
$1 = 'a' <repeats 512 times>

输入被读取没有任何问题,我的缓冲区是 512a 然后我尝试修改它的值。如果我这样做:

(gdb) set var buffer=""

并尝试打印缓冲区,它的长度现在是 511!怎么来的??

(gdb) p buffer
$2 = '\000' <repeats 511 times>et:

例如,当我尝试将其设置回 512 时a,我得到:

Too many array elements

不过我可以把它设置成511 a,真的是那个las字节不起作用...... 怎么会,有简单的解释吗?

1个回答

GDB 保护您溢出您的字符数组。

(gdb) p &buffer
$25 = (char (*)[512]) 0x7fffffffdfe0

要绕过此安全性,您可以直接写入内存:

(gdb) set 0x7fffffffe1e0=0x41414141

或者将数组转换为更大的数组,然后设置你的东西:

set {char [513]}buffer="512xA"