C Buffer Overflow - Why is there a constant number

2019-05-18 12:02发布

问题:

I was experimenting with buffer overflow in C, and found an interesting quirk:

For any given array size, there seems to be a set number of overflow bytes that can be written to memory before a SIGABRT crash. For example, in the code below the 10 byte array can be overflowed to 26 bytes before crashing at 27. Similarly, an array of 20 chars can be overflowed to 40 chars before it aborts on the 41st.

Can anyone explain why this is? Also, is the SIGABRT the same as (or caused by) a "segmentation fault"?

Mac OS 10.8 - Xcode 4.6, clang and lldb. Thanks!

#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;
}

EDIT - I've stepped through it in disassembly and found this protection just after the for-loop:

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

回答1:

That is due to the alignment of the stack on mac os.

It is not big news, if you have googled it, you would find the answer:

Why does the Mac ABI require 16-byte stack alignment for x86-32?


It is nice to see you can actually write to the stack with no side affect in chunks little than 16 bytes.

If you exploit it several times you can get into a state where all your malicious code can be lay down and you may execute it in jumps on the stack.