枚举内存范围内的页面 [英] Enumerate the pages in a memory range

查看:116
本文介绍了枚举内存范围内的页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Visual Studio 2012的Windows上使用C ++.

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.

是否存在这种方式?

免责声明; 最终页面句柄必须是基地址,以便在将Windows页面的大小添加到它们时,结果地址不会与下一页重叠.首选解决方案不是特定于平台的,而是与具有或不具有WOW64的32位兼容.

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.

推荐答案

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.

这是一个完全未经测试的函数,该函数将填充 MEMORY_BASIC_INFORMATION 结构:

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

这篇关于枚举内存范围内的页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