10

-fstack-protector-stronggcc にはスタック破壊を検出するオプションがあるためです。ただし、常にスタック バッファ オーバーフローを検出できるとは限りません。最初の関数 func では、さらに 10 文字の文字列を入力すると、プログラムが常にクラッシュするわけではありません。私の質問は、スタック バッファ オーバーフローを検出する方法がある場所です。

void func()
{
    char array[10];
    gets(array);
}

void func2()
{
    char buffer[10];
    int n = sprintf(buffer, "%s", "abcdefghpapeas");
    printf("aaaa [%d], [%s]\n", n, buffer);
}

int main ()
{
   func();
   func2();
}
4

4 に答える 4

8

スタック上のオーバーフローは、検出が難しいか、検出に非常にコストがかかります。毒を選択してください。

一言で言えば、あなたがこれを持っているとき:

 char a,b;
 char *ptr=&a;
 ptr[1] = 0;

これは技術的に合法です。関数に属するスタックに割り当てられたスペースがあります。ただとても危険です。

したがって、解決策は、 と の間にギャップを追加し、aそれbをパターンで埋めることです。しかし、まあ、実際に上記のようにコードを書く人もいます。したがって、コンパイラはそれを検出する必要があります。

または、コードが実際に割り当てたすべてのバイトのビットマップを作成し、すべてのコードをインストルメント化して、このマップに対してチェックすることもできます。非常に安全ですが、かなり遅く、メモリ使用量が増えます。良い面としては、これを支援するツールがあります ( Valgrindなど)。

私がどこに行くのか分かりますか?

結論: C では、多くの場合メモリの問題を自動的に検出する良い方法はありません。これは、言語と API があまりにも雑すぎることが多いためです。解決策は、コードをヘルパー関数に移動して、パラメーターを厳密にチェックし、常に正しいことを確認し、単体テストの範囲を広くすることです。

snprintf()選択肢がある場合は、常に関数のバージョンを使用してください。古いコードが安全でないバージョンを使用している場合は、変更してください。

于 2013-09-30T11:49:11.893 に答える
2

Valgrindというツールを使用できます

http://valgrind.org/

于 2013-09-30T11:48:28.903 に答える
0

まず第一に、使用しないでくださいgets。今ではほとんどの人が、 で発生する可能性のあるセキュリティと信頼性の問題をすべて知っていますgets。しかし、歴史的な理由からもここに含まれています。これは、悪いプログラミングの非常に良い例だからです。

コードのすべての問題を見てみましょう。

// Really bad code
char line[100];
gets(line);

gets100 文字を超える文字列の境界チェックを行わないため、メモリが上書きされます。運が良ければ、プログラムがクラッシュするか、奇妙な動作を示す可能性があります。

このgets関数は非常に悪いため、GNU gcc リンカは使用されるたびに警告を発します。

/tmp/ccI5WJ5m.o(.text+0x24): In function `main':
: warning: the `gets' function is dangerous and should not be used.

assert で配列アクセスを保護する

C/C++ は境界チェックを行いません。

例えば:

int data[10]

i = 20
data[20] = 100 //Memory Corruption

assert上記のコードの関数を使用します

#include<assert.h>


int data[10];
i=20

assert((i >= 0) && (i < sizeof(data) / sizeof(data[0]))); // throws 

data[i] = 100

配列のオーバーフローは、最も一般的なプログラミング エラーの 1 つであり、見つけようとするのは非常に面倒です。このコードはそれらを排除するものではありませんが、問題を非常に見つけやすくする方法で、バグのあるコードを早期に中止させます。

そしてsnprintf(buffer, sizeof(buffer), "%s", "abcdefghpapeas")、valgrind や GDB などのツールを使用します。

これがあなたに役立つことを願っています..

于 2014-09-12T15:55:37.487 に答える