BigBastis Blog

Codeklau & wie man eigenen Code schützen kann Teil 1

Introduction

user

Sebastian Gross

Sebastian 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.


LATEST POSTS

Handling too long scrollspy menus 10th June, 2015

Java: Create ZIP archive 23rd March, 2015

.NET

Codeklau & wie man eigenen Code schützen kann Teil 1

Posted on .

In dieser Reihe möchte ich darüber schreiben welche Probleme die Arbeit mit modernen Programmiersprachen mit sich bringt und wie man diese möglichst eindämmen und gering halten kann.

In dem ersten Teil werde ich darauf eingehen, wie und warum es möglich ist Code aus fertigen Applikationen zu extrahieren.

Das größte Problem, das jeder Closed-Source Programmierer hat, ist es den erstellten Code nicht für andere einsichtbar zu halten damit dieser nicht geklaut oder ohne Einwilligung oder Lizenzzahlungen weiterverwendet werden kann!

Aber wie ist es überhaupt möglich Code zu klauen wenn mann nur die fertige Applikation hat?

Zuerst sollte man sagen, dass es keinen 100%igen Schutz gibt! Alles kann geknackt oder modifiziert werden. Alle Firmen, die das gegenteil versprechen sind einfach nur unprofessionell. Denn alle Schutzmechanismen die es gibt sorgen lediglich dafür, dass man mehr Aufwand aufbringen muss, um diese wieder zu umgehen.

Früher war Codeklau noch sehr harte Arbeit, denn früher waren alle Anwendungen kompiliert, wurden also beim Erstellen direkt in Maschinencode gewandelt! Diesen Maschinencode wieder in lesbaren Quelltext zu wandeln ist sogut wie unmöglich, was man aber machen kann ist es diesen zu „Deassimblieren“ (engl. Disassamble). Bei diesem Vorgang wird der vorliegende Native Code (Maschinencode) in ein für den Menschen lesbaren Assembler Code umgewandelt.

Was man hier noch wissen sollte, ist dass früher (vor langer langer Zeit) alles in Assembler programmiert wurde. Assembler ist eine Sprache, die es dem Programmierer Erleichtert Code zu schreiben, dabei werden Befehle benutzt die der Prozessor, auf dem später der Code ausgeführt werden soll versteht. Somit muss man sich nicht mit Nullen und Einsen herumschlagen sondern hat was, was man auch einigermaßen lesen kann.

5623_2Grafik 1: So könnte ein Programm nach dem Disassamble-Vorgang aussehen

Hier findet ihr ein kleines Beispiel wie sich Assembler von einer Hochsprache wie zb. C++ unterscheidet!

Mit diesem erzeugten Assembler Code kann man nun weiter „arbeiten“ und versuchen den Ablauf des Programms zu verstehen und diesen dann auch eventuell zu kopieren, zu klauen! Das ist natürlich je nach Größe extrem aufwendig und langwierig.

Übrigens: genauso gehen die so genannten „Cracker“ vor wenn sie versuchen bestimmte Sicherheitmechanismen von Programmen oder Spielen zu deaktivieren. Sie suchen nach diesen Ereignissen in dem Assembler Code und versuchen diese umzuleiten oder zu löschen, sodass die „Gecrackte“ Software dann anschließend zb. ohne gültige Lizenz oder ein Spiel ohne die Original CD im Laufwerk benutzt werden kann! Wer darüber mehr wissen will sollte einen Blick in die „Hacker-Bibel von Cyberdemon98“ werfen.

Natürlich kann man mit diesem Vorgehen nicht wirklich Code „klauen“ sondern mehr versuchen zu verstehen wie ein Programm arbeitet um dann zb. andere Programme darauf abzustimmen („Schnittstellen“ schafften). Diesen Vorgang nennt man dann reverse Engeneering (deut. Umgekehrtes entwickeln).

Ein berühmtes Beispiel dafür ist der Instant Messaging Dienst ICQ, dieses Unternehmen hat keinerlei Spezifikationen über den Dienst oder das Protokoll veröffentlicht. Alle ICQ-Clients wie QIP, Miranda oder andere basieren komplett auf Reverse Engeneering! Deswegen kommt es auch oft, dass man sich gegenseitig keine Dateien schicken kann oder die Status-Nachricht eines Freundes lesen kann weil er einen anderen Client verwendet. Dies liegt einfach daran dass die Entwickler „raten“ müssen wie diese Funktionen funktionieren und Kompabilitäten nur schwer geschaffen werden können! Dadurch geht ICQ sicher, dass nur ihr eigener Client perfekt funktioniert und alle Features beherrscht!

c-flow

Grafik 2: Diese Schritte durchläuft C++ Code während der Compilierung

Diese Codevariante, die so genannten unmanaged-code hervorbringt, der aus Maschinencode besteht erstellen die „alten“ Programmiersprachen wie Delphi, C, VB6 und C++. Die Obere Grafik zeigt, dass nach der Kompilierung des Quelltextes, dieser noch weitere Schritte durchläuft und schließlich als Binäre Datei vorliegt, die nur auf einem bestimmten CPU-Typ und Betriebssystem läuft!

