C缓冲区溢出-为什么有恒定数量的字节会触发segfault?(Mac OS 10.8 64位,clang)



我在C中尝试缓冲区溢出,发现了一个有趣的怪癖:

对于任何给定的数组大小,在SIGABRT崩溃之前,似乎都有一定数量的溢出字节可以写入内存。例如,在下面的代码中,10字节数组可以溢出到26字节,然后在27处崩溃。类似地,一个由20个char s组成的数组在第41个中止之前可以溢出到40个char s。

有人能解释为什么会这样吗?此外,SIGABRT是否与"分段故障"相同(或由其引起)?

Mac OS 10.8-Xcode 4.6,clang和lldb。谢谢

#include <stdio.h>
int main(int argc, const char * argv[])
{
  char aString[ 10 ];
  char aLetter = 'a';
  printf("The size of one array slot sizeof( aString[0] ) is %zun", sizeof(aString[0]));
  printf("The size of one letter     sizeof( aLetter )    is %zun", sizeof(aLetter));
  // Overflow the aString array of chars
  // lldb claims aString is initialized with values  or NULL at all locations
  // Substitute i<27 and this code will crash regularly
  for (int i=0; i<26; i++) {
    aString[i]= aLetter;
  }
return 0;
}

编辑-我在反汇编中完成了它,并在for循环后发现了这种保护:

0x100000f27:  movq   226(%rip), %rax           ; (void *)0x00007fff793f24b0: __stack_chk_guard
0x100000f2e:  movq   (%rax), %rax
0x100000f31:  movq   -8(%rbp), %rcx
0x100000f35:  cmpq   %rcx, %rax
0x100000f38:  jne    0x100000f49               ; main + 121 at main.c:26
.
.
.
0x100000f49:  callq  0x100000f4e               ; symbol stub for: __stack_chk_fail

这是由于mac操作系统上的堆栈对齐。

这不是什么大新闻,如果你在谷歌上搜索过,你会发现答案:

为什么Mac ABI需要x86-32的16字节堆栈对齐?


很高兴看到您可以在小于16字节的块中毫无副作用地写入堆栈。

如果你多次利用它,你可能会进入一种状态,所有的恶意代码都可能被搁置,你可能在堆栈上跳转执行它。

相关内容

  • 没有找到相关文章

最新更新