枚举内存范围内的页面

Enumerate the pages in a memory range

本文关键字:范围内 内存 枚举      更新时间:2023-10-16

我在Visual Studio 2012下的Windows上使用C++。

我有一个开始和结束内存地址,需要在这两个地址之间生成一个页面基址/句柄列表。我考虑过手动探查页面的可能性,但认为一定有更好的方法来枚举它们。

这样的方式存在吗?

免责声明最后一个页面句柄必须是基地址,这样当窗口页面的大小添加到它们时,得到的地址不会重叠到下一个页面中。优选的解决方案将不是特定于平台的,并且与具有/不具有WOW64的32位兼容。

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;
}