有没有办法确定VirtualQuery()返回的段是什么类型的内存?

时间:2009-04-20 23:14:42

标签: winapi memory-management

问候,

我可以使用这样的逻辑来处理进程内存映射:

    MEMORY_BASIC_INFORMATION mbi;
    void *lpAddress=(void*)0;
    while (VirtualQuery(lpAddress,&mbi,sizeof(mbi))) {
        fprintf(fptr,"Mem             base:%-10x start:%-10x Size:%-10x Type:%-10x State:%-10x\n",
            mbi.AllocationBase,
            mbi.BaseAddress,
            mbi.RegionSize,
            mbi.Type,mbi.State);
        lpAddress=(void *)((unsigned int)mbi.BaseAddress + (unsigned int)mbi.RegionSize);
    }

我想知道给定的段是用于静态分配,堆栈和/或堆和/或其他?

有什么方法可以确定吗?

1 个答案:

答案 0 :(得分:0)

我很好奇,您打算如何处理这些信息?

如果您不需要代码,可以使用windbg扩展名!地址,它可以获取此信息。获取此信息可能会更加可靠地编写调试器脚本。

VirtualQuery无法自行将此信息返回给您,因为它不知道为什么用户模式代码会请求内存。您需要将其与其他信息源一起使用才能获得此信息,并且可能仍存在一些错误情况。

首先,您应该仅通过MEM_PRIVATE内存进行过滤。 。 。堆,堆栈和静态分配(假设它们已被修改)应该在该范围内。

静态分配(全局等)应该位于带有加载模块的地址。您可以使用PSAPI来确定地址是否在加载的模块中,例如,调用EnumProcessModules然后调用GetModuleInformation。

堆栈值,您可以使用toolhelp API来确定内存位置是否在堆栈中。使用TH32CS_SNAPSHOT创建Toolhelp32Snapshot以获取目标进程中的线程,然后使用GetThreadContext并检查生成的堆栈指针是否在段内。

我不知道在这个过程之外走一堆的好方法。 Toolhelp捕获堆列表,但不会为堆内存提供一组良好的边界。在该过程中,您可以使用GetProcessHeaps来遍历堆列表,然后在内存位置位于堆内时调用HeapValidate来执行dtermie。