2009-04-20 49 views
2

問候,有什麼方法可以確定VirtualQuery()返回的段的內存類型是什麼?

我可以在使用邏輯這樣走一個進程的內存映射:

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

我很好奇,你打算如何處理這些信息?

有一個windbg擴展,!地址,如果你不需要代碼就可以得到這些信息。編寫腳本調試器可能會更可靠,以獲取此信息。

由於VirtualQuery不知道用戶模式代碼請求內存的原因,因此VirtualBack無法將此信息自行返回給您。您需要將其與其他信息源一起使用以獲取此信息,並且可能還存在一些錯誤情況。

首先,您應該只通過MEM_PRIVATE內存進行過濾。 。 。堆,堆棧和靜態分配(只要它們已被修改)應該在該範圍內。

靜態分配(全局變量等)應該在帶有加載模塊的地址上。您可以使用PSAPI來確定地址是否位於加載的模塊中,例如,調用EnumProcessModules,然後調用GetModuleInformation。

堆棧值,您可以使用toolhelp API來確定內存位置是否在堆棧中。使用TH32CS_SNAPSHOT創建ToolTophelp32Snapshot以獲取目標進程中的線程,然後GetThreadContext並檢查生成的堆棧指針是否位於該段內。

我不知道從過程之外走過堆的好方法。 Toolhelp捕捉一個堆列表,但不會爲堆內存提供一組好的界限。在這個過程中,您可以使用GetProcessHeaps來遍歷堆列表,然後調用HeapValidate來確定內存位置是否在堆內。

+0

將此信息用作應用程序的自定義內存管理器的一部分。 – bdbaddog 2009-04-21 18:10:59

相關問題