Die neueren Programmiersprachen wie etwa Microsofts .NET (Worunter auch C#, VB.NET fällt) oder Java verfolgen einen komplett anderen Ansatz der managed code erzeugt und förmlich zum Codeklauen einlädt!

20011114_1xGrafik 3: Compilierung von Managedcode Programmen (.NET & Java)

Die Sprachen, die managed Code erzeugen, erzeugen nämlich keinen Maschinencode sondern so genannte Assemblys welche eine Art Vorkompilierte Programme sind die nicht lauffähig sind.

Grafik 3 beschreibt im Oberen Teil, den Kompilierungs Prozess, der ziemlich einfach gestrickt ist. Der Code wird garnicht „Richtig“ kompiliert sondern nur für die spätere Ausführung vorbereitet.

Warum ist das so? Nun heutzutage müssen Programme laufen, und nicht nur auf dem PC auf dem Sie geschrieben wurden sondern auch auf anderen und sogar auf anderen Betriebssystemen. Das ganze nennt sich dann Plattformunabhängigkeit!

Java Programm zb. können auf allen gängigen Betriebssystemen ausgeführt werden. Egal ob Windows, Solaris, Mac OS oder Linux Java Programme funktionieren! Und damit das möglich ist dürfen die Programme nicht kompiliert werden!

Denn wenn ein Programm kompiliert wird wird es in Maschinencode umgewandelt. Und da jede Prozessorarchitektur einen eigenen Maschinencode hat und jedes Betriebssystem auch anders aufgebaut ist kann ein kompiliertes Programm immer nur auf dem System ausgeführt werden für das es kompiliert wurde!

Um dieses Problem zu umgehen werden Java Programme nur Vorkompiliert (zu so genannten Assemblys) und dann wenn die gestartet werden (egal auf welchem Betriebssystem) werden sie erst „richtig“ kompiliert, für das System auf dem sie gerade gestartet werden!

Warum ist das gut? Naja, so kann man ein Programm schreiben, und es ohne daran viel zu machen auf allen Systemen benutzen. Leider hat das System auch viele Schattenseiten, denn um ein solches vorkompiliertes Programm ausführen zu können muss eine Virtuelle Maschine installiert sein, die unser vorkompiliertes Programm „zu ende kompiliert“ im Falle von Java ist es die JVM (Java Virtual Machine) diese kompiliert das Programm passend zum Betriebssystem und sorgt für dessen korrekte Ausführung.

Desweiteren sind diese Programme natürlich auch langsamer als die Nativen, denn zb. die Java Programme müssen vor deren Start erst kompiliert werden und laufen in einer Virtuellen Maschine, was natürlich auch Geschwindigkeitseinbußen. (vergleichbar mit einem Virtuell ausgeführten Betriebssystem durch VMWare und co)

Aber nun schweife ich schon wieder ab! Was wichtig ist, ist dass die Managedcode Programme nicht in Maschinencode kompiliert werden. Der Zustand in dem sie dann verweilen macht es uns sehr leicht das Programm wieder zurück in Quelltext zu verwandeln und diesen dann zu Klauen!

Dieser Vorgang, bei dem eine Kompilierte Datei wieder in lesbaren Quelltext verwandelt wird nennt man Dekompilierung. Anders als beim Disassambling wird hierbei der Original Quelltext den der Programmierer geschrieben hat fast perfekt wiederhergestellt!

Davon sind alle managedcode Sprachen betroffen, da sie alle nach dem Prinzip aus Bild 3 arbeiten! (zb. Java, C#, VB.NET)

Für jede Sprache gibt es auch den passenden Decompiler, der den Original Quellentext in Sekunden herausspuckt! Viele dieser Decompiler sind hochkomplexe Programme und deswegen auch nicht kostenlos! Besonders wenns an das dekompilieren von Nativen Programmen geht wird man keine kostenlosen Programme finden die brauchbare Ergebnisse liefern!

Um Java Programme (.jar-Dateien) zu dekompilieren empfehle ich den JD Java Compiler, dieser ist kostenlos und arbeitet sehr zuverlässig!

screenshot1Bild 4: Der Java Decompiler in Action

Natürlich muss man auf so etwas wie Kommentare und Ordnungen verzichten, da diese bei dem Kompilierungs Prozess automatisch aus dem Quelltext gelöscht werden, da der Prozessor damit nix anfangen kann!

Um .NET Programme oder DLLs zu dekompilieren, wobei hier disassimbliren besser passt kann ich das Tool .NET Reflector von Redgate empfehlen, es ist einfach zu benutzen und funktioniert perfekt!

Bild 5: Arbeiten mit dem .NET Reflector

Das Gute hierdran ist, dass man sogar in die .NET System Prozesse schauen kann um diese besser zu verstehen! Dieses Programm ist ebenfalls kostenlos nach einer Registrierung zu haben!

Wer das ganze mal ausprobieren will kann das gerne ja mal machen. Sucht euch einfach mal ein einfaches Java Programm, dabei ist es egal ob es ein Desktop Java Programm ist ober ein Mobile Programm aus dem J2ME. zb. den Opera Mini und schaut euch mal dessen Innereien an.

Wenn ihr mal ein .NET Programm dekompilieren wollt kann ich für den Einstieg eins der Programme empfehlen, die ich hier im Blog veröffentlicht habe. (Schaut zb. in dem Letzten Beitrag. Ladet die Beispiel Datei herunter und entpackt den Ordner und geht in den Ordner TreeViewDemo\bin\debug\ dort müsstet ihr eine .exe Datei finden an der ihr euch austoben könnt!)

Als Ergänzung will ich noch sagen, dass ein Programm immer in managedcode UND in unmanagedcode kompiliert werden kann und somit manchmal nicht (so einfach) dekompiliert werden kann!

Wie man seinen Code schützen kann werde ich dann in dem zweiten Teil behandeln, da der hier ja schon ein bissl zuu lang geworden ist!

Interessiert dich dieses Thema? Möchtest du hier mehr Beiträge darüber lesen? Schreib ein Kommentar was dir gefallen hat oder was nicht.

profile

Sebastian Gross

http://www.bigbasti.com

Sebastian 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.

Comments
user

Author fr34k

Posted at 21:28 17. Dezember 2009.

sehr interessanter artikel. danke google dass du mich hierhergeführt hast 😀

user

Author anfänger c#

Posted at 20:36 1. November 2010.

sehr interessanter artikel.

user

Author Lukadora

Posted at 11:40 5. Dezember 2011.

Ich sehe hier leider aber keine Möglichkeit den Code zu verschlüsseln wie im Titel angegeben

user

Author Profatoranimator

Posted at 18:47 29. April 2012.

@Lukadora
Deswegen steht da ja auch das er das in ein einem zweiten Teil behandeln wird 😉

Kommentar verfassen

View Comments (4) ...
Navigation