Das Decompilieren erschweren

Obwohl wir Decompilierung verhindern können, ist es noch immer nicht möglich, das bloße Disassemblieren des Bytecodes zu stören. Es gibt allerdings einige einfache Tipps, die dem motivierten Angreifer schnell die Lust am Bytecode verderben. Wir beschreiben einige Regeln, die das Entschlüsseln von Bytecode oder das Umgehen einer Seriennummerneingabe erschweren. Dazu gehören folgende Maßnahmen:

  • Verwendung von Methodennamen und Klassennamen aus Nullen, dem Buchstaben O, Einsen und dem Buchstaben l. Einige freie Obfuscatoren lassen sich leicht anpassen, sodass sie solche Bezeichner erstellen.
  • Im Quellcode sollten keine lesbaren Zeichenketten vorkommen. Daher fügen wir jeder Klasse eine individuelle Entschlüsselungsfunktion hinzu. Bessere Obfuscator-Programme machen das automatisch.
  • Mathematische Funktionen berechnen die Werte von Konstanten. Erwartet das Programm zum Beispiel die Taste KeyEvent.VK_F1, wird der Compiler automatisch für die Konstante den Wert 0x70 einsetzen. Natürlich können wir diesen Wert auch dynamisch berechnen.
  • Verwendung vieler bedingter Sprünge, die aber unnütz sind.
  • Wenn die Möglichkeit besteht, den Bytecode direkt zu manipulieren, können legale, doch unsinnige Bytecode-Sequenzen eingefügt werden. Dynamischer Java-Bytecode hat sich (noch) nicht durchgesetzt, wäre aber möglich. Denkbar ist, an bestimmten Stellen einer Klassendatei Zeichen zu schreiben, dann diese Datei über den Klassenlader zu laden und die Information anschließend wieder zurückzuschreiben. An der »bestimmten Position« könnte etwa eine Variable stehen.
  • Teile des Programmcodes sollten auf dynamisch berechnet Tabellen zurückgreifen.
  • Ein Startbildschirm mit Grafik und Text (Splash-Screen beziehungsweise Nag-Screen) kann leicht zurückverfolgt werden. Daher sollte besser darauf verzichtet werden.
  • Bei einer Seriennummer und einem Ablaufdatum lässt sich die Systemzeit natürlich zurücksetzen. Wir können kontinuierlich ein Datum verschlüsselt in eine Datei schreiben und dieses ständig erhöhen. Ist das Datum des Rechners kleiner als das Datum in der Datei, hat der Benutzer zu schummeln versucht. Ein alternativer Weg ist plattformabhängig: Einige Systemdateien weisen das Datum vor dem Zurückstellen auf, wie etwa SYSTEM.DAT.
  • Bei Seriennummern sucht der Angreifer nach Texteingabefeldern. Besser ist in diesem Fall eine Lowlevel-Event-Verarbeitung. Wir legen einen Listener zum Beispiel auf etwas ganz anderes, beispielsweise ein Label. Die Ereignisse werden abgefangen und bearbeitet. Aus dem AWT-Event holen wir dann die Zeichen heraus. Da der Angreifer aber auch nach Eventhandlern sucht, ließe sich auch die System-Queue abhorchen.
  • Checksummen von Klassen bilden, die eventuell angezapft werden könnten. In einer anderen Klasse lässt sich dann diese Checksumme testen. Zum Entschlüsseln von Daten können auch weitere Klassendateien verwendet werden.

Nun mein Lieblingstipp: Zeitmessungen vornehmen, um zu erkennen, ob jemand versucht, das Programm zu debuggen. Zudem lassen sich Cracker leicht befriedigen, indem ihnen eine offensichtliche Prüfung einer eingegebenen Seriennummer angeboten wird. An weiteren Stellen können aber ein Test auf die Seriennummer und subtile Fehlfunktionen ins Programm eingewoben sein. Das Programm hat kleine Fehler oder Unzulänglichkeiten, falls die Seriennummer diese Tests noch nicht erfüllt.

ProGuard ist ein Open-Source-Projekt unter der GPL-Lizenz, das Java-Klassen und Jar-Archive verschleiert.