We have already looked briefly at the the DOS and PE headers in the first post on Portable Executable format. In this post we’ll have a closer look at the sections in portable executable files. The bulk of the executable that contains code that the programmer codes lies in sections. The purpose of sections is to provide a logical and physical separation to the different parts of a program. It also helps while loading the executable file into memory during execution. Since different sections make access and loading in pages easier. The abstract view of a portable executable file is as shown in the figure:
As we can see most of the file consists of sections. It is important to know the different types and their importance. All PE files contain atleast 2 sections: the code and the data section. An application for Windows NT has 9 pre-defined sections named .text, .bss, .rdata, .data, .rsrc, .edata, .idata, .pdata and .debug. Not all applications need all the sections and some applications may need a different kind of section. The sections that are most commonly present in an executable are:
- Executable Code Section (commonly named .text)
- Data Sections (of which .data, .rdata, .bss are types)
- Resources Section (commonly named .rsrc)
- Export Data Section (commonly named .edata)
- Import Data Section (commonly named .idata)
- Debug Information Section (commonly named .debug)
Note that the names are not binding since the OS does not bother with the names of the sections and in fact discards the names. The operating system finds, extracts and manages the different sections using a data structure known as the Section Table. The section table is an array of the IMAGE_SECTION_HEADER structure, each of them containing information about one section. The information that the structure contains, includes but is not restricted to, the virtual size, virtual size and characteristic flags (which contain information about whether the section contains executable code or readable data,write permissions nd so on). The number of entries in the section table are therefore equal to the number of sections defined in the executable file. Let’s take a look at some of the sections:
Executable Code (Code\.text ) Section
This section contains all the code in one large section. Since modern OS use paging, having a larger unified code section makes it easier for both the OS and the programmer to manage and develop.This section contains the code from where execution starts and pointers to the import table.
The .bss section type of data section represents uninitialized data. This is to reduce the size of the executable file. Since some variables may not have values until the program is executed, it becomes a waste of space to declare and allocate space in the executable file. Hence the .bss section is used to declare the variables in the memory during execution. The .rdata section contains data that is to be only readable, such as literal strings, constants and debug directory information. Data which does not fall into the any of the two above categories, falls into the .data section.
The .rsrc section contains resource information for a module. The first 16 bytes compromises a header like other sections, but this section’s data is further structured into a hierarchy.
The .edata section contains the Export Directory for an application or DLL. It basically contains the information about the names and addresses of exported functions. Dynamic Linked Libraries provide a way to modularize applications so the functions can be reused and reused more easily. This section contains a export directory that provides the address and offset of the functions to programs that import the DLL.
The .idata section contains various information about imported functions including the Import Directory and Import Address Table. The most important of the structures defined in this section is the Import Directory and the Import Address Table. The import section makes implementation of modularity easier. Since the DLL can be modified at any time, the import section protects the application from such changes.
Debug Information Section
Debug information is initially placed in the .debug section. The PE file format also supports separate debug files as a means of collecting debug information in a central location. This section contains the debug information.
Practical View using Assembly
The above program is assembly code, compiled using FASM. It’s visible that there have been three sections defined, note that there is also an import section defined in the training.inc file included. The executable file that is formed as a result of compiling the above is this:
The screenshot basically shows the hex code version of the section table. We can see the name of the sections as defined in the code. Further posts detailing more intricate details of Portable Executable files is in the works.