I've been using Mark Russinovich's VMMap to map out the Virtual Memory for a process I'm analyzing. Using VirtualQueryEx, I can walk the space of an external process and get information on the memory regions within the process's address space. These regions match up with VMMap, sure, but VirtualQueryEx only tells me if memory is committed/reserved/free and whether it's private/shared/image.
I can't find any other documented ways to query process virtual memory. VMMap seems to know a a way to query the memory in such a way as to understand if it's "Private Data" or "Thread Stack". VirtualQueryEx labels both of those as MEM_PRIVATE. So how does VMMap make that distinction?
Is there another API function that I can use to discern those details?
Mark Russinovich never shares his secrets, he has many. I imagine it could be found from the undocumented thread environment block although I don't see great candidates. A better lead could be the page attributes. It uses MEM_TOP_DOWN, only stacks have that (check VirtualAlloc). And the combination with the guard page, the one that trips the StackOverflowException would make it completely unambiguous. That's the way I would do it anyway.