1 |
william |
336 |
parts used from: http://webster.cs.ucr.edu/Page_TechDocs/pe.txt |
2 |
|
|
Relative Virtual Addresses |
3 |
|
|
-------------------------- |
4 |
|
|
|
5 |
|
|
The PE format makes heavy use of so-called RVAs. An RVA, aka "relative |
6 |
|
|
virtual address", is used to describe a memory address if you don't know |
7 |
|
|
the base address. It is the value you need to add to the base address to |
8 |
|
|
get the linear address. |
9 |
|
|
The base address is the address the PE image is loaded to, and may vary |
10 |
|
|
from one invocation to the next. |
11 |
|
|
|
12 |
|
|
Example: suppose an executable file is loaded to address 0x400000 and |
13 |
|
|
execution starts at RVA 0x1560. The effective execution start will then |
14 |
|
|
be at the address 0x401560. If the executable were loaded to 0x100000, |
15 |
|
|
the execution start would be 0x101560. |
16 |
|
|
|
17 |
|
|
Things become complicated because the parts of the PE-file (the |
18 |
|
|
sections) are not necessarily aligned the same way the loaded image is. |
19 |
|
|
For example, the sections of the file are often aligned to |
20 |
|
|
512-byte-borders, but the loaded image is perhaps aligned to |
21 |
|
|
4096-byte-borders. See 'SectionAlignment' and 'FileAlignment' below. |
22 |
|
|
|
23 |
|
|
So to find a piece of information in a PE-file for a specific RVA, |
24 |
|
|
you must calculate the offsets as if the file were loaded, but skip |
25 |
|
|
according to the file-offsets. |
26 |
|
|
As an example, suppose you knew the execution starts at RVA 0x1560, and |
27 |
|
|
want to diassemble the code starting there. To find the address in the |
28 |
|
|
file, you will have to find out that sections in RAM are aligned to 4096 |
29 |
|
|
bytes and the ".code"-section starts at RVA 0x1000 in RAM and is 16384 |
30 |
|
|
bytes long; then you know that RVA 0x1560 is at offset 0x560 in that |
31 |
|
|
section. Find out that the sections are aligned to 512-byte-borders in |
32 |
|
|
the file and that ".code" begins at offset 0x800 in the file, and you |
33 |
|
|
know that the code execution start is at byte 0x800+0x560=0xd60 in the |
34 |
|
|
file. |
35 |
|
|
|
36 |
|
|
Then you disassemble and find an access to a variable at the linear |
37 |
|
|
address 0x1051d0. The linear address will be relocated upon loading the |
38 |
|
|
binary and is given on the assumption that the preferred load address is |
39 |
|
|
used. You find out that the preferred load address is 0x100000, so we |
40 |
|
|
are dealing with RVA 0x51d0. This is in the data section which starts at |
41 |
|
|
RVA 0x5000 and is 2048 bytes long. It begins at file offset 0x4800. |
42 |
|
|
Hence. the veriable can be found at file offset |
43 |
|
|
0x4800+0x51d0-0x5000=0x49d0. |