15

gcc はバッファ オーバーフロー攻撃を防ぐためにメモリ割り当てをインテリジェントに行いますか?

int function(char *str) {
    int a = 0;                 // See the
    char b[16] = "abcd";       // changes here

    if(!strcmp(b, str))
        a = 1;

    return a;
}

int function(char *str) {
    char b[16] = "abcd";       // See the
    int a = 0;                 // changes here

    if(!strcmp(b, str))
        a = 1;

    return a;
}

gdb でデバッグすると、メモリは常に最初に整数変数に割り当てられ、次に文字配列に割り当てられます。変数宣言の順序は関係ありません。つまり、上記の両方のケースで、コンパイラはメモリを最初に に割り当てa、次に に割り当てますb

(higher address)
  Memory
|        |
|        |
+--------+
|        |
|        |
|        |
|        |
+--------+ <----- b (16 bytes)
|        |
+--------+ <----- a (4 bytes)
|        |
(lower address)

そのため、 に 16 文字を超える文字を指定しstrても、 の値には影響しませんa。誰か助けてくれませんか?

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

4

3 に答える 3

11

はい、-fstack-protectorフラグを指定して実行する場合。

フラグを指定して実行すると、GCC はスタック カナリアを追加し、配列変数をスタック フレームの最上部に並べ替えて、オーバーフローや他の変数の破損をより困難にし、関数引数のコピーを作成して他のローカル変数と共に保存します。

詳細については、バッファ オーバーフロー保護に関するウィキペディアのページProPoliceのホームページを参照してください。

于 2013-03-19T09:20:48.517 に答える
2

GCCにバッファオーバーフローから保護するような機能がある場合でも、固定変数宣言の順序を引き起こす可能性のある他の多くの考慮事項がここにあります。宣言が行われることがそれほど重要ではない場合、コンパイラーは、実行時に変数がいつどのように使用されるかに基づいて割り当てを決定します。

最も重要なことは、コンパイラーが可能な限り最良の配置を念頭に置いて、スタックフレームに変数を割り当てることです。これは、CPUと最適化設定に応じて、まったく異なる方法で行うことができます。速度を最適化すると、メモリ消費を最適化する場合と比較して、完全に異なる割り当てが得られる場合があります。そして、ほとんどの場合、CPUレジスタにいくつかの変数を配置し、RAM割り当ての必要性全体を削除します。

だからあなたの質問に答えるために:GCCはコンパイラのポートに応じてさまざまな方法で変数を割り当てます。それがどのように行われるかは、プログラマーが過度に心配する必要があるものではありません。バッファオーバーフロー攻撃から保護するためにスタックを再配置するオプションがあるかもしれませんが、それは一部のタイプのアプリケーションでのみ意味があります。私たちが知っている限り、特定のシステムへの入力すら存在しない可能性があります。したがって、コンパイラがこのセキュリティ機能をデフォルトで有効にすることは意味がありません。

于 2013-03-19T11:43:40.777 に答える
-1

gcc はバッファ オーバーフロー攻撃を防ぐためにメモリ割り当てをインテリジェントに行いますか?

いいえ、そうではありません。常に可能であるとは限らない境界チェックなしでは、攻撃やバッファ オーバーフローを防ぐことはできません。事後にオーバーフローを検出できる場合もあります。

せいぜい、コンパイラは追加情報 (いわゆるcanary 値) をスタックの戻りアドレスの近くに含めることができ、関数から戻る前に、それがそのままであり、バッファ オーバーフローの結果として上書きされていないことを確認します。

于 2013-03-19T09:14:28.097 に答える