.NET
Codeklau & wie man eigenen Code schützen kann Teil 2
Posted on .In diesem zweiten Teil werde ich darauf eingehen, wie man seinen Code möglichst gut schützen kann. Natürlich gibt es keinen 100%igen Schutz aber man kann es jemandem durchaus schwer machen an seinen Code zu kommen.
Es gibt mehrere Ansätze wie man das Problem angehen kann. Zum Einen wäre da die Möglichkeit unseren .NET Code nicht in ein Assembly sondern in eine native Anwendung zu kompilieren. Das würde die Dekompilierung um einiges erschweren.
Dafür stellt und Microsoft mit dem .NET Framework bereits ein Tool zur Verfügung. Dieses kann eure Assemblys in Maschinencode compilieren, tut also das was der JIT-Compiler sonst erst bei der Ausführung machen würde! Dies hat den Vorteil, dass die Anwendung schneller arbeitet, da sie direkt ausgeführt werden kann, aber wird erheblich größer, da alle .NET Abhängigkeiten nun in das Programm integriert werden müssen. Es kann nun sogar ohne ein Installiertes .NET Framework ausgeführt werden!
Das Programm was das für uns erledigt nennt sich „ngen.exe“ und ist ein Kommandozeilen Programm. Im MSDN gibts eine umfassende Anleitung für das Programm weswegen ich hier nicht auf die Funktionsweise eingehen werde!
Leider bringt diese Art der Kompilierung einen entscheidenden Nachteil mitsich, nämlich dass das Programm die Plattformunabhängigkeit verliert und meistens nurnoch auf dem eigenen Rechner (auf dem es erstellt wurde) benutzt werden kann! Also müssen wir uns etwas anderes einfallen lassen!
Und tatsächlich gibt es eine weitere Möglichkeit seinen Code zu schützen und dennoch keine Nachteile aufkommen zu lassen! Das Visual Studio bringt bereits ein Programm mitsich das uns da helfen kann! Das ist der sogenannte „Dotfuscator Community Edition“ den man über das „Extras“-Menü in Visual Studio aufrufen kann!
Diese „Ofuscatoren“ machen dann, simpel ausgedrückt, den Quelltext schlechter lesbar. Was sich so simpel anhört ist aber sehr effektiv! Wie ich an einem Beispiel demonstrieren möchte:
Hier ersteinmal der Quelltext den wir geschrieben haben in der Originalform:
private void CalcPayroll(SpecialList employeeGroup) {
while (employeeGroup.HasMore()) {
employee = employeeGroup.GetNext(true);
employee.UpdateSalary();
DistributeCheck(employee);
}
}
Und nun das Ergebnis des Obfuscators:
private void a(a b) {
while (b.a()) {
a = b.a(true);
a.a();
a(a);
}
}
Wie man sieht kann man nicht mehr so einfach darauf schließen was diese Funktion eigentlich machen soll, da alle für den Menschen logischen Bezeichner fehlen!
Was macht der Obfuscator also genau? Seine Hauptaufgabe ist natürlich den Quelltext nach dem Dekompilieren für den Menschen möglichst unleserlich zu machen. Das wird dadurch erreicht, dass alle Bezeichner und alle Texte die im Quelltext vorkommen durch zufallsgenerierte Bezeichner ersetzt werden. Denn dem Computer ist es egal, ob eine Variable „anzahlBenutzer“ oder „3Fdg4§§s“ heißt. Aber der Benutzer der den Quelltext liest ist natürlich sehr verwirrt da er nichts mit diesen Bezeichnungen anfangen kann.
Es gibt auch andere Dritthersteller, die Software anbieten die genau das machen soll, nur besser versteht sich! Ich habe zum testen mal den Phoenix Protector, teLock und den im Visual Studio integrierten Dotfuscator ausprobiert.
Wobei ich teLock nicht weiter behandeln werde, da alle daraus erzeugten Programm nicht lauffähig waren und immer abgestürzt sind!
Wie kann man selbst vorgehen um zu testen wie gut sein Programm geschützt ist? Ganz einfach, indem man so vorgeht als ob man ein fremdes Programm „knacken“ würde. Dazu können wir uns dem Tool .NET Reflector bedienen, das ich im ersten Teil vorgestellt habe!
Ich werde hier als Beispiel mal das Tool aus dem Beitrag „Den Office Lizenzschlüssel aus der Registry auslesen“ verwenden. Wenn wir das Programm dekompilieren dann sehen wir ca dieses Bild:
Bild 1: Office Key Finder im Dekompilierten Zustand
Wie man sieht konnte das Programm komplett dekompiliert werden und man kann in dem Quelltext wunderbar lesen (rechts)! Ich habe des weiteren die Stellen hervorgehoben, wo man die Original Namen der Variablen und Funktionen erkennen kann! – So sieht eine ungeschützte .NET Anwendung aus.
Nun habe ich den Phoenix Protector mal drüber laufen lassen und die selben stellen markiert.
Bild 2: Dieses Mal ist der Quelltext viel schlechter lesbar!
Wie man sieht haben nun alle Klassen, Funktionen und Variablen ganz andere unlogische Namen bekommen die in keinster weise deren Funktion wiederspiegeln!
Bild 3: Der Dotfuscator beschränkt sich auf das nötigste
Bild 3 zeigt das Ergebnis des im Visual Studio eingebauten Dotfuscators. Dieser hat sogar die Klassenstruktur geändert und auf das nötigste reduziert! (links)
Ich war aber mit dem Ergebnis des Phoenix Protectors besser zufrieden, denn nach etwas herumspielen mit den Einstellungen konnte ich den Quelltext so gut „tarnen“, dass selbst der Disassambler diesen nicht mehr auflösen konnte und sich mit einem Fehler verabschiedete!
Bild 4: Das perfekte Ergebnis, der Quelltext lässt sich nicht mehr einsehen!
Das ist natürlich ein super Ergebnis! Ich habe es nicht an weiteren Programmen ausprobiert, aber ich denke nicht, dass man immer dieses Ergebnis haben wird und natürlich muss man im Hinterkopf behalten, dass auch das nicht sicher ist sondern auch mit genug Zeit ebenfalls geknackt wird!
Auch wenn diese Methode keinen perfekten Schutz bietet (den es eh nicht gibt!) ist sie trotzdem effektiv! Alle Tools die ich hier benutzt habe sind auch kostenlos und leisten dafür sehr viel! Ausprobieren lohnt sich! Als Alternative die aber auch was kostet kann ich euch .NET Reactor ans Herz legen. Dieses Tool arbeitet ebenfalls sehr gründlich sodass es teilweise nicht möglich ist zu dekompilieren kostet aber auch knappe 200 €!
Gut, kommen wir zu der dritten und auch sichersten und besten Lösung! .NET bietet uns die Möglichkeit auf fremdcode zuzugreifen zb. aus der Windows-API oder eigenen DLLs. Man kann auch Code aus dem Internet nachladen oder bestimmte Dienste in WebServices auslagern.
Und das Sollte man machen! So kann man das Hauptprogramm gerne in .NET schreiben, aber man sollte dann die besonders aufwendigen und geheimen Algorithmen und Prozeduren in eigene Native DLLs auslagern, die man dann wiederum ins Programm einbinden kann!
Das garantiert eine einfache Arbeit und höchste sicherheit! Denn auch wenn man dann das Hauptprogramm dekompiliert, ist der wichtige Teil immernoch sicher in der DLL verpackt!
Zum Schluss nochmal: hier habe ich nur .NET behandelt natürlich gibt es auch für Java und auch für Javascript Obfuscators die den selben Job machen, diese aber ebenfalls vorzustellen würde den Rahmen aber sprengen!
Ich hoffe dieser Zweiteiler hat euch gefallen und freue mich auf euer Feedback!
Interessiert dich dieses Thema? Möchtest du hier mehr Beiträge darüber lesen? Schreib ein Kommentar was dir gefallen hat oder was nicht.
Sebastian Gross
http://www.bigbasti.comSebastian Gross arbeitet in Bielefeld als Softwareentwickler für .NET und Java im Bereich Web.Als Fan der .NET-Plattform lässt er sich kein Userguppen Treffen und Community Event im Raum OWL entgehen.Dabei hat er eine besondere Vorliebe für das ASP.NET MVC Framework und für das Test Driven Development (TDD) entwickelt.
Author Gooner85
Posted at 15:40 4. Dezember 2009.
Hat man beim 3. Lösungsansatz (Erzeugung von Native DLLs) nicht auch den Nachteil, dass das Programm dann nur auf dem eigenen Rechner ausführbar ist?
Oder meinst Du, man sollte die Windows eigenen DLLs und selbstgeschriebene Native DLLs verwenden, ohne Ngen.exe zu verwenden?
Author admin
Posted at 00:09 6. Dezember 2009.
Hallo, nein, solange man die selbst erzeugten dlls mit dem programm zusammen ausliefert wird das progrann ganz normal funktionieren. Dies ist auch die bevorzugte Variante. MfG
Author DMC
Posted at 08:30 1. Oktober 2010.
HI,
danke für deinen sehr guten Artikel.
Grüße
DMC
Author anfänger c#
Posted at 21:23 1. November 2010.
Ich bedanke mich ganz herzlich. Genau diese Information habe ich gesucht!
Author java-duppel
Posted at 11:12 23. Juni 2011.
Danke!
„Ofuscatoren“ war für mich das gesuchte Lösungswort.
Aber Dll-Lösung ist schon die sicherste und die Dll-Functionen können auch portabel in ANSI-C geschrieben werden.
Author ddeveloper
Posted at 10:48 7. September 2011.
Hallo,
Wie geht man mit strong name singierten assemblies um? Angeblich ist das mit Dotfuscator Community Edition nicht möglich? Außerdem wie kann man die versteckt man Resourcen und Stringkonstanten? Dotfuscator bietet in der Prof. Version diese Möglichkeit aber für gut €2k
Danke
Author falkman
Posted at 09:20 6. September 2012.
Das mit den nativen DLL’s für geheime Funktionen ist eine gute Idee – doch wie erstellt man native DLL’s ? Wenn ich in VB.net eine DLL erstelle und compiliere läßt sich diese ohne Probleme wieder decompilieren und auslesen. Somit ist meine Passwortverschlüsselung offengelegt….hmmmm
Author Sebastian Gross
Posted at 08:01 10. September 2012.
Hallo falkman,
natürlich müsstest du für diese DLL auf eine unmanaged Sprache wie VB6 oder C/C++ ausweichen. Diese kannst du dann problemlos einbinden.
Grüße, Sebastian
Author twoDarkMessiah
Posted at 21:40 24. März 2013.
Ha,
Wer meint er kein sein Programm durch fertige Ofuscatoren wie NetReactor usw. schützen irrt sich gewaltig.
Wer mir nicht glaubt kann mir ja mal sein ach so sicher gecryptetes Programm schicken…