Friday, February 28, 2014

Dissecting the PE File Format - 7



The Import Section


This section contains info about all functions imported by the executable from DLLs. This is stored in various data structures and the most important of those being the import directory and the import address table. You might also have bound_import  and Delay_Import directories.

The Windows loader is responsible for loading all the DLLs that the application uses and mapping them into the process address space. It has to find the addresses of all the imported functions in their various DLLs and make them available for the executable being loaded.

The addresses of functions inside a DLL are not static but change when DLLs are updated. To account for this, the IAT was used. This is a table of pointers to the function addresses which is filled in the windows loader as the DLLs are loaded.

By using a pointer table, the loader does not need to change the addresses of imported functions everywhere in the code they are called. It only has to correct the addresses in the import table.


The Import Directory

It is an array of IMAGE_IMPORT_DESCRIPTOR structures. Each structure is 20 bytes and contains information about the DLL which our PE file imports functions from. The number of structures is equal to the number of DLLs the PE file imports functions from. There's no field indicating the no. of structures and the last structure is filled with all 0's.

You can find the Import Directory by looking at the Data Directory (80 bytes from the beginning of the PE header)
The first member - OriginalFirstThink which is a DWORD union, may have at one time been a set of flags.  However, Microsoft changed its meaning but did not update winnt.h. This field really contains the RVA of an array of IMAGE_THUNK_DATA structures.

ASIDE - Union is just a redefinition of the same area of memory. The union above does not contain 2 DWORDs  but only one which could either be OriginalFirstThink or Characteristics

The TimeDateStamp is 0 unless the executable is bound when it contains -1.
The ForwarderChain was used for old-style binding and not considered here.
Name1 contains a pointer (RVA) to the ascii name of the DLL.

The last member FirstThunk, also contains the RVA of an array of DWORD-sized IMAGE_THINK_DATA structures. - a duplicate of the first array. If the function described is a bound import (explained below), then FirstThunk contains the actual address of the function instead of an RVA to an IMAGE_THUNK_DATA. These structures are defined as:


Each IMAGE_THUNK_DATA is a DWORD union which effectively has only one of the two values. In the file on disk it either contains the ordinal of the imported function or the RVA to an IMAGE_IMPORT_BY_NAME structure. Once loaded, the ones pointed at by FirstThunk are overwritten  with addresses if imported functions - this becomes the IAT.

Each IMAGE_IMPORT_BY_NAME structure is defined as follows:
Hint - contains the index into the EAT of the DLL the functions resides in. This field is for use by the PE loader so it can look up the functions in the DLLs EAT quickly. The name at that index is tried and if it doesn't match then a binary search is done to find the name. For some linkers this value is not essential and is set to 0.

Name1 - contains the name of the imported function and is a null terminated ASCII string.

The most important parts are the imported DLL names and the arrays of IMAGE_THUNK_DATA structures. Each IMAGE_THUNK_DATA structure corresponds to one imported function from the DLL. The arrays pointed to by the OriginalFirstThunk and FirstThunk run parallel and are terminated by a null DWORD. There are separate paris of arrays of IMAGE_THUNK_DATA structures. for each imported DLL.

In other words, there are several IMAGE_IMPORT_BY_NAME structures. You create two arrays, then fill them with RVAs of those IMAGE_IMPORT_BY_NAME structures, so both arrays contain exactly the same values. Now you assign the RVA of the first array to OriginalFirstThunk and the RVA of the second array to FirstThunk.

The number of elements in the OriginalFirstThunk and FirstThunk arrays depend on the number of functions imported from the DLL. e.g. if the PE file imports 10 functions from user32.dll, Name1 in the IMAGE_IMPORT_DESCRIPTOR structure will contain the RVA of the string "user32.dll" and there will be 10 IMAGE_THUNK_DATAs in each array.

The 2 parallel arrays have been called by several different names but the most common are Import Address Table ( for the one pointed by FirstThunk) or Import Lookup Table (pointed by OriginalFirstThunk)

