我在 C 中试验缓冲区溢出,发现了一个有趣的怪癖:
对于任何给定的数组大小,似乎有一定数量的溢出字节可以在 SIGABRT 崩溃之前写入内存。例如,在下面的代码中,10 字节数组可以溢出到 26 字节,然后在 27 处崩溃。类似地,一个 20char
秒的数组可以char
在 41 号中止之前溢出到 40 秒。
谁能解释这是为什么?此外,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 %zu\n", sizeof(aString[0]));
printf("The size of one letter sizeof( aLetter ) is %zu\n", sizeof(aLetter));
// Overflow the aString array of chars
// lldb claims aString is initialized with values \0 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