Einzelnen Beitrag anzeigen

Benutzerbild von Assarbad
Assarbad

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

AW: 32bit-DLL mit LoadLibrary auf einem 64bit-System laden?

  Alt 7. Sep 2016, 15:47
Zitat:
Wetten daß doch?!
JO? Möchte ich schwer bezweifeln und den Beweis dafür antreten.

Ich habe eine 64Bit DLL geschrieben bzw. für ein 64Bit Betriebssystem verfügbar gemacht (Die gab es vorher nur in 32Bit)
Diese integriert sich in den Eigenschaften Dialog von *.mp3 Dateien im System 64Bit.

Wenn das so klappt wie du sagst warum werden dann diese Eigenschaften nicht mehr erkannt wenn ich
versuche eine Datei mit einer 32Bit Anwendung zu öffnen bzw. davon die Eigenschaften anzeigen zu lassen ?
Vermutlich weil eine Shellerweiterung für einen 64-bittigen Windows Explorer auch 64-bittig sein sollte? Das ist nix neues.

Ich habe dir also einen Sichtbaren beweis erbracht das es nicht geht..
Irrtum. Du hast das Thema gewechselt und eine neue Behauptung aufgestellt, die ich nie angezweifelt habe. Darf ich dich nochmals auf deine ursprüngliche Aussage aufmerksam machen, ja?

Du kannst über eine 32Bit Schnittstelle nicht mit einen 64Bit Treiber kommunizieren.
Das ist und bleibt Unsinn. Aber die Details hat Zacherl ja ausgeführt (seine Beiträge, nicht der Link)

Die üblichen Schnittstellen über die du aus dem Win32-Subsystem mit einem (KM-)Treiber kommunizierst sind DeviceIoControl, ReadFile, WriteFile (und natürlich CreateFile und CloseFile). Sind die in WOW64 verfügbar? Ja? Gut, dann kannste auch kommunizieren.

Ich schreib dir jetzt keinen extra (KM-)Treiber, keinen Bock drauf. Aber da ich selbst über lange Jahre genau diesen Anwendungsfall gewartet habe und dies bis heute tue (32-bittige Anwendung/DLL kommuniziert mit 64-bittigem Treiber auf 64-bittigem Windows), bin ich mir da auch sehr sicher

Sehr mutig Assarbad zu widersprechen
Kann zum Thema selbst nicht wirklich was beitragen, aber mich würd interessieren was am Ende rauskommt
Warum? Ist doch nix ehrenrühriges dran. Solange es der Wahrheitsfindung dient ...

Das hat aber nichts mit Treibern oder Ressourcen-DLLs zu tun.


Das Einzige, wo sich solche DLLs in der Bittigkeit unterscheiden dürfen ist bei solchen Out-Of-Process COM Servern, wo die DLL nicht im eigenen Prozess geladen wird, sondern in einem externen DLLHost ... da nimmt die COM-Schnittstelle dann die Verbindung/Datenkonvertierung/-übertragung vor.
Das unterschreibe ich voll und ganz.

Das laden einer Library von einer 32Bit Anwendung ist nicht gleichzusetzen mit der Funktion ob diese DLL dann mit 32Bit Anwendung kommunizieren kann.
Ich zitier' dich jetzt nicht noch ein zweites Mal ... siehe deine ursprüngliche Behauptung weiter oben.

Ob es nun ein Treiber oder eine normale 64Bit DLL ist spielt dabei jetzt keine rolle.
Noch deutlicher als mit Bildern kann man es nicht widergeben.
Wenn das jemand nicht sieht braucht er eine Brille.
Puh, jetzt lehnste dich aber weit aus dem Fenster.

Wir redeten doch von einem Treiber, ja? Die meisten Treiber, gerade für Hardware, existieren im Kernelmodus (KM), richtig? Wie kommunizierst du mit dem Kernelmodus? Üblicherweise paketbasiert. Die o.g. Funktionen sind ein gutes Beispiel. Übrigens sieht man hier die Verwandtschaft (im Geiste) zu Unix™. Dort benutzt man auch Funktionen um "Dateien" zu öffnen, lesen und schreiben um auf Geräte unter /dev zuzugreifen. Und auch DeviceIoControl findet seine Entsprechung in der Funktion ioctl.

Das ist der Grund warum es auch nicht geht.
Genau (bezogen auf dein Beispiel, welches in keinem Zusammenhang zu KM-Treibern steht). Mit der Ausnahme die Zacherl genannt hat. Aber diese würde ich mal unter "Hack" verbuchen und für unsere Diskussion ignorieren.

Aber er sagte doch es geht.
Dem habe ich widersprochen.

Treiber hin oder her..
Das ist der springende Punkt. Leider liegst du aber mit dem Vergleich falsch, insbesondere wenn wir von (KM-)Treibern reden.

Wenn du eine DLL lädst um Funktionen drin aufzurufen, befindest du dich im gleichen Adreßraum (wir ignorieren weiterhin den Artikel den Zacherl verlinkt hat). Wenn du eine 32-bit DLL (sei es kernel32.dll oder deine eigene) auf einem 64-bit Windows in eine 32-bit Anwendung lädst, dann kannst du die Funktionen und Daten in der DLL nur erreichen weil sie im gleichen Adreßraum sind. Das ist eine sehr direkte Geschichte und erfordert wenig Phantasie oder Wissen. Einfach Auf CPU-Ebene call und jmp usw. um zum Ziel zu gelangen.

