====== Virtualisierung für Software - .NET (CLR) ====== Das Prinzip der Virtualisierung wird auch in einigen modernen Programmiersprachen bzw. Frameworks/Plattformen angewendet. Das Programm wird dann nicht direkt nativ ausführt sondern läuft in einer eigenen virtuellen Maschine. ===== Generell ===== * Funktionsweise (vgl. auch .NET unten) * Programmcode wird vom Compiler in Bytecode kompiliert, dieser Bytecode ist unabhängig von der Hardware und vom Betriebssystem * Bei Ausführung des Programms wird dieser vorkompilierte Bytecode an die Laufzeitumgebung bzw. die virtuelle Maschine (die ein Bestandteil der Laufzeitumgebung ist) übergeben * Die virtuelle Maschine verarbeitet diesen Bytecode nun zum systemabhängigen Maschinencode weiter * Es handelt sich also quasi um eine Mischung aus kompilierter und interpretierter Sprache * Managed Code * Die virtuelle Maschine übernimmt das komplette Speichermanagement, ein Garbage Collector sorgt dafür, dass nicht mehr benötigte Daten aus dem RAM gelöscht werden. * Bei Managed Code greift das Programm nicht direkt auf die Hardware zu, sondern die virtuelle Maschine erledigt dies quasi im Auftrag des Programmes. Sogenannte systemnahe Anwendungen (v.a. Treiber) eigenen sich deshalb nicht für managed Code! * Auf Zeigerprogrammierung wird in der Regel vollständig verzichtet - es würde auch nicht zum Konzept der abgekapselten virtuellen Maschine passen, wenn dann erst wieder auf einen bestimmten Speicherbereich zugegriffen wird. Die Speicherverwaltung ist Sache der Laufzeitumgebung und nicht des Programmierers. * großer Vorteil: Plattformunabhängigkeit * Programme greifen nicht auf betriebssystemabhängige Funktionen zu, sondern laufen in der eigenen virtuellen Maschine und greifen auf die Klassen und Methoden des entsprechenden Frameworks zu * Somit muss nicht jedes einzelne Programm extra für andere Plattformen abgeändert und eigens kompiliert werden, sondern nur die Plattform (wie .NET, Java) selbst * Beispielsweise muss ein Programm in Standard-%%C++%% für Windows, Linux, etc. extra kompiliert werden. Außerdem sollte das Programm jeweils in 32-bit und 64-bit Versionen (und eventuell für andere Architekturen) kompiliert werden. Eventuell muss der Programmcode auch angepasst werden (wenn das Programm z.B. auf Win32-Funktionen zugreift, läuft es nicht ohne Weiteres unter anderen Betriebssystemen). * Ein Programm, welches mit einer Plattform, die verwalteten Code verwendet, entwickelt wurde, muss nur einmalig kompiliert werden. Angepasst werden muss nur die VM selbst, dies macht entweder der Hersteller selbst oder andere Programmierer * Wesentlicher Nachteil: Es ist deutlich einfacher, Rückschlüsse auf den ursprünglichen Quelltext von solchen Programmen, die dem Nutzer in Bytecode ausgeliefert werden, zu ziehen (Dekompilierung). Es gibt zwar verschiedene Methoden, um dies zu erschweren (vgl. [[http://de.wikipedia.org/wiki/Obfuscator|Obfuscator]] = Quelltextverschleierung), jedoch ist klar, dass die gleiche Sicherheit wie bei Programmen, die bereits in Maschinencode ausgeliefert werden, nicht erreicht werden kann! ===== .NET mit der CLR ===== {{ :inf:inf8bi_201112:virtualisierung:01_002.gif?300|}} {{ :inf:inf8bi_201112:virtualisierung:588px-net_basisprinzip_ext.svg.png?300|}} * .NET ist eine Plattform, auf die von verschiedenen Programmiersprachen zugegriffen werden kann. Die wichtigste .NET-Sprache ist C#, sie wurden eigens für .NET veröffentlicht und hat nur sehr wenige sprachabhängige Funktionen. Desweiteren gibt es eine sehr große Zahl an Sprachen (derzeit etwa 60), von denen es eine .NET-Implementierung gibt, sodass sie unter .NET ausgeführt werden und auf die .NET-Funktionen zugegriffen werden kann (VB.NET, C++/CLI, IronPython, JScript.NET, ...) * Die Syntax der Sprache und ihre sprachabhängigen Fähigkeiten ändern sich dadurch nicht - .NET verfolgt den Ansatz "eine Plattform für viele Sprachen" * Programmcode von sämtlichen .NET-Sprachen wird nicht direkt in Maschinencode kompiliert, sondern in CIL (Common Intermediate Language). Dieser CIL-Code ist unabhängig von der verwendeten Sprache. Der C#-Code class HalloWelt { public static void Main() { Console.WriteLine("Hallo Welt"); } } wird zum CIL-Code: .assembly HalloWelt { } .assembly extern mscorlib { } .method public static void Main() cil managed { .entrypoint .maxstack 1 ldstr "Hallo Welt!" call void [mscorlib]System.Console::WriteLine(string) ret } Der selbe CIL-Code wäre auch entstanden, wenn das Programm in Visual Basic .NET, IronPython usw. geschrieben worden wäre * Dieser Zwischencode wird beim Start des Programms in die CLR (Common Language Runtime), eine eigenen virtuellen Maschine, geladen und dort in Maschinencode übersetzt. Genauer gesagt geschieht die Umwandlung im JITter, einem Teil der CLR. * Die CLR besteht aus zahlreichen Diensten, die verschiedene Aufgaben rund um die Verwaltung und Ausführung des Programms übernehmen: Beispiele sind der Class Loader, der JITter, der Exception Manager, der Garbage Collector, der Thread Service, ... * Damit ist die CLR der Kern von .NET, sie übernimmt die komplette Verwaltung von .NET-Programmen zur Laufzeit * Sicherheitskonzept * Durch die Abschottung vom Host-System ist eine Manipulation von .NET-Programmen durch andere Programme deutlich schwieriger als bei Programmen in unmanaged Code. * Aufgrund des deutlich umfassendere Berechtigungsmanagement, dem nicht-systemnahen Ablauf und weiteren Sicherheitsrichtlinien ist es deutlich schwieriger Schadsoftware in .NET zu schreiben - also mehr Sicherheit für den Nutzer