我正在使用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是



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

我哪里出问题了?

最佳答案

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



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

p += info.RegionSize


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

09-10 09:31