2

I've been researching the Portable Executable format and one great work I've been reading is "ARTeam PE file format Tutorial" which is a collection of research from Michael J'OLeary, Randy Kath, Matt Pietrek, and many more.

However, one thing that I've noticed is absent is how and where the heap gets allocated for a program. Is it in one of the 9 standard sections such as .bss or .data or is it attached to the end of all sections at run-time by the loader?

I assume, since it's the heap which is dynamic memory, that it is not specified anywhere in the actual PE, but if I want to scan the heap for data, how would I get the memory address space?

Specifically, I would like answers to the following questions:

  1. how and where the heap gets allocated for a program?
  2. If I want to scan the heap for data, how would I get the memory address space?
  • the heap size is defined by fields in the PE header, but the placement in memory is assigned randomly by the OS. You can query the heap start by calling the GetProcessHeap() function, or by reading the PEB directly. – peter ferrie Mar 10 '17 at 17:57
3

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

  1. 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.

  1. 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

  • what? SizeOfStackReserve, SizeOfStackCommit, SizeOfHeapReserve, SizeOfHeapCommit are fields in the PE header and they are most definitely used for exactly that purpose. – peter ferrie Mar 10 '17 at 17:54
  • I'm not sure what you think I wrote contradicts your statement. I even mentioned stack size is set by the PE ("although the PE can set the size of the allocated stack") – NirIzr Mar 10 '17 at 18:11
  • Your short answer says that neither stack nor heap are part of the standard. That is highly misleading, and your longer description does not help much to clarify. The sizes are defined explicitly by the PE file. Only the location in memory is up to the OS. – peter ferrie Mar 11 '17 at 18:49
  • OP's original question was "where in the PE file are the stack and heap", so I think I did a decent job clarifying the stack and heap are not in the PE, and that the OS allocates those (based on a PE provided sizes, yes, as both you and I mentioned). – NirIzr Mar 11 '17 at 22:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.