Was ist in einer DLL und wie funktioniert es?

86

Ich verweise in meinem C # -Code immer auf DLLs, aber sie sind ein Rätsel geblieben, das ich gerne klären möchte. Dies ist eine Art Brain Dump von Fragen zu DLLs.

Ich verstehe, dass eine DLL eine dynamisch verknüpfte Bibliothek ist, was bedeutet, dass ein anderes Programm zur Laufzeit auf diese Bibliothek zugreifen kann, um "Funktionalität" zu erhalten. Betrachten Sie jedoch das folgende ASP.NET-Projekt mit Web.dllund Business.dll( Web.dllist die Front-End-Funktionalität und verweist Business.dllauf Typen und Methoden).

  1. Ab wann wird Web.dlldynamisch eine Verknüpfung hergestellt Business.dll? Sie bemerken viel in Windows HDD Thrashing für scheinbar kleine Aufgaben, wenn Sie Word (usw.) verwenden, und ich gehe davon aus, dass Word nicht mehr funktioniert und Funktionen anderer DLLs dynamisch verknüpft?

    1a. Was lädt und verknüpft außerdem die DLL - das Betriebssystem oder ein Laufzeitframework wie das .NET-Framework?

    1b. Was ist der Prozess der "Verknüpfung"? Werden Kompatibilitätsprüfungen durchgeführt? In den gleichen Speicher laden? Was bedeutet eigentlich Verknüpfen?

  2. Was führt den Code in der DLL tatsächlich aus? Wird es vom Prozessor ausgeführt oder gibt es eine andere Phase der Übersetzung oder Kompilierung, bevor der Prozessor den Code in der DLL versteht?

    2a. Was wird bei einer in C # .NET integrierten DLL ausgeführt: das .NET Framework oder das Betriebssystem direkt?

  3. Funktioniert eine DLL von Linux auf einem Windows-System (falls vorhanden) oder sind sie betriebssystemspezifisch?

  4. Sind DLLs spezifisch für ein bestimmtes Framework? Kann eine mit C # .NET erstellte DLL von einer mit Borland C ++ erstellten DLL verwendet werden?

    4a. Wenn die Antwort auf 4 "Nein" lautet, wozu dient dann eine DLL? Warum verwenden die verschiedenen Frameworks keine eigenen Formate für verknüpfte Dateien? Beispiel: Eine in .NET integrierte EXE-Datei weiß, dass ein Dateityp von .abc mit ihrem Code verknüpft werden kann.

  5. Gehen wir zurück zum Web.dll/ Business.dllBeispiel - eine Klasse Art von Kunden erreiche ich Referenz müssen Business.dllaus Web.dll. Dies muss bedeuten, dass Business.dlleine Art Spezifikation enthält, was eine Kundenklasse tatsächlich ist. Wenn ich meine Business.dllDatei beispielsweise in Delphi kompiliert hätte: Würde C # sie verstehen und in der Lage sein, eine Kundenklasse zu erstellen, oder gibt es eine Art Header-Information oder etwas, das besagt: "Hey, tut mir leid, Sie können mich nur von einer anderen Delphi-DLL aus verwenden." ?

    5a. Gleiches gilt für Methoden; Kann ich eine CreateInvoice()Methode in eine DLL schreiben , sie in C ++ kompilieren und dann von C # aus darauf zugreifen und sie ausführen? Was hält mich davon ab oder erlaubt es mir?

  6. Beim Thema DLL-Hijacking muss die (schlechte) Ersatz-DLL sicherlich die genauen Methodensignaturen und -typen enthalten, die entführt werden. Ich nehme an, das wäre nicht schwer, wenn Sie herausfinden könnten, welche Methoden in der ursprünglichen DLL verfügbar sind.

    6a. Was in meinem C # -Programm entscheidet, ob ich auf eine andere DLL zugreifen kann? Wenn meine entführte DLL genau die gleichen Methoden und Typen wie das Original enthalten würde, aber in einer anderen Sprache kompiliert würde, würde es funktionieren?

Was ist DLL-Import und DLL-Registrierung?

Remotec
quelle
21
Diese Frage könnte nach der längsten Antwort in der SO-Geschichte fragen.
Matti Virkkunen
4
Es sollten 12 separate Fragen gewesen sein.
Henk Holterman
2
Dies ist eine großartige Frage, aber ich stimme @Chaos und @Matti wirklich zu. Diese Frage muss stärker behandelt werden und könnte / sollte in verschiedene Fragen unterteilt werden.
Chris Thompson
3
Es war ein bisschen wie ein Brain Dump, als ich es schrieb + ich wollte Wissen in einem Bereich zentralisieren :)
Remotec
1
Sollte jetzt ein Community-Wiki sein.
Leppie

