Showing posts with label image. Show all posts
Showing posts with label image. Show all posts

Nov 23, 2014

Graphical memory layout for notepad.exe

In my previous post, I made a graphical memory layout for the notepad process. I showed the complete 4 GB virtual memory space (or at least the user-mode virtual memory).

In this post, I'm going to do a graphical memory layout for the executable notepad.exe.

The file notepad.exe is a Portable Executable (PE) file. I'm not going to specify the PE format here, there is a lot of good resources on the net where you can find this information. However, I will briefly describe some parts of the PE file here.

Let's inspect notepad.exe. There are several good tools out there to do this. I'm using PE Insider from Cerbero. PE Insider will open the executable and show the file contents in a nice way. Below you can see a screenshot when I've opened notepad.exe. It shows the major parts which builds up the PE file.


When loading notepad.exe into virtual memory (i.e. when starting notepad), the headers and sections are copied into the memory. Exactly how, will be explained below. (To be correct, the information in the PE file are copied to the memory, but the loader may overwrite some information in the memory during load time, which means that the PE file and the memory may not contain exactly the same information. But that does not impact the memory layout.)

Regarding the headers, PE Insider gives us information according to the screenshot below. The headers take up 0x400 bytes of the PE file. However, this is not entirely true. It is actually rounded to this value since the file alignment is 512 bytes (0x200). Offset is the offset in the PE file and Size is the size (in bytes) of the value at this offset.



A PE file contains a couple of sections, more specific, in this case, notepad.exe contains following sections (screenshot from PE Insider). For now, just consider a section as a block of binary information.


Each section are copied from file into the virtual memory (by the loader) according to the VirtualAddress column. The Virtual Address column contains the Relative Virtual Address (RVA). It is an address relative to the image base address (image base address = where the image are loaded in the virtual memory). Since my Windows Vista 32 bit uses Address Space Layout Randomization (ASLR), we don't really know the image base address at forehand. But just let's take an example. During one execution of notepad, the image base address was 0x00eb0000. According to the table above the RVA for the .text section is 0x1000, so the final virtual address for the .text section is 0x00eb1000. The virtual address for the .data section is 0x00eba000. The table also provide us with the size of the section, i.e. the VirtualSize column.

I will not go into detail what each section contains, but I can mention that the .text section mainly contains binary code for the processor to execute. I say mainly, because I inspected this section and realized it also contains the Import Address Table (IAT). I will probably have post about this in the future.

So thanks to the table above, I was able to do this diagram in Excel.


This is what notepad.exe looks like when it is loaded into memory. Note that the diagram does not take the image base address into account. I've just made the diagram from 0 (zero) and not an actual image base address (e.g. 0x00eb0000). The headers are copied to low memory, and then follows the four sections. Note that each section is aligned to a 4 KB page. For instance, the .text section are mapped into RVA 0x1000 (DEC: 4096), which leaves a space with zero padding to headers. The last section is the .reloc section which is 0xd18 in size and starts at RVA 0x27000. The SizeOfImage is 0x28000 bytes (DEC: 163840) and this means that final bytes in the image are zero padded as well.

You are welcome to leave comments, complaints or questions!

Oct 27, 2014

Graphical memory layout for notepad process

I've seen several sites on the internet, which describes how the virtual memory layout looks like for a Win32 application. But these sites seldom shows a virtual memory layout with real addresses, they tend to show only conceptual views. So I made a graphical layout of my own, based on real virtual addresses.

Before proceeding, just a short recap about virtual addresses. For a 32 bit application, each process got its own private memory space, which goes from 0 to 232−1 (DEC: 4294967295, HEX: FFFFFFFF), where each position occupy a single byte. We normally say that a process has about 4 GB of memory. However, only the first 2 GB is dedicated as user-mode memory. The remaining 2 GB is occupied by the kernel-mode memory. (It is possible to extend the user-mode memory from 2 GB to 3 GB, but that is not considered in this post)

I'm using Process Explorer from Sysinternals, to find out the load addresses and image sizes. I'm using Windows Vista 32 bit as platform. Windows Vista can take advantage of the Address Space Layout Randomization (ASLR) feature. ASLR, among other things, will randomly choose a load address for the EXE and DLLs. I may have a specific post about ASLR in the future. However, in my case, the ASLR is in action, which can be verified from the screenshot below.


Screenshot of Process Explorer, showing some of the loaded images

Note that notepad.exe is mapped to the address 0xCF0000 and occupy 0x28000 bytes. Since ASLR is in action, the load address will probably differ in another boot session. Yes, that's right. A new load address will be given to notepad.exe each time you reboot your computer. But the load address remains if you only restart notepad during the same boot session.

Since the load address and the size of the image is known, I simply enter this information to Excel and plot a diagram. The diagram below is made from another boot session.



I've colored the upper 2 GB (kernel-mode memory) black. Process Explorer does not really tell us what's going on there. As you can see, the images does not occupy that much space. There is a lot of space for the heap, stacks and so on.

Unfortunately I was not able to use hex numbers on the Y-axis. But 2 147 483 648 is equal to 0x80000000, which is half of the 32 bit address space.