6

私は今日、バッファ オーバーフローについて学んでおり、脆弱なプログラムの例を数多く見つけました。私が興味を持っているのは、次のようにプログラムの引数を処理する理由があるかどうかです。

int main(int argc, char *argv[])
{
    char argument_buffer[100];
    strcpy(argument_buffer, argv[1]);

    if(strcmp(argument_buffer, "testArg") == 0)
    {
        printf("Hello!\n");
    }
    // ...
}

単純に:

int main(int argc, char *argv[])
{
    if(strcmp(argv[1], "testArg") == 0)
    {
        printf("Hello!\n");
    }
}

私は短所などについて知っていることに注意してくださいstrcpy。これは単なる例です。私の質問は、一時バッファを使用して argv からの引数を格納する本当の理由はありますか? 何もないと思いますが、実際には使用されていないのに、オーバーフローの例にあるのはなぜですか? 純粋な理論のせいかもしれません。

4

4 に答える 4

2

*.foo考えられる実世界の例の 1 つ: 名前を*.bar;に変更するプログラム。への呼び出しのために、元のファイル名と、その.foo一部を に変更したコピーの両方が必要になります.barrename()

于 2012-04-20T15:42:14.067 に答える
1

一部のプログラムは、ファイル名の前にデフォルト パスを追加します。

void OpenLogFile (const char *fileName) {
  char pathName[256];
  sprintf(pathName, "/var/log/%s", fileName);
  logFd = open(pathName, ...);
  ...
}

int main (int argc, char **argv) {
  ...
  OpenLogFile(argv[i]);
  ...
}

プログラムを呼び出すエンティティが 255-9 などよりも長い名前を渡すと、sprintfの末尾を超えて上書きさpathNameれ、ブームになります。

于 2012-04-20T15:53:48.787 に答える
1

以前は、IIRC argv とその内容は、すべてのプラットフォームで書き込み可能で安定していることが保証されていませんでした。C89 / C90 / ANSI-C は、既存のプラクティスの一部を標準化しました。envp[] についても同様です。コピーのルーチンは、古いプラットフォーム (MS-DOS など) にメモリ保護がないことに触発された可能性もあります。通常 (そして最近では) OS および/または CRT が引数を呼び出し元のメモリからプロセスのプライベート メモリ アリーナにコピーします。

于 2012-04-20T15:55:03.387 に答える
0

私はバッファオーバーフローやセキュリティの観点からこれに答えているわけではありませんが、なぜ誰かが argv の内容のコピーを作成したいのかについて厳密に答えています.

実行パスや処理モードを変更するフラグなど、プログラムが多くの引数を受け入れる場合、argv の内容をログ ファイルに直接転送するか、一時的にバッファに保存することができます。argv の内容に対するすべての決定が main で行われ、それでも argv の内容をログに記録したい場合は、おそらくバッファーにコピーする必要はありません。

ディスパッチされたスレッド、プロセス、または argv の内容に基づいて決定を行うサブルーチンに依存している場合は、おそらく argv 値をバッファーに配置して、それらを渡すことができるようにする必要があります。

編集:

ポインターの受け渡しが心配な場合は、argv の内容を固定サイズのバッファーにコピーします。

于 2012-04-20T15:36:17.907 に答える