XProfan & 64-Bit

  • Hier bitte 64-Bit Themen zu XProfan posten. Sollte der Thread seinen Rahmen sprengen, wird er zu einem eigenen Unterforum umgewandelt. Bislang aber erst einmal testweise in dieser Form.

    Weitere 64-Bit-Threads
    http://www.paules-pc-forum.de/forum/xprofan/…it-xprofan.html
    http://www.paules-pc-forum.de/forum/xprofan/…en-bringen.html
    http://www.paules-pc-forum.de/forum/xprofan/…ebsystemen.html

    • Anzeige

    Hallo!

    Wenn du gerade an deiner Website arbeitest oder dein aktuelles Hosting überdenkst: Wir betreiben mit NetzLiving eine Hosting-Plattform, die speziell auf Performance, Sicherheit und einfache Verwaltung ausgelegt ist.

    • ✔️ Schnelle Ladezeiten (optimiert für WordPress, WoltLab & Co.)
    • ✔️ Deutsche Server & DSGVO-konform
    • ✔️ Persönlicher Support (kein 0815-Ticket-System)

    Mehr erfahren

    Wenn du Fragen hast, kannst du dich gerne jederzeit an @Maximilian Rupp wenden

    Hinweis:

  • Das Grundproblem



    Das eigentlich Problem, das sich ergibt wenn man 32Bit Programme auf 64Bit Systemen laufen lassen möchte, lässt sich sehr leicht rechnerisch darlegen:

    Code
    [LEFT]2^32 = 4294967296[/LEFT]


    Auf einem 32Bit System können also virtuelle Adressen von 0 bis 4294967296 vergeben werden, mehr geht nicht. Davon wird unter NT basierenden Systemen in der Regel die Hälfte für die Nutzung durch Usermode-Programme und ihre DLLs vorgesehen, die andere Hälfte erhält der Kernel mit seinen Treibern.

    Code
    2^64 = 18446744073709551616


    Wie man daraus sieht, können unter 64Bit sehr viel höhere Adressen verwaltet werden. DLLs können in höhere Adressbereiche geladen werden und sie können ihre Variablen in höhere Bereiche schreiben - Bereiche, die ein 32Bit Programm nicht auslesen kann, da der Zahlenbereich dort gar nicht so hoch reicht.
    Was würde nun passieren, wenn ein 32Bit Programm 64Bit Dlls verwenden würde? Ganz einfach, es würde gewaltig crashen :lol:!

    Programmierung funktioniert über API - und API ist nichts anderes als das Ansprechen von Funktionen in vom jeweiligen Programm geladenen System-DLLs.
    Ooops 8O - 64Bit DLLs können von einem 32Bit Programm ja gar nicht verwendet werden! Wie regelt M$ das bloß, das auch 32Bit Programme auf 64Bit laufen?
    Ganz einfach, M$ liefert ganz locker einen zweiten Satz DLLs für 32Bit mit.
    Das Problem dabei: Alle Programme laden System-DLLs aus dem Systemverzeichnis (manchmal mit und manchmal ohne Pfadangabe) - und im selben Verzeichnis können sich nicht zwei verschiedene DLLs mit gleichem Namen befinden (einmal für 32Bit und einmal für 64Bit)! 32Bit Programme laufen deshalb in einem Emulator (genannt WOW64), der 32Bit Programmen eine ganz andere Oberfläche vorgaukelt und nebenbei auch Pfade umbiegt.
    Unter anderem aus diesem "Umbiegen" heraus ergeben sich einige Spezialitäten bei der Programmierung, die man beachten muss, damit ein 32Bit Programm unter 64Bit lauffähig ist und nicht falsch reagiert.
    Um diese Spezialitäten soll es hier gehen - unter anderem mit Quellcodebeispielen.

    2 Mal editiert, zuletzt von AxT (19. Dezember 2014 um 14:20)

  • Auf 64Bit System testen



    Am Anfang ist es erst einmal wichtig zu wissen, ob der eigene 32Bit Prozess überhaupt auf einem 64Bit System läuft oder nicht. Dieser Code wird später noch öfters benötigt, deswegen schreibe ich ihn hier erst mal separat hin:


    Die Abfrage mit GetProcAdress dient eigentlich nur dazu, um den Code auch unter älteren Systemen lauffähig zu halten. Die Variable 64Bit erhält unter einem 64Bit System den Wert 1, unter einem 32Bit System den Wert 0.

  • Die Umleitung von Systemordnern und ihre Aufhebung



    Wie ich schon angemerkt habe, biegt der WOW64 Emulator unter 64Bit für die 32Bit Programme unter anderem Pfade um. "Umbiegen" heißt, er leitet sämtliche Zugriffe auf den Ordner System32 ($SYSPATH) im Windows Installationsordner in den Ordner SysWOW64 im Windowsordner ($WINPATH+"\"+"SysWOW64") um. Diese Umleitung besteht auch für die meisten Unterordner von System32, zum Beispiel für den Ordner System32\Drivers.
    Wenn man sich das sämtliche einmal etwas auf der Zunge zergehen lässt, wird man wohl jetzt schon merken, dass das zu ganz gewaltigen Verwicklungen führen kann, auf die ich später noch eingehen werde. Es muss also eine Möglichkeit vorhanden sein, diese Umleitung bei Bedarf aufzuheben - und diese Möglichkeit gibt es auch. Nötig dazu sind zwei APIs, eine hebt die Umleitung auf, die andere aktiviert sie wieder. Eine Aktivierung bzw. Deaktivierung der Umleitung erfolgt immer nur für den aktuellen Thread, nicht für das ganze Programm.
    Hier ist der Code dazu:



    Bei den Codes zum Deaktivieren und zum Aktivieren der Umleitung fällt einiges an Besonderheiten auf:

    1. ) Die APIs werden über Call angesprochen, nicht über External, DEF oder die Header von Profan.
    Da die Umleitung aufgehoben wird, bevor der Befehl External beendet wurde, bin ich mir nicht sicher, ob beim Ansprechen der API über eine andere Art und Weise als durch Call Profan immer mit der richtigen DLL hantiert. Ich rate deshalb erst mal an, das ebenso zu machen.

    2. ) Vor dem Aufruf der API zum Aufheben der Umleitung wird der FastMode auf 1 gesetzt und erst nach der Reaktivierung der Umleitung wieder auf 0.
    Während die Dateiumleitung sollten keine Messages verarbeitet werden. Würden, während der Zeit, in der die Umleitung deaktiviert ist, Profan Subclassingroutinen aufgerufen werden, würde Profan unter Umständen versuchen, die DLLs aus dem 64Bit Ordner zu laden - das wäre tötlich.

    Wichtig: Sämtliche API Aufrufe, die erfolgen während die Umleitung deaktiviert ist, müssen über den Call Befehl erfolgen, da sonst versucht wird, falsche DLLs zu laden. Die Adresse für den Call Befehl muss ermittelt werden, bevor die Umleitung deaktiviert wird!
    Die Umleitung sollte nur solange deaktiviert bleiben, wie dies unbedingt erforderlich ist. Danach sollte sie sofort wieder reaktiviert werden!

  • Das Codewort SysNative

    Neben der schon beschriebenen Deaktivierung der Umleitung des Dateisystems gibt es eine zweite Möglichkeit, von einem 32Bit Programm aus Zugriff auf den SYSTEM32 ($SYSPATH) Ordner zu erhalten - die Verwendung des Codewortes Sysnative anstatt System32.
    Das heißt: Für C:\Windows\System32 einfach C:\Windows\Sysnative schreiben - das wars.
    Wichtig: Bei manchen Sachen ist es unideal, den Zugriffs mittels Codewort zu regeln, manche APIs funktionieren aber scheinbar nur mittels dieses Codewortes und nicht mit deaktivierter Umleitung! Näheres dazu kommt später

    Einmal editiert, zuletzt von AxT (23. November 2015 um 19:19)

  • Der Profan 32Bit Befehl FileSize auf 64Bit Systemen



    Aufgrund der schon erwähnten Umleitung des Dateisystems reagiert der Profanbefehl FileSize in der Regel nicht korrekt, wenn die Dateigröße einer Datei ausgelesen werden soll, die sich in dem Ordner System32 oder einem seiner Unterordner befindet. Hier ist Code zum Testen:


    Ist die Checkbox nicht abgehakt und wird dann der Button Testen angeklickt, wird bei mir (Windows7 64Bit) für die NTDLL eine Dateigröße von 1289712 Bytes angegeben.
    [Blockierte Grafik: http://s3.postimage.org/1aV0G9.jpg]
    Ist die Checkbox abgehakt und wird dann Testen geklickt, steht dort 1736792 Bytes.
    [Blockierte Grafik: http://s2.postimage.org/1Q4_xA.jpg]

    Warum ist das so? Ganz einfach - ist die Umleitung aktiv, wird die Größe der Datei C:\Windows\SysWOW64\ntdll.dll ermittelt; ist sie deaktiviert ermittelt der Code die Größe der wirklich angegebenen Datei C:\Windows\System32\ntdll.dll.

    PS: Was für FileSize gilt, gilt natürlich auch für GetFAttr, GetFDate$, GetFTime$, ...

  • Die Profan 32Bit Befehle DirExists und FileExists auf 64Bit Systemen



    Man will öfters bei der Programmierung ganz gerne mal überprüfen, ob etwas, das der User eingegeben hat oder irgendwie anders ermittelt wurde eine Datei oder ein Ordner ist. Dafür eignen sich die Profanbefehle FileExists und DirExists recht gut - unter 64Bit machen aber auch dies Befehle im system32 Verzeichnis Probleme.
    Hier ist Code zum Testen für DirExists:


    Ist die Checkbox nicht abgehakt und wird dann der Button Testen angeklickt, wird bei mir (Windows7 64Bit) zurückgemeldet, dass der Ordner C:\Windows\System32\Boot nicht existiert - schaut man in den WindowsExplorer, gibt es den Ordner aber.
    [Blockierte Grafik: http://s1.postimage.org/1x9ID9.jpg]

    Ist die Checkbox abgehakt und wird dann der Button Testen angeklickt, wird bei mir (Windows7 64Bit) zurückgemeldet, das der Orner existiert - was ja korrekt ist.
    [Blockierte Grafik: http://s1.postimage.org/1xagy9.jpg]

    Wie ist das zu erklären? Ist die Umleitung aktiv, wird nicht im Ordner Boot im Verzeichnis C:\Windows\System32 auf seine Existenz hin überprüft, sondern der Ordner Boot im Verzeichnis von C:\Windows\SysWOW64 - und da existiert er nicht!


    Gleiches gilt auch für FileExists - hier ist Code:



    [Blockierte Grafik: http://s3.postimage.org/1b04j0.jpg]

    [Blockierte Grafik: http://s4.postimage.org/XHDO9.jpg]

  • Der Profan 32Bit Befehl FindFirst$ auf 64Bit Systemen
    Die Tatsache, das alle Zugriffe auf den System32 umgeleitet werden, gilt natürlich auch für das Listing von Dateien. Wil man den Inhalt von C:\Windows\System32 listen, listet man, wenn die Dateiumleitung noch aktiviert ist, in wirklichkeit den Inhalt des Ordners C:\Windows\SysWow64.
    Hier ein Quellcode, der mittels FindFirst$ Dateien im Ordner C:\Windows\System32\Drivers listen will :lol:.

    Ist die Umleitung noch aktiviert, liefert bei mir der Code folgende Rückmeldung:

    Code
    C:\Windows\System32\Drivers\gm.dls: Geändert-> 20090610, Größe -> 3440660 Bytes
    C:\Windows\System32\Drivers\gmreadme.txt: Geändert-> 20090610, Größe -> 646 Bytes
    C:\Windows\System32\Drivers\ssmdrv.sys: Geändert-> 20090511, Größe -> 28520 Bytes
    C:\Windows\System32\Drivers\wimmount.sys: Geändert-> 20090714, Größe -> 19008 Bytes

    Ist die Umleitung deaktiviert, listet der Code folgende Dateien:

    Wie im Code zu sehen ist, muss für FindNext$ die Umleitung nicht deaktiviert werden!

    Einmal editiert, zuletzt von AxT (19. Dezember 2014 um 14:22)

  • Welche APIs sind von der Umleitung des Dateisystems betroffen?



    In der MSDN Dokumentation steht, das sämtliche Zugriffe umgeleitet werden - es müssten also eigentlich alle APIs betroffen sein, die in irgendeiner Art und Weise mit einem Pfad hantieren. In Wirklichkeit ist das aber nicht der Fall. Die APIs zum auslesen von Dateiresourcen (hier GetFileVersionInfoSize und GetFileVersionInfo) reagieren zum Beispiel ganz normal und landen im richtigen Verzeichnis.
    Hier Code zum Testen:


    Beispiele für APIs die auf jeden Fall umgeleitet werden sind:
    CreateFile, FindFirstFile und WinVerifyTrust.

    Bei WinVerifyTrust ist zu beachten, dass hier auf keinen Fall die Dateiumleitung deaktiviert werden darf - Wow64DisableWow64FsRedirection darf also nicht benutzt werden, um für diese API im richtigen Pfad zu landen! WinVerifyTrust reagiert mit deaktivierter Dateiumleitung nicht korrekt und unter Windows7 passieren sogar schwere Fehler, die die API so zerschießen, das auch im Nachhinein Signaturen nicht mehr korrekt ausgelesen werden können.
    Um mit WinVerifyTrust die korrekten Signaturen auszulesen, muss das Codewort Sysnative statt System32 werwendet werden! C:\Windows\System32\Drivers\ACPI.sys sollte zum Beispiel also, bevor man damit die API bestückt, in C:\Windows\Sysnative\Drivers\ACPI.SYS umgewandelt werden.
    Nach dem Deaktiviren der Dateiumleitung unter Windows7 liefert WinVerifyTrust 8 (Für diesen Befehl ist nicht genügend Speicher verfügbar.) zurück und versagt auch bei späterem Deaktivieren der Umleitung und gleichzeitiger Verwendung des Codewortes Sysnative den Dienst.

  • 64Bit Betriebsysteme und das Umbiegen von Umgebungsvariablen für 32Bit Programme



    Neben den Systempfaden biegen 64Bit Betriebsysteme auch einige Pfade von Umgebungsvariablen um -> %ProgramFiles% und %commonprogramfiles%. %ProgramFiles% wird vom Standardpfad C:\Program files auf C:\Program Files (x86) umgebogen, %commonprogramfiles% landet von C:\Program Files\Common Files auf C:\Program Files (x86)\Common Files.
    Hier ist Code zum Testen:

    Code
    '#####################################################################################
    '#########                          Code von AHT                             #########
    '#########      Gepostet für [URL]http://www.paules-pc-forum.de[/URL]                   #########
    '#####################################################################################
     
    Clearlist 
     
    Addstring GetEnv$("ProgramFiles")
    Addstring GetEnv$("CommonProgramFiles")
    EditBox("Pfade",1)



    Anhand der hier zu lesenden Dokumentation könnte man denken, dass man unter WOW64 durch Anwendung der API SHGetSpecialFolderLocation mit der CSIDL CSIDL_PROGRAM_FILES an den %ProgramFiles% Ordner für 64Bit Programme kommt - dem ist aber nicht so!
    Sowohl CSIDL_PROGRAM_FILES als auch CSIDL_PROGRAM_FILESX86 verweisen in 32Bit Programmen auf den selben Pfad.
    Gleiches gilt auch für CSIDL_PROGRAM_FILES_COMMON und CSIDL_PROGRAM_FILES_COMMONX86.

  • Automatische Umleitung von Registryzugriffen für 32Bit Programme unter 64Bit



    Neben der Umleitung des Dateisystems werden auch Registryzugriffe für 32Bit Programme unter 64Bit umgeleitet. Aber was bedeutet das genau?
    Hier mal etwas Code zum Testen:


    Der Code liefert nach dem Klicken des Testen Buttons als Rückgabe bei mir (Windows7, 64Bit) den Pfad C:\Program Files (X86)\Common Files\Microsoft Shared zurück.
    [Blockierte Grafik: http://s4.postimage.org/19TJiS.jpg]
    Schaut man an gleicher Stelle in die Registry, steht dort aber der Pfad C:\Program Files\Common Files\Microsoft Shared\ 8O.
    [Blockierte Grafik: http://s3.postimage.org/1oz51r.jpg]
    Warum ist das so?

    Zur Lösung des Rätsels schauen wir einmal mit Regedit in die Registry.
    Unter HKEY_LOCAL_MACHINE\Software (ein Wert eines Unterschlüssels dieses Keys wird hier ja ausgelesen) finden wir einen Registryschlüssel mit dem Namen Wow6432Node.
    [Blockierte Grafik: http://s3.postimage.org/1oyJA9.jpg]

    Als Unterschlüssel dieses Keys finden wir dort so ziemlich alle Schlüssel wieder, die auch unter HKEY_LOCAL_MACHINE\Software vorhanden sind.
    [Blockierte Grafik: http://s3.postimage.org/1ozIWJ.jpg]

    Öffnen wir nun mit Regedit den Schlüssel HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Shared Tools. Unter SharedFilesDir finden wir an dieser Stelle folgendes :birne::
    [Blockierte Grafik: http://s1.postimage.org/1KhrL9.jpg]
    Hier steht also das, was eigentlich unter HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools stehen sollte!

    32Bit Programmen wird also für manche Keys eine ganz andere Registry vorgegaukelt. Für diese Keys werden sämtliche Zugriffe in einen Unterschlüssel mit dem Namen Wow6432Node umgeleitet (das gilt natürlich auch für Schreibzugriffe). So kann es nicht nur dazu kommen, das 32Bit Programme andere Werte auslesen als 64Bit Programme - nein, der auszulesende Key kann für 32Bit Programme in manchen Fällen auch gar nicht existieren!

    Natürlich gibt es mit der API auch Möglichkeiten, die 64Bit Werte auszulesen und zu bearbeiten - mit den Profanbefehlen Readini$ und Writeini geht das aber nicht!

  • Mit Profan 32Bit Programmen die 64Bit Registry auslesen



    Um unter 32Bit Programmen Zugriff auf die 64Bit Registry zu bieten, hat M$ einen zusätzlichen Zugriffsflag für Registryschlüssel eingeführt:
    KEY_WOW64_64KEY = $100
    Wird $100 zusätzlich (Verknüpfung mit | ) beim samDesired Parameter von RegOpenKeyEx oder RegCreateKeyEx angegeben, wird bei 32Bit Programmen, die unter 64Bit Windows laufen, der 64Bit Registryschlüssel geöffnet.
    Hier Code zum Testen:


    Wichtig: Es ist zwingend notwendig, zuvor auf 64Bit Systeme zu testen, denn zumindestens unter Windows2000 führt die Angabe des zusätzliche Flag $100 dazu, das RegOpenKeyEx und RegCreateKeyEx nicht funktionieren!

  • Besonderheiten beim Listen von Registryinhalten unter HKEY_LOCAL_MACHINE unter 64Bit



    Registryschlüssel unter HKEY_LOCAL_MACHINE\Software existieren aufgrund der erwähnten Umleitung von Registryschlüsseln in der Regel auf 64Bit Windowssystemen in doppelter Ausführung - einmal in der 32Bit Version und einmal in der 64Bit Version.
    Um zum Beispiel zuverlässig alle durch den Registryschlüssel RUN unter HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion gestarteten Programme zu listen, ist es erforderlich, das Listing doppelt durchzuführen - einmal mit dem Flag $100 und einmal ohne diesen Flag. Programme, die dies nicht berücksichtigen, funktionieren unter 64Bit Systemen nicht korrekt.

  • Mit 32Bit Programmen unter 64Bit Module (DLLs) listen



    Wie sieht es nun aber aus, wenn man sich die von den einzelnen Prozessen geladenen DLLs listen lassen möchte? Die Toolhelp Funktionen bieten dafür ja die APIs Module32First und Module32Next.
    Hier ist Code zum Testen:


    Damit der Code unter Vista und Windows7 richtig funktioniert, benötigt er Adminrechte. Zum Ausführen des Codes also zuerst den Profaneditor mit Adminrechten starten.
    Die Listbox wird nach dem Start mit den laufenden Prozessen gefüllt - hinter dem Dateinamen steht, ob es sich bei dem Prozess um einen 32Bit oder 64Bit Prozess handelt.
    Klickt man auf einen Prozess, werden in einer EditBox die vom markierten Prozess geladenen DLLs gelistet. Klickt man auf den Button Prozesse listen, werden die Prozesse neu ausgelesen.
    Klickt man auf ´den Button Wintrust.DLL ohne Pfad laden, lädt der Code die Wintrust.dll in den eigenen Prozess - im Code wird diese DLL ohne Angabe des genauen Pfads geladen.

    Code
    Wintrust_DLL& = UseDLL("Wintrust.dll")


    Klickt man auf ´den Button Wintrust.DLL mit Pfad laden, lädt der Code ebenfalls die Wintrust.dll in den eigenen Prozess - im Code wird aber diese DLL mit Angabe des genauen Pfads geladen.

    Code
    Wintrust_DLL& = UseDLL($SYSPATH + "" + "Wintrust.dll")


    Soweit zur Funktionsweise des Codes.

    In 32Bit Systemen listet der Code (wenn er mit Adminrechten ausgestattet wird) fast in allen Prozessen die geladenen DLLs - wie sieht das aber unter 64Bit aus?
    Unter 64Bit Systemen können 32Bit Programme nur geladene 32Bit Module listen (warum das so ist, erläutere ich bei anderen APIs noch)- bei jedem 64Bit Prozess ist die EditBox also leer, da 64Bit Prozesse auch nur 64Bit DLLs laden können und 32Bit Prozesse nur 32Bit DLLs.
    So, jetzt kommt die etwas haarige Besonderheit, die auf den MSDN Seiten nicht zu finden ist...
    Wir schauen uns dazu mal die Module an, die vom Prozesse geladen wurden, den unserer Code erzeugt hat. Hier das, was bei mir unter Windows7 in der EditBox steht:


    Hier fällt auf, das manche DLLs mit der Pfadangabe C:\Windows\system32 gelistet werden, andere aber wiederum mit der Pfadangabe C:\Windows\syswow64! Was ist da los?
    Um der Sache auf den Grund zu gehen, klicken wir mal zuerst auf den Button Wintrust.DLL ohne Pfad laden und dann wieder auf unseren Profan.exe Prozess.
    So sieht dann die Rückgabe aus:



    KLicken wir danach auf den Button Wintrust.DLL mit Pfad laden, sieht die Rückgabe so aus:



    Daraus ergibt sich folgende, wichtige Sache:
    Die Pfadangaben der gelisteten DLLs sind nicht immer korrekt! Hat der Prozess die DLLs ohne Angabe des Pfades geladen, wird der korrekte Pfad zurückgegeben. Wurde die DLL mit Angabe des Systempfades geladen, wird der nicht korrekte System32 Pfad angezeigt!
    Auch das Umwandeln aller System32 Angaben in SysWow64 führt nicht immer zur Ermittlung des richtigen Pfades, denn in seltenen Fällen lädt ein 32Bit Prozess auch DLLs aus dem System32 Verzeichnis!

    PS: Wer mit XP 64Bit arbeitet, wird im Code noch auf eine weitere Besonderheit stoßen - dazu kommt aber später noch was.

    Einmal editiert, zuletzt von AxT (19. Dezember 2014 um 14:32)

  • GetModuleFileNameEx unter 64Bit mit 32Bit Programmen



    Unter 32Bit konnte man die API GetModuleFileNameEx noch recht gut dazu benutzen, das Prozesserzeugende Modul einer Anwendung herauszubekommen. Unter 64Bit hat die API endgültig ausgespielt, denn diese API kann das Prozesserzeugende Modul von 64Bit Programmen von 32Bit Programmen aus nicht mehr ermitteln.
    Der Dateiname des Prozesserzeugenden Moduls lässt sich ab Vista aber sehr gut mit der API QueryFullProcessImageName herausbekommen.
    Unter XP 64Bit wird das ganze schon etwas schwieriger - hier muss zuerst der native Pfad über GetProcessImageFileName ermittelt und der Pfad dann umständlich (und unsicher) mit dem Hilfsmittel QueryDosDevice umgewandelt werden.

  • Warum können 32Bit Programme keine 64Bit Moduldaten auslesen?



    Neben GetModuleFileNameEx und Module32First schlagen auch noch andere APIs fehl, wenn man versucht in 64Bit Prozessen von 32Bit Prozessen aus DLLs auszulesen. Aber warum ist das so?

    Informationen über geladene Module befinden sich im virtuellen Speicherbereich des Prozesses, der die Module geladen hat - und zwar in der Struktur PEB_LDR_DATA. Wo sich diese Struktur befindet wird in einer weiteren Systemstruktur gespeichert - dem PEB.
    Um an die Adresse des PEBs für den jeweiligen Prozess zu kommen, nutzt Windows intern eine native API -> NtQueryInformationProcess.
    Da der virtuelle Adressbereich eines 64Bit Prozesses wesentlich größer ist als der eines 32Bit Prozesses kann sich der PEB in Speicherbereichen befinden (oder auf diese verweisen), die von einem 32Bit Prozess gar nicht ausgelesen werden können. Windows regelt das intern so, dass es für alle 64Bit Prozesse, die von einem 32Bit Prozess mittels NtQueryInformationProcess beschossen werden, einen PEB von 0 zurückgiebt.

    Wichtig: Demnach schlagen alle APIs für 64Bit Prozesse fehl, die intern die Adressse des PEBs benötigen, wenn sie von einem 32Bit Prozess ausgeführt werden!

    Hier noch Code zum Testen:

  • Speicher eines 64Bit Programms mit einem 32Bit Programm scannen



    Natürlich ist es auch möglich, den virtuellen Speicher eines 64Bit Prozesses mit einem 32Bit Prozess zu scannen und auszulesen - aber natürlich nur die unteren 4GB.
    Unter 32Bit Betriebsystemen bestand hier die Möglichkeit, zum Scannen des Speichers die API VirtualQueryEx in einer Schleife mit sich erhöhenden Werten so lange aufzurufen, bis die API 0 zurückgab - dann war der Speicher komplett durchsucht. Auf 64Bit Prozesse angewendet liefert die API aber normalerweise nie 0 zurück, da hier die kompletten unteren 4GB des Prozesses ja dem Usermode angehören (für 32Bit Prozesses sind nur 2GB auslesbar, die 2GB darüber gehören dem Kernel).
    Eine Rückgabe von 0 für VirtualQueryEx darf also nicht als alleiniges Kriterium dafür hergenommen werden, den Scanvorgang abzubrechen (man fängt sich sonst in einer Endlosschleife) - es muss auch überprüft werden, ob die gesammten 4GB bereits durchsucht worden sind.

  • 32Bit Programme und die Dateidialoge auf 64Bit Betriebsystem



    Auch das Browsen in den Dateidialogen der COMDLG32.DLL oder der SHELL32.DLL läuft unter 64Bit in einem 32Bit Programm anders ab, als auf einem 32Bit Betriebsystem.

    Wichtig: Eine Aufhebung der Dateiumleitung vor dem Aufrufen der Dialoge führt dazu, das der entsprechende Dialog gar nicht mehr angezeigt wird! Eine Aufhebung der Umleitung für diese Dialoge ist scheinbar nicht möglich!

    Zu welchen Problemen kann es für den User kommen, wenn Common Dialogs von 32Bit Programmen verwendet werden, die unter 64Bit laufen:

    • Der User kann eine spezielle Datei aus dem System32 Ordner und dessen Unterordnern nur auswählen, wenn diese Datei auch im SysWOW64 Ordner vorhanden ist, ansonsten wird sie nicht angezeigt. Besonders auffällig wird das im Ordner C:\Windows\System32\Drivers, denn hier zeigt der Dialog kaum eine Datei an.
    • Will der User einen Unterordner des System32 Ordners auswählen, kann er ihn nur auswählen, wenn er auch als Unterordner im SysWOW64 Ordner vorhanden ist - ansonsten wird er nicht angezeigt.

    Anmerkung zur Rückgabe der Dialoge:
    Wer die angesprochenen Dialoge unter Vista bereits einmal genutzt hat wird bemerkt haben, dass die Dialoge die "Displaynames" bei der Rückgabe in ihre wirklichen Pfade umwandeln - aus dem ausgewählten Ordner C:\Benutzer wird zum Beispiel C:\Users (so heißt er im Dateisystem ab Vista).
    Bei den durch die automatische Umleitung geänderten Ordnername ist das natürlich nicht so. Wählt der User zum Beispiel die Datei C:\Windows\System32\atl.dll aus, so steht nicht in der Rückgabe des Dialoges C:\Windows\SysWOW64\atl.dll (das ist ja die eigentlich ausgewählte Datei), sondern (wie angeklickt) C:\Windows\System32\atl.dll.

  • Die Message LB_DIR unter WOW64 versenden



    Auch das Senden der Message LB_DIR ist von der automatischen Umleitung des Dateisystems betroffen, wenn man sie unter 64Bit Systemen von einem 32Bit Programm aus sendet. Will man zum Beispiel mit LB_DIR den Inhalt des Ordners System32 listen lassen, wird auch hier der Inhalt des Ordners SysWOW64 angezeigt. Besonders deutlich wird das beim Ordner C:\Windows\System32\Drivers. Hier ist Code dazu:



    Um hier den Inhalt des richtigen Ordners zu erhalten, ist vor dem Aufruf von Sendmessage mit LB_DIR die Umleitung zu deaktivieren und danach sofort wieder zu aktivieren.

    [Blockierte Grafik: http://s2.postimage.org/TPdG0.jpg]

    [Blockierte Grafik: http://s2.postimage.org/TPiFi.jpg]

  • Profans AddFiles unter 64Bit



    Auch der Profanbefehl Addfiles landet aufgrund der der Umleitung des Dateisystems unter Umständen im falschen Verzeichnis.
    Hier auch Code dazu:

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!