PE re-positioning of PE knowledge review
Relocation means correcting the meaning of the offset. such as an address bit 0x401234, Imagebase = 0x400000. Then the RVA is 1234. If ImageBase becomes 0x300000, then the correction is ImageBase + RVA = 0x300000+1234 = 0x301234.
First of all we know. An EXE file. Many DLLs (PE) are called to make up a number of PE files.
EXE file starts with the base address (ImageBase) is 0x40000. Let's say we call three DLLs a B C.
A DLL in EXE expanded base address location is 0x10000000
Then the location of the B DLL expansion is also 0x1000000 two DLL locations where the expansion is the same. Then there is the problem.
Such as:
The operating system will fix it for us. Swap the B DLL for a memory location. To expand. This is also why a lot of games plug-ins. And so on. Select DLL injection. Because the system helps you reposition all kinds of information. The code is written in the DLL.
such as: B DLL from 0x20 .... Expanded. Circumvent the use of the same address
Although this resolves the entry base address is different. Memory expansion is not the same. but we know. There are many RVA in the PE file. The RVA is stored relative to the offset of the imagebase. It would be nice if the PE file was RVA.
But not necessarily.
As shown in the code:
#include <stdio.h><stdlib.h><Windows.h>int g_value; int Main () { ten; }
View its disassembly
We found that when assigning a value to a global variable. The address is a fixed one. He's not RVA.
Run again:
We found the address changed. and hard coding is a fixed one. 0x012c813c, he compiles the binaries directly into the binary file.
He put the value of ImageBase + RVA. Compiled directly into the binary. That means. The address of this global variable. is an RVA + IMAGEBASE address. But he was compiled directly into the binary.
The problem lies in:
Assuming that the address of a compiled global variable is RVA + iMAGEbase assumed to be 0x1012345, then the position a expands is 0x10 ... Then the global variable address is correct. But if B compiles. The address is also 1012345. But the module base is loaded differently. Then there will be a problem. such as:
According to the above we have found the problem. So now we need a table. Recording that place requires relocation. Let's change the value of this place.
That is, we want to record where we need to reposition. The code is disassembled for viewing.
This is where the records need to be relocated.
The relocation table is the record of all addresses that need to be corrected. As long as the relocation table is available. We don't have to worry about our imagebase.
A very important table.
Ii. positioning and structure of reposition table
Reposition table. Locate the data directory in the extension header. The 6th item in the Data directory is the RVA offset of the relocated table. and the size of the reposition table.
Navigates to the relocation table, there is an additional structure to describe the relocation table.
struct _image_base_relocation { DWORD virtualaddress; DWORD Sizeofblock; The stored value is in bytes. How large is the byte. Indicates how fast a relocation is. // WORD typeoffset[1]; * pimage_base_relocation;
Look at the focus table on two members. It's actually very complicated. We set the virtualaddress to x sizeofblock y
As shown, a lattice is 1 bytes.
The first line is four bytes x. that is virtualaddress. Y is the second member.
Sizeofblock members you mean. In bytes. Represents how fast the relocation is. We know that. A PE file needs to be relocated in many places. For example, this record
Size is 16. That is, two relocation blocks, the size of our relocation table is as follows:
The following is the new relocation table. The structure is the structure of the reposition table, if the szieofblock size is 20 bytes. Then reposition the table size is 20 of its own.
The third, and so on, the end of the relocation table is kept looking down, knowing that the last Relocatable table structure member you are 0
The reason for this design:
Arithmetic questions.
For example, we have address 101234 101235 101236 This fix has 10,000 addresses.
Then each address has a 4-byte. Then 4 * 10000 = 40,000 bytes. That is, we are going to prepare a 40,000-byte table to save the relocation.
But we found a pattern. The offset of the table we want to fix is very close, 1234 1235 ....
Then can we do that. We're going to take 100000 out. Two bytes of storage 1234 additional two addresses store 1235, without having to prepare four bytes. The small offset of our two bytes of storage. In this way, our table's bytes will shrink by half.
Virtualladdress is the 100000 value that is stored, which is the address that needs to be "base" "public."
Sizeofblock is the following offset by how big, we want to fix the offset is virtualaddress + Sizeofblock below the value.
Such as:
Our relocation table, the base address to be corrected is 0x11000, and the size is 54. Then the offset to be corrected is "36b0" "36BC" "36e0" ....
Our base + offset is the position to be corrected.
The concept of offset:
The relocation table is stored according to a physical page (4KB). That is, a 4kb of memory, there is a relocation block, a relocation table, just the relocation of their current physical page.
The size of the record offset for a relocated table is 2 bytes , or 16 bits. And the size of the record offset. is determined by the Sizeofblock.
But we record the position of the offset, 12 bits is enough. 4-bit high. Move him. The offset is corrected only if it is not recorded. Only when the height is 4 bits is 3. Relocation (base + offset)
Real fix location virtualaddress + (high four bit is 3?) Low 12-bit offset: a value that doesn't matter.)
That is, the high four-bit 3 Vir + low 12-bit offset is equal to the RVA that is really to be repaired, such as the 36b0 high of 3 low 12 bits is 6b0 to repair the RVA = Vir + 6b0, if the imagebase of the current DLL is the virtual address to be repaired (VA) we The calculation is RVA
If the high is not 3, then this value is irrelevant. Because of the reason for the memory alignment.
For example, relocate a table. 0x11000 represents the block location that is currently being repaired. To fix an offset address the first is 36b0. A high level of 3 is to be repaired.
So the low is 6b0. So the location of the fix is 0x116b0. 0x116b0 + The imagebase of the current PE file is the location to relocate
The imagebase of the current PE is the 0x400000 reposition place for the 0x4116b0 position.
Our first fix is the location of the 4116b0, from memory. Disassembly view. The value of the 4116b0 location is 0x0041813c. That is, the value of this position. We need to relocate. Which is the program we wrote above. When assigning a value to a global variable. The address of the global variable. Changes are required.
Values that need to be relocated. is the RVA value of the global variable + Imagebase is filled in here. Global variables are stored in the data section in memory. So watch the previous blogs. You can know how to position global variables in the file location.
Iii. Summary Relocation
The relocation table has two members. Virtualladdress Sizeofblock
1.virtualladdress records the starting address where the current physical page needs to be relocated.
2.sizeofBlock records how large the relocation table is. Remove 8 bytes (reposition table size) The following is a record of the offset that the relocation table needs to relocate.
3. The offset is 2 bytes of storage. 12-bit storage offset. The high 4-bit storage is relocated. A height of 4 bits of 3 is required for relocation. Virtuall + Low 12-bit is the RVA offset to be corrected.
The re-positioning table of PE for PE knowledge review