Converting raw offsets (the one in a file you see in a HexEditor)
to virtual offsets (the one you see in a debugger) is very useful if you work
with the PE header. This short essay will explain how to convert them. For this
purpose you need to know some values you can read from the PE header of Win32
PE files (EXE/DLL). You need to know the ImageBase of the file and you have
to perform some calculations with the section definitions of the PE header.
Below you see an example of a PE header from the beginning of the file (where
it is actually a MZ header until offset 0x80) until the section definitions
end (offset 0x23F). The example is taken from my notepad.exe.
00000000 4D5A 9000 0300 0000 0400 0000 FFFF 0000 MZ..............
00000010 B800 0000 0000 0000 4000 0000 0000 0000
This e-mail address is being protected from spam bots, you need JavaScript enabled to view it
00000020 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000030 0000 0000 0000 0000 0000 0000 8000 0000 ................
00000040 0E1F BA0E 00B4 09CD 21B8 014C CD21 5468 ........!..L.!Th
00000050 6973 2070 726F 6772 616D 2063 616E 6E6F is program canno
00000060 7420 6265 2072 756E 2069 6E20 444F 5320 t be run in DOS
00000070 6D6F 6465 2E0D 0D0A 2400 0000 0000 0000 mode....$.......
00000080 5045 0000 4C01 0500 6591 4635 0000 0000 PE..L...e.F5....
00000090 0000 0000 E000 0E01 0B01 030A 0040 0000 .............@..
000000A0 0072 0000 0000 0000 CC10 0000 0010 0000 .r..............
000000B0 0050 0000 0000 4000 0010 0000 0010 0000
This e-mail address is being protected from spam bots, you need JavaScript enabled to view it
000000C0 0400 0000 0000 0000 0400 0000 0000 0000 ................
000000D0 00E0 0000 0004 0000 D509 0100 0200 0000 ................
000000E0 0000 1000 0010 0000 0000 1000 0010 0000 ................
000000F0 0000 0000 1000 0000 0000 0000 0000 0000 ................
00000100 0060 0000 8C00 0000 0070 0000 E453 0000 .`.......p...S..
00000110 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000120 00D0 0000 3C09 0000 0000 0000 0000 0000 ....<...........
00000130 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000140 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000150 0000 0000 0000 0000 E062 0000 4002 0000
This e-mail address is being protected from spam bots, you need JavaScript enabled to view it
00000160 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000170 0000 0000 0000 0000 2E74 6578 7400 0000 .........text...
00000180 9C3E 0000 0010 0000 0040 0000 0010 0000 .>
This e-mail address is being protected from spam bots, you need JavaScript enabled to view it
00000190 0000 0000 0000 0000 0000 0000 2000 0060 ............ ..`
000001A0 2E64 6174 6100 0000 4C08 0000 0050 0000 .data...L....P..
000001B0 0010 0000 0050 0000 0000 0000 0000 0000 .....P..........
000001C0 0000 0000 4000 00C0 2E69 6461 7461 0000
This e-mail address is being protected from spam bots, you need JavaScript enabled to view it
000001D0 E80D 0000 0060 0000 0010 0000 0060 0000 .....`.......`..
000001E0 0000 0000 0000 0000 0000 0000 4000 0040 ............@..@
000001F0 2E72 7372 6300 0000 0060 0000 0070 0000 .rsrc....`...p..
00000200 0060 0000 0070 0000 0000 0000 0000 0000 .`...p..........
00000210 0000 0000 4000 0040 2E72 656C 6F63 0000 ....@
This e-mail address is being protected from spam bots, you need JavaScript enabled to view it
00000220 9C0A 0000 00D0 0000 0010 0000 00D0 0000 ................
00000230 0000 0000 0000 0000 0000 0000 4000 0042
This e-mail address is being protected from spam bots, you need JavaScript enabled to view it
Example 1 - Converting raw offset 7800h to a virtual offset:
At first we have to find out in which section raw offset 800h lies. The section
definitions start F8h bytes after the PE header start, in our case 178h. It
is this part:
00000170 2E74 6578 7400 0000 .........text...
00000180 9C3E 0000 0010 0000 0040 0000 0010 0000 .>
This e-mail address is being protected from spam bots, you need JavaScript enabled to view it
00000190 0000 0000 0000 0000 0000 0000 2000 0060 ............ ..`
000001A0 2E64 6174 6100 0000 4C08 0000 0050 0000 .data...L....P..
000001B0 0010 0000 0050 0000 0000 0000 0000 0000 .....P..........
000001C0 0000 0000 4000 00C0 2E69 6461 7461 0000
This e-mail address is being protected from spam bots, you need JavaScript enabled to view it
000001D0 E80D 0000 0060 0000 0010 0000 0060 0000 .....`.......`..
000001E0 0000 0000 0000 0000 0000 0000 4000 0040 ............@..@
000001F0 2E72 7372 6300 0000 0060 0000 0070 0000 .rsrc....`...p..
00000200 0060 0000 0070 0000 0000 0000 0000 0000 .`...p..........
00000210 0000 0000 4000 0040 2E72 656C 6F63 0000 ....@
This e-mail address is being protected from spam bots, you need JavaScript enabled to view it
00000220 9C0A 0000 00D0 0000 0010 0000 00D0 0000 ................
00000230 0000 0000 0000 0000 0000 0000 4000 0042
This e-mail address is being protected from spam bots, you need JavaScript enabled to view it
The colored values tell us the following values:
|
Name of the Section
|
Virtual Size
|
Virtual Offset
|
Raw Size
|
Raw Offset
|
|
.text
|
3E9C
|
1000
|
4000
|
1000
|
|
.data
|
84C
|
5000
|
1000
|
5000
|
|
.idata
|
DE8
|
6000
|
1000
|
6000
|
|
.rsrc
|
6000
|
7000
|
6000
|
7000
|
|
.reloc
|
A9C
|
D000
|
1000
|
D000
|
The section definitions should be easy to understand. If not - or if you want
deeper knowledge about it - consult a PE reference. The orange
coloured values are not of interest for the conversion but have other functions.
We want to convert raw offset 7800h. It seems obvious that this offset lies
in the .rsrc section because it starts at 7000h (Raw Offset) and is 6000h bytes
long (Raw Size). Offset 7800h is located 800h bytes after the section starts
in the file. Since the sections are copied to the memory just like they are
in the file, this address will be found 800h bytes after the section starts
in memory (7000h; Virtual Offset). The offset we search is at 7800h. This is
absolutely not common that the raw offset equals the virtual offset (without
imagebase). In this case it is only because the sections start at the same offset
in memory and in the file.
The general formula is: RawOffsetYouHave-RawOffsetOfTheSection+VirtualOffsetOfTheSection+ImageBaseOfTheFile
The ImageBase is another value you can read from the PE header: It is a DWORD
value 34h bytes after the PE header begins. In our case it is 400000h (like
in 99.9% of all Win9X EXE files).
The conversion from a virtual offset to a raw offset just goes the other way
round:
The general formula is: VirtualOffsetYouHave-ImageBase-VirtualOffsetOfSection+RawOffsetOfSection
For 40A000 that is: 40A000-400000-7000+7000 = A000
|