Version: 0.9
Type: Full Script
Category: Other
License: GNU General Public License
Description: POBS stands for PHP Obfuscator/Obscurer. It is a free and open PHP program that makes PHP sourcecode almost impossible to read and edit for normal humans. It is a simple way to protect your PHP sourcecode from people who whould like to adjust it or who would like to know the inner workings of it. Now you can deploy your application and feel pretty safe about it.
How it works
POBS works by replacing User-defined functionnames, variables and constants with a MD5 key of 8 characters. It really removes information that humans would like to have but computers don’t care about. It’s not ideal but quite a good option in my idea.
Advantages
Really removes information from your sourcecode
Hard to reverse-engineer
Cross-platform, cross PHP version
Open Source. So it can be adjusted to your own needs
Works with PHP cachers like APC and ZEND Cache
Works with Zend Encoder (although you probably don’t need it anymore)
Visit http://pobs.mywalhalla.net for downloads and info
<? /* POBS - PHP Obfuscator 24 October 2001 Version: 0.9 http://pobs.mywalhalla.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ include("pobs-ini.inc"); echo "<HTML>n<HEAD>n<TITLE>POBS - A PHP Obfuscator</TITLE>n<STYLE TYPE='text/css'>n"; echo "td { font-family: Verdana, sans serif;font-size:".$FontSize."pt; vertical-align: top; }n"; echo "</STYLE>n</HEAD>nn<BODY>n"; define("TdStart", "<TD VALIGN=TOP>n"); define("TdBlue", "<TD BGCOLOR=#6699CC VALIGN=TOP>n"); define("TdGrey", "<TD BGCOLOR=#E6E6E6 VALIGN=TOP>n"); define("TrStart", "<TR>n"); define("TrEnd", "</TR>n"); define("TdEnd", "</TD>n"); define("TableEnd", "</TABLE>n"); CheckSafeMode(); $StartTime=time(); $TotalFileSizeRead=0; $TotalFileSizeWrite=0; $ExVarArray=array(); $FuncArray=array(); $ConstArray=array(); $VarArray=array(); $LineArray=array(); $FileArray=array(); $UdExcVarArrayWild=array(); if ($PA) ProcessIt(); // if action parameter in querystring else ShowScreen(); function ProcessIt() { global $SourceDir, $TargetDir; if (!(is_readable($SourceDir))) { echo "Error. Source Directory ".$SourceDir." is not readable. Program will terminate<br>"; exit; } if (!(is_writeable($TargetDir))) { echo "Error. Target Directory ".$TargetDir." is not writeable. Program will terminate<br>"; exit; } GetWildCards(); ScanSourceFiles(); ShowArrays(); WriteTargetFiles(); } function ShowScreen() { global $TimeOut, $FileExtArray, $TargetDir, $SourceDir, $UdExcFuncArray, $UdExcVarArray, $UdExcConstArray; global $ReplaceFunctions, $ReplaceConstants, $ReplaceVariables, $RemoveComments, $RemoveIndents, $ConcatenateLines; global $FilesToReplaceArray; echo "<TABLE CELLPADDING=0 WIDTH=100% CELLSPACING=0 BORDER=0>n"; echo TrStart.TdBlue."<A HREF='http://pobs.mywalhalla.net' TARGET=_new><IMG SRC=pobslogo.gif HSPACE=20 WIDTH=150 HEIGHT=61 BORDER=0></A>".TdEnd; echo TdBlue."<br><b>A PHP Obfuscator".TdEnd; echo TrEnd.TableEnd."<br>"; CheckSafeMode(); echo "<TABLE CELLPADDING=3 WIDTH=100% CELLSPACING=0 BORDER=0>n"; echo TrStart.TdBlue." <CENTER><DIV style="font-size:13pt;"><b>Settings</DIV></CENTER>".TdEnd.TrEnd.TableEnd."<br>"; echo "<TABLE CELLPADDING=3 WIDTH=100% CELLSPACING=0 BORDER=0>n"; echo TrStart."<TD VALIGN=TOP ROWSPAN=2>"; echo "<TABLE CELLPADDING=3 WIDTH=100% CELLSPACING=0 BORDER=1>n"; echo TrStart.TdGrey." TimeOut (sec)".TdEnd.TrEnd; echo TrStart.TdStart.$TimeOut.TdEnd.TrEnd; echo TrStart.TdGrey." Source Directory".TdEnd.TrEnd; echo TrStart.TdStart.$SourceDir.TdEnd.TrEnd; echo TrStart.TdGrey." Target Directory".TdEnd.TrEnd; echo TrStart.TdStart.$TargetDir.TdEnd.TrEnd; echo TrStart.TdGrey." Allowed File Extensions".TdEnd.TrEnd; echo TrStart.TdStart; foreach($FileExtArray as $Key => $Value ) echo $Value."<br>"; echo TdEnd.TrEnd; echo TrStart.TdGrey." Replacements".TdEnd.TrEnd; echo TrStart.TdStart." Functions: ".GetYesNo($ReplaceFunctions)."<br>"; echo " Constants: ".GetYesNo($ReplaceConstants)."<br>"; echo " Variables: ".GetYesNo($ReplaceVariables)."<br>"; echo TdEnd.TrEnd; echo TrStart.TdGrey." Removals".TdEnd.TrEnd; echo TrStart.TdStart; echo " Comments: ".GetYesNo($RemoveComments)."<br>"; echo " Indents: ".GetYesNo($RemoveIndents)."<br>"; echo " Returns: ".GetYesNo($ConcatenateLines)."<br>"; echo TdEnd.TrEnd; echo TrStart.TdGrey; echo "<FORM METHOD=POST ACTION="".$GLOBALS[PHP_SELF]."?PA=P">n"; echo "<INPUT TYPE=SUBMIT NAME=Ok VALUE='Start scanning and replacing'>"; echo "</FORM>n"; echo TdEnd.TrEnd; echo TableEnd; echo TdEnd; echo TdStart; echo "<TABLE CELLPADDING=3 WIDTH=100% CELLSPACING=0 BORDER=1>n"; echo TdGrey." Exclude Functions".TdEnd.TrEnd; echo TrStart.TdStart; foreach($UdExcFuncArray as $Key => $Value ) { echo $Key.": ".$Value."<br>"; } echo TdEnd.TrEnd; echo TdGrey." Exclude Constants".TdEnd.TrEnd; echo TrStart.TdStart; foreach($UdExcConstArray as $Key => $Value ) { echo $Key.": ".$Value."<br>"; } echo TdEnd.TrEnd; echo TdGrey." Selected files to be replaced".TdEnd.TrEnd; echo TrStart.TdStart; if (sizeof($FilesToReplaceArray)) { foreach($FilesToReplaceArray as $Key => $Value ) { echo $Key.": ".$Value."<br>"; } } else echo "All scanned files"; echo TdEnd.TrEnd; echo TableEnd; echo TdEnd; echo TdStart; echo "<TABLE CELLPADDING=3 WIDTH=100% CELLSPACING=0 BORDER=1>n"; echo TdGrey." Exclude Variables".TdEnd.TrEnd; echo TrStart.TdStart; foreach($UdExcVarArray as $Key => $Value ) { echo $Key.": ".$Value."<br>"; } echo TdEnd.TrEnd; echo TableEnd; echo TdEnd; echo TrEnd.TableEnd; } function GetYesNo($Value) { if ($Value==FALSE) return "No"; else return "Yes"; } function GetWildCards() { // Scan UdExcVarArray and move the Variables with Wildcards (*) to a separate array // Separating the variables with wildcards speeds up the scanning and checking process global $UdExcVarArray, $UdExcVarArrayWild; foreach( $UdExcVarArray as $Key => $Value ) { $pos=strrpos($Value, "*"); if ($pos!==FALSE) { echo "WildCardValue:".$Value."<br>"; array_push($UdExcVarArrayWild, str_replace("*", "", $Value)); $UdExcVarArray[$Key]="Niets".$Key; } } } function ScanSourceFiles() { global $ExVarArray, $FuncArray, $ConstArray, $VarArray, $LineArray, $FileArray; global $SourceDir, $FileExtArray, $ReplaceVariables; global $UdExcVarArray, $UdExcVarArrayWild, $UdExcConstArray; $dir=dir($SourceDir); while($FileNaam=$dir->read()) { if (is_file($SourceDir."/".$FileNaam)) { // bepaal of het een PHP file is $Suffix=substr($FileNaam,(strrpos($FileNaam, ".")+1)); if (in_array($Suffix, $FileExtArray) and sizeof($FileArray) < 400) { echo "Scanning Filename:".$FileNaam."<br>n"; array_push ($FileArray, $FileNaam); $LineArray=file($SourceDir."/".$FileNaam); flush(); for ($rgl=0; $rgl<sizeof($LineArray); $rgl++) { $Line=trim(strtolower($LineArray[$rgl])); if (substr($Line, 0, 9)=="function ") { // Search for Function declaration $posEinde=strpos($Line, "("); $FunctieNaam=substr(trim($LineArray[$rgl]), 0, $posEinde); $FunctieNaam=trim(str_replace("function ", "", $FunctieNaam)); if (!($FuncArray[$FunctieNaam])) $FuncArray[$FunctieNaam]="F".substr(md5($FunctieNaam), 0,8); $FunctieTeller++; } elseif (substr($Line, 0, 6)=="define") { // Search for Constant declaration $posStart=strpos($Line, "("); $posEnd=strpos($Line, ","); //echo "Posstart: ".$posStart."<br>"; $ConstantName=substr(trim($LineArray[$rgl]), ($posStart+1), ($posEnd-$posStart-1)); $ConstantName=str_replace('"',"",$ConstantName); $posDollar=strpos($ConstantName, "$"); // name constant may not be a variable if ($posDollar===FALSE) { if (!($ConstArray[$ConstantName]) and !(in_array($ConstantName,$UdExcConstArray))) { $ConstArray[$ConstantName]="C".substr(md5($ConstantName), 0,8); } } } if ($ReplaceVariables) SearchVars($LineArray[$rgl]); // *** Search Variables } } } } $dir->close(); asort ($FuncArray); asort ($ConstArray); sort ($FileArray); } function ShowArrays() { global $FuncArray, $VarArray, $ConstArray, $FileArray, $UdExcVarArray, $UdExcVarArrayWild, $FunctieTeller; DisplayArray($FuncArray, "Found functions that will be replaced", $BgColor="FFF0D0"); DisplayArray($ConstArray, "Found constants that will be replaced", $BgColor="8DCFF4"); $VarsArr=$VarArray; ksort ($VarsArr); DisplayArray($VarsArr, "Found variables that will be replaced", $BgColor="89CA9D"); DisplayArray($UdExcVarArray, "User Defined Exclude Variables", $BgColor="BFBFBF"); DisplayArray($FileArray, "Scanned Files", $BgColor="EA6B48"); echo "<br><br>Number of userdefined elements to be replaced<br>"; echo "Functions:".sizeof($FuncArray)."<br>"; echo "Variables:".sizeof($VarArray)."<br>"; echo "Constants:".sizeof($ConstArray)."<br>"; echo "<br>Scanned Files:".sizeof($FileArray)."<br>"; } function WriteTargetFiles() { global $FilesToReplaceArray, $FileArray, $StartTime, $TotalFileSizeRead, $TotalFileSizeWrite; echo "**** START REPLACING AND WRITE THE TARGET FILES ***** <br>"; if (sizeof($FilesToReplaceArray)) $FileArray=$FilesToReplaceArray; /// only selected files if defined foreach( $FileArray as $Key => $FileName) { $FileStartTime=time(); echo "Replaced ".$FileName." Nr:".($Key+1)." of ".sizeof($FileArray); ReplaceThem($FileName); echo " - Elapsed Time: ".(time()-$FileStartTime)." sec.<br>"; flush(); } echo "Start Time: ".$StartTime."<br>"; echo "Finish Time: ".time()."<br>"; echo "Elapsed Time: ".(time()-$StartTime)." sec<br>"; echo "Total FileSize of parsed Files: ".$TotalFileSizeRead ." Bytes <br>"; echo "Total FileSize of written Files: ".$TotalFileSizeWrite ." Bytes <br>"; } // ** FUNCTIONS ** function SearchVars($Line) { global $VarArray, $StdExcVarArray, $UdExcVarArray, $UdExcVarArrayWild; while (ereg('$([0-9a-zA-Z_]*)', $Line, $regs)) { //echo "Var:".$regs[1]."<br>"; $VarName=$regs[1]; if (!$VarArray[$VarName] and !(in_array($VarName,$StdExcVarArray)) and !(in_array($VarName,$UdExcVarArray))) { // check in Wildcards Array foreach( $UdExcVarArrayWild as $Key => $Value ) { if (substr($VarName, 0, strlen($Value))==$Value) { echo "Variable with name ".$VarName." added to list of variables to be excluded.<br>"; array_push($UdExcVarArray, $VarName); // add to excluded Variables array //continue; ?? } } if (!(in_array($VarName,$UdExcVarArray))) { // check again in Excluded Variables Array //echo "Variable with name ".$VarName." added for replacement.<br>"; $VarArray[$VarName]="V".substr(md5($VarName), 0,8); } } //if (!(in_array ($regs[1], $VarArray))) array_push ($VarArray, $regs[1]); $pos=strpos($Line, '$'); $Length=($pos+strlen($regs[1])); $Line=substr($Line, (strpos($Line,'$')+1)); } } function ReplaceThem($FileName) { global $VarArray,$FuncArray, $ConstArray, $SourceDir, $TargetDir, $ReplaceVariables; global $ReplaceConstants, $ReplaceFunctions, $RemoveIndents, $RemoveComments, $ConcatenateLines; $FileRead=$SourceDir."/".$FileName; $FileWrite=$TargetDir."/".$FileName; $FdRead=fopen($FileRead, "r"); $contents=fread($FdRead, filesize($FileRead)); $GLOBALS["TotalFileSizeRead"]+=filesize($FileRead); echo " - Size:".filesize($FileRead); fclose ($FdRead); // Attention: TABS are used in some regex functions but not visible. // You can probably make them visible by making the spaces (and also tabs) visible in your texteditor // It is recommended to test your edited or new regex functions in a small program before editing them here // *** REPLACE VARIABLENAMES if ($ReplaceVariables) { foreach( $VarArray as $Key => $Value ) { $contents=ereg_replace('([ "']NAME=["']*)'.$Key.'([ "'>])','1'.$Value.'2', $contents); $contents=ereg_replace('$('.$Key.')([^0-9a-zA-Z_])','$'.$Value.'2', $contents); //werkt $contents=ereg_replace('&('.$Key.')([^0-9a-zA-Z_])','&'.$Value.'2', $contents); //werkt if (ereg('&('.$Key.')([^0-9a-zA-Z_])', $contents, $Reggies)) { echo "File Read Ampersand:".$FileRead."<br>"; } $contents=ereg_replace('($GLOBALS)([ ]*)([)([ "' ]*)'.$Key.'([ "' ]{1,3})(])', '134'.$Value.'56',$contents); } } // *** REPLACE FUNCTIONNAMES if ($ReplaceFunctions) { foreach( $FuncArray as $Key => $Value ) { $contents=ereg_replace("([^a-zA-Z0-9_])(".$Key.")[ ]*(()","1".$Value."3", $contents); //werkt } } // *** REPLACE CONSTANTNAMES if ($ReplaceConstants) { foreach( $ConstArray as $Key => $Value ) { $contents=ereg_replace("([^a-zA-Z0-9_$])(".$Key.")([^a-zA-Z0-9_])","1".$Value."3", $contents); //werkt } } if ($RemoveIndents) { $contents=ereg_replace("n[ ]*", "n", $contents); // REMOVE INDENT TABS and SPACES } if ($RemoveComments) { $contents=ereg_replace("[ ]{1,2}//[^n]*", "", $contents); // REMOVE COMMENTS $contents=ereg_replace("n[ ]*//[^n]*", "n", $contents); // REMOVE COMMENTS AFTER RETURN } if ($ConcatenateLines) { $contents=ereg_replace("([{};:])[ ]*n", "1", $contents); // CONCATENATE LINES } $contents=ereg_replace("n{2,20}", "n", $contents); // REMOVE EMPTY LINES $FdWrite=fopen($FileWrite, "w"); $NumberOfChars=fwrite($FdWrite, $contents); fclose ($FdWrite); clearstatcache(); $GLOBALS["TotalFileSizeWrite"]+=filesize($FileWrite); } function DisplayArray($ArrayName, $HeaderText="", $BgColor="FFF0D0") { global $TableColumns; echo "<br><br>".$HeaderText.":<br>"; echo "<TABLE BORDER=1 BGCOLOR=#".$BgColor.">".TrStart; $Cnt=0; foreach( $ArrayName as $Key => $Value ) { $Cnt++; echo TdStart.$Key."<br>".$Value.TdEnd; if (($Cnt%$TableColumns)==0) echo TrEnd.TrStart; //echo "<TD>".$Key.": ".$Value."</TD>"; } echo TrEnd.TableEnd; flush(); } function CheckSafeMode() { global $TimeOut; $SafeMode=strtolower(get_cfg_var("safe_mode")); if (!$SafeMode) set_time_limit($TimeOut); else echo "<b><FONT COLOR=orange>Warning: SafeMode is on. Can not set timeout.</b></FONT><br>"; } ?> </BODY> </HTML>