Why are there 2 parallel arrays of pointers to IMAGE_IMPORT_BY_NAME structures?
The Import Name Table is left alone and never modified. The IAT is overwritten by the actual function addresses by the loader. The loader iterates through each pointer in the arrays and finds the address of the function that each structure refers to. The loader then overwrites the pointer to IMAGE_IMPORT_BY_NAME with the function's addresses. The arrays of RVAs in the Import Name Tables remain unchanged so that if the need arises to find the names of imported functions, the PE loader can still find them.

Although the IAT is pointed to by entry number 12 in data directory, some linkers dont set this directory entry and the app will run nevertheless. The loader only uses this to temporarily mark the IATs as read-write during import resolution and can resolve imports without it.

This is how the windows loader is able to overwrite the IATs when it resides in the read-only section. At load time, the system temporarily sets the attribute of the pages containing the imports data to read/write. Once the imports table is initialized the pages are set back to their original attributes.


Calls to imported functions take place via a function pointer in the IAT and can take 2 forms, one more efficient than the other. e.g. imagine the address 00405030 refers to one of the entries in the FirstThunk array thats overwritten by the loader with the address of GetMessage in USER32.DLL
The efficient way to call GetMessage looks like this: 
0040100C CALL DWORD PTR [00405030 ] 
The inefficient way looks like this: 
0040100C CALL [00402200] 
....... 
....... 

00402200 JMP DWORD PTR [00405030] 

The second method achieves the same but with 5 additional bytes of code and takes longer to execute.
Why are calls to imported functions implemented this way?
The compiler cannot distinguish between calls to ordinary functions within the same module and imported functions and emits the same output for both: CALL [XXXXXX]
where XXXXXX has to be an actual code address (not a pointer) to be filled by the linker later. The linker does not know the address of the imported function and so has to supply a substitute chunk of code - the JMP stub seen above.

The optimized form is obtained using the __declspec(dllimport) modifier to tell the compiler that the function resides in a DLL. It will then output CALL DWORD PTR [XXXXXX].

If __declspec(dllimport) has not been used when compiling the executable there will be a whole collection of jump stubs for imported functions located together somewhere in the code. This has been known by various names - "transfer area", "trampoline", "jump thunk table".

Functions Exported By Ordinal Only
When functions are exported by ordinal only, there will be no IMAGE_THUNK_BY_NAME structure for that function in the caller's module. Instead, the IMAGE_THUNK_DATA for that  function contains the ordinal for that function.
Before the executable is loaded, you can tell if the IMAGE_THUNK_DATA structure contains an ordinal or an RVA by looking at the MSB or high bit. If set, then the lower 32 bits are treated as an ordinal value. If clear, the value is an RVA to an IMAGE_IMPORT_BY_NAME.

Bound Imports
When the loader loads a PE file into memory, it examines the import table and loads the required DLLs into the process address space. Then it walks the array pointed at by FirstThunk and replaces the IMAGE_THUNK_DATAs with the real addresses of import functions. If somehow the programmer can predict the addresses of functions correctly, the PE loader doesn't have to fix the IMAGE_THUNK_DATAs each time the PE file is run as the correct address is already there.

Microsoft compilers come with a utility bind.exe  that examines the IAT of a PE file and replaces the IMAGE_THUNK_DATA dwords with the addresses of imported functions. When the file is loaded, the loader must check i the addresses are valid. If the DLL versions do not match the ones in the PE file or if the DLLs need to be relocated, the loader knows that the bound addresses are stale and it walks the INT to calculate new addresses.

Therefore, although the INT is not necessary for the executable to load, if not present the executable cannot be bound.

The Bound Import Directory

