4

Visual Studio 2012 の Windows で C++ を使用しています。

開始メモリ アドレスと終了メモリ アドレスがあり、2 つのアドレス間のページ ベース アドレス/ハンドルのリストを生成する必要があります。手動でページを調査する可能性を検討しましたが、それらを列挙するより良い方法があるに違いないと考えました。

そのような方法は存在しますか?

免責事項; 最終的なページ ハンドルは、Windows ページのサイズが追加されたときに結果のアドレスが次のページに重ならないように、ベース アドレスである必要があります。推奨されるソリューションはプラットフォーム固有ではなく、WOW64 の有無にかかわらず 32 ビットと互換性があります。

4

1 に答える 1

6

VirtualQueryほとんどあなたの唯一のオプションです。かなり効率的です。

この関数は、リージョン内の最初のページの属性を判別し、ページの範囲全体をスキャンするか、属性のセットが一致しないページが検出されるまで、後続のページをスキャンします。

したがって、関心のある範囲の先頭で呼び出すことから始めれば、ページの単一のチャンクが返されます。次の呼び出しはそのチャンクの直後に開始され、次の呼び出しはその後に続きます。

MEMORY_BASIC_INFORMATION以下は、構造体の配列を生成する完全にテストされていない関数です。

int EnumVirtualAllocations(const void* ptr, size_t length, MEMORY_BASIC_INFORMATION* info, int size)
{
    const void* end = (const void*)((const char*)ptr + length);
    int index = 0;
    while (index < size && ptr < end &&
        VirtualQuery(ptr, &info[index], sizeof(*info)) == sizeof(*info))
    {
        MEMORY_BASIC_INFORMATION* i = &info[index];
        if (i->State != MEM_FREE) index++;
        ptr = (const void*)((const char*)(i->BaseAddress) + i->RegionSize);
    }
    return index;
}
于 2013-02-22T06:51:18.807 に答える