Antworten:

74

Zunächst müssen Sie den Unterschied zwischen zwei sehr unterschiedlichen Arten von DLLs verstehen. Microsoft entschied sich für die gleichen Dateierweiterungen (.exe und .dll) sowohl für .NET (verwalteter Code) als auch für nativen Code. Verwaltete Code-DLLs und native DLLs sind jedoch im Inneren sehr unterschiedlich.

1) Ab wann wird web.dll dynamisch mit business.dll verknüpft? Sie bemerken viel in Windows HDD Thrashing für scheinbar kleine Aufgaben bei der Verwendung von Word usw. und ich denke, dass dieses Word losgeht und Funktionen in anderen DLLs dynamisch verknüpft?

1) Im Fall von .NET werden DLLs normalerweise bei Bedarf geladen, wenn die erste Methode ausgeführt wird, die versucht, auf etwas von der DLL zuzugreifen. Aus diesem Grund können Sie TypeNotFoundExceptions an einer beliebigen Stelle in Ihrem Code abrufen, wenn eine DLL nicht geladen werden kann. Wenn so etwas wie Word plötzlich häufig auf die Festplatte zugreift, wird es wahrscheinlich ausgetauscht (Daten, die auf die Festplatte ausgelagert wurden, werden abgerufen, um Platz im RAM zu schaffen).

1a) Was lädt und verknüpft zusätzlich die DLL - das Betriebssystem oder ein Laufzeitframework wie das .NET-Framework?

1a) Bei verwalteten DLLs wird das .NET Framework geladen, JIT kompiliert (kompiliert den .NET-Bytecode in nativen Code) und verknüpft die DLLs. Bei nativen DLLs ist dies eine Komponente des Betriebssystems, die die DLL lädt und verknüpft (eine Kompilierung ist nicht erforderlich, da native DLLs bereits nativen Code enthalten).

1b) Was ist der Prozess der "Verknüpfung"? Werden Überprüfungen auf Kompatibilität durchgeführt? In den gleichen Speicher laden? Was bedeutet eigentlich Verknüpfen?

1b) Beim Verknüpfen werden Verweise (z. B. Methodenaufrufe) im aufrufenden Code auf Symbole (z. B. Methoden) in der DLL durch die tatsächlichen Adressen der Dinge in der DLL ersetzt. Dies ist erforderlich, da die möglichen Adressen der Dinge in der DLL nicht bekannt sind, bevor sie in den Speicher geladen wurden.

2) Was führt den Code in der DLL tatsächlich aus? Wird es vom Prozessor ausgeführt oder gibt es eine andere Phase der Übersetzung oder Kompilierung, bevor der Prozessor den Code in der DLL versteht?

2) Unter Windows sind EXE-Dateien und DLL-Dateien ziemlich identisch. Native EXE- und DLL-Dateien enthalten nativen Code (das gleiche, was der Prozessor ausführt), sodass keine Übersetzung erforderlich ist. Verwaltete EXE- und DLL-Dateien enthalten .NET-Bytecode, der zuerst von JIT kompiliert (in nativen Code übersetzt) ​​wird.

2a) Was wird bei einer aus C # .net erstellten DLL ausgeführt? Das .Net Framework oder das Betriebssystem direkt?

2a) Nachdem der Code JIT-kompiliert wurde, wird er genauso ausgeführt wie jeder andere Code.

3) Funktioniert eine DLL von beispielsweise Linux auf einem Windows-System (falls vorhanden) oder sind sie betriebssystemspezifisch?

3) Verwaltete DLLs funktionieren möglicherweise unverändert, solange die Frameworks auf beiden Plattformen auf dem neuesten Stand sind und derjenige, der die DLL geschrieben hat, die Kompatibilität nicht absichtlich durch native Aufrufe verletzt hat. Native DLLs funktionieren nicht as-in, da die Formate unterschiedlich sind (obwohl der darin enthaltene Maschinencode der gleiche ist, wenn beide für dieselbe Prozessorplattform gelten). Unter Linux werden "DLLs" übrigens als .so-Dateien (Shared Object) bezeichnet.

4) Sind sie spezifisch für einen bestimmten Rahmen? Kann eine mit C # .Net erstellte DLL von einer mit Borland C ++ erstellten DLL verwendet werden (nur Beispiel)?

4) Verwaltete DLLs gelten speziell für das .NET Framework, funktionieren jedoch natürlich mit jeder kompatiblen Sprache. Native DLLs sind kompatibel, solange alle dieselben Konventionen verwenden (Aufrufkonventionen (wie Funktionsargumente auf Maschinencodeebene übergeben werden), Symbolnamen usw.).

5) Zurück zum Beispiel web.dll / business.dll. Um einen Klassentyp eines Kunden zu erhalten, muss ich auf business.dll aus web.dll verweisen. Dies muss bedeuten, dass business.dll eine Spezifikation enthält, wie eine Kundenklasse tatsächlich aussieht. Wenn ich meine business.dll-Datei in say Delphi kompiliert hätte, würde C # sie verstehen und in der Lage sein, eine Kundenklasse zu erstellen - oder gibt es eine Art Header-Information oder etwas, das besagt: "Hey, tut mir leid, Sie können mich nur von einer anderen Delphi-DLL verwenden." .

5) Verwaltete DLLs enthalten eine vollständige Beschreibung aller darin enthaltenen Klassen, Methoden, Felder usw. AFAIK Delphi unterstützt .NET nicht, daher werden native DLLs erstellt, die in .NET nicht direkt verwendet werden können. Sie können wahrscheinlich Funktionen mit PInvoke aufrufen, aber Klassendefinitionen werden nicht gefunden. Ich verwende Delphi nicht, daher weiß ich nicht, wie Typinformationen in DLLs gespeichert werden. C ++ basiert beispielsweise auf Header-Dateien (.h), die die Typdeklarationen enthalten und mit der DLL verteilt werden müssen.

6) Beim Thema DLL-Hijacking muss die (schlechte) Ersatz-DLL sicherlich die genauen Methodensignaturen enthalten, Typen wie die, die entführt wird. Ich nehme an, dies wäre nicht schwer zu tun, wenn Sie herausfinden könnten, welche Methoden usw. in der ursprünglichen DLL verfügbar waren.

6) In der Tat ist es nicht schwer, die DLL einfach zu wechseln. Um dies zu vermeiden, kann die Codesignatur verwendet werden. Damit jemand eine signierte DLL ersetzen kann, muss er den Signaturschlüssel kennen, den er geheim hält.

6a) Eine kleine Wiederholungsfrage hier, aber dies geht zurück auf das, was in meinem C # -Programm entscheidet, ob ich auf eine andere DLL zugreifen kann? Wenn meine entführte DLL genau die gleichen Methoden und Typen wie das Original enthalten würde, aber in einer anderen Sprache kompiliert würde, würde es funktionieren?

6a) Es würde funktionieren, solange es sich um eine verwaltete DLL handelt, die mit einer beliebigen .NET-Sprache erstellt wurde.

  • Was importiert DLL? und DLL-Registrierung?

"DLL-Import" kann viele Dinge bedeuten, normalerweise bedeutet es, auf eine DLL-Datei zu verweisen und Dinge darin zu verwenden.

Die DLL-Registrierung wird unter Windows durchgeführt, um DLL-Dateien global als COM-Komponenten zu registrieren und sie für jede Software auf dem System verfügbar zu machen.

Matti Virkkunen
quelle
3
Ich möchte # 4 hinzufügen, dass .NET DLLs übersetzen kann, damit sie mit jedem nativen Programm kompatibel sind, das COM (Common Object Model) versteht / verwendet. Sehr gute Antworten tho.
MerickOWA
7

Eine DLL-Datei enthält kompilierten Code, den Sie in Ihrer Anwendung verwenden können.

Manchmal ist das Tool zum Kompilieren der DLL wichtig, manchmal nicht. Wenn Sie in Ihrem Projekt auf die DLL verweisen können, spielt es keine Rolle, mit welchem ​​Tool die exponierten Funktionen der DLL codiert wurden.

Die Verknüpfung erfolgt zur Laufzeit, im Gegensatz zu statisch verknüpften Bibliotheken wie Ihren Klassen, die zur Kompilierungszeit verknüpft werden.

Sie können sich eine DLL als Black Box vorstellen, die etwas bietet, das Ihre Anwendung benötigt und das Sie nicht selbst schreiben möchten. Ja, jemand, der die Signatur der DLL versteht, kann eine andere DLL-Datei mit einem anderen Code erstellen, und Ihre aufrufende Anwendung kann den Unterschied nicht erkennen.

HTH

Beth
quelle
6

1) Ab wann wird web.dll dynamisch mit business.dll verknüpft? Sie bemerken viel in Windows HDD Thrashing für scheinbar kleine Aufgaben bei der Verwendung von Word usw. und ich denke, dass dieses Word losgeht und Funktionen in anderen DLLs dynamisch verknüpft?

1) Ich denke, Sie verwechseln das Verknüpfen mit dem Laden. Der Link ist, wenn alle Checks and Balances getestet werden, um sicherzustellen, dass das, was angefordert wird, verfügbar ist. Beim Laden werden Teile der DLL in den Speicher geladen oder in die Auslagerungsdatei ausgelagert. Dies ist die HD-Aktivität, die Sie sehen.

Die dynamische Verknüpfung unterscheidet sich von der statischen Verknüpfung darin, dass bei der statischen Verknüpfung der gesamte Objektcode zur Verknüpfungszeit in die Haupt-EXE-Datei eingefügt wird. Bei der dynamischen Verknüpfung wird der Objektcode in eine separate Datei (die DLL) gestellt und zu einem anderen Zeitpunkt als die EXE-Datei geladen.

Dynamische Verknüpfungen können implizit (dh die App verknüpft mit einer Importbibliothek) oder explizit (dh die App verwendet LoadLibrary (ex) zum Laden der DLL) sein.

Im impliziten Fall kann / DELAYLOAD verwendet werden, um das Laden der DLL zu verschieben, bis die App sie tatsächlich benötigt. Andernfalls werden zumindest einige Teile davon im Rahmen der Prozessinitiierung geladen (in den Prozessadressraum abgebildet). Die DLL kann auch anfordern, dass sie niemals entladen wird, während der Prozess aktiv ist.

COM verwendet LoadLibrary, um COM-DLLs zu laden. Beachten Sie, dass das System auch im impliziten Fall etwas Ähnliches wie LoadLibrary verwendet, um die DLL entweder beim Start des Prozesses oder bei der ersten Verwendung zu laden.

2) Was führt den Code in der DLL tatsächlich aus? Wird es vom Prozessor ausgeführt oder gibt es eine andere Phase der Übersetzung oder Kompilierung, bevor der Prozessor den Code in der DLL versteht?

2) DLLs enthalten Objektcode genau wie .exes. Das Format der DLL-Datei ist fast identisch mit dem Format einer Exe-Datei. Ich habe gehört, dass es nur ein Bit gibt, das sich in den Headern der beiden Dateien unterscheidet.

Bei einer aus C # .net erstellten DLL wird sie vom .NET-Framework ausgeführt.

3) Funktioniert eine DLL von beispielsweise Linux auf einem Windows-System (falls vorhanden) oder sind sie betriebssystemspezifisch?

3) DLLs sind plattformspezifisch.

4) Sind sie spezifisch für einen bestimmten Rahmen? Kann eine mit C # .Net erstellte DLL von einer mit Borland C ++ erstellten DLL verwendet werden (nur Beispiel)?

4) DLLs können mit anderen Frameworks zusammenarbeiten, wenn besondere Sorgfalt angewendet wird oder ein zusätzlicher Klebercode geschrieben wird.

DLLs sind sehr nützlich, wenn ein Unternehmen mehrere Produkte mit überlappenden Funktionen verkauft. Zum Beispiel pflege ich eine Raster-I / O-DLL, die von mehr als 30 verschiedenen Produkten im Unternehmen verwendet wird. Wenn Sie mehrere Produkte installiert haben, können durch ein Upgrade der DLL alle Produkte auf neue Rasterformate aktualisiert werden.

5) Zurück zum Beispiel web.dll / business.dll. Um einen Klassentyp eines Kunden zu erhalten, muss ich auf business.dll aus web.dll verweisen. Dies muss bedeuten, dass business.dll eine Spezifikation enthält, wie eine Kundenklasse tatsächlich aussieht. Wenn ich meine business.dll-Datei in say Delphi kompiliert hätte, würde C # sie verstehen und in der Lage sein, eine Kundenklasse zu erstellen - oder gibt es eine Art Header-Information oder etwas, das besagt: "Hey, tut mir leid, Sie können mich nur von einer anderen Delphi-DLL verwenden." .

5) Abhängig von der Plattform werden die Funktionen einer DLL auf verschiedene Arten dargestellt, durch .h-Dateien, .tlb-Dateien oder auf andere Weise auf .net.

6) Beim Thema DLL-Hijacking muss die (schlechte) Ersatz-DLL sicherlich die genauen Methodensignaturen enthalten, Typen wie die, die entführt wird. Ich nehme an, dies wäre nicht schwer zu tun, wenn Sie herausfinden könnten, welche Methoden usw. in der ursprünglichen DLL verfügbar waren.

6) Dumpbin / Exporte und Dumbin / Importe sind interessante Werkzeuge für .exe und .dlls

Edgman
quelle
3) DLL sind plattformspezifische
Henk Holterman