2011-07-09 5 views
2

私はバッファオーバーフローで悩んでいますが、Mac OSで次の単純なCプログラムを実行しているときに私が探しているものが混乱しています。 2バイトにBUFの長さを設定することにより期待通りにセグメンテーション違反が発生しない

#include <stdio.h> 

int main(void) { 

     char buf[2]; 

     scanf("%s", buf); 

     printf("%s\n", buf); 

} 

、私は、文字列「CCC」を入力するときにセグメンテーションフォールトを引き起こすことが予想されるが、それは起こりません。長さが24文字の文字列を入力する場合のみ、セグメント化エラーが発生します。

何が起こっているのですか?文字エンコーディングとは何か?

ありがとうございました。

答えて

5

バッファオーバーフローを起こすと、プログラムの動作は未定義です。何でも起れる。それを予測することはできません。

バッファの後にコード実行に重要ではないパディングバイトが存在する場合もあれば、そうでない場合もあります。あなたはそれに頼ることはできません。 32ビットと64ビットでコンパイルされた別のコンパイラは、そのオーバーフローの後にコードの実行を変更する可能性があるすべての設定をデバッグします。

+0

です。私はペニーが落ちたと思う。悪意のある攻撃者は、スタックの残りの部分をオーバーフローさせ、結果的にレジスタを上書きすることを目指すでしょうか?しかし、彼らはスタックの残りの部分をどのように予測しますか? OSは毎回固定量のメモリを割り当てますか? –

+0

アセンブリの出力を見ると、試行錯誤は "残りのスタック"を決定する最も良い方法です。 _same環境内の_sameバイナリの実行では同じままになる可能性はありますが、保証はありません。バッファオーバーフローはレジスタを上書きしません。スタックまたはヒープを上書きします。 – Mat

+0

@Martin典型的な考え方は、スタック上にあるバッファをオーバーフローさせて、スタック上のデータを上書きすることです。これは、関数から戻るとCPUがどこに戻るかを示します。詳細は、「スタックを壊す」を参照してください。 –

1

推測これはメモリレイアウトに関連しています。あなたが上書きしているものがあなたのプロセス(ページwritableにマップされている)にアクセスできる場合、OSはあなたが何か「間違っている」ことを見ているチャンスを持っていません。

実際、このようなことをするときは、Cプログラマーの目から「それはまったく間違っています!しかし、OSの視点からは、「OK、彼はいくつかのページに書き込んでいます。ページは適切な権限でマップされていますか?

1

セグメンテーション違反がまったく発生しないという保証はありません。 char buf[2]を上書きした後にデータが増えると、セグメンテーション違反が発生する場合もありません。

1

bufがスタックに割り当てられているため、使用されていない領域を上書きするだけで、誰もそれに不平を言うことはありません。いくつかのプラットフォームでは、あなたのコードは段落全体を受け入れます。

2

bufがスタックしています。上書きを開始すると、そこに割り当てられているもの(たとえば、コンパイラによって作成されたレジスタのスピルスロット)に応じて、OSがキャッチしないプログラムに属するスタックを上書きし始めます。割り当てられたスタック境界を越えると、OSはセグメンテーションを発生させる可能性があります。

関連する問題