The information the loader uses to determine if bound addresses are valid is kept in a IMAGE_BOUND_IMPORT_DESCRIPTOR structure. A bound executable contains a list of those structures, one for each imported DLL that has been bound:
TimeDateStamp must match the TimeDateStamp of the exporting DLL's FileHeader; if it doesn't match the loader assumes that the binary is bound to a wrong dll and will re-patch the import list.
The OffsetModuleName member contains the offset (not RVA) from the first IMAGE_BOUND_IMPORT_DESCRIPTOR  to the name of the DLL in the null-terminated ASCII.
The NumberOfModuleForwarderRefs member contains the number of IMAGE_BOUND_FORWARDER_REF structures that immediately follow this structure.


Its almost similar to the previous structure. The reason to have 2 similar structures like this is that when binding against a function which is forwarded to another DLL, the validity of that forwarded DLL has to be checked at load time too. This structure contains the details of those forwarded DLLs.

e.g. the function HeapAlloc in kernel32.dll is forwarded to RtAllocateHeap in ntdll.dll. If we created an app which imports HeapAlloc and used bind.exe on the app, there would be an IMAGE_BOUND_IMPORT_DESCRIPTOR for kernel32.dll followed by an IMAGE_BOUND_FORWARDER_REF for ntdll.dll.


In the next post we talk more about the loader.





Thursday, February 27, 2014

Dissecting the PE File Format - 6

The Export Section

The following image is from the Win32 Programmer's reference:















Functions can be exported by a DLL in two ways - "by name"  or "by ordinal only". An ordinal is a 16-bit number that uniquely identifies a function in a particular DLL. The number is unique only within the DLL it refers to.

If a function is exported by name, when other DLLs or functions want to call they use either the name or its ordinal in GetProcAddress which returns the address of the function in the DLL.

A screenshot of GetProcAddress from MSDN:
































GetProcAddress can do this because the names and addresses of exported functions are stored in a well defined structure in the Export Directory. We can find the export directory since its the first element in the data directory and the RVA to it is contained at offset 78h from the start of the PE header.

The export structure is called IMAGE_EXPORT_DIRECTORY.

nName - The internal name of the module. This is necessary as the name of the file can be changed by the user. If this happens, the PE loader will use this internal name.

nBase - Starting ordinal number (needed to get into the addresses-of-function array - see below)

NumberOfFunctions-  Total no. of functions exported by this module

NumberOfNames - Number of symbols that are exported by name. The value is not the number of all functions/symbols in the module. For that you need to check NumberOfFunctions. It can be 0. In that case, the module may export by ordinal only. If there is no function/symbol to be exported, the RVA of export table in the data directory will be 0.

AddressOfFunctions - An RVA that points to an array of pointers to (RVAs of) the functions in the module - the EAT. In other words, the RVAs to all functions in the module are kept in an array and this field points to the head of that array.

AddressOfNames - An RVA that points to an array of RVAs of the names of the functions in the module. - the Export Name Table (ENT)

AddressOfNameOrdinals - An RVA that points to a 16-bit array that contains the ordinal of the named functions - the Export Ordinal Table (EOT)

The IMAGE_EXPORT_DIRECTORY structure points to three arrays and a table of ASCII strings. The important array is the EAT, which is an array of function pointers that contain the address of exported functions. The other 2 arrays (ENT and EOT) run parallel in ascending order based on the name of the function. So, a binary search for a function's name can be performed and the result is its ordinal being found in the other array. The ordinal is simply the index into the EAT for that function.

Since the EOT array exists as a linkage between the names and the addresses, it cannot contain more elements than the ENT array i.e. each name can have only one associated address. The reverse is not true: an address may have several names associated with it.

e.g. if a DLL exports 40 functions it must have 40 members in the array pointed to by AddressOfFunctions (the EAT) and the NumberOfFunctions field must contain the value 40. To find the address of the function from its name, the OS must obtain values of NumberOfFunctions and NumberOfNames in the Export Directory. Next, it walks the arrays pointed to by the AddressOfNames and AddressOfNameOrdinals in parallel searching for the function name. If the name is found in the ENT, the value of that in EOT is extracted and used as an index into the EAT.

