VirtualQueryEx错误 - 页面太多

时间:2013-01-05 11:04:02

标签: c++ windows winapi memory-management paging

我正在使用VirtualQueryEx枚举模块的内存页面,其代码如下:

unsigned char *p = (unsigned char *)module;
    MEMORY_BASIC_INFORMATION info;
    unsigned long usage = 0;
    for ( ;VirtualQueryEx(hProcess, p, &info, sizeof(info)) == sizeof(info);
        p += info.RegionSize ) 
    {
        printf("%#10.10x (%6uK)\t", info.BaseAddress, info.RegionSize/1024);

        switch (info.State) {
        case MEM_COMMIT:
            printf("Committed");
            break;
        case MEM_RESERVE:
            printf("Reserved");
            break;
        case MEM_FREE:
            printf("Free");
            break;
        }
        printf("\t");
        switch (info.Type) {
        case MEM_IMAGE:
            printf("Code Module");
            break;
        case MEM_MAPPED:
            printf("Mapped     ");
            break;
        case MEM_PRIVATE:
            printf("Private    ");
        }
        printf("\t");

        if ((info.State == MEM_COMMIT) && (info.Type == MEM_PRIVATE))
            usage +=info.RegionSize;

        int guard = 0, nocache = 0;

        if ( info.AllocationProtect & PAGE_NOCACHE)
            nocache = 1;
        if ( info.AllocationProtect & PAGE_GUARD )
            guard = 1;

        info.AllocationProtect &= ~(PAGE_GUARD | PAGE_NOCACHE);

        switch (info.AllocationProtect) {
        case PAGE_READONLY:
            printf("Read Only");
            break;
        case PAGE_READWRITE:
            printf("Read/Write");
            break;
        case PAGE_WRITECOPY:
            printf("Copy on Write");
            break;
        case PAGE_EXECUTE:
            printf("Execute only");
            break;
        case PAGE_EXECUTE_READ:
            printf("Execute/Read");
            break;
        case PAGE_EXECUTE_READWRITE:
            printf("Execute/Read/Write");
            break;
        case PAGE_EXECUTE_WRITECOPY:
            printf("COW Executable");
            break;
        }

        if (guard)
            printf("\tguard page");
        if (nocache)
            printf("\tnon-cachable");
        printf("\n");
    }

这段代码来自另一篇文章。

问题是:VirtualQueryEx不会停止枚举当前模块的页面(它只是在内存不在进程时停止)并且结果错误

这是我的输出和VMMap的一个

enter image description here

正如您所看到的那样,从突出显示的地址开始,页面都是错误的,VirtualQueryEx甚至不会停止枚举它们。

我哪里出错?

1 个答案:

答案 0 :(得分:3)

VMMap知道文件格式(部分.data,.text,ext),而VirtualQueryEx则不知道。 MEMORY_BASIC_INFORMATION.RegionSize - 所有页面具有相同保护属性的区域的大小(屏幕截图中为RW)。这就是为什么计算区域VMMap和VirtualQueryEx不匹配的原因。

enter image description here

VirtualQueryEx甚至不会停止枚举它们。

p += info.RegionSize

扫描整个用户模式虚拟内存地址空间。如果要停止扫描,请检查AllocationBase字段。