Thread Perl Skript unlesbar machen?
(18 answers)
Opened by Gast at 2007-07-04 23:44
[quote=vayu,05.07.2007, 11:33][quote=renee,05.07.2007, 11:27]....
So 100%ig kann man seinen Perl-Code nicht verstecken. Dann muss man C/C++ schreiben ;)[/quote] und selbst da gibt es möglichkeiten ... :)[/quote] Das würde ich beides so nicht sagen. Das Kompilieren in ein Binärprogramm ist niemals eine eindeutig umkehrbare Operation (das gilt auch für die Transformation von Perlquellcode in Parsebäume und die Anwendung von Deparse). Die eigentliche Schwierigkeit beim Dekompilieren ist nun aber nicht, das Kompilat in irgendeine gültige Quellcoderepräsentation zu transformieren, sondern vielmehr, eine Repräsentation zu erstellen, die leicht verständlich ist, bzw. einen meschlichen Leser den ursprünglichen Sinn des Programmes erkennen lässt! In der Tat ist es wegen Laufzeittypinformationen, symbolischer Namen und enger an die Quellsprache angepasster Befehlssätze oft einfacher, Binärprogramme für virtuelle Maschinen verständlich in die Ausgangssprache zurück zu übersetzen. Das verdeutlicht aber nur die Richtigkeit der Annahme, dass es neben einer kanonischen Transformation der Befehlssequenzen auch Informationen über den Sinngehalt von Programmteilen bedarf, um lesbaren Quellcode zurückzuerhalten. Damit folgt aber unmittelbar, dass man in jeder Sprache schlecht dekompilierbaren Code erstellen kann, indem man sich an einige einfache Regeln hält: * Symbolische Namen sollten wenn möglich vermieden werden. Wo immer sie zwingend notwendig sind, sollte man sie völlig zufällig generieren. * Klassen und Strukturierte Typen sollten nicht benutzt werden. Basisdatentypen sollten vorzugsweise so benutzt werden, dass sie nicht den eigentlichen Typ verarbeiteter Daten widerspiegeln. * Alle Datenverarbeitungsschritte sollten in möglichst breiter Streuung über den gesamten Quelltext verteilt werden. * Um die Analyse des Kontrollflusses zu erschweren, sind dynamisch berechnete Sprünge und dynamisch generierter Code nützlich. Besonders schön sind zufällig dynamisch ausgewählte Ausführungspfade, die mehrfach rekursiv durch eine ganze Hierarchie von zur Laufzeit generierten, unleserlich benannten Subroutinen springen, um schließlich doch ein verwendbares Endergebnis zu liefern. * Zu guter letzt, sollte der Code niemals irgendein extern verwendbares Interface bereitstellen, damit jeder, der ihn wiederverwenden möchte, auch wirklich gezwungen ist, ihn komplett zu verstehen. Kurzum: Misachte sämtliche Grundsätze sauberer Programmierung, ja verkehre sie komplett ins Gegenteil und niemand wird deinen Code lesen und weiterverwenden können (zumindest aber nicht wollen). Durch die Steigerung der Komplexität wird das Dekompilieren schlichtweg ineffektiv, denn nach der Dekompilation ist das Programm genauso unverständlich wie zuvor. Natürlich könnte man die Transformation eines "ordentlichen" Programmes in ein solch übles Konstrukt auch automatisieren. Um wirklich effektiv zu sein, sollte der Transformationscode aber cleverer oder zumindest ausdauernder als ein möglicher Dekompilierer sein. Auf jeden Fall darf die Transformation nicht nur das Aussehen des Quellcodes entstellen, sie muss um effektiv zu sein auch seine Funktion so modifizieren, dass zwar das gleiche Resultat erreicht wird, das aber auf verschlungenen Pfaden. Wer jetzt sagt, ich würde übertreiben, der kann sich ja gerne mal den Binärcode gewisser kommerzieller Software zu Gemüte führen -- ein populäres VoIP-Programm für Windows ist ein schönes Beispiel -- und wird feststellen, dass solche Techniken tatsächlich eingesetzt werden. Ich bin aber der Meinung, dass solche Strategien weder der Programmstabilität noch dem Vertrauen der Benutzer in die korrekte Funktion der Software zuträglich sind. When C++ is your hammer, every problem looks like your thumb.
|