2

次の 2 つの (簡略化された) 例が segfault を実行するのはなぜですか (Win7 で GCC でコンパイル)。

ケース 1 - 関数ポインタへの書き込み

void f() {return;}
int main()
{
  memcpy(&f, "", 1);
  return 0;
}

ケース 2 - データ ポインターの呼び出し

char f[] ={0xC3};
typedef void(*p)();
int main()
{
  ((p)f)();
  return 0;
}

メモリの RO セクションを書き込んでいて、実行不可能なメモリ セクションにジャンプしているためです。(またはそのようなもの)。私の質問は、大局的な意味での「なぜ」
です。これを正確に実施するシステムは何ですか? それはOSレベルですか?ハードウェアレベルで?ハードウェアレベルですが、バイナリをメモリにロードするときに OS によって設定する必要がありますか? これはどのサブシステムですか? 等...

「なぜ」よりも「どのように」の方が適切な質問かもしれません。

4

2 に答える 2

0

x86 プラットフォームではハードウェアに実装されています。CPU はメモリをページ (32 ビット プラットフォームでは通常 4kb のサイズ) に分割し、それぞれにさまざまなアクセス ビットがあります (ただし、実行アクセス フラグは実際には比較的遅くまでサポートされていませんでした)。

ページ情報自体はメモリ内のテーブルに格納されます。CPU は、マスター テーブルを指すレジスタを保持するだけであり、おそらくいくつかのキャッシュされたコンテンツも保持します。

OS レベルでは、OS は各コンテキスト スイッチ中に対応するテーブル ポインターを設定する (そしてメモリを割り当てるシステム コール中にフラグ値を変更する) ため、CPU は現在のプロセスがアクセスできるページを常に認識します。

于 2013-09-17T12:35:11.913 に答える
0

Windows の場合、これはページ保護によって OS レベルで適用されます。各ページには、その特性 (読み取り可能、書き込み可能、​​実行可能、保護ページなど) を指定する一連の保護フラグが割り当てられています。ページ保護はVirtualProtectで変更でき、その後コード ページに書き込むことができます。

実行可能ではないコードを持つカバーの下では、本質的VirtualProtectにトグルしているものである NX フラグなどのハードウェアによってサポートされている場合があります。

于 2013-09-17T12:13:27.117 に答える