The image_optional_header32 structure is followed by the image_optional_header structure. As the name implies, this is an optional image header and an optional structure. However, the image_file_header structure described in the previous lesson is far from defining the attributes of the PE file. Therefore, these attributes are defined in the image_optional_header structure. Therefore, these two structures are combined to form a complete "PE file structure ".
Then we should talk about it in a simple way [1].Definition of the image_optional_header32 structure typedef struct _ image_optional_header {// standard fields. // + 18 h word magic; // flag, ROM image (0107 H), common executable file (010bh) + 1ah byte majorlinkerversion; // The main version of the linked program + 1bh byte minorlinkerversion; // The minor version of the linked program + 1ch DWORD sizeofcode; // the total size of all sections containing code + 20 h DWORD sizeofinitializeddata; // total size of all nodes with initialized Data + 24 h DWORD sizeofuninitializeddata; // size of all nodes with uninitialized data + 28 h DWORD addressofentrypoint; // Program execution entry RVA + 2ch DWORD baseofcode; // The starting RVA + 30 h DWORD baseofdata of the code block; // The starting RVA of the data block /// nt additional fields. the following fields are added to the NT structure. // + 34 h DWORD imagebase; // The preferred loading address of the program + 38 h dword sectionalignment; // The alignment size of the block in the memory + 3ch DWORD filealignment; // The alignment size of the block in the file + 40 h word majoroperatingsystemversion; // The primary version number of the minimum version number of the operating system + 42 h word minoroperatingsystemversion; // The minor version number of the Minimum operating system version + 44 h word majorimageversion; // The major version number that can be run on the operating system + 46 h word minorimageversion; // The minor version number that can run on the operating system + 48 h word majorsubsystemversion; // The major version number of the minimum subsystem version + 4ah word minorsubsystemve Rsion; // The minor version number + 4ch DWORD win32versionvalue of the minimum subsystem version is required; // a field is not required. If it is not used by viruses, it is generally 0 + 50 h DWORD sizeofimage; // The total size after the image is loaded into the memory + 54 h DWORD sizeofheaders; // all headers + block table size + 58 h DWORD checksum; // check the image and + 5ch word subsystem; // The expected subsystem of the executable file + 5eh word dllcharacteristics; // when the dllmain () function is called, the default value is 0 + 60 h DWORD sizeofstackreserve; // The stack size during initialization + 64 h DWORD sizeofstackcommit; // The stack size actually submitted during initialization + 68 h DWORD sizeofheapreserve; // during initialization Heap size retained + 6ch DWORD sizeofheapcommit; // The heap size actually submitted during initialization + 70 h DWORD loaderflags; // The default value is 0 + 74 h DWORD numberofrvaandsizes; // The number of items in the data directory below. This field has been 16 + 78 h image_data_directory datadirectory [partition] since Windows NT was released. // The data directory table} image_optional_header32, * pimage_optional_header32; in fact, most of the fields in this structure are not important. You can understand the meaning of these fields from the annotations. I will explain the important fields in detail below. In addition, we must never stick to this stuff. We need to change the vast majority of time, rather than remember it. You don't need to take notes. Just repost this article to your blog. The addressofentrypoint field specifies the entry address when the file is executed. This is an RVA address (the meaning of RVA is described in the next section ). If you attach a piece of code to an executable file and want the code to be executed first, you only need to point this entry address to the additional code. The imagebase field indicates the preferred Mount address of the output file. That is to say, when the file is executed, if possible, windows first loads the file to the address specified by the imagebase field, only when the specified address has been used by the ** module, files are loaded into the ** address. When the linker generates an executable file, it generates the machine code corresponding to this address. Therefore, when the file is loaded into this address, it does not need to be relocated. The loading speed is the fastest, if the file is loaded to the ** address, it will have to be relocated, which takes a little longer. For an EXE file, because each file always uses an independent virtual address space, the priority load address cannot be occupied by the ** module, so the EXE can always be loaded according to this address, this also means that the EXE file no longer needs to be relocated. For DLL files, because multiple DLL files use the address space of the host EXE file, it cannot be ensured that the preinstallation address is not used by the ** DLL, therefore, the DLL file must contain relocation information, just in case. Therefore, in the characteristics field of the image_file_header structure described above, the image_file_relocs_stripped bit of the DLL file is always 0, while the flag bit of the EXE file is always 1. When linking, you can specify the/base: Address option for link.exe to customize the priority load address. If this option is not specified, the default priority load address of the EXE file is set to 00400000 H, the default load address of DLL files is set to 10000000 H. The sectionalignment field and the filealignment field sectionalignment field specify the alignment unit after the section is loaded into memory. That is to say, the address loaded in each section must be an integer multiple of the values specified in this field. The filealignment field specifies the alignment unit when the section is stored in the disk file. The subsystem field specifies the subsystem that uses the interface. Its value is shown in Table 17.3. This field determines how the system creates an initial interface for the program. The/subsystem: ** option at the link specifies the value of this field, in the programming in the previous chapter, we already know that if the subsystem is specified as windows Cui, the system will automatically create a console window for the program and specify it as Windows GUI, the window must be created by the program itself. Value and meaning of the interface subsystem
| Value |
Predefined values in windows. inc |
Meaning |
| 0 |
Image_subsystem_unknown |
Unknown Subsystem |
| 1 |
Image_subsystem_native |
Subsystems (such as drivers) are not required) |
| 2 |
Image_subsystem_windows_gui |
Windows GUI |
| 3 |
Image_subsystem_windows_cui |
Windows console interface |
| 5 |
Image_subsystem_os2_cui |
Os2 console interface |
| 7 |
Image_subsystem_posix_cui |
POSIX console interface |
| 8 |
Image_subsystem_native_windows |
Subsystem not required |
| 9 |
Image_subsystem_windows_ce_gui |
Windows CE graphical interface |
The datadirectory field is one of the most important fields. It consists of 16 identical image_data_directory structures, although the data in the PE file is put in different sections according to the page attribute after the memory is loaded, however, the data in each section can be divided into exported tables, imported tables, resources, relocated tables, and other data blocks by purpose, the 16 image_data_directory structures are used to define data blocks for different purposes (as shown in Table 17.4 ). The definition of image_data_directory structure is simple. It only specifies the location and length of a data block. Image_data_directory structvirtualaddress DWORD? ; Data start rvaisize DWORD? ; Description of the data block length image_data_directory ends data directory list
| Suo Yin |
Predefined index value in windows. inc |
Corresponding data block |
| 0 |
Image_directory_entry_export |
Export table |
| 1 |
Image_directory_entry_import |
Import table |
| 2 |
Image_directory_entry_resource |
Resources |
| 3 |
Image_directory_entry_exception |
Exception (details) |
| 4 |
Image_directory_entry_security |
Security (details) |
| 5 |
Image_directory_entry_basereloc |
Relocation table |
| 6 |
Image_directory_entry_debug |
Debugging information |
| 7 |
Image_directory_entry_architecture |
Copyright information |
| 8 |
Image_directory_entry_globalptr |
Details |
| 9 |
Image_directory_entry_tls |
Thread Local Storage |
| 10 |
Image_directory_entry_load_config |
Details |
| 11 |
Image_directory_entry_bound_import |
Details |
| 12 |
Image_directory_entry_iat |
Import function Address Table |
| 13 |
Image_directory_entry_delay_import |
Details |
| 14 |
Image_directory_entry_com_descriptor |
Details |
| 15 |
Unused |
|
When you look for specific data in the PE file, it starts from the image_data_directory structure. For example, to access resources, you must start from the 3rd image_data_directory structure (index 2) to obtain the size and location of the resource data block. Similarly, if you want to check which DLL files are imported to the PE file and which API functions, you must first obtain the position and size of the import table from the 2nd image_data_directory structure.
*.*
Image_optional_header32 Structure Function