AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) IAT von kernel32.dll zur Laufzeit patchen
Thema durchsuchen
Ansicht
Themen-Optionen

IAT von kernel32.dll zur Laufzeit patchen

Ein Thema von Assarbad · begonnen am 27. Nov 2016 · letzter Beitrag vom 4. Dez 2016
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Assarbad
Assarbad

Registriert seit: 8. Okt 2010
Ort: Frankfurt am Main
1.234 Beiträge
 
#1

IAT von kernel32.dll zur Laufzeit patchen

  Alt 27. Nov 2016, 23:59
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:
  • IMAGE_THUNK_DATA[774BBF34] == RVA[000CBF34]
  • IMAGE_THUNK_DATA[774BBF44] == RVA[000CBF44]
  • IMAGE_THUNK_DATA[774BBF58] == RVA[000CBF58]
  • IMAGE_THUNK_DATA[774BBF78] == RVA[000CBF78]
  • IMAGE_THUNK_DATA[774BBF8C] == RVA[000CBF8C]
  • IMAGE_THUNK_DATA[774BBFA4] == RVA[000CBFA4]
  • IMAGE_THUNK_DATA[774BBFB4] == RVA[000CBFB4]

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:
  • IMAGE_IMPORT_BY_NAME[744E00E5]
  • IMAGE_IMPORT_BY_NAME[744E0115]
  • IMAGE_IMPORT_BY_NAME[745202B1]
  • IMAGE_IMPORT_BY_NAME[744E0153]
  • IMAGE_IMPORT_BY_NAME[74520483]
  • IMAGE_IMPORT_BY_NAME[744E01D3]
  • IMAGE_IMPORT_BY_NAME[745204FE]

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? MSDN-Library durchsuchenDecodePointer und MSDN-Library durchsuchenDecodeSystemPointer hab ich beide schon ausprobiert. Die Rückgabewerte sehen noch sinnloser aus und führen letztlich auch ins Nirvana.

Nochmal kurz zur Methode:
  1. Ermittle PIMAGE_NT_HEADERS mithilfe von RtlImageNtHeader (ntdll) aus der Adresse der geladenen kernel32.dll
  2. Ermittle den ersten IMAGE_IMPORT_DESCRIPTOR der geladenen kernel32.dll mithilfe von RtlImageDirectoryEntryToData(..., TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, ...)
  3. Gehe durch die IMAGE_IMPORT_DESCRIPTOR-Records bis der .Name irgendwann 0 als RVA-Wert hat
  4. Benutze .Name um den IMAGE_IMPORT_DESCRIPTOR für ntdll.dll aufzuspüren
  5. Konvertiere RVA für .OriginalFirstThunk mit RtlImageRvaToVa zu einer VA (Zeiger auf eine Liste mit RVAs)
  6. Iteriere über die Liste der RVAs welche zu IMAGE_THUNK_DATA zeigen
  7. Benutze .AddressOfData aus dem IMAGE_THUNK_DATA-Eintrag um die (R)VA zum Namen der Funktion zu ermitteln
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

AW: IAT von kernel32.dll zur Laufzeit patchen

  Alt 28. Nov 2016, 00:33
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.

Nicooooooo!

OK. Hilft dir nicht weiter, aber aus Neugier: Wozu braucht man so was?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#3

AW: IAT von kernel32.dll zur Laufzeit patchen

  Alt 28. Nov 2016, 00:38
Klingt für mich eigentlich korrekt was du machst 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;
        }
    }
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

AW: IAT von kernel32.dll zur Laufzeit patchen

  Alt 28. Nov 2016, 00:46
Öhm. Könnte mich bitte mal jemand aufklären was Assarbad da versucht zu machen?

Und das Wunder der DP hat mal wieder zugeschlagen.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#5

AW: IAT von kernel32.dll zur Laufzeit patchen

  Alt 28. Nov 2016, 00:56
