#native_company# #native_desc#
#native_cta#

POBS – PHP Obfuscator

By Johan Verbruggen
on October 25, 2001

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>