2016-05-16 2 views
1

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:

  1. Stellen Adressen von Systemmodulen statisch, wenn sie in Anwendung
  2. -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:

  1. Konvertieren und Validieren von Parametern und Flags
  2. Öffnen des Bildes zu
  3. das Windows-Executive-Prozess Objekt erstellen ausgeführt werden
  4. Erstellen der Initial Thema und seine Stapel und Kontext
  5. Performing Windows-Subsystem-spezifische post- Initialisierung
  6. Starten der Ausführung des Anfangs Thema
  7. 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.

+1

* 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

Antwort

1

ntdll wird während der Erstellung des Prozesses vom Kernel gemappt. Wenn der Befehl des ersten Benutzermodus im Prozess ausgeführt wird (dies ist LdrInitializeThunk von ntdll), wird ntdll bereits im Prozess zugeordnet (beim Start werden nur exe und ntdll gemappt, alle anderen DLLs werden von ntdll oder späte by exe geladen).und ntdll muss in allen Prozessen geladen an derselben Adresse, weil die Systemverwendung Adresse einiger Rückrufe befindet sich in ntdll (LdrInitializeThunk, KiUser * Dispatcher)

0

Es gibt einige (theoretisch) Optionen:

  • Verwendung delegierte ntdll für WOW64-Prozesse unter Windows 10 (Ich habe das nie versucht, aber theoretisch sollten Sie in der Lage sein Registrierungseinstellungen anzugeben. Siehe http://redplait.blogspot.de/2017/07/delegatedntdll.html)
  • Legen Sie einige Kompatibilitätsoptionen (um sicherzustellen, dass apphelp.dll geladen ist) und Manifest verwenden Dateien, um eine benutzerdefinierte apphelp.dll zu laden, die Sie verwenden können, um Ihre eigene ntdll zu laden und die geladene Modulliste zu patchen, um Ihre eigene dll zu erstellen, die verwendet werden soll als Import für andere Module. Ich tat dies bisher nicht (ich versuche es gerne, wenn ich die Zeit finde), aber ich konnte eine benutzerdefinierte win32u.dll laden, die die meisten Exporte an eine Kopie der ursprünglichen win32u.dll weiterleitet und in einige hakt win32 syscalls. Siehe auch http://stackoverflow.com/questions/2100973/dll-redirection-using-manifests
Verwandte Themen