Stacktraces decodieren
Die Verschleierung einer Anwendung schützt geistiges Eigentum und verschafft einen Wettbewerbsvorteil, weil sie das Reverse Engineering erschwert. Dieser zusätzliche Schutz bringt jedoch Schwierigkeiten bei der Fehlerberichterstattung mit sich. Die Verschleierung kann die Analyse von Abstürzen erschweren, weil der Stacktrace oft zu einer Folge unlesbarer Symbole wird, was das Debuggen komplizierter macht.
Stacktraces in .NET decodieren
.NET-Entwickler stützen sich in der Regel auf Stacktraces, um die Ursache von Anwendungsfehlern zu finden. Die Verschleierung macht diese Stacktraces jedoch unverständlich. Mit Babel Obfuscator lassen sich verschleierte Stacktraces einfach decodieren. Das Tool benötigt dazu eine Map-Datei, die bei der Verschleierung erzeugt wird.
Map-Datei erzeugen
Wenn Sie in Babel Obfuscator die Erzeugung der XML-Map-Datei einschalten, wird die Map-Datei standardmäßig im selben Verzeichnis wie die verschleierte Assembly erzeugt. Die Datei trägt den Namen der ursprünglichen Assembly mit dem Zusatz .map.xml (zum Beispiel MyApp.exe.map.xml).
Die erzeugte Map-Datei enthält die Zuordnung zwischen den verschleierten und den ursprünglichen Symbolnamen.
Beachten Sie, dass die überladene Umbenennung ausgeschaltet sein sollte (--nooverloaded), weil sie verschiedenen Methoden denselben Namen gibt und die Decodierung des Stacktrace dadurch mehrdeutig werden kann. Ist die überladene Umbenennung eingeschaltet, gibt Babel bei der Decodierung alle infrage kommenden Methoden aus.
Den Ausgabeort der Map-Datei können Sie auf verschiedene Weise anpassen, je nachdem, wie Sie Babel verwenden.
Befehlszeile
babel MyApp.exe --mapout CustomPath/MyMapping.xmlWenn Sie den Dateipfad weglassen, wird die Standardbenennung im Zielverzeichnis verwendet.
MSBuild-Aufgabe
<Babel GenerateMapOutFile="true" MapOutFile="CustomPath/MyMapping.xml" />NuGet-Paket von Babel Obfuscator
<PropertyGroup>
<GenerateMapOutFile>true</GenerateMapOutFile>
<BabelMapOutFile>CustomPath/MyMapping.xml</BabelMapOutFile>
</PropertyGroup>Babel Desktop
Wählen Sie in Babel Desktop die Assembly aus und schalten Sie in der Gruppe Output & diagnostics des Eigenschaftenbereichs GenerateMapOutFile ein. Setzen Sie MapOutFile, um die Map-Datei in einen eigenen Pfad zu schreiben. Siehe Verschleierungsprojekte.
Verschleierten Stacktrace decodieren
Wenn eine verschleierte Anwendung abstürzt und einen verschleierten Stacktrace liefert, decodieren Sie ihn mit Babel. Babel Obfuscator bringt Tools mit, die verschleierte Stacktraces mithilfe der Map-Dateien decodieren.
Babel Desktop
Die folgenden Schritte sind eine Zusammenfassung. Die vollständige Anleitung finden Sie unter Stack-Decoder.
Stack-Decoder öffnen
Öffnen Sie die Befehlspalette und führen Sie Werkzeuge: Stack-Decoder aus.
Map-Dateien hinzufügen
Fügen Sie die XML-Map-Dateien mit Map-Dateien hinzufügen… hinzu oder ziehen Sie sie auf den Decoder. Sie können mehrere Map-Dateien hinzufügen, wenn sich der Stacktrace über mehrere Assemblys erstreckt.
Stacktrace einfügen
Fügen Sie den verschleierten Stacktrace ein oder laden Sie ihn mit Ablaufverfolgung öffnen… aus einer Datei.
Decodieren
Klicken Sie auf Decodieren, um den decodierten Stacktrace anzuzeigen.
Befehlszeile
Alternativ verwenden Sie das Befehlszeilentool babel:
babel --stacktrace StackTrace.txt --mapin MyApp.exe.map.xml --mapin Library.dll.map.xmlSie können mehrere Map-Dateien angeben, wenn der Stacktrace mehrere Assemblys betrifft.
Frames von Dynamic Proxy
Wenn Dynamic Proxy eingeschaltet ist, leitet Babel geeignete Aufrufe über generierte Brückenmethoden. Jede Brücke erscheint als zusätzlicher Frame, sodass sich in einem decodierten Stacktrace Ihre eigenen Methoden mit den Hilfsmethoden von Babel abwechseln. Babel hält in der Map-Datei fest, für welche Methode jede Brücke steht, und der Decoder gibt sie aus:
at Acme.Backup.ZipReader.OpenZip(System.String filename)
at (System.String ) -> proxy for System.IO.Compression.ZipFile::OpenRead
at Acme.Backup.BackupReader.IsBackupFile(System.String path)Der Zusatz -> proxy for <DeclaringType>::<Method> zeigt Ihnen genau, welche Methode die Brücke aufgerufen hat. Die Signatur steht bereits am Frame und wird deshalb im Zusatz nicht wiederholt. Map-Dateien aus älteren Versionen von Babel, die das Ziel des Proxys nicht festhalten, werden wie bisher decodiert und zeigen stattdessen den allgemeinen Hinweis -> babel generated code.
Von Babel generierte Frames ausblenden
Wenn Sie nur Ihre eigene Aufrufkette interessiert, kann Babel alle Frames entfernen, die es generiert hat, also die Proxy-Brücken und die anonymen Laufzeit-Frames, über die sie aufrufen. Übrig bleibt ein Stacktrace, der mit dem der nicht verschleierten Anwendung identisch ist.
Fügen Sie auf der Befehlszeile der Option --stacktrace den Schlüssel frames=user hinzu:
babel --stacktrace StackTrace.txt --stacktrace frames=user --mapin MyApp.exe.map.xmlframes=all ist der Standard und behält alle Frames. In Babel Desktop blendet der Stack-Decoder diese Frames standardmäßig aus: Von Babel hinzugefügte Frames ausblenden ist aktiviert. Deaktivieren Sie das Kontrollkästchen, um alle Frames zu behalten.
Sind die generierten Frames ausgeblendet, wird aus dem obigen Stacktrace:
at System.IO.Compression.ZipFile.Open(System.String archiveFileName)
at Acme.Backup.ZipReader.OpenZip(System.String filename)
at Acme.Backup.BackupReader.IsBackupFile(System.String path)Decodierung von Stacktraces automatisieren
Babel Obfuscator stellt eine Schnittstelle bereit, mit der sich die Decodierung von Stacktraces automatisieren lässt. Fügen Sie Ihrer .NET-Assembly eine Referenz auf babel.dll (oder auf babel.exe bei älteren Anwendungen für .NET Framework) hinzu und decodieren Sie Stacktraces programmgesteuert mit der bereitgestellten API.
Das folgende Codebeispiel zeigt, wie Sie eine Konsolenanwendung einrichten, die einen aus einer externen Datei geladenen Stacktrace decodiert:
// Example of setting up the console application
static int Main(string[] args)
{
if (args.Length < 2)
{
Console.WriteLine("Usage: stackdecode.exe <filename> <xmlmapfile1> [xmlmapfile2 ...]");
return 1;
}
StackTraceDeobfuscator stk = new StackTraceDeobfuscator();
foreach (var xmlMapFile in args.Skip(1))
{
try
{
stk.AddMapFile(xmlMapFile);
}
catch (Exception ex)
{
Console.WriteLine(String.Format("Error reading XML map file '{0}':n{1}", xmlMapFile, ex.Message));
return 1;
}
}
try
{
StreamReader sr = new StreamReader(args[0]);
Console.WriteLine("Deobfuscated Stack Trace:");
Console.WriteLine(stk.DeobfuscateStack(sr));
}
catch (Exception ex)
{
Console.WriteLine(String.Format("Could not decode stack trace file '{0}':n{1}", args[0], ex.Message));
return 1;
}
return 0;
}Um beim programmgesteuerten Decodieren die von Babel generierten Frames zu entfernen (siehe Von Babel generierte Frames ausblenden), setzen Sie HideGeneratedFrames am Deobfuskator, bevor Sie DeobfuscateStack aufrufen:
StackTraceDeobfuscator stk = new StackTraceDeobfuscator();
stk.HideGeneratedFrames = true;Die programmgesteuerte Schnittstelle zur Decodierung von Stacktraces fügt sich nahtlos in die Debugging-Abläufe von Entwicklern ein. Wer diesen Mechanismus in seine Anwendungen einbindet, kann die Decodierung automatisieren, verschleierte Stacktraces effizient verarbeiten und die Integrität und Sicherheit seiner Codebasis wahren.
PDB-Dateien mit verschleierten Stacktraces verwenden
Optional können Sie PDB-Dateien in der Produktion verwenden, um im decodierten Stacktrace Quelldateien und Zeilennummern zu erhalten. Babel kann nämlich Dateinamen und Symbolnamen in den PDB-Dateien verschlüsseln, sodass sie in Stacktraces verschlüsselt erscheinen und keine sensiblen Dateipfade preisgeben.
Um diese Funktion einzuschalten, legen Sie ein PDB-Passwort fest. Wählen Sie ein sicheres Passwort: Es verschlüsselt die Dateinamen in der PDB-Datei und wird später zum Decodieren der Stacktraces benötigt.
- Befehlszeile: Verwenden Sie die Option
--pdbpwd, zum Beispielbabel MyApp.exe --debug --pdbpwd <password>. - MSBuild: Setzen Sie die Eigenschaft
PdbPwdder Babel-Aufgabe. - Babel Desktop: Wählen Sie die Assembly aus und setzen Sie
PdbPwdin der Gruppe Advanced des Eigenschaftenbereichs. Das Passwort wird nur für die laufende Sitzung behalten: Es wird nicht im Projekt gespeichert und muss nach einem Neustart von Babel Desktop erneut eingegeben werden.
Sobald diese Funktion eingeschaltet und das PDB-Passwort festgelegt ist, verschlüsselt Babel bei der Verschleierung die Dateinamen und weitere relevante Informationen. In Ihren Stacktraces erscheinen die Dateinamen dann als verschlüsselte Zeichenfolgen statt als ursprüngliche Dateipfade.
System.Exception: (0x80131904): A network-related or instance-specific error occurred while establishing a connection to the server.
at System.Data.SqlClient.SqlConnection.Open()
at b.a(String g)
at c.b() in <GFpQHv9iwQzX1Zmh+… >:line 21
at c.a(String h)
at Acme.ViewModel.MainViewModel.get_Message() in <GFpQHv9iwQzX1Zmh+… >:line 28 Alle zum Entschlüsseln nötigen Daten sind in der XML-Map-Datei gespeichert, die PDB-Datei wird zum Decodieren also nicht benötigt. Der decodierte Stacktrace enthält den entschlüsselten Dateinamen.
System.Exception: (0x80131904): A network-related or instance-specific error occurred while establishing a connection to the server.
at System.Data.SqlClient.SqlConnection.Open()
at Acme.Entities.DatabaseContext.ConnectToDatabase(System.String connectionString)
at Acme.ViewModel.RS.CheckResourceLoaded() in C:AcmeAcme.ViewModelRS.cs:line 21
at Acme.ViewModel.RS.GetString(System.String name)
at Acme.ViewModel.MainViewModel.get_Message() in C:AcmeAcme.ViewModelViewModelMainViewModel.cs:line 28Dieses Verfahren verbindet Sicherheit und Wartbarkeit. Es schützt das geistige Eigentum, das in Ihren Dateistrukturen steckt, und lässt Sie dennoch Stacktraces für das Debuggen und die Fehleranalyse auswerten.
Mit der PDB-Verschlüsselung bleiben die interne Struktur und die Dateiorganisation Ihrer Anwendung sicher und vertraulich, auch wenn Sie PDB-Dateien zur Fehlerbehebung oder für den Support weitergeben.