![]() |
IAT von kernel32.dll zur Laufzeit patchen
Also, ich würde gern die IAT von kernel32.dll zur Laufzeit patchen um eine bestimmte Funktion aus ntdll.dll zu ersetzen (wenn IAT nicht klappt, erledige ich das inline über nen Hook). IAT scheint mir mit dem geringsten Aufwand verbunden. Leider bin ich auf ein paar Stolpersteine gestoßen.
Auf einem weitgehend gepatchten Windows 7 x64 mit einem 32-bittigen Prozeß bekomme ich bspw. kernel32.dll an Adresse 773F0000 geladen. IMAGE_IMPORT_DESCRIPTOR für ntdll.dll findet sich an 774BABD4. Dabei benutze ich RtlImageDirectoryEntryToData (ntdll) um den Eintrag für IMAGE_DIRECTORY_ENTRY_IMPORT zu ermitteln. Und nun wird's seltsam. Gehe ich nun durch die Liste unter RVAs unter OriginalFirstThunk (im IMAGE_IMPORT_DESCRIPTOR), bekomme ich Werte die als RVA keinen Sinn machen (deutlich größer als eine geladene kernel32.dll), die aber als VA zu Speicherzugriffsfehlern führen. Die Konvertierung von RVA zu VA überlasse ich dabei übrigens der Funktion RtlImageRvaToVa (ntdll). Gucke ich mir bspw. die Adressen der Thunks an, sind die total sinnvoll:
Schaue ich mir die enthaltenen - angeblichen RVAs - an, sehen die wie VAs aus, sind aber außerhalb der geladenen kernel32.dll angesiedelt; und führen, wie schon geschrieben, ins Nirvana:
Hat hier irgendjemand ne Ahnung woher diese unsinnigen Werte rühren und ob es einen Weg gibt diese Zeigerwerte in korrekte Werte zu überführen? ![]() ![]() Nochmal kurz zur Methode:
|
AW: IAT von kernel32.dll zur Laufzeit patchen
Oh Gott. Unser Assarbad in Reinkultur. Geht das auch verständlich ohne Abkürzungen?
Was ich verstanden habe: kernel32.dll. Funktion. Patchen. Dann hört es auf. :roll: Nicooooooo! OK. Hilft dir nicht weiter, aber aus Neugier: Wozu braucht man so was? |
AW: IAT von kernel32.dll zur Laufzeit patchen
Klingt für mich eigentlich korrekt was du machst :gruebel: Hier mal ein Auszug aus einem C-Programm von mir, was über die Imports iteriert und beim Fund einer übergebenen Adresse den Namen ausgibt:
Code:
if (ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
{ PIMAGE_IMPORT_DESCRIPTOR descriptor = (PIMAGE_IMPORT_DESCRIPTOR)((uint8_t*)moduleHandle + ntHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); while (descriptor->OriginalFirstThunk) { const char* moduleName = (char*)((uint8_t*)moduleHandle + descriptor->Name); PIMAGE_THUNK_DATA originalThunk = (PIMAGE_THUNK_DATA)((uint8_t*)moduleHandle + descriptor->OriginalFirstThunk); PIMAGE_THUNK_DATA thunk = (PIMAGE_THUNK_DATA)((uint8_t*)moduleHandle + descriptor->FirstThunk); while (originalThunk->u1.ForwarderString) { if (!(originalThunk->u1.Ordinal & 0x80000000)) { if (address == (uintptr_t)&thunk->u1.Function) { PIMAGE_IMPORT_BY_NAME import = (PIMAGE_IMPORT_BY_NAME) ((uint8_t*)moduleHandle + originalThunk->u1.AddressOfData); printf("%s%s", moduleName, import->Name); return; } } ++originalThunk; ++thunk; } ++descriptor; } } |
AW: IAT von kernel32.dll zur Laufzeit patchen
Öhm. Könnte mich bitte mal jemand aufklären was Assarbad da versucht zu machen?
Und das Wunder der DP hat mal wieder zugeschlagen. :thumb: |
AW: IAT von kernel32.dll zur Laufzeit patchen
Zitat:
Jedes Modul (.exe, .dll, etc) besitzt eine eigene Import Address Table (IAT), über die Funktionen aus anderen Modulen importiert werden, da deren Position ja nicht statisch ist. Der Windows Loader füllt diese Tabelle beim Laden mit der effektiven Adresse. Ein Aufruf von
Delphi-Quellcode:
ist dann auf Assembler-Ebene eigentlich ein
MessageBoxW
Delphi-Quellcode:
(Dereferenzierung beachten). Wenn man jetzt den Zeiger im entsprechenden Feld mit der Adresse einer eigenen Funktion (die den gleichen Prototyp besitzt) ersetzt, kann man alle Aufrufe dieser Funktion abfangen.
CALL [IAT.FuncPtr.MessageBoxW]
|
AW: IAT von kernel32.dll zur Laufzeit patchen
Zitat:
Zitat:
Ach ja, ich sollte noch erwähnen, daß ich halt RtlImageRvaToVa benutze, aber auch geprüft habe, daß die Rückgabewerte Modul+RVA entsprechen (du machst die Berechnung ja inline). Zitat:
Also vielen Dank Zacherl, dann nehme ich an daß es u.U. an Windows 7 liegt. Ich werde mir das nochmal auf früheren Versionen zu Gemüte führen, schließlich existiert das zu lösende Problem nur auf Windowsversionen vor Vista. |
AW: IAT von kernel32.dll zur Laufzeit patchen
Zitat:
Aber da die Systembibliotheken in neueren Windows-Versionen reloziert werden können, würde ich mir den Unterschied zwischen ursprünglicher und tatsächlicher Basisadresse ansehen... |
AW: IAT von kernel32.dll zur Laufzeit patchen
Das ist ein guter Ansatz. Gucke ich direkt mal nach.
Allerdings würde ich ja dennoch erwarten in der IAT die echten Adressen zu sehen. Ich glaub ich muß da nochmal mit IDA ran. |
AW: IAT von kernel32.dll zur Laufzeit patchen
Moin, also das mit dem Offset schien nicht hinzukommen, oder ich hab's falsch gemacht.
Einerlei, ich hab jetzt ne alte Methode benutzt. Und da ich das nur für Versionen vor Vista brauche, klappt diese meine alte Methode noch. Dabei ermittle ich über ![]() Code und Programme findet ihr ![]() |
AW: IAT von kernel32.dll zur Laufzeit patchen
Der Link zur Dokumentation auf der Seite geht nicht: 404.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:11 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz