Beispielregeln
Um die Verschleierung durch Babel Obfuscator anzupassen, können Benutzer eigene XML-Regeln schreiben. Diese Regeln legen fest, wie der Obfuscator unter anderem mit bestimmten Klassen, Methoden und Eigenschaften verfährt. Sie erlauben eine genaue Steuerung, mit der Benutzer die Ergebnisse des Obfuscators verfeinern. Dieser Abschnitt zeigt einige Beispiele für XML-Regeln für Babel Obfuscator.
Umbenennung einer Klasse ausschalten
Um die Umbenennung für eine bestimmte Klasse mit den XML-Regeln von Babel Obfuscator auszuschalten, können Sie die folgende XML-Regel verwenden:
<Rule name="disable-myclass-renaming" feature="renaming" exclude="true"
applyToMembers="true">
<Target>Classes</Target>
<Pattern>MyNamespace.MyClass</Pattern>
<Description>Disable renaming for MyClass.</Description>
</Rule>Hinweis:
Ersetzen Sie MyNamespace.MyClass durch den vollqualifizierten Namen der Klasse, die Sie von der Umbenennung ausschließen möchten.
- Das Attribut
featurehat den Wert „renaming“, damit die Regel für die Umbenennung gilt. - Das Attribut
excludehat den Wert „true“, um die Umbenennung der angegebenen Klasse zu verhindern. applyToMembershat den Wert „true“, um die Umbenennung der Member der Klasse zu verhindern.- Das Element
Targetgibt an, dass die Regel für Klassen gilt. - Das Element
Patterngibt den vollqualifizierten Namen der Klasse an.
Vom Compiler generierter Code
Die folgende Regel schließt vom Compiler generierten Code von einigen erweiterten Verschleierungsfunktionen aus.
<Rule name="no-compiler-generated"
feature="control flow, value encryption, string encryption"
exclude="true" applyToMembers="false">
<Target>Classes</Target>
<Pattern>*</Pattern>
<HasAttribute onEnclosingType="false">
System.Runtime.CompilerServices.CompilerGeneratedAttribute,
System.Diagnostics.DebuggerHiddenAttribute
</HasAttribute>
<Description>Do not obfuscate compiler-generated methods.</Description>
</Rule>Anonyme Typen
In C# ist ein anonymer Typ ein Typ, der ohne Namen definiert wird, und zwar mit dem Operator new und einem Objektinitialisierer.
var query =
from prod in products
select new { prod.Name, prod.Price };
foreach (var v in query)
{
Console.WriteLine("Name={0}, Price={1}", v.Name, v.Price);
}So lassen sich Objekte ad hoc erzeugen, ohne vorher einen eigenen Typ zu definieren. Der Compiler generiert für den anonymen Typ einen Typnamen, der in der Regel mit den Zeichen <>f__Anonymous beginnt. Der generierte Name ist eindeutig und nicht dafür gedacht, vom Entwickler verwendet zu werden.
Anonyme Typen werden häufig in LINQ-Abfragen und in anderen Szenarien wie ASP.NET-Webanwendungen verwendet, in denen Objekte ad hoc erzeugt werden müssen.
Bei der Verschleierung können anonyme Typen Schwierigkeiten bereiten, weil ihre generierten Namen verschleiert werden könnten. Ihre Umbenennung kann Probleme in dem Code verursachen, der sie verwendet. Deshalb wird oft empfohlen, sie von der Verschleierung auszuschließen.
Eine Möglichkeit ist eine Regel, die für jedes Symbol mit dem Attribut
System.Runtime.CompilerServices.CompilerGeneratedAttribute
gilt und so den gesamten vom Compiler generierten Code ausschließt, einschließlich der anonymen Typen.
<Rule name="rule1" feature="renaming, dead code" exclude="true" applyToMembers="true">
<Pattern>*</Pattern>
<HasAttribute>System.Runtime.CompilerServices.CompilerGeneratedAttribute</HasAttribute>
</Rule>Eine andere Möglichkeit ist ein Muster mit einem regulären Ausdruck, das auf den Namen jedes dieser Typen passt, da sie in der Regel das Präfix <>f__Anonymous tragen.
<Pattern isRegEx="true">
<![CDATA[<>f__Anonymous.*]]>
</Pattern>Ob der Name eines anonymen Typs diesem Schema folgt, können Sie in einem Inspektionstool für .NET-Assemblys wie ILSpy oder dotPeek prüfen.
Filter für Dynamic Proxy verwenden
Die Filter für Dynamic Proxy (Dynamic Proxy Call Filters) sind in Babel Obfuscator ein nützliches Mittel, um die Erzeugung dynamischer Proxys fein abzustimmen und die gewünschte Verschleierungsstufe bei bestmöglicher Leistung zu erreichen (siehe Dynamic Proxy).
<Rule name="rule1" feature="dynamic proxy" exclude="false" applyToMembers="true">
<Pattern>*</Pattern>
<Description>Set Dynamic Proxy Call Filters</Description>
<Properties>
<DynamicProxyCallFilters>IEnumerator.*;ICollection.*</DynamicProxyCallFilters>
</Properties>
</Rule>Die gezeigte XML-Regel ist eine Babel-Konfiguration, die die Filter für Dynamic Proxy setzt.
Mit den Filtern für Dynamic Proxy legen Sie genau fest, welche Methodenaufrufe abgefangen und durch dynamische Proxys ersetzt werden. So schützen Sie kritische Teile Ihres Codes und lassen andere unberührt. Da die Filter reguläre Ausdrücke annehmen, können Sie die Regel auf bestimmte Namensmuster von Methoden oder auf Verhaltensweisen zuschneiden, die dynamische Proxys erfordern. Damit passen Sie Verschleierung und Schutz an die Anforderungen Ihrer Anwendung an.
Den Verschleierungs-Agent steuern
Der Verschleierungs-Agent von Babel Obfuscator führt während der Verschleierung eine Reihe von Aufgaben nach vordefinierten Regeln aus. Er soll vor allem Probleme verhindern, die durch die Verschleierung entstehen und die resultierende Assembly unbrauchbar machen könnten. So stellt der Agent zum Beispiel sicher, dass per Reflexion verwendete Symbole nicht verschleiert werden, weil dies zu Fehlern zur Laufzeit führen könnte. Die Aufgaben des Agents reichen von einfachen Prüfungen, etwa der Felder serialisierbarer Typen, bis zu komplexeren Vorgängen mit statischer Analyse des MSIL-Codes.
Der Verschleierungs-Agent ist entscheidend dafür, dass verschleierter Code reibungslos funktioniert. Es kann dennoch Fälle geben, in denen Entwickler ein bestimmtes Verschleierungsergebnis erreichen möchten und dafür einzelne Agent-Aufgaben ausschalten müssen.
Um bestimmte Agent-Aufgaben mit XML-Regeln zu überspringen, definieren Entwickler eine Ausschlussregel für die Funktion agent. Um zum Beispiel die Aufgaben „Serializable types“ und „Reflected strings“ auszuschalten, sieht eine XML-Regel so aus:
<Rule name="rule1" feature="agent" exclude="true">
<Pattern>ACME.Data.*</Pattern>
<Properties>
<TaskNameList>Serializable types;Reflected strings</TaskNameList>
</Properties>
</Rule>Der Verschleierungs-Agent sorgt also maßgeblich dafür, dass verschleierter Code störungsfrei läuft. Trotzdem gibt es Situationen, in denen Entwickler einzelne Aufgaben ausschalten müssen, um das gewünschte Verschleierungsergebnis zu erreichen. Gehen Sie dabei vorsichtig vor und machen Sie sich klar, wie sich jede ausgeschaltete Aufgabe auf die fertige Anwendung auswirkt.