English 中文(简体)
How can I locate a process global and stack areas in Win32?
原标题:

How can I locate which areas of memory of a Win32 process contain the global data and the stack data for each thread?

问题回答

There is no API (that I know of) to do this. But If you have a DLL in the process, then you will get DLL_PROCESS_ATTACH/DLL_THREAD_ATTACH notifications in DllMain when each thread is created. You can record the thread ID and the address of a stack object for that thread when you get these notifications, because you will get called on the new thread. So store the thread id and stack address in some table that you create at that time. Don t try to do a lot of work in DllMain, just record the stack location and return.

You can then use VirtualQuery to get turn the address of a variable on each thread stack into a virtual allocation range, that should give you the base address of the stack (remember that stacks grow from high addresses to low addresses). The default allocation size for a stack is 1Mb, but that can be overridden by a linker switch or by the thread creator, but a stack must be contiguous. So what you get back from VirtualQuery will be the full stack at that point in time

As for the heap location - there can be multiple locations for the heap, but in general if you want to assume a single contigous heap location then use HeapAlloc to get the address of a heap object and then VirtualQuery to determine the range of pages for that section of the heap.

Alternatively You can use VirtualQuery on the hModule for the EXE and for each DLL. and then you can assume that anything that is read-write and isn t a stack or a module is part of the heap. Note that this will be true in most processes, but may not be true in some because an application can call VirtualAlloc or CreateFileMapping directly, resulting in valid data pointers that are not from either stack or heap. Use EnumProcessModules to get the the list of modules loaded into a process.

VirtualQuery basically takes a random address, and returns the base address of the collection of pages that that address belongs to, as well as the page protections. So it s good for going from a specific pointer which type of allocation.

Take the address of variables allocated in the memory regions you are interested. What you do with the addresses when you have them is another question entirely.

You can also objdump -h (I think it s -h, might be -x) to list the section addresses, including data sections.

Global Data

By "Global" I m going to assume you mean all the data that is not dynamically allocated using new, malloc, HeapAlloc, VirtualAlloc etc - the data that you may declare in your source code that is outside of functions and outside of class definitions.

You can locate these by loading each DLL as a PE File in a PE file reader and determining the locations of the .data and .bss sections (these may have different names for different compilers). You need to do this for each DLL. That gives you the general locations for this data for each DLL. Then, if you have debugging information, or failing that, a MAP file, you can map the DLL addresses against the debug info/mapfile info to get names and exact locations for each variable.

You may find the PE Format DLL helps you perform this task much easier than writing the code to query the PE file yourself.

Thread Stacks

Enumerate the threads in the application using ToolHelp32 (or PSAPI library if on Windows NT 4). For each thread, get the thread context and read the ESP register (RSP for x64). Now do a VirtualQuery on the address in the ESP/RSP register read from each context. The 1MB (default value) region around that address (start at mbi.AllocationBase and work upwards 1MB) is the stack location. Note that the stack size may not be 1MB, you can query this from the PE header of the DLL/EXE that started the thread if you wish.

EDIT, Fix typo where I swapped some register names, thanks @interjay





相关问题
How to read exact number of bytes from a stream (tcp) socket?

In winsock, both the sync recv and the async WSARecv complete as soon as there is data available in a stream socket, regardless of the size specified (which is only the upper limit). This means that ...

AcquireCredentialsHandle returns SEC_E_NO_CREDENTIALS

I created a self-signed certificate (created using OpenSSL) and installed it into the Certificate Store using the Certificates MMC snap-in (CertMgr.msc) on Windows Vista Ultimate. I have managed to ...

Calling Win32 EnumThreadWindows() in C#

I m trying to get a call to EnumThreadWindows working, but I always get a Wrong Parameter-Error, although my code is nearly the same as this example on pinvoke.net. I don t know why this doesn t work: ...

COM Basic links

folks can you provide me the tutorial link or .pdf for learning basic COM?. i do google it.. still i recommend answers of stackoverflow so please pass me.. Thanks

Handling multiple windows WIN32 API

HI I m trying to create an application in the Win32 environment containing more than one window. How do i do that? all the Win32 Tutorials on web i found only showed how to manage one window. How do i ...

Creating a thread in DllMain?

It seems that when a thread is created from within DllMain upon DLL_PROCESS_ATTACH it won t begin until all dll s have been loaded. Since I need to make sure the thread runs before I continue, I get a ...

热门标签