2

C でバッファ オーバーフローを実験していたところ、興味深い癖が見つかりました。

任意の配列サイズに対して、SIGABRT がクラッシュする前にメモリに書き込むことができるオーバーフロー バイト数が設定されているようです。たとえば、以下のコードでは、10 バイトの配列が 27 でクラッシュする前に 26 バイトにオーバーフローするchar可能性がありますchar

これがなぜなのか説明できる人はいますか?また、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
4

1 に答える 1

3

macこれは、 OS上のスタックの配置によるものです。

これは大したニュースではありません。ググれば答えが見つかります。

Mac ABI が x86-32 に対して 16 バイトのスタック アラインメントを必要とするのはなぜですか?


16 バイト未満のチャンクで副作用なしで実際にスタックに書き込むことができるのは素晴らしいことです。

これを何度か悪用すると、すべての悪意のあるコードを配置できる状態になり、スタック上でジャンプして実行する可能性があります。

于 2013-02-23T08:37:14.910 に答える