Du meinst also, dass die ImageBase des Programmes, das du in Olly lädst, immer anders ist? Oder die Adresse einer geladenen Dll?
Exen müssen nämlich eigentlich nicht reloziert werden, da sie immer zuerst alloziiert werden. Eine Ausnahme ist ASLR, das soweit ich weiß aber standardmäßig nicht aktiviert ist. Ein paar mehr Informationen, was genau du lädst/betrachtest, wären ganz gut.
Mit dem folgenden Code bekommst du EIP, also die absolute Adresse der derzeitigen Instruktion:
Quote:
Wenn du jetzt noch
add eax,4 hinzufügst, hast du bei der nächsten Instruktion die Adresse derselben in eax.
Ziehst du 5 ab, hast du die Adresse von
call x.
Dann ziehst du manuell die Adresse von
call x von der Adresse deines Strings ab und hast das Offset, das du auf EAX-5 addierst, um zur Laufzeit die Adresse deines Strings zu erhalten, ohne statische Adressen zu benutzen.
Du könntest auch die Adresse deines Strings nehmen, die momentane ImageBase abziehen und die ImageBase aus dem PE Header draufaddieren und für die Stelle, an der du die Adresse benutzt, einen Relocation-Eintrag hinzufügen, sodass die Adresse beim Laden des Moduls korrigiert wird, was allerdings etwas aufwendiger ist (s. unten).
Wenn LoadLibrary nicht in den Imports des Moduls, das du bearbeitest, nicht vorhanden ist, fügst du es hinzu (manuell (falls du Spaß mit dem Hex-Editor willst) oder via LordPE/IIDKing), holst dir die Adresse des IAT-Eintrages, in dem nach dem Laden des Moduls die Adresse der Funktion steht (wird dir von LordPE/IIDKing angezeigt), und hast dann wieder die beiden gleichen Optionen wie oben.
So fügst du mit LordPE eine Relocation-Tabelle mit einem Eintrag hinzu (vorrausgesetzt dass im PE Header noch genug Platz ist):
Angenommen im PE Header steht als ImageBase 400000h, das Modul wurde aber auf 500000h reloziert und an der Adresse 501000h möchtest du die Adresse deines Strings haben:
Quote:
501000h - B8 00 20 50 00 - mov eax,502000h
//...
502000h - 74 65 73 74 ... - ASCII "test.dll"
|
Damit die Relocations richtig angewandt werden, musst du die statische Adresse des Strings erst einmal auf die Standard-ImageBase anpassen:
Du subtrahierst die momentane ImageBase und addierst die aus dem PE Header: 502000h - 500000h + 400000h = 402000h. Du änderst das
mov eax,502000h also zu
mov eax,402000h und speicherst die Exe ab.
An 501000h befindet sich die Instruktion, die mit der statischen Adresse des Strings arbeiten möchte. Exakter steht die Adresse des Strings an 501001h (B8h = mov-Opcode; 00 20 50 00 => 502000h).
Die RVA dieser Stelle ist 1001h (Adresse - momentane ImageBase).
Jetzt muss für diese Adresse (1001h) ein Relocation-Eintrag vorhanden sein, sodass an der Adresse die Adresse des Strings angepasst wird:
Damit die Relocs richtig aligned sind, muss zuerst Folgendes sichergestellt werden:
(LordPE öffnen und PE Datei laden -> Directories -> Relocation -> '...'-Button)
Wenn die letzte Relocation-Tabelle eine ungerade Anzahl an Relocations hat, muss sie um IMAGE_REL_BASED_ABSOLUTE erweitert werden.
Dafür zählst du zuerst alle Elemente der vorhergehenden Reloc-Tabellen zusammen:
Angenommen es gibt 3 Reloc-Tabellen, die erste hat 322d (d = dezimal), die zweite 22d und die dritte hat 55d Elemente.
Dann endet die letzte Tabelle mit einer ungeraden Anzahl. Also nimmst du die Anzahl der Elemente der Tabellen davor (322+22=344) mal 2 und addierst 8 mal Anzahl der Tabellen - 1 und nochmal 4 dazu. Macht (344 * 2) + (8 * (3 - 1)) + 4 = 708d / 2C4h.
Dann lässt du dir die Relocs in LordPEs Hex-Editor anzeigen ('H'-Button) und gehst vom Anfang der Relocs 2C4h Bytes weiter.
Da die letzte Reloc-Tabelle 55d Elemente hat, ist sie 8 + (55 * 2) = 118d / 76h Bytes groß. Du siehst daher im Hex-Editor an der errechneten Stelle "76 00 00 00", 76h in Little Endian. Diesen Wert erhöhst du um 2, macht "78 00 00 00".
Nun gehst du an das Ende der Relocs (Fenster schließen und erneut den 'H'-Button drücken und dann an das Ende der selektierten Bytes gehen):
An diese Stelle kommt der neue letzte Eintrag der letzten Reloc-Tabelle, sodass sie auf 56d Elemente kommt und aligned ist, nämlich IMAGE_REL_BASED_ABSOLUTE (Null-WORD), also einfach zwei Nullen.
Jetzt folgt die RVA der Adresse, die korrigiert werden soll (also 1001h) als DWORD (macht "01 10 00 00"), was eine neue Reloc-Tabelle einleitet, danach folgt deren Größe als DWORD "0C 00 00 00" (8 + (2 * 2)), dann kommt der eigentliche Eintrag für 401001h bzw. 501001h "00 30" (ein IMAGE_REL_BASED_HIGHLOW-Eintrag mit dem Offset 0) und zum Schluss wieder IMAGE_REL_BASED_ABSOLUTE ("00 00").
(IMAGE_REL_BASED_ABSOLUTE ist optional, falls die Reloc-Tabelle die letzte Tabelle in den Relocations ist, und notwendig, wenn dem nicht so ist und eine ungerade Anzahl an Einträgen enthalten ist.)
Insgesamt hängst du also an das Ende der Relocs Folgendes an:
00 00 01 10 00 00 0C 00 00 00 00 30 00 00 (14d / 0Eh Bytes)
Nun muss noch der Header angepasst werden:
Das Size-Member des Relocation-DataDirectory muss also um 0Eh erhöht werden, ebenso die RawSize der Sektion, in der die Relocs vorhanden sind (meistens gibt es eine eigene Sektion für Relocations ".reloc" (LordPE passt nach dem Vergrößern einer Sektion SizeOfImage automatisch an)).
Falls du es einfacher haben möchtest, hol' dir EIP über das Call-Pop-Konstrukt und addiere die statischen Offsets (zu deinem String, zu dem IAT-Eintrag von LoadLibrary, etc.) darauf.
Edit:
Also mit
call x | x: pop eax ist gemeint, dass du direkt die nächste Adresse aufrufst (call $+5), wodurch die Rücksprungadresse (auch $+5) auf den Stack gepusht wird, sodass man sie dann poppen kann und praktisch den Inhalt von EIP hat.