The transformation of the RVA and Foa of PE in the review of PE knowledge two states of PE
First of all we know that PE has two states. One is memory expansion. One is the state in the file. So we have a need at this point.
We want to change the initial value of a global variable. What to do at this time. You know the virtual address. or the file location. So how do you convert yourself.
This means that the data in memory is located by the section data in the file. or vice versa.
Before we find out, we have to first make a few concepts.
ImageBase: module base Address. The beginning of the program.
VA: Full name virtualaddress virtual address. is the in-memory virtual address. such as 0x00401000
Rva:rva is the relative virtual offset. is the offset address. such as 0x1000. The RVA of the virtual address 0x00401000 is 0x1000. RVA = Virtual Address-imagebase
FOA: File offset. Is the address where the file is located.
Second, because of the two states of PE. So you need to convert.
The above describes what is VA RVA and Foa So why should we convert.
The reason is this. The data of our program. The address in the PE file is assumed to be 0x400, so it is 0x1000 position when expanded in memory.
So how do we get through the memory location. Find the location of this data in the file. or vice versa. If it is found, it can be modified.
The reason is that there are two states of PE. There is memory alignment with the file. If the memory alignment is the same as the file alignment. The data is in the same location.
For example, file alignment is 0x1000, and memory is the same. The value of the 0x1000 location in the file. The value stored in the memory is the same as PE. So there is no need to convert. Change directly in the file or in memory.
Because the alignment values are not the same. That's why we need to convert.
For example:
The file alignment value is 0x200, and the memory alignment is 0x1000
Iii. Conversion method
Now that you know the memory state of PE. As well as the file status form. Then the conversion is well understood.
1. Memory-to-file offset calculation 1.1. Calculate RVA
This one is about the memory-to-file offset. Just know a memory address. We want to see where the files are stored.
The first step: we know that PE is expanded in memory. It is in the imagebase position. The header is the same as the file. Only the section data is expanded in different locations.
So the first is our memory address-image the RVA
Below our memory address I set it to X.
x-imagebase = RVA The relative offset of our x position in memory is obtained. The relative offset is where we calculate the address at the beginning of the position.
The imagebase is stored in the extension head. We can look at it. Specifically, you can see the first few words. Attribute resolution.
Note that the 16 binary is added to the calculation.
According to the RVA we derive from above. And then we're going to find our data in the file from the first number of RVA bytes. This is not possible. Because file alignment is not the same as memory alignment. So we have to think about alignment. If the file alignment is the same as the memory alignment. Then you can go and find it.
2. Addressing Foa
Now that the RVA has been found. Then find out where Foa is. That is, where the file is offset. Finding this value is simple. A few steps are required.
2.1. Determine which section/head the RVA belongs to.
If the RVA belongs to the head (DOS+NT) then no calculations are required. Because the header is expanded in the root memory of the file. Find the RVA byte directly from the start position.
If you are not in the head, you must judge in that section. Determines the start position of the section. and the end position. Our RVA is inside this value.
Where the end of the section virtual address is the size + virtual address size that is aligned with the section data. For details, refer to the previous section table parsing.
Formula: RVA >= section. Virtualaddress && RVA <= (knots. Virtualaddress + knots. Sizeofrawdata)
2.2 Calculates the difference offset. The offset of the virtual address from the starting position of the section data.
Then calculate the difference offset:
difference = RVA-section. virtualladdress
Difference Offset:
Why is the difference calculated? Because the difference we calculate is the offset of our RVA distance from the beginning of our section data. Because this position is not going to change.
For example: The section data start position is 0x1000 our RVA = 0x1024 then the difference is 0x24. If the section data in the file begins at the location of 0x400. Then our difference offset will not change. Then the file offset + difference offset. Then there is the location in the file. such as 0x424
2.3 Calculation Foa
Foa is a good calculation. The difference offset is already out. We will know the offset of the start position of our RVA distance section data. Then we add the file offset is Foa
Formula: FOA = Difference offset + section. Pointtorawdata
Memory goto File Offset Summary:
1. Calculate RVA formula: X-imagebase = = RVA
2. Calculate the difference offset. RVA-section. virtualaddress = = Difference offset.
3. Calculate FOA Difference offset + section. Pointertorawdata = = FOA
2. File offset to memory virtual address
The above explains that we can navigate to the location in the file based on the virtual address. Then instead. We can also pass the file location. Navigate to the virtual address.
What you need to understand is the difference offset. It's just a role swap. .
Set X as any position of the section data
1. Calculate the difference offset: X-section. Pointertorawdata (where the section data begins in the file) = = Difference offset.
2. Calculate RVA difference offset + section. Virtualladdress (where the section data is expanded in memory) = = RVA
3. Compute virtual Address: RvA + ImageBase = = VA
It's important to note that our X is in which section. x <= section. Pointertorawdata + knots. Sizeofrawdata
Iv. Practical Exercises
We write a program. Its code is as follows:
#include <stdio.h><stdlib.h>int0x12345678; int Main (intChar *argv[]) { printf (" global variable address =%p \ r \ n ", &g_testvalue); printf (" global variable value =%x \ r \ n", g_testvalue); GetChar ();}
PS: If it is a vs series compiler, remove the random base address from the join in properties---. Otherwise you need to calculate. Or you can change the file properties of the file header in PE. Change to. 0x0103
Program:
At this point we already know the global variable address. Then we're going to switch to the file. This global variable address is modified. That is, we modify the file. A means of modifying the values of our global variables.
Ideas:
1. Calculate the RVA. We also know how RVA is calculated. We need to look at the value of the ImageBase member of the extension header in the PE. I've seen it here. The value is 0x400000. Then our RVA = 19000
2. Determine which section belongs to, Calculate travel value offset
In our. Data section. The difference offset calculates the result as 0.
3. Calculate the FOA position.
Because the compiler now has the same file alignment and memory alignment. So we're not allowed to do calculations. The file offset is the Foa location.
Otherwise we have a difference offset plus a file offset = = FOA. Now our difference offset is 0 0 + the section offset is the position of the global variable in the file.
7400 is our Foa.
4. Jump to Foa to modify the value of a global variable
Jump to our Foa position and we can see that the initial value of our global variable is the 0x12345678 of the small end mode, then we make the modification. Save the file.
5. Modify the file re-open program
Modified to 0x55555555, re-open the program to view the results.
This is the actual combat of memory-to-file offset. If the person who has learned the converse should have been exposed to OD. or x64dbg. If we modify in memory. To save to a file. That's the formula.
Change of RVA and Foa of PE in PE knowledge review