PHP-Obfuscation by tionsys.de

  • Hey Leute,


    sicherlich kennt der eine oder andere Webentwickler das Problem, dass man eine Software entwickelt hat und sie ausgeben möchte, jedoch meistens keine Lust hat, dass alle sich aus dem Sourcecode bedienen.
    In den letzten Tagen habe ich mich mal an Code-Obfuscation gemacht, was in etwa das "verschleiern von Code" ist. Das bedeutet, dass er für Menschen nur noch sehr schwer zu lesen ist - als Beispiel habe ich mal eine Klasse genommen und sie verschleiert:

    PHP
    // WICHTIGE ANMERKUNG - In dem echten obfuscierten Text steht PHP-Code in 1 Zeile, aus übersichtsgründen ist das hier jetzt eingerückt.<?phpclass c2690851a1 {    private  $v317d37b0e = null;    private  $vcf1e8c14e = null;    private  $v901555fb0 = null;    public  function __construct($vcf1e8c14e, $v901555fb0=7777 ) {        $this-&gt;        vcf1e8c14e = $vcf1e8c14e;        $this-&gt;        v901555fb0 = $v901555fb0;        $this-&gt;        v317d37b0e = fsockopen("udp://" .$this-&gt;        vcf1e8c14e, $this-&gt;        v901555fb0, $v8f90f2980, $vfa5389291, 2 );        socket_set_timeout($this-&gt;        v317d37b0e, 2 );    }    public  function fbced893c4() {        @fwrite($this-&gt;        v317d37b0e, $this-&gt;        feb5c2d1d1("i" ));        fread($this-&gt;        v317d37b0e, 11 );        $v2d5e1b562 = array ();        $v2d5e1b562['password' ] = (integer)  ord(fread($this-&gt;        v317d37b0e, 1 ));        $v2d5e1b562['players' ] = (integer)  $this-&gt;        f9f7fa7b15(fread($this-&gt;        v317d37b0e, 2 ));        $v2d5e1b562['maxplayers' ] = (integer)  $this-&gt;        f9f7fa7b15(fread($this-&gt;        v317d37b0e, 2 ));        $ve1b5fe1db = ord(fread($this-&gt;        v317d37b0e, 4 ));        if (!$ve1b5fe1db) return  -1 ;        $v2d5e1b562['hostname' ] = (string)  fread($this-&gt;        v317d37b0e, $ve1b5fe1db);        $ve1b5fe1db = ord(fread($this-&gt;        v317d37b0e, 4 ));        $v2d5e1b562['gamemode' ] = (string)  fread($this-&gt;        v317d37b0e, $ve1b5fe1db);        $ve1b5fe1db = ord(fread($this-&gt;        v317d37b0e, 4 ));        $v2d5e1b562['map' ] = (string)  fread($this-&gt;        v317d37b0e, $ve1b5fe1db);        return  $v2d5e1b562;    }    public  function f8949d0673() {        @fwrite($this-&gt;        v317d37b0e, $this-&gt;        feb5c2d1d1("c" ));        fread($this-&gt;        v317d37b0e, 11 );        $v17f1559ab = ord(fread($this-&gt;        v317d37b0e, 2 ));        $va2bbabfe7 = array ();        if ($v17f1559ab &gt;        0 ) {            for ($v865c0c0b4 = 0 ;            $v865c0c0b4 &lt;            $v17f1559ab;            ++ $v865c0c0b4) {                $ve1b5fe1db = ord(fread($this-&gt;                v317d37b0e, 1 ));                $va2bbabfe7[$v865c0c0b4] = array  ( "name"  =&gt;                (string)  fread($this-&gt;                v317d37b0e, $ve1b5fe1db), "score"  =&gt;                (integer)  $this-&gt;                f9f7fa7b15(fread($this-&gt;                v317d37b0e, 4 )), );            }        }        return  $va2bbabfe7;    }    public  function ff1133985a() {        @fwrite($this-&gt;        v317d37b0e, $this-&gt;        feb5c2d1d1("d" ));        fread($this-&gt;        v317d37b0e, 11 );        $v17f1559ab = ord(fread($this-&gt;        v317d37b0e, 2 ));        $va2bbabfe7 = array ();        for ($v865c0c0b4 = 0 ;        $v865c0c0b4 &lt;        $v17f1559ab;        ++ $v865c0c0b4) {            $v912af0dff['playerid' ] = (integer)  ord(fread($this-&gt;            v317d37b0e, 1 ));            $ve1b5fe1db = ord(fread($this-&gt;            v317d37b0e, 1 ));            $v912af0dff['nickname' ] = (string)  fread($this-&gt;            v317d37b0e, $ve1b5fe1db);            $v912af0dff['score' ] = (integer)  $this-&gt;            f9f7fa7b15(fread($this-&gt;            v317d37b0e, 4 ));            $v912af0dff['ping' ] = (integer)  $this-&gt;            f9f7fa7b15(fread($this-&gt;            v317d37b0e, 4 ));            $va2bbabfe7[$v865c0c0b4] = $v912af0dff;            unset ($v912af0dff);        }        return  $va2bbabfe7;    }    public  function fb62d56475() {        @fwrite($this-&gt;        v317d37b0e, $this-&gt;        feb5c2d1d1("r" ));        fread($this-&gt;        v317d37b0e, 11 );        $vca703ee63 = ord(fread($this-&gt;        v317d37b0e, 2 ));        $va4f86f7bf = array ();        for ($v865c0c0b4 = 0 ;        $v865c0c0b4&lt;        $vca703ee63;        ++ $v865c0c0b4) {            $ve1b5fe1db = ord(fread($this-&gt;            v317d37b0e, 1 ));            $v981c1e7b3 = (string)  fread($this-&gt;            v317d37b0e, $ve1b5fe1db);            $ve1b5fe1db = ord(fread($this-&gt;            v317d37b0e, 1 ));            $va4f86f7bf[$v981c1e7b3] = (string)  fread($this-&gt;            v317d37b0e, $ve1b5fe1db);        }        return  $va4f86f7bf;    }    public  function f213ecff1a() {        $vdf911f015 = 0 ;        $vceb172632 = microtime(true);        @fwrite($this-&gt;        v317d37b0e, $this-&gt;        feb5c2d1d1("r" ));        fread($this-&gt;        v317d37b0e, 15 );        $va745d640f = microtime(true);        $vdf911f015 = ($va745d640f - $vceb172632) * 1000 ;        return  round($vdf911f015);    }    private  function f9f7fa7b15($vb45cffe08) {        if ($vb45cffe08 ===  "" ) {            return  null;        }        $vfa7153f7e = 0 ;        $vfa7153f7e +=  (ord($vb45cffe08[0 ]));        if (isset ($vb45cffe08[1 ])) {            $vfa7153f7e +=  (ord($vb45cffe08[1 ]) &lt;            &lt;            8 );        }        if (isset ($vb45cffe08[2 ])) {            $vfa7153f7e +=  (ord($vb45cffe08[2 ]) &lt;            &lt;            16 );        }        if (isset ($vb45cffe08[3 ])) {            $vfa7153f7e +=  (ord($vb45cffe08[3 ]) &lt;            &lt;            24 );        }        if ($vfa7153f7e &gt;        =  4294967294 ) {            $vfa7153f7e -=  4294967296 ;        }        return  $vfa7153f7e;    }    private  function feb5c2d1d1($v599dcce29) {        $v9c509e44d = "SAMP" ;        $v9c509e44d .=  chr(strtok($this-&gt;        vcf1e8c14e, "." ));        $v9c509e44d .=  chr(strtok("." ));        $v9c509e44d .=  chr(strtok("." ));        $v9c509e44d .=  chr(strtok("." ));        $v9c509e44d .=  chr($this-&gt;        v901555fb0 & 0xFF );        $v9c509e44d .=  chr($this-&gt;        v901555fb0 &gt;        &gt;        8  & 0xFF );        $v9c509e44d .=  $v599dcce29;        return  $v9c509e44d;    }    public  function fb640a0ce4() {        $v06aa6fa8b = false;        fwrite($this-&gt;        v317d37b0e, $this-&gt;        feb5c2d1d1("p0101" ));        if (fread($this-&gt;        v317d37b0e, 10 )) {            if (fread($this-&gt;            v317d37b0e, 5 ) ==  'p0101' ) {                $v06aa6fa8b = true;            }        }        return  $v06aa6fa8b;    }    public  function f716f6b305() {        @fclose($this-&gt;        v317d37b0e);    }}

    Wer jetzt auf Anhieb errät, was die Klasse macht, ist gut :P
    Wer nicht, für den ist sie hier noch mal:

    PHP
    <?php/** * * @author Edward McKnight (EM-Creations.co.uk) *//* *****************************************************************// SampQuery.class.php// Version 1.0// This class connects to a specific SA-MP server via sockets.// Copyright 2012 Edward McKnight (EM-Creations.co.uk)// Creative Commons Attribution-NoDerivs 3.0 Unported License// http://creativecommons.org/licenses/by-nd/3.0/// Credits to Westie for the original PHP SA-MP API and inspiration for this API.* *****************************************************************/$query = new SampQuery("server.life-of-german.org", 7777);if($query->connect())  echo'Server online';else  echo'Server offline';class SampQuery {    private $sock = null;    private $server = null;    private $port = null;    /**    *	Creates a new SampQuery object.    *	@param $server server hostname    *	@param $port port of the server    */    public function __construct($server, $port=7777)    {        $this->server = $server;        $this->port = $port;        $this->sock = fsockopen("udp://".$this->server, $this->port, $errorNum, $errorString, 2);        socket_set_timeout($this->sock, 2);    }    /**    * Returns an array of server information.     * @return Array[]    * (    *   [password] => 0 or 1    *   [players] => players    *   [maxplayers] => maxPlayers    *   [hostname] => hostName    *   [gamemode] => gamemode    *   [map] => map    * )    */    public function getInfo() {        @fwrite($this->sock, $this->assemblePacket("i"));        fread($this->sock, 11);        $serverInfo = array();        $serverInfo['password'] = (integer) ord(fread($this->sock, 1));        $serverInfo['players'] = (integer) $this->toInt(fread($this->sock, 2));        $serverInfo['maxplayers'] = (integer) $this->toInt(fread($this->sock, 2));        $strLen = ord(fread($this->sock, 4));        if(!$strLen) return -1;        $serverInfo['hostname'] = (string) fread($this->sock, $strLen);        $strLen = ord(fread($this->sock, 4));        $serverInfo['gamemode'] = (string) fread($this->sock, $strLen);        $strLen = ord(fread($this->sock, 4));        $serverInfo['map'] = (string) fread($this->sock, $strLen);        return $serverInfo;    }    /**    * Returns a multidimensional array of basic player information.    * @return Array[]    * (    *   [0] => Array[]    *       (    *           [name] => playerName    *           [score] => score    *       )    *	...    * )    * @see getDetailedPlayers()    */    public function getBasicPlayers() {        @fwrite($this->sock, $this->assemblePacket("c"));        fread($this->sock, 11);        $playerCount = ord(fread($this->sock, 2));        $players = array();        if($playerCount > 0) {            for($i = 0; $i < $playerCount; ++$i) {                $strLen = ord(fread($this->sock, 1));                $players[$i] = array                (                    "name" => (string) fread($this->sock, $strLen),                    "score" => (integer) $this->toInt(fread($this->sock, 4)),                );            }        }        return $players;    }    /**    * Returns a multidimensional array of detailed player information.     * @return Array[]    * (    *   [0] => Array    *	(    *       [playerid] => playerid    *       [nickname] => playername    *       [score] => score    *       [ping] => pinh    *	)    *   ...     * )    * @see getBasicPlayers()    */    public function getDetailedPlayers() {        @fwrite($this->sock, $this->assemblePacket("d"));        fread($this->sock, 11);        $playerCount = ord(fread($this->sock, 2));        $players = array();        for($i = 0; $i < $playerCount; ++$i) {            $player['playerid'] = (integer) ord(fread($this->sock, 1));            $strLen = ord(fread($this->sock, 1));            $player['nickname'] = (string) fread($this->sock, $strLen);            $player['score'] = (integer) $this->toInt(fread($this->sock, 4));            $player['ping'] = (integer) $this->toInt(fread($this->sock, 4));            $players[$i] = $player;            unset($player);        }        return $players;    }    /**    * Returns an array of server rules.    * @return Array[]    * (    *   [gravity] => gravity    *   [mapname] => map    *   [version] => version    *   [weather] => weather    *   [weburl] => weburl    *   [worldtime] => worldtime    * )    */    public function getRules() {        @fwrite($this->sock, $this->assemblePacket("r"));        fread($this->sock, 11);        $ruleCount = ord(fread($this->sock, 2));        $rules = array();        for($i = 0; $i< $ruleCount; ++$i) {            $strLen = ord(fread($this->sock, 1));            $rule = (string) fread($this->sock, $strLen);            $strLen = ord(fread($this->sock, 1));            $rules[$rule] = (string) fread($this->sock, $strLen);        }        return $rules;    }    /**    * Returns the server's ping.    * @return integer    */    public function getPing() {        $ping = 0;        $beforeSend = microtime(true);        @fwrite($this->sock, $this->assemblePacket("r"));        fread($this->sock, 15);        $afterReceive = microtime(true);        $ping = ($afterReceive - $beforeSend) * 1000;        return round($ping);    }    private function toInt($string) {        if($string === "") {            return null;        }        $int = 0;        $int += (ord($string[0]));        if(isset($string[1])) {            $int += (ord($string[1]) << 8);        }        if(isset($string[2])) {            $int += (ord($string[2]) << 16);        }        if(isset($string[3])) {            $int += (ord($string[3]) << 24);        }        if($int >= 4294967294) {            $int -= 4294967296;        }        return $int;    }    private function assemblePacket($type) {        $packet = "SAMP";        $packet .= chr(strtok($this->server, "."));        $packet .= chr(strtok("."));        $packet .= chr(strtok("."));        $packet .= chr(strtok("."));        $packet .= chr($this->port & 0xFF);        $packet .= chr($this->port >> 8 & 0xFF);        $packet .= $type;        return $packet;    }    /**    * Attempts to connect to the server and returns whether it was successful.    * @return boolean    */    public function connect() {        $connected = false;        fwrite($this->sock, $this->assemblePacket("p0101"));        if(fread($this->sock, 10)) {            if(fread($this->sock, 5) == 'p0101') {                $connected = true;            }        }        return $connected;    }    /**    * Closes the connection    */    public function close() {        @fclose($this->sock);    }}

    Das beste daran ist, dass das Script / die Webseite dadurch nicht langsamer und die Dateien kleiner wird - ersteres, weil ja nur alle Variablen und Funktionen umbenannt werden, zweiteres, weil Kommentare und unnötiger Whitespace ( wie Einrückungen ) verschwinden.
    Die SAMP-Query API wurde von 7.122 Bytes auf 4564 Bytes "gschrumpft" ( alleine wegen der Kommentare :O und dem Whitespace ).
    Der Text lässt sich nicht automatisiert zurückverschlüsseln... Und das Nachvollziehen der Datei oben währe wohl sehr schwer gewesen, wenn ihr sie nicht "SampQueryAPI" nennt ;)


    URL zum Obfuscator: https://apps.tionsys.de/encode/


    Wer mir nicht traut, darf gerne auch die halb-offline-Version aus Java benutzen :)
    Sie ist aber noch Alpha und ich konnte sie noch nicht ausreichend testen - deswegen bitte ich euch, Bugs zu berichten ;)
    Update: Die Beta-Version hat nun auch einen Dialog und unterstützt Multi-Threading, was das ganze noch etwas schneller macht.
    Auch kann er nebenbei den CSS-Code etwas "schrumpfen" & verschleiern, indem Kommentare und Whitespace entfernt werden.
    Erlaubnis von Trooper, den Source-Code unter Verschluss zu halten ;)


    Bitte feedbacken, aber nicht trollen - und wer sagt, Ioncube ist besser, dem gebe ich eine Kopfnuss :thumbup:

    Webdesign (bevorzugt backend) • Android-Development • node.js • Pawn • Linux
    Reverse Engineering • Social Engineering • Cryptoanalyse • PGP-Key
    Referenzen[color=#696969]Mein Facebook-Acc

    4 Mal editiert, zuletzt von Tion () aus folgendem Grund: 1: Einrücken lassen 2: Edit vergessen 3: Java Code 4: Beta Version

  • Beitragszahlen? Pff, selbst ich mit über 2800 Beiträgen hab schon leute so derbst verarscht und abgezogen das die danach 2 Wochen lang geheult haben ;O


    Okay natürlich hab ich das nicht :D Aber eine gute Idee wäre den Source der Seite durch die Seite laufen zu lassen und das Ergebnis hier hochzuladen. So kann der der es will lokal verschlüsseln :D

  • Aber eine gute Idee wäre den Source der Seite durch die Seite laufen zu lassen und das Ergebnis hier hochzuladen. So kann der der es will lokal verschlüsseln :D

    Ich greife leider nur auf PHP-Funktionen zurück, die ja nicht mit verschlüsselt werden ^^


    md5
    substr
    switch & case
    pack


    Ich kann es ja mal "angucken", wie es obfuscated aussieht ;)


    Also, es sieht schon mal schlecht aus, das einzige, was man nicht erkennen kann, ist praktischerweise die ZIP-Funktion ( die ich sowieso entfernt hätte ^^ MEIN SCHATZ ^^ )
    Ich arbeite gerade noch an einer Java-Version, allerdings hat sie jetzt noch ein paar Bugs und wurde nicht ausreichend getestet; Ich habe die Klassen noch nicht getestet und es werden verneinte Funktionen ( "!isset" ) als ganze Funktion angesehen ^^
    Die JAVA-Version wird auch Internet benötigen, aber etwas erfahrenere können dann ja bestätigen, dass nichts geuploaded wird - sondern nur gedownloaded

    Webdesign (bevorzugt backend) • Android-Development • node.js • Pawn • Linux
    Reverse Engineering • Social Engineering • Cryptoanalyse • PGP-Key
    Referenzen[color=#696969]Mein Facebook-Acc

    Einmal editiert, zuletzt von Tion () aus folgendem Grund: Alles nach dem ";)" - Smilie

  • Obfuscators gibt es bereits wie Sand am Meer.
    Zum Teil sogar um einiges besser, mit Base64-Encoding, hex-Zahlen, ohne Einrückung und Leerzeilen etc.
    Ich finde man muss das Rad nicht neu erfinden.

    Professioneller Webentwickler.

  • Zum Teil sogar um einiges besser, mit Base64-Encoding, hex-Zahlen, ohne Einrückung und Leerzeilen etc.
    Ich finde man muss das Rad nicht neu erfinden.

    Base64 kann der auf der Webseite auch wobei das Script dadurch langsamer wird... Ist aber überall so ;)
    Einrückungen und Leerzeilen werden entfernt
    Wie meinst du das mit Hexzahlen ? ^^
    Außerdem müsste man nach deiner theorie nichts mehr scripten, weil alles schon mal gescriptet wurde ;) Warum Fraktionen scripten ? Gibt es doch im GF
    Warum Vehicle-Ownership scripten ? Gibt es auch schon auf irgendeinem Server...


    (e)


    Es wird eine komplett neue, hübschere Version folgen :love:
    Hier schon mal ein Preview:

    Es ist so noch nicht fertig, es werden noch weitere "Sprachen" folgen, unter anderem auch Javascript und Pawn ;)
    Ich weiß, CSS ist keine Programmiersprache X(