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:
// 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-> vcf1e8c14e = $vcf1e8c14e; $this-> v901555fb0 = $v901555fb0; $this-> v317d37b0e = fsockopen("udp://" .$this-> vcf1e8c14e, $this-> v901555fb0, $v8f90f2980, $vfa5389291, 2 ); socket_set_timeout($this-> v317d37b0e, 2 ); } public function fbced893c4() { @fwrite($this-> v317d37b0e, $this-> feb5c2d1d1("i" )); fread($this-> v317d37b0e, 11 ); $v2d5e1b562 = array (); $v2d5e1b562['password' ] = (integer) ord(fread($this-> v317d37b0e, 1 )); $v2d5e1b562['players' ] = (integer) $this-> f9f7fa7b15(fread($this-> v317d37b0e, 2 )); $v2d5e1b562['maxplayers' ] = (integer) $this-> f9f7fa7b15(fread($this-> v317d37b0e, 2 )); $ve1b5fe1db = ord(fread($this-> v317d37b0e, 4 )); if (!$ve1b5fe1db) return -1 ; $v2d5e1b562['hostname' ] = (string) fread($this-> v317d37b0e, $ve1b5fe1db); $ve1b5fe1db = ord(fread($this-> v317d37b0e, 4 )); $v2d5e1b562['gamemode' ] = (string) fread($this-> v317d37b0e, $ve1b5fe1db); $ve1b5fe1db = ord(fread($this-> v317d37b0e, 4 )); $v2d5e1b562['map' ] = (string) fread($this-> v317d37b0e, $ve1b5fe1db); return $v2d5e1b562; } public function f8949d0673() { @fwrite($this-> v317d37b0e, $this-> feb5c2d1d1("c" )); fread($this-> v317d37b0e, 11 ); $v17f1559ab = ord(fread($this-> v317d37b0e, 2 )); $va2bbabfe7 = array (); if ($v17f1559ab > 0 ) { for ($v865c0c0b4 = 0 ; $v865c0c0b4 < $v17f1559ab; ++ $v865c0c0b4) { $ve1b5fe1db = ord(fread($this-> v317d37b0e, 1 )); $va2bbabfe7[$v865c0c0b4] = array ( "name" => (string) fread($this-> v317d37b0e, $ve1b5fe1db), "score" => (integer) $this-> f9f7fa7b15(fread($this-> v317d37b0e, 4 )), ); } } return $va2bbabfe7; } public function ff1133985a() { @fwrite($this-> v317d37b0e, $this-> feb5c2d1d1("d" )); fread($this-> v317d37b0e, 11 ); $v17f1559ab = ord(fread($this-> v317d37b0e, 2 )); $va2bbabfe7 = array (); for ($v865c0c0b4 = 0 ; $v865c0c0b4 < $v17f1559ab; ++ $v865c0c0b4) { $v912af0dff['playerid' ] = (integer) ord(fread($this-> v317d37b0e, 1 )); $ve1b5fe1db = ord(fread($this-> v317d37b0e, 1 )); $v912af0dff['nickname' ] = (string) fread($this-> v317d37b0e, $ve1b5fe1db); $v912af0dff['score' ] = (integer) $this-> f9f7fa7b15(fread($this-> v317d37b0e, 4 )); $v912af0dff['ping' ] = (integer) $this-> f9f7fa7b15(fread($this-> v317d37b0e, 4 )); $va2bbabfe7[$v865c0c0b4] = $v912af0dff; unset ($v912af0dff); } return $va2bbabfe7; } public function fb62d56475() { @fwrite($this-> v317d37b0e, $this-> feb5c2d1d1("r" )); fread($this-> v317d37b0e, 11 ); $vca703ee63 = ord(fread($this-> v317d37b0e, 2 )); $va4f86f7bf = array (); for ($v865c0c0b4 = 0 ; $v865c0c0b4< $vca703ee63; ++ $v865c0c0b4) { $ve1b5fe1db = ord(fread($this-> v317d37b0e, 1 )); $v981c1e7b3 = (string) fread($this-> v317d37b0e, $ve1b5fe1db); $ve1b5fe1db = ord(fread($this-> v317d37b0e, 1 )); $va4f86f7bf[$v981c1e7b3] = (string) fread($this-> v317d37b0e, $ve1b5fe1db); } return $va4f86f7bf; } public function f213ecff1a() { $vdf911f015 = 0 ; $vceb172632 = microtime(true); @fwrite($this-> v317d37b0e, $this-> feb5c2d1d1("r" )); fread($this-> 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 ]) < < 8 ); } if (isset ($vb45cffe08[2 ])) { $vfa7153f7e += (ord($vb45cffe08[2 ]) < < 16 ); } if (isset ($vb45cffe08[3 ])) { $vfa7153f7e += (ord($vb45cffe08[3 ]) < < 24 ); } if ($vfa7153f7e > = 4294967294 ) { $vfa7153f7e -= 4294967296 ; } return $vfa7153f7e; } private function feb5c2d1d1($v599dcce29) { $v9c509e44d = "SAMP" ; $v9c509e44d .= chr(strtok($this-> vcf1e8c14e, "." )); $v9c509e44d .= chr(strtok("." )); $v9c509e44d .= chr(strtok("." )); $v9c509e44d .= chr(strtok("." )); $v9c509e44d .= chr($this-> v901555fb0 & 0xFF ); $v9c509e44d .= chr($this-> v901555fb0 > > 8 & 0xFF ); $v9c509e44d .= $v599dcce29; return $v9c509e44d; } public function fb640a0ce4() { $v06aa6fa8b = false; fwrite($this-> v317d37b0e, $this-> feb5c2d1d1("p0101" )); if (fread($this-> v317d37b0e, 10 )) { if (fread($this-> v317d37b0e, 5 ) == 'p0101' ) { $v06aa6fa8b = true; } } return $v06aa6fa8b; } public function f716f6b305() { @fclose($this-> v317d37b0e); }}
Wer jetzt auf Anhieb errät, was die Klasse macht, ist gut
Wer nicht, für den ist sie hier noch mal:
<?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