Enumerate the pages in a memory range

混江龙づ霸主 提交于 2019-12-23 12:31:14

问题


I'm using C++ on Windows under Visual Studio 2012.

I have a start and end memory address and need to generate a list of page base addresses/handles between the two addresses. I considered the possibility of probing the pages manually but thought there must be a better way to enumerate them.

Does such a way exist?

Disclaimer; The final page handles must be the base address such that when the size of a windows page is added to them the resulting address does not overlap into the next page. The preferred solution would not be platform specific and be compatible with 32-bit with/without WOW64.


回答1:


VirtualQuery is pretty much your only option. It should be fairly efficient:

The function determines the attributes of the first page in the region and then scans subsequent pages until it scans the entire range of pages or until it encounters a page with a nonmatching set of attributes.

So you'd start by calling it at the beginning of the range that you care about, and you'd get back a single chunk of pages. The next call would start right after that chunk, and the next one after that, and so on.

Here's a completely untested function that would populate an array of MEMORY_BASIC_INFORMATION structures:

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


来源:https://stackoverflow.com/questions/15018376/enumerate-the-pages-in-a-memory-range

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!