e.g. FunctionX is the 39th element in the ENT. The corresponding 39th element in the EOT is 5. We look at the 5th element in the EAT to find the RVA of FunctionX

If you already have the ordinal, you can directly go to the EAT. However, if the DLL is updated, the ordinals are altered and if the program depends on that, the DLL will break.

Exporting By Ordinal Only
When a function is exported by ordinal, its not present in the ENT.
But if there are 70 functions and only 40 are present in the ENT,. How do we find the remaining 30 functions which are exported by ordinal only? 
You must find out by exclusion i.e. the entries in the EAT that are not referenced by the EOT contain the RVAs of functions that are exported by ordinal only.
The programmer  specifies the starting ordinal number in a .def file. So, the tables above could start at 200. If order to prevent 200 empty entries in the array, the nBase holds the starting value and the loader subtracts the ordinal numbers from it to obtain the true index into the EAT.

Export Forwarding
Sometimes function appear to be exported by a DLL but actually reside in a completely different DLL. This is called export forwarding. e.g. in Windows, the kernel32.dll function HeapAlloc is forwarded to RtHeapAlloc exported by ntdll.dll. NTDLL.dll contains the native API set which is a direct interface to the kernel. Forwarding is performed at link time by a special instruction in the .def file.

When packed executables which have been unpacked and had their import tables constructed manually on one OS do not run on other OS, it because the API forwarding system or some other detail has been altered.

When a function is forwarded by its RVA clearly cant be code or data address in the current module. Instead, the EAT contains a pointer to an ASCII string of the DLL and function name to which its forwarded.

If therefore the EAT entry for a function points to an address inside the Exports section (i.e ASCII string) rather than outside into another DLL, you know the function is forwarded.


Dissecting the PE File Format - 5

The PE File Sections

The sections contain the main content of the file including code, data, resources and other executable information. Each section has a header contained in the Section Table but the section bodies lack a rigid file structure. They can be filled with any information as long as the header has enough info to decipher the data.

Executable Code
All code segments reside in .text. Since a page-based system is used in Windows, a large code section is easier to manage for both the OS and the app developer. This section also contains the entry point mentioned earlier and the jump thunk table which points to the IAT.

Data
The .bss section represents uninitialized data, including all variables declared as static within a function.
The .rdata section is read-only data such as literal strings, constants and debug directory information.
All other variables are in the .data section. These are application or module global variables.

Resources
The .rsrc section contains resource information. The first 16 bytes comprises a header like most other sections but this section's data is structured into a resource tree which is best viewed using a resource editor. (e.g. ResHacker)
This is a powerful tool for cracking. It quickly displays dialog boxes including those concerning incorrect registration details. A shareware app can be cracked by just deleting the nag screen dialog resource in ResHacker.

Export Data
The .edata section contains the export directory for an app or DLL. This contains info about names and addresses of exported functions

Import Data
The .idata section contains info about the imported functions including the Import Directory and IAT.

Debug Information
usually placed in the .debug section. Separate debug files (.DBG) are also supported for collecting debug information. The debug section contains debug information but the debug directories live in the .rdata section. Each of these directories references debug information in the .debug section.

Thread Local Storage
Windows supports multiple threads of execution per process. Each thread has its own private storage, Thread Local Storage or TLS, to keep data specific to that thread, such as pointers to data structures and resources the thread is using. The linker creates a .tls section in a PE file that defines the layout for the TLS needed by routines in the executable and any DLLs which it directly refers. Each time a process creates a thread, the new thread gets its own tls, created using the .tls section as a template.

Base Relocations
When the linker creates the EXE, it makes an assumption about where the file will be mapped  into memory. Based on this, the linker puts the real addresses of code and data items of the executable file. If the executable ends up being loaded somewhere else in the virtual address space, the address the linker plugged into the image are wrong. The information stored in the .reloc section allows the PE loader to fix these addresses in the loaded image so that they are correct again.
The entries in the .reloc section are called base relocations since their use depends on the base address of the loaded image. Base relocations are simply a list of locations that need a value added to them. The format of the base relocation data is quirky. The base relocation entries are packages in a series of variable length chunks. Each chunk describes the relocations for one 4KB page in the image.

