问候,
我可以使用这样的逻辑来处理进程内存映射:
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);
}
我想知道给定的段是用于静态分配,堆栈和/或堆和/或其他?
有什么方法可以确定吗?
答案 0 :(得分:0)
我很好奇,您打算如何处理这些信息?
如果您不需要代码,可以使用windbg扩展名!地址,它可以获取此信息。获取此信息可能会更加可靠地编写调试器脚本。
VirtualQuery无法自行将此信息返回给您,因为它不知道为什么用户模式代码会请求内存。您需要将其与其他信息源一起使用才能获得此信息,并且可能仍存在一些错误情况。
首先,您应该仅通过MEM_PRIVATE内存进行过滤。 。 。堆,堆栈和静态分配(假设它们已被修改)应该在该范围内。
静态分配(全局等)应该位于带有加载模块的地址。您可以使用PSAPI来确定地址是否在加载的模块中,例如,调用EnumProcessModules然后调用GetModuleInformation。
堆栈值,您可以使用toolhelp API来确定内存位置是否在堆栈中。使用TH32CS_SNAPSHOT创建Toolhelp32Snapshot以获取目标进程中的线程,然后使用GetThreadContext并检查生成的堆栈指针是否在段内。
我不知道在这个过程之外走一堆的好方法。 Toolhelp捕获堆列表,但不会为堆内存提供一组良好的边界。在该过程中,您可以使用GetProcessHeaps来遍历堆列表,然后在内存位置位于堆内时调用HeapValidate来执行dtermie。