Пишем простенький обфускатор кода PHP
Категория: / DEV Блог
/ PHP (LAMP)
Постановка задачи:
Необходимо модифицировать код для неудобного его дальнейшего изменения. В часности - убрать комментарии, почитстить пробелы, переносы строк.
Зачем? Бывают разные ситуации, когда нужно передать код в третьи руки для ознакомления/тестирования. Чтобы гарантировать оплату (если есть опасения), можно передать
в измененном, неудобном для чтеня человеком виде.
В php есть волшебная функция token_get_all, которая разбирает код на лексемы и выдает результат в виде массива.
Отбросив ненужные части кода, мы получим нужный нам рафинированныый код, который можно смело отдавать на съедение неизвестным тетям и дядям.
Итак,
По-умолчанию берем текущий каталог, с помощью fs::build_tree получаем рекурсивный список всех файлов в этой папке (код класса fs не привожу, напишите сами),
затем организуем цикл по этому списку файлов и запускаем obfuscator::run для файлов *.php и просто копируем файлы другого типа. Преобразованный код кладется
такой же структурой в папку обозначенную в переменной $dir_to.
Запускается из командной строки (консоли), куда и выводит все проделанные действия.
Необходимо модифицировать код для неудобного его дальнейшего изменения. В часности - убрать комментарии, почитстить пробелы, переносы строк.
Зачем? Бывают разные ситуации, когда нужно передать код в третьи руки для ознакомления/тестирования. Чтобы гарантировать оплату (если есть опасения), можно передать
в измененном, неудобном для чтеня человеком виде.
В php есть волшебная функция token_get_all, которая разбирает код на лексемы и выдает результат в виде массива.
Отбросив ненужные части кода, мы получим нужный нам рафинированныый код, который можно смело отдавать на съедение неизвестным тетям и дядям.
Итак,
<?php
// CONFIG
$dir_from = dirname(__FILE__);
$dir_to = 'C:/php/code_obfuscated';
$copyright = 'copyright (C) 2008';
// BEGIN
$data = fs::build_tree($dir_from);
obfuscator::head($copyright);
foreach ($data['files'] as $file) {
$to = str_replace($dir_from, $dir_to, $file);
if (substr($file, -4) == '.php') {
// obfuscate
printf("Convert %s\n", $file);
obfuscator::run(
$file,
$to
);
}
else {
// just copy
printf("Copy %s\n", $file);
@mkdir(dirname($to), 0, true);
@copy ($file, $to);
}
}
class obfuscator {
static private $_IGNORED_TOKENS = array(
T_COMMENT
, T_DOC_COMMENT
, T_WHITESPACE
, T_ML_COMMENT
);
static private $_head;
static function head($string) {
self::$_head = sprintf("<?php\n/*\n%s\n*/\n?>", $string);
}
static function run($from, $to = null) {
$file = file_get_contents($from);
$tokens = token_get_all($file);
$file = '';
foreach ($tokens as $token) {
if (is_string($token)) {
// ;{}[]
$file .= $token;
}
else
if (isset($token[1]) && !in_array($token[0], self::$_IGNORED_TOKENS)) {
$_token = $token[0];
$pre_spacer = (
$_token == T_AS
|| $_token == T_EXTENDS
|| $_token == T_IMPLEMENTS
|| $_token == T_INSTANCEOF
)
? ' '
: '';
$post_spacer = (
$_token == T_VARIABLE
|| $_token == T_DOUBLE_COLON
|| $_token == T_STRING
|| $_token == T_OBJECT_OPERATOR
|| $_token == T_DOUBLE_ARROW
|| $_token == T_CONSTANT_ENCAPSED_STRING
|| $_token == T_LNUMBER
|| $_token == T_NUM_STRING
|| $_token == T_DOLLAR_OPEN_CURLY_BRACES
|| $_token == T_CURLY_OPEN
|| $_token == T_ENCAPSED_AND_WHITESPACE
)
? ''
: ' ';
if ($_token == T_STRING && lcfirst($token[1]) == 'exception') $post_spacer = ' ';
$file .= ($pre_spacer . $token[1] . $post_spacer);
}
}
if (self::$_head) {
$file = self::$_head . $file;
}
if ($to) {
@mkdir(dirname($to), 0, true);
file_put_contents($to, $file);
}
return $file;
}
}
По-умолчанию берем текущий каталог, с помощью fs::build_tree получаем рекурсивный список всех файлов в этой папке (код класса fs не привожу, напишите сами),
затем организуем цикл по этому списку файлов и запускаем obfuscator::run для файлов *.php и просто копируем файлы другого типа. Преобразованный код кладется
такой же структурой в папку обозначенную в переменной $dir_to.
Запускается из командной строки (консоли), куда и выводит все проделанные действия.
http://www.skillz.ru/downloads/uploads/src/fsmon.phps
if( $aAND $b )
добавить: T_LOGICAL_OR и T_LOGICAL_AND
$pre_spacer = (
$_token == T_AS
|| $_token == T_EXTENDS
|| $_token == T_IMPLEMENTS
|| $_token == T_INSTANCEOF
|| $_token == T_LOGICAL_AND
|| $_token == T_LOGICAL_OR
) ? ' ' : '';