Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Ja, so geht die Umrechnung von RVA zu FileOffset aber nicht
00050EFC müsste es sein - falls wir über die gleiche calc Version verfügen.
Wichtig: die Angaben im PE-Header sind üblicherweise RVAs, keine VAs (auch wenn in Dokus ab und zu etwas anderes steht). Die VA der Datadirectory wäre bei ASLR/DLLs gar nicht bekannt
Umrechnung "zu Fuß": RVA nehmen, zugehörige Section in Section-Headers suchen, Minus VA(oder VirtualOffset, je nach Dokumentation) der Section, Plus RawOffset dieser Section.
Ansonsten würde ich auch zu Lernzwecken den CFF Explorer empfehlen, da dieser neben einem eingebauten Hexeditor auch das komplette PE Format samt RVA/VA/FileOffset/Disassembly/Ressourcenansicht usw. "kann".
Vornweg: wie schon gesagt, man sollte ganz strickt zwischen "FileOffset", VA und RVA unterscheiden.
RVA = relativ zu dem "Anfang", gilt aber für eine schon in den Speicher geladene Executable.
VA = "absolute" Adresse im Speicher. Kann prinzipiell aus RVA + (ImageBase Wert) berechnet werden, kann aber bei DLLs oder Exen, die Relocations mitführen variieren (da die ImageBase vom System bestimmt wird => üblich seit "ASLR" bei Exen und schon viel viel viel länger bei DLLs (da bei einem Haufen DLLs öfters vorkommen kann, dass die "gewünschte" aka im PE-Header eingetragene Adresse schon belegt ist)).
FileOffset: Position in der Datei selbst, wird benötigt, wenn man per Hexeditor oder über eigenen Code PE auslesen möchte. Die Angaben im PE Header sind aber _alle_ als RVA zu betrachten. Umrechnung ist nur "umständlich" möglich - über SectionHeader Einträge.
Zu beachten wäre noch, dass die Werte, die man im Hexeditor sieht, im Little-Endian Format vorliegen.
---------------------------------------------------
Konkretes Beispiel: die kompilierte Version (VS 2010, 32-Bit, statisch gelinkt) von http://www.hackerboard.de/code-kitchen/46624-c-bitmap-erstellen.html
(angehängt)
Mit "Dump" ist ein Ausschnitt aus dem Hexeditor gemeint.
---------------------------------------------------
Part1:
Wo ist der PE Header?
Code:
OLD EXE (MZ header)
+0 WORD e_magic; // Magic number MZ
2 WORD e_cblp; // Bytes on last page of file
28 WORD e_res2[10]; // Reserved words
3C DWORD e_lfanew; // File address of new exe header
NEW EXE
+0 PE
4 WORD Machine;
6 WORD NumberOfSections;
8 DWORD TimeDateStamp;
C DWORD PointerToSymbolTable;
10 DWORD NumberOfSymbols;
14 WORD SizeOfOptionalHeader;
...
70 DWORD LoaderFlags;
74 DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
/* IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16 */
80 DWORD ImportDirectory RVA
84 DWORD ImportDirectory Size
Die Offsetangaben sowohl hier wie auch in der offiziellen Dokumentation beziehen sich auf den PE-Headerstart .
In unserem Fall wäre das also Adresse von "PE" + 0x80 = 0xE0 + 0x80 = 0x160
4c 12 01 => 0x01124C
Das ist eine RVA. Damit kommen wir im Hexeditor nicht weiter. Umrechnung:
(das Suchen der SectionHeaders und das Auslesen der Werte im Hexeditor spare ich mir in diesen Part ):
0x01124C
gehört also zu der 2 Section ".rdata" (startet an 0xF000 und endet an 0xF000+0x2A00 = 0x11A00)
VirtualAddress (so wird es jedenfalls in fast allen PE Editoren und Dokumentationen bezeichnet) ist trotzem eine relative Angabe
pecoff hat gesagt.:
For executable images, the address of the first
byte of the section relative to the image base
when the section is loaded into memory.
also 5 DWORDS = 20 Bytes. Das Ende wird durch eine "leere" Struktur signalisiert - also 5 x 00 00 00 00 (im Dump oben ab 0xfe60).
Also hier nur 1 ImportDir Eintrag.
Jetzt sollte man wissen, dass nicht alle Einträge "Pflichtangaben" sind (OriginalFirstThunk, TimeDataStamp und ForwarderChain sollten optional sein) - meist wird es aber im Zusammenhang mit "nicht-ms" Linkern oder Packern interessant.
Wir können uns die Einträge mal ansehen:
erster Eintrag ist "OriginalFirstThunk"
74 12 01 00 => 0x011274 = RVA (zum Umrechnen nutze ich nun die eingebaute Funktion von CFF Explorer) => FileOffset = 0000FE74
Dumpausschnitt:
An import lookup table is an array of 32-bit numbers for PE32 or an array of 64-
bit numbers for PE32+. Each entry uses the bit-field format that is described in the
following table. In this format, bit 31 is the most significant bit for PE32 and bit 63
is the most significant bit for PE32+. The collection of these entries describes all
imports from a given DLL. The last entry is set to zero (NULL) to indicate the end of
the table.
Also einfach eine Liste mit DWORD Werten, die entweder ein Ordinalimporteintrag sind oder auf einen ASCII-String verweisen, terminiert durch 0.
genaues siehe PECOFF, Seite 74
also einfach mal nachschauen, was es ist:
9c 13 01 = 0x139c (RVA) = FileOffset: 0x0000FF9C
Dump:
Die ersten 2 Bytes sind ein "Hint" zum Suchen des Eintrags in der Exporttabelle der "anbietenden" DLL (interessant nur für den PE-Loader von Windows).
Der nächste Eintrag: ae 13 01 00 =>Fileoffset 0000FFAE: