Skip to Content
Neue Version 12 verfügbar 🎉
ObfuscatorUmbenennung von SymbolenAssemblyübergreifende Umbenennung

Assemblyübergreifende Umbenennung

Bei der Verschleierung benennt Babel Obfuscator alle Symbole um, die außerhalb der Assembly nicht sichtbar sind, also private und interne Symbole. Babel ändert demnach die Namen von Feldern, Methoden, Klassen und anderen Codeelementen, auf die von außerhalb der Assembly nicht zugegriffen werden soll.

Symbole, die außerhalb der Assembly sichtbar sind, etwa öffentliche Symbole, benennt Babel nicht um. Auf öffentliche Symbole sollen andere Assemblys zugreifen, und eine Umbenennung würde die Funktion der Anwendung beeinträchtigen. Babel benennt deshalb nur die Symbole um, auf die andere Assemblys nicht zugreifen sollen, sodass die Anwendung weiterhin wie vorgesehen funktioniert.

Babel kann jedoch sowohl öffentliche als auch interne Member über mehrere Assemblys hinweg verschleiern. Dazu werden die Namen der verschleierten Symbole, die in jeder Assembly referenziert werden, mithilfe von XML-Map-Dateien angepasst.

Der Grund: Wenn eine Assembly verschleiert wird, ändern sich die Namen ihrer Symbole. Jede Referenz einer anderen Assembly auf diese Symbole muss daher auf die neuen Namen umgestellt werden. Wenn Sie diese XML-Map-Dateien als Eingabe und Ausgabe angeben, kann Babel Obfuscator damit die Namensreferenzen zwischen allen beteiligten Assemblys anpassen. So funktioniert der verschleierte Code korrekt und scheitert nicht an falschen Symbolnamen.

Halten Sie Map-Dateien unbedingt unter Verschluss und liefern Sie sie unter keinen Umständen mit der verschleierten Anwendung aus. Mit ihnen lässt sich die Verschleierung rückgängig machen, was die Sicherheit der Anwendung gefährdet.

Assemblyübergreifende Umbenennung einrichten

Um die assemblyübergreifende Umbenennung einzurichten, müssen alle Assemblys berücksichtigt werden, die an der Umbenennung beteiligt sind. Betrachten Sie die Hauptassembly der Anwendung, MainAssembly.dll, die die öffentliche Schnittstelle zweier externer Komponenten verwendet: Library1.dll und Library2.dll. Library1.dll muss außerdem auf die öffentliche Schnittstelle von Library2.dll zugreifen, nach folgendem Schema:

  • MainAssembly.dll
    1. Library1.dll
    2. Library2.dll
  • Library1.dll
    1. Library2.dll

Diese Konfiguration zeigt die Beziehungen zwischen den Assemblys, die an der Verschleierung beteiligt sind. Im ersten Schritt konfigurieren Sie Babel so, dass es die öffentlichen Symbole in Library1.dll und Library2.dll verschleiert. Dazu fügen Sie dem Quellcode beider Bibliotheken das folgende benutzerdefinierte Attribut auf Assemblyebene hinzu:

[assembly: System.Reflection.ObfuscateAssembly(true)]

Dieses Attribut weist Babel an, die öffentlichen Symbole der angegebenen Assembly zu verschleiern, ohne dass externe XML-Regeldateien nötig sind. Ist der boolesche Parameter auf true gesetzt, wird die öffentliche Schnittstelle der Assembly als privat behandelt, sodass die Namen öffentlicher Member gefahrlos verschleiert werden können.

Alternativ können Sie Babel mit einer XML-Regeldatei so konfigurieren, dass es die öffentliche Schnittstelle einer Assembly umbenennt. Dieses Verfahren ist flexibler und gibt Ihnen mehr Kontrolle, weil Sie Teile der öffentlichen Schnittstelle gezielt verschleiern können. Das folgende Beispiel zeigt eine XML-Regeldatei namens public.xml, die die Verschleierung aller Namen öffentlicher Member erzwingt:

<Rules> <Rule name="obfuscate public" exclude="false"> <Access>Public</Access> <Pattern isRegEx="false">*</Pattern> <Description>Obfuscate all public symbols.</Description> </Rule> </Rules>

Verglichen mit dem Attribut ObfuscateAssembly lässt sich mit der XML-Regel feiner steuern, welche öffentlichen Symbole verschleiert werden. Mit dem Ausdruck im Element Pattern geben Sie an, welche Teile der öffentlichen Schnittstelle verschleiert werden sollen, und stimmen die Verschleierung so auf Ihren Bedarf ab.

