Copyright (C) 2005 Martijn Loots, Cosix Automatisering, NL
PhpCodeBuster is a PHP code obfuscator, written in PHP.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the 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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
A copy of the GNU General Public License is available at
PhpCodeBuster is based on the ideas of PhpTrasher from Setec Astronomy.
PhpCodeBuster is a work in progress, but mature enough to publish. The
first time I published, I only suggested a version number of 0.9. All
later versions will return their name and version number by referring
to the class function "PhpBustVersion()".
I would like to add any useful contributions to the package that you
might have, in order to present a better obfuscator to the world. Or
you publish better revisions yourself, whatever you like best under
I am developing a PHP/MySQL driven website for one of my customers, with
all kinds of bells and whistles. Last time I checked, it was over 21000
It is the result of some 600 hours of coding effort, during which time
the specifications sometimes changed (brrrrr)... Well worth calling it
"a baby of my brain" I think.
This website using this code is fully oprational, though it is still
developing very much, even now. It lives on two secure webservers, so,
upto now at least, I had no real need to scramble te PHP code as it was
for my eyes only.
But now it appears that the site has to move to "some hosting provider".
As I now seem to lose control over who can see or obtain the code, I
definately want to obfuscate it before moving it to the new location.
I cannot (customer order) and will not (too many private hours spent
in the creation process and it might be usable for new customers..)
make it an open source product, although I'm a big fan of Open Source.
That said, I tried locating a suitable open source obfuscator. I found
two different ones, that seemed to do the job, but both corrupted my
code all the same... :( To make a long story short: the one called
PhpTrasher caught my eye, as it is based on KISS (Keep It Simple, Stupid),
what I always favor as the way to go... I decided to write my own
obfuscator, based on the principles used by PhpTrasher. This became
PhpCodeBuster (what's in a name ?) and yes: available under GPL :)
PROBLEMS AND SOLUTIONS
Before one can start obfuscating any code, there are some hurdles to
jump over. A KISS based obfuscator needs reasonably clean code as input
or you end up with "rubbish in = rubbish out". Use the tips below if
necessary and it will probably improve the quality of your code. At
least, that was my own experience.
A code obfuscator *has* to parse the Code To Be Obfuscated (CTBO from
now on), before it can do anything at all. In my humble opinion, code
parsing is a ridiculous complex job using a language packed with
features such as PHP. Even if you *like* creating code parsers, it is
very likely that there are many problems to solve before you can start
Enter PHP Zend extension called Tokenizer. The tokenizer parses the
entire CTBO and returns it as an array of tokens. Neat eh ?
You definately need it, PhpCodeBuster won't work without it.
I use Mandriva 2005 Limited Edition as my development platform
and needed to install the extension separately (it comes with the
php-devel packages). Your mileage may vary.
PHP has some nice features to do variable substitution and function
name creation at run time (i.e. $$varname, call_user_func()).
This is deadly using a KISS based code obfuscater that only has
a compile time scope. At run time it results in creating names
that are *not* obfuscated that try to refer to names that *are*
obfuscated before... Bad, bad, baaaad.
The simple solution: *don't* use run time variable substitution...
Yeah, this bothered me too. I had some really ingenious tricks in
my CTBO :-(
So I started rewriting the affected parts in the CTBO and in doing
so, discovered that the net result was cleaner, more robust and more
readable code. Not so bad after all, I learned again what I once knew:
tricks are mostly nice to have, but are hazard prone in real life. I
write better code now.
The old-fashioned way to obtain HTML form variables as input for your
script, by referring to them as variable with the same name as in the
HTML form, will be broken by PhpCodeBuster (and by any other obfuscator
for that matter). By example:
HTML: ... <input name="myvariable" ...
PHP: ... if ( isset($myvariable) ) ...
The only good solution: *don't* use this style of parameter passing.
It is bad practice, creates insecure websites and delivers badly
readable code (variables just pop up from nowhere...). Use the
standard $_COOKIE, $_PRE, $_POST and $_REQUEST globals instead.
And yes, I had to rewrite two of the oldest scripts in my CTBO, I
Using PHP to process PHP code is "The Way To Go", as it is all in
the package already (tokenizer). That said, the PHP environment can
also lead to unwanted interference with the CTBO. To minimize this
is a problem for the person developing the obfuscator, but you as
the user *can* experience interference problems.
In my view, there are a few possible problems:
1) A native PHP function name gets scrambled.
2) A function defined in the CTBO won't get scrambled.
3) Namespace conflicts between the CTBO and the PhpCodeBuster
4) Namespace conflicts between the CTBO and the code calling
To differentiate between native PHP functions and a function belonging
to the CTBO is necessary. Only the latter need to be changed !
The solution I use is to check the function name with "is_callable()".
Only native PHP functions should be resolved as "callable". Even
function names in the CTBO that are equal to function names in the
PhpCodeBuster class will not be recognized as function, because it
would need "this->" prepended to the name. This solves 1) and 2).
Only a broken PHP environment can end up in 1).
If it ever occurs, 2) should not be a real problem, as long as it
occurs consequently. 2) is about forgetting specific names in the
obfuscation process. It is not harmful: it only shows the affectted
names in plain text as they were before.
The best way to isolate namespace in PHP is by using a class method.
PhpTrasher did that, as does PhpCodeBuster. This solves 3), but
be aware about 4) !
** Don't use PhpCodeBuster from within complex PHP programs: chances
** are that your function names are present as function names in the
** CTBO. It is no disaster: the result will work as expected, but the
** affected names will not get obfuscated.
I cannot help myself: I think this is Very Good (TM) solution of the
interference problem, but somewhere in the back of my mind it 5) keeps
USEABILITY AND PRECONDITIONS
- I already mentioned this: you need the PHP Tokenizer extension on
your favourite platform. It is a standard extension to PHP as of
version 4.3.0, so that should prove not to be difficult.
- Rewrite your code before obfuscating. Look for $$ variables,
call_user-, create_function et al and old fashioned form parameter
There are probably many more hazardous constructs that I did not
mention or am aware of. In my view, they all have in common that
the name space differs at run time.
Be prepared if you use PhpCodeBuster and let me know if you discover
new problems. I'd be happy if you have the solution to go with it...
- The 3 files presented in this package (bust.php, phpbuster and
phpcodebuster.class.php) are used as a command line tool in a
Linux environment. They are probably good for any UNIX, xBSD
or Linux developer, but need some rework to be usable on Windows.