C中自发的缓冲区溢出

丹尼尔


我想知道是否有可能以编程方式生成缓冲区溢出,我的意思是,没有任何用户输入。

我一直在尝试使用该memcpy函数导致缓冲区溢出,将缓冲区的内容复制到另一个较小的缓冲区中。现在,分段错误仅在源缓冲区初始化时触发,如下所示:

char * overflow = "\x40\40\x40...";

要么:

char * overflow = {"\x40\40\x40..."};

如果我将此缓冲区复制到另一个较小的变量中,它会成功溢出它。但是这种声明使源缓冲区成为只读的,所以我想知道是否可以动态生成缓冲区的内容,例如,程序可以在运行时生成一个缓冲区,该缓冲区可以将指令指针重定向到某些也在运行时计算的内存地址。所以我尝试将其更改为:

char overflow[] = {"\x40\x40\x40\x40..."}

但是,无论缓冲区有多长,此声明都不会由于某种我不太了解的原因触发分段错误。

为什么只读常量字符串可以触发缓冲区溢出,而变量不能?

这是我正在使用的代码:

int WINAPI mainCRTStartup(){
  char buffer[100];
  char * overflow = {   "\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
    "\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
    "\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
    "\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
    "\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
    "\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x64\x63\x62\x61\x40\x40\x40\x40"
    "\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
    "\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
    "\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
    "\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40"
  };

  printf("Ready:\n");
  // 117
  memcpy(buffer, overflow, 117);
  //strcpy(buffer, overflow);
  printf("String: %s\n", buffer);
  return 0;
}

我编译它:

i686-w64-mingw32-gcc -O2 -s -DNDEBUG -static \
    -nostdlib -m32 \
    -o deleteme.exe deleteme.c \
    -lkernel32 -lmsvcrt -fno-stack-protector

此代码成功地将指令指针设置为地址 0x61626364。
我知道这可能没有任何实际用途,我只是对这种行为感到好奇。

巴马

当您使用 时char overflow[]overflow数组的内存与位于同一堆栈帧中buffer,并且它可能就在它之后。因此,当您超出 的边界时buffer,您将写回overflow,而不是覆盖堆栈帧中的返回地址字段。

制作它static char overflow[],或制作overflow一个全局变量。那么它就不会在堆栈帧中。您也可以尝试更改两个变量声明的顺序。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章