This section is the last one. In fact, there are many other things in the PE format, such as resources, which are also very complicated, but I am not interested in it, write something you are interested in-Base Relocations of PE files ). As we have mentioned above, each module has a priority loading address ImageBase. This value is provided by the connector, therefore, the address in the connector Generation Command is generated on the premise that the module is loaded to ImageBase, so that once the module is not loaded to ImageBase as expected, then the commands in the program need to be modified. The following is an example: assume that an executable file has a base address of 0x400000. 0x2134 is a pointer pointing to a string. The string starts at the actual address 0x404002, so the pointer content should be 0x404002. You can load the file, but the loader decides to map it to the actual address 0x600000. The difference between the base address of the connector and the start address of the actual load is called delta. In this example, delta is 0x20000. The position of the entire image is increased by 0x20000, and the string is of course (now it should be 0x604002 ). So the pointer to the string is wrong. delta should be added to the pointer value. To enable the Windows loader to make such adjustments, the executable file contains many base-relocation item items for those locations that store pointers (in this example, 0x2134. The loader must add delta to each address. In this example, the loader should add 0x20000 to the original pointer value (0x404002) and write the result 0x604002 back to the original position. Display this process:
Figure 1
The above term "base relocation item" appears. The loader uses it to know which commands need to be modified if the module is not loaded as expected. Therefore, the focus of our research in this section will be "baseline relocation item 」. First, the loader uses the data directory to locate the "baseline relocation item. Then let's take a look at the true face of "base relocation item. The baseline relocation item is encapsulated as a series of continuous segments with different lengths. Each segment describes the relocation information of a 4 K page (that is, one page) in the image (because each page has different numbers of commands that require duplicate positions, the segment length varies ). They start with an IMAGE_BASE_RELOCATION structure in the following format:
DWORD VirtualAddress
This field contains the initial RVA values of these base relocation items. The offset position of each "base relocation item" (that is, the 12-bit lower of the TypeOffset field below, which is the offset of the instruction relative to the first instruction on its page) this value must be added to form a real RVA, pointing to the baseline relocation item 」.
DWORD SizeOfBlock
Structure size, plus all the "base relocation data items" (all WORDs) following ). To determine the number of "base relocation item" in the block, first subtract this value from the size of the IMAGE_BASE_RELOCATION structure (8 bytes) and then divide it by 2 (WORD size ). If this field is 44, there are 18 base relocation item items 」:
(44-sizeof (IMAGE_BASE_RELOCATION)/sizeof (WORD) = 18
WORD TypeOffset
This is not a separate WORD. In fact, it is an array of WORDs. The number of array elements can be calculated from the previous formula. The bottom 12 digits of each WORD represent the offset position of the base relocation data item, but the VirtualAddress field value of the header of the base relocation data item must be added. The maximum four locations are the type of the "base relocation data item. For PE files executed in Intel CPUs, you will see two types:
0 (IMAGE_REL_BASED_ABSOLUTE): This "base-Relocated data item" is meaningless and only used for filling. This makes the total size of all "base-Relocated data items" a multiple of DWORD.
3 (IMAGE_REL_BASED_HIGHLOW): add the delta value to the RVA value to be calculated. Other types are also defined in WINNT. H. Most of them are for CPUs other than i386.
The following lists some basic relocation data items. Note that the RVA value has been corrected by the VirtualAddress field in the IMAGE_BASE_RELOCATION structure.
Virtual Address: 00001000 Size: 0000012C
00001032 HIGHLOW
2017106d HIGHLOW
201710af HIGHLOW
201710c5 HIGHLOW
// Rest of chunk omitted...
Virtual Address: 00002000 Size: 0000009C
201720a6 HIGHLOW
00002110 HIGHLOW
00002136 HIGHLOW
00002156 HIGHLOW
// Rest of chunk omitted...
Virtual Address: 00003000 Size: 00000114
2017300a HIGHLOW
2017301e HIGHLOW
Listen 303b HIGHLOW
2017306a HIGHLOW
// Rest of chunk omitted...
Through the above instance, we can see that the Virtual Address of the adjacent section is different from 0x1000, that is, 4 k, this confirms the above-mentioned "each section describes a 4 K page (that is, a page) in the image) "At the same time, we can see that the Virtual Address of the first section is 00001000, which is normal. the RVA of the text segment.
Now the problem is basically clear. Once the module is not loaded to the expected position, the loader will correct the repair instructions to be corrected based on the "base relocation data item, in this way, the program can be correctly executed.