Short answer: The heap, stack and other PE loader related tasks are not part of the PE standard or definition.
General Information
the PE file does not describe the entire memory space of an executable. It only contains the data required to execute a program, and the OS keeps the right to add additional regions without the user's awareness. Things such as the heap, the stack and other internal memory regions required for a process to function and operate are not the responsibility of a PE file (or any executable file for that matter).
A PE doesn't define a heap, it requests a heap to be allocated for it from the OS (AllocateHeap
is a Windows API that does that). There's no need to actually eat up space for a heap "placeholder" in the PE file. The same goes for the stack, the PEB, and other memory objects a process has.
Additionally, a user(i.e. programmer) does not usually need to even call AllocateHeap
for it's process to have a heap. OSes usually allocate a default heap for the process when loading it (either by the loader itself or by startup code the OS runs before control is given to the PE's Entry Point). Other times the compiler prefixes the code with code that allocates a heap.
Similarly, the stack is allocated as part of the process creation, and is not part of the PE or defined by it. This is mandatory, for a process cannot exist without a stack (although the PE can set the size of the allocated stack).
If you're interested in learning about the NT Loader (and the PE file format), I suggest you take a look at the following articles and resources:
You might have already read some of the, but I included most of them for future reference.
A lot of information about the heap and other types of memory are part of the (relatively big) topic of Memory Management in windows and you may want to also dive into that, here are are few articles about the heap and memory management:
Technical questions
- how and where the heap gets allocated for a program?
Heaps are memory pages reserved and committed upon creation (of the heap). The OS assigns designated pages and those are on the actual RAM and/or Page File.
As I mentioned before, a process can have multiple heaps (but always has at least one, default, heap). Additional heaps are allocated and freed by the process at run-time, and a process can have a different amount of heaps depending to run-time logic.
See above for a short description of how the default heap (or, more precisely the first heap, as a process may change it's default heap to a heap later allocated) is created.
- If I want to scan the heap for data, how would I get the memory address space?
This slightly depends on the purpose and specific reasons and type of data you want to scan for. If you want to scan for data anywhere in the process's memory, you should use VirtualQuery
or VirtualQueryEx
for all committed memory pages. This won't only let you scan all available heaps, but will also let you scan the stack, the PE sections, and other memory used by the program (for example, pages allocated directly with VirtualAlloc
).
If you want to get the address range of a specific (or several heaps), you'll need to use some Heap memory functions, msdn such as GetProcessHeap
GetProcessHeaps