Ich versuch mal zu erklären was abgeht ohne zu tief in die Materie einzudringen. Dafür muß ich etwas vereinfachen. Für eine grobe Erklärung kannste dir eine aktuelle Ausgabe von "Windows Internals" zur Hand nehmen. Für Details zusätzlich einen Debugger, die WDK-Dokumentation und einen Disassembler. Alternativ bietet sich auch an in die Quellen von ReactOS zu schauen, welches Windows nachzubilden versucht.

Wenn du eine Anforderung stellst, die in den Kernelmodus geht, bspw. eine Datei liest, oder eben ein Hardwaregerät anspricht, wird ein sogenannter IRP (I/O Request Packet) an das CDO (Control Device Object) oder PDO (Physical Device Object) eines Treibers geschickt [1]. Um eine Datei zu öffnen wäre das bspw. IRP_MJ_CREATE, weshalb man halt CreateFile als extra Funktion hat.

Wenn du dir WinObj von Sysinternals zur Hand nimmst und unter \GLOBAL?? guckst, siehste da bspw. symbolische Links zu einer Volume-Instanz. Der I/O Manager sieht nun bspw. einen Pfad wie \??\C:\boot.ini, welchen kernel32.dll bereits aus der Dos/Win32-Form in die native Form überführt hat. Für diese Erklärung nimm einfach an, daß \GLOBAL?? == \??. Der I/O Manager geht nun den Pfad ab und sieht daß \GLOBAL?? ein Gerät (Device) oder einen Symlink namens C: enthält ... und löst den Namen mithilfe des Object Managers auf und gelangt bspw. zu \Device\Harddisk\Volume2. Der Pfad wird also zu \Device\Harddisk\Volume2\boot.ini. Nun weiß der I/O Manager aber, daß \Device\Harddisk\Volume2 ein Gerät ist und weiß welcher Treiber (üblicherweise der Festplattentreiber und Dateisystemtreiber) dafür verantwortlich ist (es handelt sich um einen Gerätestapel ... so filtert übrigens auch ein AV-Treiber Dateizugriffe). Also wendet er sich vertrauensvoll an dieses Gerät (\Device\Harddisk\Volume2) und übergibt dem zuständigen Treiber den restlichen Pfad (\boot.ini). Wenn ein Festplattentreiber involviert ist, reicht er es an das Dateisystem weiter (wenn du aber bspw. den Bootsektor ausliest, erledigt das der Festplattentreiber normalerweise). Der Dateisystemtreiber weiß dann damit was anzufangen (oder auch nicht, wenn die Datei nicht existiert) und extrahiert die Informationen aus dem IRP und reagiert entsprechend. Nach diversen Sicherheitschecks (schließlich kam die Anforderung ja in einem Benutzer- und Prozeßkontext), mag das Öffnen erfolgreich sein. In diesem Fall bekommt der UM ein Handle zurück. Wenn nun ReadFile oder WriteFile mit diesem Handle benutzt wird, wird ein IRP mit IRP_MJ_READ oder IRP_MJ_WRITE in den Kernelmodus übertragen und dort entsprechend weiterverarbeitet. Wenn man DeviceIoControl benutzt, ist es IRP_MJ_DEVICE_CONTROL und ein vordefinierter IOCTL (I/O Control Code), den du bspw. WinIoctl.h entnehmen kannst für diverse in Windows eingebaute Treiber. Das Handle wiederum wird intern in einen Zeiger auf ein FILE_OBJECT umgewandelt, wenn der Dateisystemtreiber (oder Dateisystemfiltertreiber) damit zu tun haben. Diese Objekte sind in der Tat Objekte im OOP-Sinn, auch wenn sie das nicht im Delphi- oder C++-Sinn sind. Sie haben Funktionen (öffnen, schließen usw.) und Daten. Der Object Manager ist verantwortlich dafür. Einen Überblick über die Objekttypen erhält man in \ObjectTypes, denn dort existieren die "Klassen" als Instanzen des Objekttyps "Type".

So, durch diese paketbasierte Kommunikation kann nun ein 32-bit Prozeß (oder eine darin geladene 32-bittige DLL) auf einem 64-bittigen Windows mit einem 64-bittigen (KM-)Treiber kommunizieren. Q.E.D.

[1] Ein AV-Treiber hat bspw. ein CDO um eben gesteuert werden zu können (Scanner aktivieren, deaktivieren oder bspw. Ausnahmen für Pfade konfigurieren oder Einstellungen am Scanner vornehmen, bspw. Archive scannen ja/nein). Kann aber auch andere Device Objects erzeugen und damit anderes machen. Es gibt nicht nur CDOs und PDOs. Treiber die nur Software ansprechen nennt man Virtual Device Drivers (VDD), im Gegensatz zu jenen die eine Schnittstelle zu einem Hardwaregerät herstellen.
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)

Geändert von Assarbad ( 7. Sep 2016 um 15:52 Uhr)
  Mit Zitat antworten Zitat