1

私は以下のコードを持っています:

char buffer[10];      

void main(int argc, char *argv[]) {

   strcpy(buffer, argv[1]);
   printf("value of buffer %s\n",buffer);
}

main関数内にバッファ変数を配置すると、スタックがオーバーフローする可能性があることはわかっていますが、グローバル変数として宣言することで、コマンドラインから入力したASCII文字の数に関係なく、何も起こりません。セグメンテーション違反を予想していましたが、入力したすべての文字が印刷されているようです。どうして?

このトピックに関連する別の質問があります。プログラムにバッファオーバーフローの脆弱性がある場合、たとえばスタックオーバーフローの場合、脆弱な変数に必要な大きさのコードを入力できますか、またはコードがユーザープログラムに割り当てられたメモリの境界?

4

6 に答える 6

7

このコードは未定義の動作につながります。つまり、セグメンテーション違反は予想できません。何でも起れる。

于 2012-10-27T16:12:02.367 に答える
6

次の mod を試して、副作用を確認してください。

char buffer[10];      
char buffer1[10] = "123456789";      

void main(int argc, char *argv[]) {

   strcpy(buffer, argv[1]);
   printf("value of buffer %s\n",buffer);
   printf("value of buffer1 %s\n",buffer1);
}
于 2012-10-27T16:14:34.863 に答える
4

グローバル変数がオーバーフローしています。それが原因で (明らかに) 悪いことが起こらないだけです。コードを次のように変更してみてください。

char before[20];
char buffer[10];
char after[20];

bufferツールチェーンがメモリをどのようにレイアウトするかに応じて、beforeまたはでオーバーフローの結果を確認できるはずですafter

SEGV を取得できない具体的な理由は、格納しようとする場所が、オペレーティング システムがプロセスに割り当てたリージョンの外にある場合にのみ発生するためです。この割り当ては 4k ユニッ​​ト (通常) で行われ、通常はそれらのいくつかで行われるためglobal、SEGV をトリガーするには、おそらく少なくとも 4kB、おそらく 1MB 以上オーバーフローする必要があります。

于 2012-10-27T16:16:36.873 に答える
1

グローバル変数はスタックに格納されません。それらは .data/.bss に格納され、より高いアドレス空間に向かって成長します。スタック変数は、より低いアドレス空間に向かって大きくなります。プログラム命令は .data よりも (.text 内で) 下位に保持されるため、グローバルがオーバーフローしても上書きされません。

とにかくLinuxで。

于 2012-10-27T16:17:46.547 に答える
1

他の回答が説明しているように、言語仕様では、バッファ オーバーランに対する特定の反応を期待する権利はありません(グローバル変数であろうとローカル変数であろうと)。

実際には、使用するために予約されていないメモリの一部bufferが上書きされます。ただし、プログラムは の直後に終了するためprintf、そのメモリを使用していたものは何でも、そこにあるはずの値がもう存在しないことに気付く機会がない可能性があります。たとえば、書き込み可能なデータ セグメントのサイズを 4096 の倍数またはその他の便利なブロック サイズに切り上げている場合など、リンカが の後に未使用の領域を割り当てた可能性もあります。buffer

于 2012-10-27T16:18:58.237 に答える
1

次の例のように、より大きな入力バッファで試してください。

 ./tst $(perl -e "print 'A'x10000")

そして、おそらくセグメンテーション違反に陥るでしょう。

過去の回答で述べたように、オブジェクトは未定義の動作であり、何でも起こり得ます。

また、C ではスタックやヒープについては言及しませんが、ファイル スコープの変数 (bufferプログラムなど) は通常、スタックに格納されません。

バッファがスタックにある場合、非常に高速に (つまり、非常に大きな入力を必要とせずに) バッファが関数の戻りアドレスをランダムなアドレスで上書きします。これが、関数が戻るときに segfault が発生する理由です。

于 2012-10-27T16:23:09.077 に答える