Damit sind Library1.dll und Library2.dll entweder mit dem Attribut ObfuscateAssembly oder mit der XML-Regeldatei (hier public.xml) konfiguriert:

  • MainAssembly.dll
  • Library1.dll (konfiguriert mit public.xml)
  • Library2.dll (konfiguriert mit public.xml)

Für jede Assembly, die so konfiguriert ist, dass ihre öffentliche Schnittstelle umbenannt wird, muss die Erzeugung einer XML-Map-Datei eingeschaltet werden.

Diese Datei enthält die Zuordnung zwischen den ursprünglichen Symbolnamen und ihren verschleierten Entsprechungen. Die XML-Map-Datei wird von allen an der Verschleierung beteiligten Assemblys verwendet, die mindestens eine Assembly mit umbenannter öffentlicher Schnittstelle referenzieren. So werden die Namen über die verschleierten Assemblys hinweg korrekt aufgelöst.

Um Library1.dll und Library2.dll zu verschleiern, verwenden Sie die folgende CLI-Syntax:

babel Library2.dll --rules public.xml --mapout

Dieser erste Befehl verschleiert Library2.dll und erzeugt eine XML-Map-Datei namens Library2.map.xml, die die Zuordnung zwischen den ursprünglichen und den verschleierten Symbolnamen enthält.

Weil Library1.dll die Assembly Library2.dll referenziert und deren öffentliche Schnittstelle verwendet, muss bei der Verschleierung von Library1.dll die Datei Library2.map.xml als Eingabe angegeben werden, damit die verschleierten Symbole von Library2.dll korrekt zugeordnet werden. Da außerdem die öffentliche Schnittstelle von Library1.dll verschleiert werden soll, wird Babel so konfiguriert, dass es die Regeldatei public.xml lädt und eine entsprechende XML-Map-Datei für Library1.dll erzeugt.

Der CLI-Befehl für diesen Schritt lautet:

babel Library1.dll --rules public.xml --mapout --mapin Library2.map.xml

So referenziert Library1.dll die verschleierten Symbole aus Library2.dll korrekt und erzeugt zugleich eine eigene Map-Datei, die im weiteren Verlauf der Verschleierung verwendet wird.

Um schließlich MainAssembly.dll zu verschleiern, muss Babel die XML-Map-Dateien von Library1.dll und Library2.dll laden, weil MainAssembly diese Assemblys referenziert. So kann MainAssembly bei der Verschleierung die verschleierten Symbole der Bibliotheken, von denen es abhängt, korrekt auflösen.

Der CLI-Befehl für diesen Schritt lautet:

babel MainAssembly.dll --mapin Library1.map.xml --mapin Library2.map.xml

Dieser Befehl liest die zuvor erzeugten Map-Dateien (Library1.map.xml und Library2.map.xml) ein, damit die Referenzen auf die verschleierten Symbole dieser Bibliotheken in MainAssembly korrekt behandelt werden.

Es ist entscheidend, die Assemblys in der richtigen Reihenfolge zu verschleiern. Bibliotheken, die von anderen Assemblys referenziert werden, wie Library2.dll und Library1.dll, müssen zuerst verschleiert werden, damit die nötigen Map-Dateien entstehen. Danach können abhängige Assemblys wie Library1.dll und MainAssembly.dll mit diesen Map-Dateien verschleiert werden.

Einrichtung mit der MSBuild-Aufgabe

Um die assemblyübergreifende Umbenennung mit MSBuild zu konfigurieren, müssen für jede Assembly des Verschleierungsprojekts die XML-Map-Dateien für Eingabe und Ausgabe sowie die XML-Regeldatei angegeben werden. Jede verschleierte Assembly muss eine XML-Map-Datei erzeugen, die dann allen anderen verschleierten Assemblys, die diese Ziel-Assembly referenzieren, als Eingabe dient.

Das folgende Beispiel zeigt, wie Sie die assemblyübergreifende Umbenennung zwischen einer Hauptassembly und zwei referenzierten Assemblys konfigurieren, die nach folgendem Schema angeordnet sind.

  • MainAssembly.dll
    1. Library1.dll
    2. Library2.dll
  • Library1.dll
    1. Library2.dll

Den Anfang macht das Projekt Library2, das keine Abhängigkeiten hat. Weil es von keiner anderen Assembly abhängt, kann es unabhängig verschleiert werden und braucht keine XML-Map-Dateien als Eingabe.

Projekt der Assembly Library2

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <GenerateMapOutFile>true</GenerateMapOutFile> </PropertyGroup> <Target Name="Obfuscate" AfterTargets="CoreCompile"> <ItemGroup> <RulesFile Include="path\to\referenced\public.xml" /> </ItemGroup> <Babel Input="$(TargetPath)" RulesFiles="@(RulesFile)" GenerateMapOutFile="$(GenerateMapOutFile)" /> </Target> </Project>

Beachten Sie: Weil Library1 die Assembly Library2 referenziert, muss das Verschleierungsprojekt nicht nur mit GenerateMapOutFile=true die XML-Map-Datei erzeugen, sondern auch die für Library2 erzeugte Map-Datei referenzieren.

Projekt der Assembly Library1

<Project Sdk="Microsoft.NET.Sdk"> <ItemGroup> <Reference Include="path\to\referenced\Library2.dll" /> </ItemGroup> <PropertyGroup> <GenerateMapOutFile>true</GenerateMapOutFile> </PropertyGroup> <Target Name="Obfuscate" AfterTargets="CoreCompile"> <ItemGroup> <MapInFile Include="path\to\referenced\Library2.dll.map.xml" /> </ItemGroup> <ItemGroup> <RulesFile Include="path\to\referenced\public.xml" /> </ItemGroup> <Babel Input="$(TargetPath)" MapInFiles="@(MapInFile)" RulesFiles="@(RulesFile)" GenerateMapOutFile="$(GenerateMapOutFile)" /> </Target> </Project>

Weil das Projekt MainAssembly die beiden Bibliotheken Library1 und Library2 referenziert, deren öffentliche Schnittstelle verschleiert wurde, muss die Babel-Aufgabe so konfiguriert werden, dass sie die beiden XML-Map-Dateien lädt, die für die Bibliotheken erzeugt wurden.

Projekt der Hauptassembly

<Project Sdk="Microsoft.NET.Sdk"> <ItemGroup> <Reference Include="path\to\referenced\Library1.dll" /> <Reference Include="path\to\referenced\Library2.dll" /> </ItemGroup> <Target Name="Obfuscate" AfterTargets="CoreCompile"> <ItemGroup> <MapInFile Include="path\to\referenced\Library1.dll.map.xml" /> <MapInFile Include="path\to\referenced\Library2.dll.map.xml" /> </ItemGroup> <Babel Input="$(TargetPath)" MapInFiles="@(MapInFile)" /> </Target> </Project>

So werden alle gegenseitigen Referenzen zwischen Library1 und Library2 bei der Verschleierung korrekt behandelt. Wird die für Library2 erzeugte XML-Map-Datei nicht referenziert, behandelt die Verschleierung von Library1 die Referenzen zwischen den beiden Bibliotheken möglicherweise nicht korrekt, was zur Laufzeit zu Problemen führen kann. Achten Sie deshalb bei der Konfiguration der assemblyübergreifenden Umbenennung darauf, dass alle nötigen XML-Map-Dateien erzeugt und korrekt referenziert werden.

Einrichtung in Babel Desktop

Ein Projekt in Babel Desktop kann alle beteiligten Assemblys enthalten. Verbinden Sie auf der Zeichenfläche des Projekts jede Bibliothek mit der Assembly, die sie verwendet, und wählen Sie Map-Datei weitergeben: Die Bibliothek schreibt dann ihre Map-Datei, die verwendende Assembly liest sie, und die Bibliothek wird zuerst verschleiert. Im obigen Beispiel verbinden Sie Library2 mit Library1 und mit MainAssembly sowie Library1 mit MainAssembly. Eine Verbindung mit Nur Ausführungsreihenfolge legt die Reihenfolge fest, gibt aber keine Map-Datei weiter.

Die Regeln für die Umbenennung der öffentlichen Symbole fügen Sie weiterhin jeder Bibliothek hinzu, mit XML-Regeln oder RulesFiles. Die Gruppe Map-Dateien in den Eigenschaften des Ziels zeigt die Maps, die jedes Ziel schreibt und liest, und dort können Sie Map-Dateien aus früheren Builds hinzufügen. Siehe Ausführungsreihenfolge und Map-Dateien.

Last updated on