NAME:
The (sort of) PHP Compiler v0.1
SYNOPSIS:
include('Compiler.class.php');
$Compiler = new Compiler('uncompiled.php', 'compied.php');
DESCRIPTION:
What is "The (sort of) PHP Compiler"?
First let me cover what this is NOT. This is not a compiler in the sense that it will
NOT make an executable application that can be executed on target systems independently
of PHP. If you are looking for that of thing you need to look for the Roadsend PHP
Compiler, one of the many PHP opcode caching applications or the bcompiler set of
functions within PHP (get bcompiler from http://pecl.php.net/get/bcompiler).
This is a compiler in the sense that it makes a compilation from multiple PHP files,
after that it will obfuscate the source code. The main way of obfuscating the code
is by compressing the code with gzip, this is used as the base obfuscation filter
because it yields the functional side effect of making the source code smaller, where
as you'll find almost any further obfuscation will probably make the source larger
(which isn't always handy).
After the base obfuscation has been completed, extra filters can be used, either
your own filters in the form of your own function or method or a built in filter
within the Compiler class.
So "The (sort of) PHP Compiler" is not really a compiler?
No. In reality this is an obfuscation tool. I know there is a standards junkie out-
there who can't handle something like this being called a "compiler" but it does
make a compilation of PHP files and last time I checked, computer scientists didn't
invent the word compile, just deal with it.
How can "The (sort of) PHP Compiler" be useful to me?
Well I'm not promising anything, but the reason why I wrote this was because I wanted
an easy way to play with different homemade obfuscation techniques, for copy protection
at the PHP level. I came back to this script recently because I wanted to conceal
the contents of a bash script written in PHP so it finally became of more use to me
than just a "what if" experiment so maybe it will for you too.
Look I wouldn't go try "compile" your entire CMS into a single compressed
and obfuscated PHP file or anything, not only is this library not ready for that sort
of responsibility but it would just add uneccesary overhead to both script
execution and maintenence. However this *could* be useful if you have
a single function within one of your CMS scripts that you want to hide or some
classes or maybe a single script you want to obfuscate or compress.
This is also useful if you want to explore your own obfuscation and copy protection
methods, it will make your life a bit easier by handling all the crappy stuff for
you so you can just get to the actual obfuscation bit of things. If you do make
anything thats actually hard to "crack", let me know.
Isn't obfuscation of PHP at the PHP level a waste of time?
Kinda.. There are real PHP compilers out there (none that you would use on anything
mission critical though) and compiling PHP into an exe might seem like the best
solution but it would also mean the code wouldn't be portable and you would need
to have different builds for different systems (win32 or linux, sparc or x86).
There is the Bytecode Compiler project for PHP that, according to the PHP manual,
plans to seek the feasability of making a PHP to C thingy. That would be cool and
general Bytecode Compiling would definately be helpfull in PHP obfuscation and
copy protection, but those functions are experimental and you probably won't find
them enabled on that many production servers just yet and when you do I imagine
it wouldn't be too hard to reverse.
So the problem remains, how do you obfuscate something that needs to reversed at
run time so that it is unviable to try "crack", its a cool problem because it's
one of those areas where it pays to be a little eccentric in your thinking/
The real beauty of obfuscation of PHP at the PHP level (and indeed any
other high level interpreted language) is that its a seemingly unsolvable problem
because no matter what you do with the source, one constant remains, that at some
point you will have to reverse the obfuscation to execute the code, there are
some cool tricks you can do to fool the "cracker" but it will never be 100% solid
and uncrackable (although to be honest the same can be said for lower level
obfuscation and protection schemes).
Obfuscation is an unsolved problem, so if you have the time and skill why don't
you take this class and try solve it. Besides what better way to stick it to the man
than invent your own leet obfuscation technique and release it into the public
domain so developers don't have to go pay some company for a viable solution for
obfuscation and/or copy protection.
How does it work?
The (sort of) PHP Compiler reads all the specified files and joins them together
being carefull to get rid of things we don't need like comments and extra white
spaces. The joined up source code is then compressed with gzip and base64 encoded
so that we can store it in a normal ASCII file, this step is the obfuscation base.
After the base obfuscation is done, control is passed to the filter functions if
any are specified. A filter function can either be your own method or function
within your own code, a function within a filter file (in which case you only
specify the name of the file, minus the '.inc.php' bit, or a built in filter.
If you play around with your own obfuscation/encryotion filters you can use the
MakeCode method to build the formatted source code from the encrypted string.
Your own filter functions should take the source fragment (the PHP code minus
the opening and closing PHP tags ,<? and ?> by default) as thier only argument
and return the final source segment after they have obfuscated the code.
If your own filter needs to run some special code to reverse the obfuscation
then you should use the $reverseCode parameter with the MakeCode() helper function.
Once we have our final obfuscated source code we output the code to a file (if
an output file was specified) and return the results.
REQUIREMENTS:
This class requires PHP with the zlib library both on the machine on which you compile
the code and the target machine on which you intend the compiled code to run.
CLASS METHODS:
Compile($sourceFiles [, $outputFile, $filters])
-----------
Description:
This will merge all the source file(s) into one and compress and obfuscate the results.
You can specify your own custom filters to obfuscate the source code further as the
default filter is easy to reverse (but a good basis on which to obscure the code more).
Arguments:
mixed $sourceFiles - This holds the name(s) of the file(s) you want to compile. This
can be provided as a glob style string (/some/directory/*.php), a file name or
a comma and/or space seperated string of file names and/or glob style strings.
You may also supply the above strings in a one dimensional array if you are feeling
extra cool and want to use files from multiple locations. The files are merged in the
order they are supplied.
string $outputFile - This is the optional output file, if this is set we will attempt
to write the final code to this file.
mixed $filters - These are extra filter callbacks you wish to run the obfuscated
code through to obfuscate it further. You can supply filters as a function callback
(by supplying a string with the function name), a method call back (by supplying the
object that contains the method and method name in an array ie. array($Object, 'MethodName')
or you can use the name of one of the built in filter methods within the Compiler class
ie. if you want to use the LeetFilter() function you supply the string 'leet' as the
filter. You can supply multiple filters if you wish by putting them into a one dimensional
array. NOTE: See the FILTERS section in this README for a list of filters that are
build into the Compiler class, also see the MakeCode() function if you want to make
your own filters or modify existing ones.
Returns:
A string containing the obfuscated source code
MakeCode($codeVar [, $reverseCode, $escapeWith])
-----------
Description:
This is a function to be used in your own obfuscation filters to easily build
code. You pass the code to be eval()'d as a string or array (of characters or
whatever represents the characters). If the obfuscation needs to be reversed
before the code can be run you can supply the $reverseCode argument that contains
the code string that will reverse the obfuscation, the string should contain
the tag specified in the Compilers $InsertCodeTag variable so that we know where to
inject the obfuscated source so it can be reverse at runtime. The $escapeWith
argument is a sub string that we will prepend to each character in the final code,
this allows us to escape the characters for hex and octal style obfuscation or
to seperate each characters data with a unique token that we can use the reverse
the obfuscation at run time.
Arguments:
mixed $codeVar - This holds the code either as a single string or an array of
characters.
string $reverseCode - This is the code to reverse the obfuscation at run time,
for instance if you base64 encode the source code to obfuscate it you would set
this is 'base64_decode(__C0D3__)', __C0D3__ is the default tag so the compiler
knows where it should insert the obfuscated code in the final source.
string $escapeWith - This is the string that will be appended to each character
of the obfuscated source, for instance if you get the hex values of each character
in the source and want to use that as a form of obfuscation then you can supply
'\\x' so that each hex element will have \x appended which will make sure when
the source is parsed each hex element is converted back into its original byte
value.
Returns:
A string containing the obfuscated source code
CLASS VARIABLES: DESCRIPTION
$SourceCode An array that holds the source code of the file(s) we want to compile
$CompiledCode The compiled source code
$VariableName The name of the variable that holds the compiled code in the final source
$CharsPerLine The number of characters per line in the final code (not counting indent)
$InsertCodeTag This is a unique tag so the compiler knows where to insert code in special PHP code strings (only useful if you make or modify obfuscation filters)
$ShebangLine The shebang line (if any) to put at the top of the final code (eg. /usr/local/bin/php -q)
$HeaderComment The comment block (if any) to put into the final code
$OpenPHPTag This is the opening PHP tag in the final code
$ClosePHPTag This is the closing PHP tag in the final code
BUILT IN FILTERS: DESCRIPTION
Leet This will hex encode the source code, it increases your code size by 4.
The resulting code looks a bit like \xDE\xAD\xBE\xEF and it does not need
anything special to reverse the obfuscation at run time.
Octal This will turn the source code into an octal escaped string
EXAMPLES:
1. Example of how to compile all PHP files in a directory called source and add
a shebang line to it so it can be used as a bash script called omgwtf.php:
<?
// Include the Compiler class
include_once('Compiler.class.php');
// Instantiate the Compiler object
$Compiler = new Compiler;
// Set the shebang ine
$Compiler->ShebangLine = '#!/usr/local/bin/php -q';
// Compile all the PHP files in the source directory
$Compiler->Compile('source/*.php', 'compiled.php');
?>
2. Example of how to compile a single PHP file and obfuscate the results further
with the 'Leet' Filter (build in):
<?
// Include the Compiler class
include_once('Compiler.class.php');
// Compile the single.php file into output.php and obfuscate further with the leet filter
$Compiler = new Compiler('single.php', 'output.php', 'leet');
?>
3. How to compile multiple scripts from different locations into one script, add a custom
header file (a block comment) and collect the resulting source in a variable:
<?
// Include the Compiler class
include_once('Compiler.class.php');
// Instantiate the compiler object
$Compiler = new Compiler;
// These are all the places where our files are kept
$Files = array('classes/*.class.php',
'include/something.php',
'test.php, index.php, admin.php',
'libs/all.inc.php /some/path/to/somefile.php',
'more/php/*.php yet/more/php/files/*');
// This is the block comment we want to prepend the PHP code with
$Compiler->HeaderComment = file_get_contents('header.file.php');
// We have everything we need, compile the scripts and grab the resulting source
$FinalCode = $Compiler->Compile($Files);
// ... We can do whatever with the source from here
?>
4. Example of how to change the variable name of the variable that holds the obfuscated
code at the end of the obfuscation.
<?
// Include the Compiler class
include_once('Compiler.inc.php');
// Instantiate the Compiler object
$Compiler = new Compiler;
// Set the variable name to $OMGWTF
$Compiler->VariableName = 'OMGWTF';
// Compile somefile.php to compiled.php
$Compiler->('somefile.php', 'compiled.php');
?>
COPYRIGHT:
Copyright (c) 2006 Warren Smith. All rights reserved.
This software is released under the GNU General Public License.
Please read the disclaimer at the top of the Compiler.class.php file.
THANKS:
Special Thanks to:
That guy from Frasier.
|