Öhm. Könnte mich bitte mal jemand aufklären was Assarbad da versucht zu machen?
Ich vermute mal, dass er einen IAT Hook basteln will, um alle Aurufe einer bestimmten API aus der kernel32.dll heraus auf einen eigenen Callback umzulenken

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 MessageBoxW ist dann auf Assembler-Ebene eigentlich ein CALL [IAT.FuncPtr.MessageBoxW] (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.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von Assarbad
Assarbad

Registriert seit: 8. Okt 2010
Ort: Frankfurt am Main
1.234 Beiträge
 
#6

AW: IAT von kernel32.dll zur Laufzeit patchen

  Alt 28. Nov 2016, 08:51
Ich vermute mal, dass er einen IAT Hook basteln will, um alle Aurufe einer bestimmten API aus der kernel32.dll heraus auf einen eigenen Callback umzulenken
Jenau! Schrieb ich ja auch schon. Und zwar geht es um die äußerst unzuverlässigen Funktionen um verschiedene Ressourcentypen zu laden, bzw. die Funktion aus ntdll.dll welche als Unterbau benutzt wird. Damit will ich die Auswahl der richtigen Sprache in einem Modul gewährleisten. Microsoft hat nämlich leider alles rund um Sprachauswahl bis Windows Vista (exklusive) verbockt. Daher auch immer deren Empfehlung die einzelnen Sprachen in separate DLLs mit jeweils nur einer Sprache auszulagern. Das Problem wurde nämlich erst mit Windows Vista zuverlässig gelöst.

Klingt für mich eigentlich korrekt was du machst Hier mal ein Auszug aus einem C-Programm von mir, was über die Imports iteriert und beim Fund einer übergebenen Adresse den Namen ausgibt
Danke, bis auf die Tatsache, daß ich bei den Thunks die RVAs aus der Liste einzeln in VAs übersetze, ist mein Code funktionell identisch. Vermutlich sind die Linker so vernünftig die IMAGE_THUNK_DATA-Records direkt als lückenlose Liste hinzupappen, weshalb es auch geht nur die RVA zum ersten zu übersetzen und beim Rest halt jeweils sizeof(IMAGE_THUNK_DATA) dazu.

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).

Und das Wunder der DP hat mal wieder zugeschlagen.
Das ist aber ein nettes Kompliment an Zacherl. Und in der Tat bin ich auch immer wieder von seinen fundierten Antworten begeistert. Die machen Freude.

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.
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)

Geändert von Assarbad (28. Nov 2016 um 09:00 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von NicoDE
NicoDE

Registriert seit: 16. Jul 2012
Ort: Darmstadt
26 Beiträge
 
Delphi 10.3 Rio
 
#7

AW: IAT von kernel32.dll zur Laufzeit patchen

  Alt 28. Nov 2016, 10:31
Und nun wird's seltsam.
Im Moment habe ich leider keine Zeit, mir das genauer anzusehen.
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...
Nico Bendlin
  Mit Zitat antworten Zitat
Benutzerbild von Assarbad
Assarbad

Registriert seit: 8. Okt 2010
Ort: Frankfurt am Main
1.234 Beiträge
 
#8

AW: IAT von kernel32.dll zur Laufzeit patchen

  Alt 28. Nov 2016, 10:46
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.
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)
  Mit Zitat antworten Zitat
Benutzerbild von Assarbad
Assarbad

Registriert seit: 8. Okt 2010
Ort: Frankfurt am Main
1.234 Beiträge
 
#9

AW: IAT von kernel32.dll zur Laufzeit patchen

  Alt 3. Dez 2016, 21:34
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 MSDN-Library durchsuchenGetProcAddress die Adresse der Funktion LdrFindResource_U und suche die dann in der FirstThunk-Liste. Muß das noch auf Windows 2000 und x64-Versionen testen und dann ist es auch schon reif für den nächsten Release.

Code und Programme findet ihr hier: ntobjx.
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#10

AW: IAT von kernel32.dll zur Laufzeit patchen

  Alt 4. Dez 2016, 00:06
Der Link zur Dokumentation auf der Seite geht nicht: 404.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:20 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz