Recently one of my friends was working with some commercial PHP software where the code had been heavily obfuscated. He needed to customize it, so he, obviously, needed access to the source code. The original authors had run it through a long line of things like gzdeflate(), base64_encode(), etc then wrapped it in an eval. Ultimately it ended up looking something like this (I deleted about 300 lines of rubbish for sanity):
<?php eval(gzinflate(base64_decode('FZzHjuNAlkV/ZXbTDS7oHWa6G/SkSNH7zYDee8+v HyVQmypAylBEvHvPUUn5n3//73/mev6v4kz6f1RvM5Z9shf/SJOtILD/y4tsyot//LcYv3K3mUzn 2aCdFj5T5ZhIHBazYw7aUwimQShr8vBDjt8oithczMM4xboabM8SJGmU8GOwFwui5E1gQMaka0xq puNjzgR6pMUho0UgA0Eh1sN3LDSpvJhTQ3jcWFYeel+swFlCnk66rfGhueJ9Fu8hOFA246x7lA2W AN6lYxI0wzhRDVU2GnhJ6HES6jwOZPsYMeJ24CgakRzn6FZjvYxZNpk4TIl4NPHICot4u4ioC28v OQFdtMldIgk/IvSM2VoZRpU593jzFjSAfvIgI8f9qQWehgrwHQpo4ySQQVNgk5MBd1jDLDw+QpUn A/jVL7wDzrpFpsluE7fvnr/coyqIrtXUyYh+TFJ5uSfcdz5PnQncr0ewMJc1vFxrDVWRt+Rv'))) ?>
The problem was that every time you ran an eval() on it you were left with another obfuscated layer. After decoding down 2-3 layers I quickly realized that this was a losing battle and I needed to let code do my work for me, a good thing too. On the first file I decoded there were 122 layers of obfuscation.
Here's the code I wrote to do the work:
<?php // this wants to be run like this: // $php decoder.php input_file.php // open the input file $fh = fopen($argv[1], 'r'); $encoded_script = fread($fh, filesize($argv[1])); fclose($fh); // decode while (true) { if (preg_match('/^\??>?<\?php\s+eval(.+)\s+\?><?\??/s', $encoded_script, $matches)) $encoded_script = eval('return ' . $matches[1] . ';'); else break; } // write the output file $fh = fopen($argv[1] . '.decoded', 'w') or die("can't open file"); fwrite($fh, $encoded_script); fclose($fh); ?>
This simply starts up a loop that runs the eval() as many times as it takes to get to the real source. It then writes the decoded source to a new file. This is pretty specific to the source files in question, but I'm sure it could prove useful as a starting point if you ever come across anything like this.