-5
  1. バグのコード

    int main()
    {
        void *ptr = 0;    
        int overrun = 1;
        ptr = malloc(overrun);
        while(overrun++)
        {
            if(!ptr)
                while(1) Sleep(500);
            *((char*)ptr + (overrun+1)) = 'a';
            printf("\n%d\n",overrun);
        }
        return 0;
    }
    
  2. Visual Studio 2010のプロジェクトメニューから、ビルドが「リリース」および「x64」(マシンはx64)であることを確認しました

  3. フルページヒープを有効にする

    gflags /p /enable test.exe /full
    
  4. windbgをデフォルトのデバッガーにする

    E:\installed\Debugging Tools for Windows (x64)>windbg -I
    
  5. cmdデバッガなしとは別のexeとしてコードを実行します

    出力:

    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    

    その後、windbgが破損をキャッチしているのが見られます。そして、フルページヒープは破損を即座にキャッチすることを想定していると思いました。

    なぜフルページヒープがダメなのかについてのコメントはありますか?

4

2 に答える 2

31

ヒープ割り当ては整列する必要があるため、メモリ保護はバイト単位ではなくページ単位であるため、オーバーランが発生した時点でアライメント境界を超えないオーバーランをキャッチすることはできません。これはハードウェアの制限です。メモリを解放すると、オーバーランが検出され、末尾のバイトの改ざんがチェックされます。

(ちなみに、何かが悪いと言うと、あなたが吸っていると非難した人があなたの問題を手伝ってくれる可能性が低くなります。ほんのヒントです。)

于 2012-11-09T18:49:12.567 に答える
6

レイモンドの応答を拡張します。malloc によって返された元のポインターをデバッガーで調べると、ページの末尾から 16 バイトであることがわかります。これは、x64 での HeapAlloc アライメント要件が 16 バイトであるためです。そのため、要求した 1 バイトをページの最後にできるだけ近づけて配置しました。ページの最後から離れたら、失敗します。

于 2012-11-09T18:58:59.847 に答える