Ich arbeite an einer Anwendung, die Status des benutzerdefinierten Prozesses speichert und dann von dem Punkt, an dem gestoppt wurde, wiederherstellt.Gibt es eine Möglichkeit, Windows 7 x64 laden ntdll.dll aus dem lokalen Verzeichnis, nicht System32?
Im Moment gibt es das folgende Problem. Wenn das System neu gestartet wird, werden alle Basisadressen von Systemmodulen randomisiert (ntdll.dll
, kernelbase.dll
, kernel32.dll
und so weiter). Betriebssystem ist Windows 7 x64 Enterprise. Beim Versuch, die Anwendung nach dem Neustart wiederherzustellen, stürzt sie offensichtlich ab (aber vor dem Neustart funktionierte sie vom Wiederherstellungspunkt aus). Ich sehe zwei Lösungen dazu:
- Stellen Adressen von Systemmodulen statisch, wenn sie in Anwendung
- -Patch alle Verweise auf Ziel Module in der Anwendung (Adressen von Funktionen auf Stapel, Adressen geladen werden, die gespeichert werden können, in einem Haufen und so weiter)
Offensichtlich ist der zweite Weg schwierig. Wir sollen die volle Anwendungsanalyse machen, den Code von den Daten unterscheiden, die Daten unterscheiden, wo es eine einfache ganze Zahl von der Referenz zum Systemmodul sein kann ... Also habe ich den 1. Weg gewählt.
Beim Laden von Modulen in den virtuellen Speicher überprüft das Betriebssystem zuerst, ob bereits ein Modul mit einem solchen Namen im physischen Speicher vorhanden ist. Wenn es einen gibt, wird dieses Modul einfach dem virtuellen Adressraum zugeordnet. In diesem Fall wird das Modul von seiner ursprünglichen Position geladen, bei ntdll.dll
- von C:\Windows\System32\ntdll.dll
. Selbst wenn Sie dieses Modul in das Anwendungsverzeichnis kopieren, deaktivieren Sie das ASLR-Flag und patchen Sie image base auf einen Wert. Dieses Modul wird weiterhin aus dem Systemverzeichnis geladen. Eine Art der Umleitung ist erforderlich.
Von MSDN lernen wir die folgenden (Abschnitt „Suchreihenfolge für Desktop-Anwendungen“):
Desktop-Anwendungen können die Position steuern, von dem eine DLL, indem Sie einen vollständigen Pfad geladen wird, mit DLL redirection, oder unter Verwendung einer manifest. Wenn keine dieser Methoden verwendet wird, sucht das System zum Laden nach der DLL, wie in diesem Abschnitt beschrieben.
Es gibt also wieder mindestens 2 Möglichkeiten, um das Ziel zu erreichen.
Sie auf der Seite über DLL-Umleitung wir sehen:
bekannte DLLs nicht umgeleitet werden kann. Eine Liste bekannter DLLs finden Sie im folgenden Registrierungsschlüssel: HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ Sitzungsmanager \ KnownDLLs. Das System verwendet Windows-Dateischutz, um sicherzustellen, dass System-DLLs wie diese nicht aktualisiert oder gelöscht werden, außer durch Betriebssystemupdates wie Service Packs.
Module, die ich umleiten möchte, sind bekannte DLLs, daher kann diese Variante nicht angewendet werden.
Manifeste sind übrig. Es gibt eine ausgezeichnete article über die Verwendung von ihnen. Der Autor des Artikels erstellt Stub-DLL, um Original (user32.dll
) zu ersetzen, und macht dann Anwendung, um diese ersetzte DLL zu laden. Der Punkt ist, dass diese DLL geladen wird, wenn nach importierten Funktionen gesucht wird, nicht am Anfang der Anwendung, wie ntdll.dll
.
Um genauer zu sein, beziehen wir uns auf "Windows Internals, Sixth Edition", p. 359 wo Details der Prozesserzeugung erklärt werden. Es gibt 7 Stufen gibt:
- Konvertieren und Validieren von Parametern und Flags
- Öffnen des Bildes zu
- das Windows-Executive-Prozess Objekt erstellen ausgeführt werden
- Erstellen der Initial Thema und seine Stapel und Kontext
- Performing Windows-Subsystem-spezifische post- Initialisierung
- Starten der Ausführung des Anfangs Thema
- Performing Prozessinitialisierung im Kontext des Neuen Prozesses
Die wichtigsten Punkte, hier:
Kartierung von
ntdll.dll
bei Stufe 3 auftritt;bei Beginn der Stufe 5 lesen wir (Schwerpunkt ist von mir):
An diesem Punkt sendet Kernel32.dll eine Nachricht an das Windows-Subsystem, so dass es SxS einrichten können Informationen (siehe das Ende dieses Abschnitts für weitere Informationen zu parallelen Assemblys) wie Manifestdateien, DLL-Umleitungspfade und Out-of-Process-Ausführung für den neuen Prozess.
Dies bedeutet, dass ntdll.dll
geladen wird, bevor die Umleitung eine Chance hat. Es gibt viele Fragen zu SO zum Thema Umleitung, aber sie alle sind über DLLs, die beim Suchen nach importierten Funktionen oder explizit über LoadLibrary
geladen werden, wenn eine Umleitung in der Anwendung auftreten kann.
ntdll.dll
wird jedoch in jedem Fall in einem sehr frühen Stadium in Anwendung geladen.
Unter Verwendung aller Informationen, die ich bisher gesammelt habe, konnte ich die Anwendersuche zum Beispiel für kernel32.dll
im Anwendungsverzeichnis vornehmen (über den Link von diesem Absatz). Aber ich konnte die Suche nach ntdll.dll
nicht umleiten.
Ist es überhaupt vom Benutzermodus möglich?
P.S. Es gibt eine Möglichkeit, ASLR global zu deaktivieren, siehe post. Es ist jedoch ein sehr unhöflicher Weg, Anwendungen wie Internet Explorer
, Adobe Reader
funktionieren nicht und das gesamte Betriebssystem ist offen für Sicherheitslücken.
* ntdll.dll * enthält den Prozess Bootstrapping-Code. Es muss das erste Modul sein, das einem Prozessobjekt zugeordnet ist. Sie können das nicht ändern, ohne den Kernel neu zu schreiben. – IInspectable