e.g.  if the assumed base address is 0x10000. At offset 0x2134 within the image is a pointer containing the address of a string. The string starts at physical address 0x14002. You then load the file but the loader maps the file at physical address 0x60000.  The difference between the linker-assumed base load address and the actual load address is called delta which is 0x50000 in this case. Since the entire image is 0x50000 bytes higher in memory, so is the string. The executable file contains a base relocation for the memory location where the pointer to the string resides. To resolve the base relocation, the loader adds the delta value to the original value at the base relocation address. So the string will now point to 0x64002.

Dissecting the PE File Format - 4


THE SECTION TABLE

After the PE header, we have an array of IMAGE_SECTION_HEADER structures, each containing information about one section in the PE file, such as its attribute and virtual offset. The structures are 40 bytes each and there is no padding between them.

Name1 - (8 bytes). Just a label and can be blank.
VirtualSize - The actual size of the section's data in bytes. This may be less than the size of the section on disk (SizeOfRawData) and will be what the loader allocates in memory for this section.
VirtualAddress - The RVA of the section. The PE loader examines and uses this value in this field when it's mapping the section into memory. Thus, if this is 1000h and the PE file is loaded at 400000h, the section is loaded at 401000h
SizeOfRawData - The size of the section's data in the file on disk, rounded up to the next multiple of file alignment by the compiler.
PointerToRawData (raw offset) very useful as its the offset from the file's beginning to the section data. If 0, the sections data are not contained in the file.
Characteristics - Contains flag to indicate if it contains executable code, initialized data, can it be written or read from etc.



























You can bypass the PE header and search for the section name in the hex editor. After the section headers we find the section themselves. In the file on disk, each section starts as an offset that is multiple of the FileAlignment value found in the OptionalHeader. Between each header you'll find a 00 byte padding.
When loaded in RAM, the sections always start at page boundaries so that the first byte of each section corresponds to a page. On x86 CPUs are 4kB aligned, whilst on IA-64 they are 8kB aligned. This alignment value is stored in SectionAlignment in OptionalHeader.
You can find the sections with PointerToRawData or VirtualAddress, and you need not bother with alignments.

In the next post, we talk about the various PE file sections.

Dissecting the PE File Format - 3

THE DATA DIRECTORY

DataDirectory is the final 128 bytes of OptionalHeader which is the final member of IMAGE_NT_HEADERS.
DataDirectory is an array of 16 IMAGE_DATA_DIRECTORY structures. Each array refers to a predefined item such as the import table. The structure has 2 members which contain the location and the size of the data structure in question.
VirtualAddress is the relative virtual address (RVA) of the data structure
iSize contains the size in bytes of the data structure.
The 16 directories to which these structures refer are defined in windows.inc

A file may not have all the 16 members. Some of them might be unused. For e,g, our example as seen in LordPE has only 4 members.
For e.g. in the picture, the "import table" fields contain the RVA and the size of IMAGE_IMPORT_DESCRIPTOR array - the Import directory. The picture below shows the PE header with the data directory outlined in red.

To locate a particular directory, you determine the relative address from the data directory. Then use the virtual address to determine which section the directory is in. once you determine which section contains the directory, the section header for that section is used to find the exact offset.

In the next post we move on to the Section Table

Dissecting the PE File Format - 2

PE HEADER

A general term for a structure named IMAGE_NT_HEADERS
It has 3 members and is defined in windows.inc. Thus:
Signature is always PE as described in the previous post.
The next 20 bytes is the FileHeader which contains info about the physical layout and properties of the file. e.g. no. of sections. The OptionalHeader is always present and it contains info about the logical layout of the PE file. e.g. address of entry point.

FileHeader is defined as follows:
Most of these members are not of any use. If we add sections to the file, we must modify the NumberOfSections field. Characteristics have flags which indicate if the PE file is an executable or a DLL. 
In the hex editor, we can find the numberOfSections by counting a DWORD and a WORD from the start of the PE header. This can be verified using PEView.


This is verified using PE View as seen in the figure.
PEid is another useful tool to scan executables and reveal the packer which has been used to compress/encrypt them. It also has the Krypto ANALyzer plugin for detecting the use of cryptography e.g. MD5, CRC. it can also utilize a user-defined list of packer signatures. This should be the first tool to use in any unpacking session.




Next, to the OptionalHeader which takes 224 bytes, the last 128 of which contain the Data Directory.

AddressOfEntryPoint - The RVA of the first instruction that will be executed when the PE loader is ready to run the PE file. If you want to divert the flow of execution, you need to change this value. Packers generally redirect this value to their decompression stub, after which execution jumps back to the original entry point of the app.
Note - StarForce protection in which the CODE section is not present in the file on disk but is written to virtual memory on execution. The value in this field is therefore a VA.

ImageBase - The preferred load address of the PE file. e.g. if its 400000h, the PE loader will try to load the file into virtual address space starting at 400000h. However, the loader may not load the file at this address if this space has already been occupied by some other module.

SectionAlignment - The granularity of the alignment of sections in memory. Generally 1000h. Each section must begin at multiples of this value.

FileAlignment - The granularity of the alignment of sections in the file. Generally 512h.

SizeOfImage - The overall size of the PE image in memory. Its the sum of all headers and sections aligned to section alignment.

SizeOfHeaders - The size of headers + section table. This value can probably also be used as an offset to the first section.

DataDirectory - An array of 16 IMAGE_DATA_DIRECTORY structures, each relating to an important data structure in the PE file. This structure will be discussed in the next post.

The overall layout of the PE header:


Ollydbg can also parse PE headers into a meaningful display. Open the file in Olly and press the M button on top to open the memory map - this shows how the sections of the PE file have been mapped.

Now right click on PE header, select dump to CPU. Next, in the hex window, right click again and select PE header.
There are specific points of interest here. If the last 2 members are given bogus values:
e.g. LoaderFlags = ABDBFFDEh
NumberOfRvaAndSizes = DFFFDDEh

Olly determines this as a bad image and will eventually run the app without breaking at the entry point. To avoid this when analyzing malware, open it in a hex editor first and check if the NumberOfRvaAndSizes is 10h. 

In addition, the SizeOfRawData field can be given a very high value for one of the sections. This causes difficulty in a lot of debugging and disassembly tools.

An interesting twist - You might have noticed some garbage data between the DOS stub and the PE header. The origins of this data though not important is quite interesting.
PE files produced using M$ development tools contain extra bytes in the DOS stub inserted by the linker at compile time. In all cases, the penultimate DWORD is 'Rich'. This data is not present in files produced by other linkers( Borland, gcc)

The data includes encrypted codes to identify the components used to compile the PE file. The DWORD after 'Rich' is a key generated by the linker which repeats several times in the garbage data.When we compile a program the compiler puts the string "@comp.id" followed by a DWORD-sized compiler ID number in our obj file. When we link our obj file the linker extracts the @comp.id number and XORs it with the key and writes it in the "garbage" as the 2nd DWORD before "Rich"

 The first DWORD before "Rich" is the key XORed with a hard coded constant 536E6144h. If we search @comp.id in the obj file and substitute the DWORD after it with zeroes, we see that the second DWORD before "Rich" is the key.

Hello World in a hex editor:
Its possible to patch the linker to stop this. SignFinder.exe by Asterix allows you to quickly find the code which needs patching in any version of Link.exe

So open Link.exe in Olly and press Ctrl+G. Enter 0044510C (address from SignFinder + ImageBase). Then highlight that instruction, rightclick and select Binary->fill with NOPs.

Finally, right click again and select copy to executable->all modifications. Then click "copy all" and rightclick in the new window that pops up to save the file. If we use a patched linker to recompile the same program, we see the extra byes are gone.


The only difference are ofcourse e_lfanew, TimeDateStamp and SizeOfHeaders.

In the next post, we talk about The data directory.













Wednesday, February 26, 2014

Dissecting the PE File Format - 1

PE is the native Win32 file format. But, why know about it?
 - Adding code to executables
 - manually unpacking executables

In a packed executable, the import tables are destroyed and encrypted. The packer has code to unpack the code and it then jumps to the original entry point. If we manage to dump the memory region after the packer finished unpacking the executable, we still need to fix sections and import tables before our app runs. This cannot be done without knowing about the PE format. 


At a minimum the PE file has 2 section - code & data

There are 9 predefined sections - .text (executable section), .bss (data section), .data(data section), .rdata(data section), .rsrc(Resources), .edata(Export data), .idata(import data), .pdata  and .debug.

The names are largely irrelevant and only to assist the programmer.
The structure of the PE file is the same on disk and on memory. However, it is not copied exactly as is into memory. The windows loader decides which parts need mapping in and omits others. Data not mapped is placed at the end of the file past any parts that are mapped i.e. debug information.

The location of the file on disk is different from the location its loaded on memory because of the page-based virtual memory management that windows uses. When the sections are loaded into RAM, they are aligned to fit to 4kb memory pages, each section starting on a new page.

Virtual memory can be considered as an invisible layer between the software and the physical memory. Every time an attempt is made to access memory, a page table is consulted which indicates which physical memory address to use. Its not practical to have a page table entry for every byte of memory, so the processor divides memory into pages. This has several advantages:

  • enables creation of multiple address spaces. An address space is an isolated page table that only allows access to memory pertinent to the current program or process. It helps to keep the programs isolated and ensures that they dont infect each other.
  • enables the programmer to enforce certain rules on how memory is used. At load time, the memory manager sets access rights on memory pages for different sections based on its settings. This determines whether a given section is readable, writeable or executable. This means that each section starts on a fresh page.
    The default page size for Windows is 1000h and its wasteful to align executables to a 4kb page boundary on disk. Hence, the PE header has 2 different alignment fields - section alignment and file alignment. Section alignment is how sections are aligned in memory. File alignment  (200h) is how sections are aligned in the file on disk and its a multiple of disk sector size to optimize the loading process.
  • enables a paging file to be used on the hard drive to temporarily store pages from physical memory whilst not in use. An app, if idle, can be paged out to disk to make room for another app which needs to be loaded into RAM.
When PE files are loaded into memory, the in-memory version is known as the module.  The starting address where the file-mapping begins is called the HMODULE.  A module in memory represents all the code, data and resources from an executable file that is needed for execution, whilst the term process basiclaly refers to an isolated address space which can be used for running such a module.

THE DOS HEADER
At the start of a PE file, you have 64 bytes of the DOS header.  If a program is run in DOS, the DOS stub located immediately after the header is run. The DOS stub generally just prints a string like "This program cannot be run in DOS mode". When building an application, the linker links a default stub program called WINSTUB.EXE into your executable. This can be replaced using the -STUB linker option.
The DOS Header has 19 members of which magic and lfanew are of interest.
Magic part = 4Dh, 5Ah which signify a vlid DOS header and they translate to MZ
lfanew = DWORD at the end of the DOS header, just before the stub. It contains an offset to the PE header. The windows loader looks for this offset so it can skip the DOS stub and go directly to the PE header.

The last 4 bytes of the DOS header int he figure read 00 00 01 00 which is the offset to the PE header. The PE header begins with the signature 50 45 00 00 (letters "PE")
NE = 16-bit Windows New Executable
LE = Windows 3.x virtual device driver
LX = OS2/2.0

The PE header will be continued in the next post.