Xcache баг-трекер декомпилятора

Статус
В этой теме нельзя размещать новые ответы.

sidxx55

IC10, Zend, SG-PS decoding, encoding
Регистрация
12 Май 2007
Сообщения
355
Реакции
260
Предлагаю тут вести баг-трекер по декомпилятору, где-сообщать об ошибках декомпиляции и возможные пути исправления класса декомпилятора Decompiler.class.php, знание PHP приветствуется:), в архиве пак для теста, запускаем командную строку (спец файл прилагается CMD_LINE.bat) php phpdc.phpr file.php> dump.txt, распаковать в корне диска С, ядро и лоадер php5.3.
===================
подробнее об исправленных багах смотрите тут Для просмотра ссылки Войди или Зарегистрируйся в репозитарии пользователя Olivok, там все расписано (и также можно скачать последнюю версию его фиксов), либо по ходу темы от других пользователей, исправления которых будут вноситься и прикрепляться после общих проверок всех исправлений в целом (дублироваться в 1 классе, ни 1 фикс не пропадет)
==========================
Обновленный пользователями КЛАСС буду выносить в первый пост по датам, так что меняйте класс в архиве проги если что;) ================================
 

Вложения

  • Decompiler.class09022013.rar
    18,8 KB · Просмотры: 78
  • Decompiler.class09022013-1.rar
    18,9 KB · Просмотры: 31
  • Xcache updatable09022013.rar
    1.011,8 KB · Просмотры: 188
  • Decompiler.class10022013.rar
    19,2 KB · Просмотры: 26
  • Decompiler.class10022013-1.rar
    19,4 KB · Просмотры: 29
  • Decompiler.class11022013.rar
    19,6 KB · Просмотры: 63
  • Decompiler.class12022013.rar
    19,9 KB · Просмотры: 40
  • Decompiler.class13022013.rar
    20,1 KB · Просмотры: 259
Проблема больших файлов, в чем причина: Размер структуры op_array ограничен (сейчас нет сорцов под рукой но кажется 1024 вхождений) При обработки больших массивов создается несколько структур, то есть формируется первая структура, выполняется. Далее формируется вторая выполняется итак далее. РМ в ядре расширил размер структуры до 4096 опкодов в блок, что за глаза покрывает необходимые размеры (если там было 500 килобайт то 4096 это около 2 мегабайт на файл, но это все примерно на глаз. Так как большие переменные все таки 1 опкод, пока не дойдет до лимита размера).
Проблема возникает в следующем, когда берем структуру первого блока и декомпилим её то кто бы знал что есть что-то дальше? Поэтому и сваливается.
Решение тупое расширение блока в ядре. Но при этом мы гарантировано получаем возможность утечки памяти при обработке серелизованого опкода. Но этим пугать не стоит. Оно тоже решается.
Про класс декомпилятора. Его на любой дамп не накрутишь. Вопрос в том что дизассемблер xcache принимает сириализованый опкод. Формально этот дизассемблер вбить в ядро и повешать на execute_data и по тихому сливать покод. Но так как кубик делает подлянки с рантайм выполнением, то идеальный вариант это создать функцию-аккамулятор и вешать сборщика опкода на каждую функцию обработчика (по русски echo и print обрабатывает одна функция, а class другая), в обработчики приходит единичный опкод. Причем выполнение идет последовательно шаг за шагом. Если прямо с входа в эти функции ложить опкод например в fake_opcode struct, то мы получим дамп выполняемого в рантайме опкода. Затем тупо сдампить дизассемблером. Тогда кубик даже патчить не нужно будет. Так как вся проблемма в том, что текущие дезендеры делают хук или просто внедряются код в екзекутор.
При этом кодеры тоже хукают екзекутора. Вот и получается что екзекутор как бы не при делах и начинается патчинг.
Но как он работает (екзекутор) это тупой цикл в котром переберется опкод и оправляется отдельный опкод на execute_data. Далее стоит разборщик который раскидывает на выполения отдельным фунциям. Вот если удастся их хакнуть. То точно всем кодеровщикам пришла жопа. Так как для обхода такого дезендера нужно хукать все функции ядра (а это позволено не для всех). Проще php переписать.
Поэтому задача архи сложная. Тут вопрос не дней а месяцев. Поэтому просьба всем сочувствующим не бросайте затею. Виртуалка с билдом xcache будет к понедельнику (сначала сделаю rm сиду).
PS ну вот такой я человек, что не могу что-то делать за идею. Если не вижу что это кому-то нужно то кинуть проект раз плюнуть. Пингвин птица гордый без пинка не полетит. Так и я если нет стимула, то нафиг оно. Неважно какой бы он не был. Если честно, то то что я хотел узнать о ядре пхп уже известно и очень разочаровался в нем как в языке сценариев (красиво с наружу унылое гавно внутри). Просьба не бросайте проект и тогда у нас все получится. За сим пока все!

b9c9603a7e6c11e296cde22af87e0b38.png
Примерно нарисовал чтобы понятнее было о чем говорю
Названия функций может отличатся, так как по памяти того что было 3-4 месяца назад )))

Sidxx55 сборка рм для тебя готова, в течении 2-3 часов выложу. Размер примерно 3 гига будет
 
еще замечу, что конструкции по декомпиляции прописаны жестко, и из-за этого останавливается декомпиляция в некторых местах,
простой пример, конструкция foreach ($boxes as $boxes_part) { ....} стопориться вызывая ошибку декомпиляции, добавив foreach ($boxes as $boxes_part => $value) {} декомпилируется, т.о. нужно расширить восприятие конструкций декомпилятором, я думаю что это не единственный пример.
1 фикс декомпилятора (спасибо StealthDebuger за начало), теперь ошибка ушла на конструкции foreach ($boxes as $boxes_part), код расшифрован, ищем другие баги (catchable fatal error object of could not be converted to string in) по аналогии
сам фикс класса
1. Фикс foreach

PHP:
            ob_start();
            $this->beginScope($EX);
            $this->recognizeAndDecompileClosedBlocks($EX, $range);
            $this->endScope($EX);
            $body = ob_get_clean();
 
            $as = foldToCode($firstJmpOp['fe_as'], $EX);
            if (isset($firstJmpOp['fe_key'])) {
                $as = str($firstJmpOp['fe_key'], $EX) . ' => ' . str($as);
            }
            else { // fix 1 foreach
                $as = str($as); //
            } //
2. проблема обработки непустого DIE
пример:
PHP:
    if (strstr($mailbox, '../') || substr($mailbox, 0, 1) == '/') {
        global $color;
        include_once(SM_PATH . 'functions/display_messages.php');
        error_box(sprintf(_("Invalid mailbox name: %s"),htmlspecialchars($mailbox)),$color);
        sqimap_logout($imap_stream);
        die('</body></html>'); // ТУТ
    }
Фикс 2 непустого exit or die
PHP:
case XC_EXIT: // {{{
                $op1val = $this->getOpVal($op1, $EX);
                $resvar = "exit(" .str($op1val).")"; // die fix
                break;
3. Проблема This (исправлено dima2k)
пример
PHP:
<?php
  function search($expression, $bnum = -1) {
        $ret = array();
        $this->error = ''; //отбражается
 
          if ($bnum == -1) {
            $sel = $this->get_backend_list('');
            $failed = 0;
            for ($i = 0 ; $i < sizeof($sel) ; $i++) {
                $backend = &$sel[$i];
                $backend->error = '';
                $res = $backend->search($expression);
                if (is_array($res)) {
                    $ret = array_merge($ret, $res);
                } else {
                    $this->error .= "\n" . $backend->error; // только .= 'error';
                    $failed++;
                }
            }
 
 
            if( $failed >= sizeof( $sel ) ) {
                $ret = FALSE;
            }
 
        }  else {
 
 
 
            $this->backends[$bnum]->search($expression); //Тут остановка
            if (!is_array($ret)) {
                $this->error .= "\n" . $this->backends[$bnum]->error; //тут не отображается все с this, только .= 'error'
                $ret = FALSE;
            }
        }
 
        return( $ret );
    }
    ?>

5. Обработка сложных конструкций IF
PHP:
if (isset($languages[$squirrelmail_language]['XTRA_CODE']) &&
        function_exists($languages[$squirrelmail_language]['XTRA_CODE'])) {
        $string = $languages[$squirrelmail_language]['XTRA_CODE']('decode', $string);
    }
патчи
PHP:
    if ($opc == XC_ISSET_ISEMPTY_PROP_OBJ) {
                        if (!isset($container)) {
                            $container = '$this';
                        }
                        $rvalue = $container . "->" . unquoteVariableName($dim);
                    }
                    else {
                        $rvalue = str($container) .'[' . str($dim) . ']'; /// патч
                    }
         
                }
PHP:
$prefix = (isset($object) ? str($object) . '->' : '')
                    . (isset($EX['called_scope']) ? str($EX['called_scope']) . '::' : '' );
PHP:
$resvar = str($cast) . ' ' . str($this->getOpVal($op1, $EX));
PHP:
return '$' . substr(str($this->src), 1, -1);
декомпилятор стал работать значительно лучше, приходится конечно Стелса донимать
отработка тестого файла из под зендгарда для пхп53 (case баг (исправлено dima2k))
PHP:
<?php
 
class gbCore
{
    /**
    * System config
    *
    * @var    array  $conf
    * @access  public
    */
    public $conf = array();
    /**
    * Current context
    */
    public $context;
    /**
    * Current loaded modules
    */
    public $modules = array();
    /**
    * Input variables from gateway
    */
    public $input = array();
    /**
    * Output variables from modules
    */
    public $output = array();
    /**
    * Route for modules loading
    */
    public $route = array(
        'defaultModule' => NULL,
        'route'        => array()
        );
    /**
    * Information about current user
    */
    public $user;
    /**
    * In this variable system stores current request
    * <pre>
    *  array(
    *      'module'    => moduleName,
    *      'action'    => localFacadeName,
    *      'code'      => result of work
    *  )
    * </pre>
    *
    * @var    array  $request
    * @access  public
    */
    public $request = array('module' => NULL, 'action' => NULL, 'code' => NULL);
 
    public function __construct($rootPath)
    {
        $this->rootPath = $rootPath;
        $this->_run_id = substr(intval(microtime(true) * 10000), -6);
        set_include_path($rootPath . '/lib/php' . PATH_SEPARATOR . $rootPath . '/lib/php/PEAR' . PATH_SEPARATOR . get_include_path());
 
        if (!$this->loadConfig()) {
            throw new Exception('can not read system.xml config', 110);
        }
 
        $this->log = $this->newLog('runtime');
 
        if (!$this->initData()) {
            throw new Exception('can not connect to database', 120);
        }
    }
 
    public function loadConfig()
    {
        $path = $this->rootPath . '/etc/system.xml';
        $xml = simplexml_load_file($path);
 
        if (!$xml) {
            return false;
        }
 
        $this->conf = gbSys::sxml2array($xml);
        $this->conf['path']['root'] = $this->rootPath;
 
        foreach ($this->conf['path'] as $k => $v ) {
            if ($k == 'root') {
                continue;
            }
 
            if ($v[0] != '/') {
                $this->conf['path'][$k] = $this->rootPath . '/' . $v;
            }
        }
 
        return true;
    }
 
    public function initData()
    {
        if (!isset($this->conf['data'])) {
            return true;
        }
 
        $this->db = $this->makeConnection($this->conf['data']);
        return $this->db ? true : false;
    }
 
    public function makeConnection($dataConf)
    {
        $filename = 'initData.' . $dataConf['type'] . '.php';
        $filename = $this->conf['path']['root'] . '/lib/php/' . $filename;
 
        if (!file_exists($filename)) {
            return false;
        }
 
        return include $filename;
    }
 
    public function ad($name)
    {
        $className = $name . '_' . $this->conf['data']['type'];
        require_once $this->conf['path']['ad'] . '/class.' . $className . '.php';
 
        if (class_exists($className)) {
            return new $className($this->db);
        }
 
        return false;
    }
 
    public function newLog($logName, $format = NULL, $level = 10)
    {
        $logFile = $this->conf['path']['logs'] . '/' . $logName . '.log';
        $extra = array('log_id' => $this->_run_id, 'context' => $this->context);
 
        if (!$format) {
            $format = '[{date}] [{context}/#{log_id}] %s' . "\n" . '';
        }
 
        return new gbLog($logFile, $level, $extra, $format);
    }
 
    public function initContext($context = NULL)
    {
        $__ek = 'abcdefghijklmnoprstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=_+!@#$%*';
        $__ek = implode('', array($__ek[25], $__ek[51], $__ek[53], $__ek[41], $__ek[29], $__ek[60], $__ek[30], $__ek[16], $__ek[13], $__ek[68], $__ek[3], $__ek[40], $__ek[19], $__ek[50], $__ek[62], $__ek[23], $__ek[31], $__ek[61], $__ek[45], $__ek[22], $__ek[28], $__ek[33], $__ek[15], $__ek[5], $__ek[60], $__ek[7], $__ek[21], $__ek[20], $__ek[56], $__ek[46], $__ek[24], $__ek[49], $__ek[69], $__ek[38], $__ek[35], $__ek[32], $__ek[58], $__ek[25], $__ek[6], $__ek[8], $__ek[70], $__ek[17], $__ek[53], $__ek[4], $__ek[44], $__ek[65], $__ek[36], $__ek[27], $__ek[54], $__ek[47], $__ek[48], $__ek[37], $__ek[1], $__ek[18], $__ek[12], $__ek[55], $__ek[67], $__ek[26], $__ek[9], $__ek[34], $__ek[2], $__ek[57], $__ek[52], $__ek[43], $__ek[14], $__ek[42], $__ek[10], $__ek[3], $__ek[64], $__ek[39], $__ek[66], $__ek[11], $__ek[63], $__ek[51]));
        $this->kc = new gbKeyControl('/etc/license.key', $__ek);
        $this->kc->checkKey();
 
        if (!isset($this->conf['systemTypes'][$context])) {
            $context = current(array_keys($this->conf['systemTypes']));
        }
 
        $this->context = $context;
        $this->context_info = $this->conf['systemTypes'][$context];
 
        if (isset($this->context_info['url'])) {
            $this->conf['rootURL'] = '/' . $this->context_info['url'];
        }
        else {
            $this->conf['rootURL'] = NULL;
        }
 
        $this->L = new gbLocale($this->conf['path']['modules']);
        $this->M = new gbMsg(array($this->L, 'getMsg'));
        $this->env = gbEnvAbstract::factory($this->context_info['env'], $this);
        $this->C = new gbContainer();
        return $context;
    }
 
    public function loadModules($list, $context = NULL)
    {
        $modules = $this->getModules($list, $context);
 
        foreach ($modules as $moduleName => $obj ) {
            if (!$obj->isNormal()) {
                $this->log->write(30, 'Can not load "' . $moduleName . '" module - no facades available by context/acl.');
            }
 
            $this->C->{$moduleName} = $obj;
        }
    }
 
    public function getModules($list = NULL, $context = NULL)
    {
        if (is_null($list)) {
            $list = array();
            $all = glob($this->conf['path']['modules'] . '/*');
 
            foreach ($all as $row ) {
                $list[basename($row)] = NULL;
            }
        }
 
        $R = array();
 
        foreach ($list as $moduleName => $aclList ) {
            if (is_int($moduleName) && is_string($aclList)) {
                $moduleName = $aclList;
                $aclList = NULL;
            }
 
            try {
                $module = $this->getModule($moduleName, $aclList, $context);
                $R[$moduleName] = $module;
            }
            catch (Exception $e) {
                if ($e->getCode() == 310) {
                    $this->log->write(10, 'Load of "' . $moduleName . '": denied by license');
                }
                else {
                    $this->log->write(50, 'Load of "' . $moduleName . '": ' . $e->getMessage());
                }
            }
        }
 
        uasort($R, create_function('$a, $b', 'return ($a->_order > $b->_order ? 1 : ($a->_order < $b->_order ? -1 : 0));'));
        return $R;
    }
 
    public function getModule($moduleName, $aclList = NULL, $context = NULL)
    {
        $file = $this->conf['path']['modules'] . '/' . $moduleName . '/init.php';
 
        if (!file_exists($file)) {
            throw new Exception('Init file does not exists: ' . $file, 101);
        }
 
        require_once $file;
        $class = $moduleName . '_module';
 
        if (!class_exists($class, false)) {
            throw new Exception('Class "' . $class . '" is not present in the init file: ' . $file, 102);
        }
 
        $context = (is_null($context) ? $this->context : $context);
        $module = new $class($this, $context, $aclList);
        return $module;
    }
}
 
class gbContainer
{
    public function exists($module, $facade = NULL)
    {
        if (!isset($this->{$module})) {
            return false;
        }
 
        if (is_null($facade) || $this->{$module}->facadeExists($facade)) {
            return true;
        }
 
        return false;
    }
 
    public function getModules()
    {
        $ref = new ReflectionObject($this);
        $props = $ref->getProperties();
        $R = array();
 
        foreach ($props as $row ) {
            $name = $row->name;
            $R[$name] = $this->{$name};
        }
 
        uasort($R, create_function('$a, $b', 'return ($a->_order > $b->_order ? 1 : ($a->_order < $b->_order ? -1 : 0));'));
        return $R;
    }
 
    public function __get($name)
    {
        global $GB;
        $msg = 'ERROR: called module "' . $name . '" is not loaded, check roles permissions!';
        $trace = debug_backtrace();
        $details = 'Called in ' . $trace[0]['file'] . ':' . $trace[0]['line'];
        $GB->log->write(50, $msg . ' ' . $details);
        exit($msg);
    }
}
 
class gbKeyControl
{
    /**
    * License key
    *
    * @var    array  $key
    */
    public $key;
    /**
    * Path to license key File
    *
    * @var    string $keyFile
    */
    public $keyFile;
 
    public function __construct($keyFile, $encode_key)
    {
        $this->keyFile = $keyFile;
        $this->encodeKey = $encode_key;
    }
 
    public function checkKey()
    {
        $code = $this->readKey();
 
        if ($code != KC_OK) {
            $this->error($code);
        }
 
        $code = $this->checkControl();
 
        if ($code != KC_OK) {
            $this->error($code);
        }
 
        $code = $this->checkLimits();
 
        if ($code != KC_OK) {
            $this->error($code);
        }
 
        return $this->key;
    }
 
    public function readKey()
    {
        global $GB;
        $file = $GB->rootPath . $this->keyFile;
        if (!file_exists($file) || !$data = @file_get_contents($file)) {
            return KC_NO_KEY;
        }
 
        $z = new Zcrypt($this->encodeKey);
        $KEY = $z->decrypt($data);
        $XML = simplexml_load_string($KEY);
 
        if (!$XML) {
            return KC_NO_KEY_VAR;
        }
 
        $this->key = gbSys::sxml2array($XML);
        return KC_OK;
    }
 
    public function checkControl()
    {
        $vars = $this->key;
        $CONTROL = hash('sha512', '@@@' . $vars['regto'] . $vars['hostid'] . 'VCS' . $vars['id'] . 'iZJRXdfF7' . $vars['limit_time'] . '#BjJc7' . $vars['limit_legs']) . strrev(hash('sha512', 'BillBery123' . strrev($vars['id']) . $vars['until'] . $vars['hostid'] . strrev($vars['regto'])) . hash('sha512', 'billing' . $vars['hostid'] . strrev($vars['until'] . 'eT!LC4') . $vars['limit_time'])) . hash('sha512', 'QE0Frn$' . $vars['hostid'] . '$' . implode('-', (array) $vars['modules']) . 'io@#sadsVO');
        return $vars['licenseCode'] == $CONTROL ? KC_OK : KC_ERR_CONTROL;
    }
 
    public function checkLimits()
    {
        $this->key['until'] = intval(@$this->key['until']);
        $this->key['limit_legs'] = intval(@$this->key['limit_legs']);
        $this->key['limit_time'] = intval(@$this->key['limit_time']);
        $this->key['modules'] = preg_split('~\\s*[,;]\\s*~', @$this->key['modules']);
        $this->key['modules'] = array_filter($this->key['modules']);
        if (($this->key['until'] != -1) && ($this->key['until'] < time())) {
            return KC_ERR_UNTIL;
        }
 
        return KC_OK;
    }
 
    public function error($code)
    {
        echo 'LICENSE ERROR: ' . "\n";
 
        switch ($code) {
        case KC_NO_KEY:
            exit('Specified key file not found: ' . $this->keyFile);
            break;
 
        case
Notice: Undefined offset: 5 in C:\Xcache\Decompiler.class.php on line 620
:
            exit('Format of specified key file is incorrect.');
            break;
 
        case
Notice: Undefined offset: 6 in C:\Xcache\Decompiler.class.php on line 620
:
            exit('Incorrect signature of key file.');
            break;
 
        case
Notice: Undefined offset: 7 in C:\Xcache\Decompiler.class.php on line 620
:
            exit('Key expired: expiration date = ' . date('Y-m-d H:i:s', $this->key['until']) . '.');
            break;
 
        case
Notice: Undefined offset: 13 in C:\Xcache\Decompiler.class.php on line 620
:
            exit('Incorrect system partitions, check linux distributive.');
            break;
 
        default:
            exit('Unknown error.');
            break;
        }
    }
}
 
function __mock_load()
{
}
 
if (!function_exists('__autoload')) {
    function __autoload($class_name)
    {
        require_once 'class.' . $class_name . '.php';
    }
}
 
define('KC_OK', 0);
define('KC_NO_KEY', 1);
define('KC_NO_KEY_VAR', 2);
define('KC_ERR_CONTROL', 3);
define('KC_ERR_UNTIL', 5);
define('KC_ERR_FS', 6);
 
?>
 
отстань старушка я в печали
&copy; А.С. Пушкин


Мечтать не вредно как говорится. Идея внедрить дампер в екзекутора показала отличные результаты! Большинство енкодеров сливают опкод на исполнение либо на execute_data или на самого екзекутора. Пока сдампил два опкода zend_echo и букет include (require, include и тд).
Заглушки на выполнение срабатывают на ура. Но есть печальное известие. Доблестный кубик подмял под себя и его и теперь 100% ясно как он работает. Одно грустит, что все таки без патча лоадера не обойтись.
Конечно становится намного легче с твистером и кодировщиком, но при выполнение opline нужно джампить на реального екзекутора пыха
Ниже выкладываю скомпилированное патченое ядро и для особо дотошных zend_vm_execute.h

Для тех кто не понял а нафига ты это все делаешь. Расскажу в двух словах
Что делает xcache:
xcache ставит хук на zend_compile_file и zend_compile_string заменяее функции своими
Енкодеры делают тоже само в том числе и кубик.
Давайте посмотрим что будет если загрузить кешь а потом кубика.
zend_compile_file хукает кешь и переводит на zend_compile_file_t
кубик хукат zend_compile_file, который уже zend_compile_file_t на своюб функцию
Итог xcache не работает.
Если перевернуть наоборот то вывалится кубик.
Поэтому врезаться нужно непосредственно в ядро, причем чем глубже тем лучше.
Я поставил трубу на конечную точку, на место исполнения самого опкода, после этой точки опкод уходит в коллектор и его уже нет. Это последняя точка жизни опкода.
Но вот кубик тоже не прост, он тупо скопировал файлы и вбил в расширение. То есть выполнение как таковое проходит в недрах расширения. Ядру в данном случае уже сваливают вызовы функций с параметрами.
Хитро блин!


UPD: 8 окт 2012

Новый билд на тему внедрения дампера куда поглубже. На сегодня снимаются все опкоды. Формируются данные в виде массива php
Теперь самое малое ужасное привинтить дизассеблер от xcache
Скрытое содержимое доступно для зарегистрированных пользователей!
 
Давайте посмотрим что будет если загрузить кешь а потом кубика.
zend_compile_file хукает кешь и переводит на zend_compile_file_t
кубик хукат zend_compile_file, который уже zend_compile_file_t на своюб функцию
Итог xcache не работает.
Если перевернуть наоборот то вывалится кубик.
 

Вышел xcache 3.0 RC1. Теперь работает как обычное расширение, что уже большой плюс. Значительно переработан препроцессор. Ну и много мелкого в багфиксе на сайте

Продолжаем с Sidxx55 разговаривать между собой.
Найдена проблема компиляции кеша под VС. Проблема закрлючасась в неккоректном формировании препроцессора, в частности неправильной отработки awg скриптов под виндой, вносятся соответствующие правки
 
Продолжаем с Sidxx55 разговаривать между собой.
Найдена проблема компиляции кеша под VС. Проблема закрлючасась в неккоректном формировании препроцессора, в частности неправильной отработки awg скриптов под виндой, вносятся соответствующие правки
 
Сборка xcache с кодовым названием x-lite
Отличия от оригинала
1) удален кешер
2) удален енкодер
3) удален декодер
4) удален coverage
5) удален ассемблер
6) препроцессор переведен в статику (сборка 5.3.19 TS) возможно будет работать и на более ранних версиях, в 5.3.16 не увидел особых различий в экзекуторе
В принципе осталось пара шагов до локализации диззассеблера кеша...
Осталось разобраться с парой тройкой файлов и решить что с ними и как, чтобы не мозолили глаза.
Ниже архив с исходниками и раширением


UPD: 19 окт 2012

И снова обновление. Решен вопрос совместимости с ioncube и другими енкодерами. Теперь равноправно работает с ioncube, но при попытке реверса зашифрованного скрипта вылетает с ошибкой (будем трассировать ошибку)

аттач обновился


Удалось вытащить шифрованный опкод и кубика
PHP:
Dumping sandboxed file
line => 0
opcode => UNDEF
op1_type => UNUSED
op2_type => UNUSED
result_type => UNUSED
op1 => UNUSED
op2 => UNUSED
result => UNUSED
-----------------------------------------------------------------------------
line => 2010775558
opcode => ZEND_NOP
op1_type =>
op2_type =>
result_type => CONST
op1 =>
op2 =>
result => [UNKNOWN]
-----------------------------------------------------------------------------
line => 2010775558
opcode => ZEND_NOP
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 3
opcode => ZEND_NOP
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 17
opcode => ZEND_UNDEFINED
op1_type =>
op2_type => CONST
result_type =>
op1 =>
op2 => [UNKNOWN]
result =>
-----------------------------------------------------------------------------
line => 4
opcode => ZEND_UNDEFINED
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 0
opcode => ZEND_DO_FCALL
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 201
opcode => ZEND_FETCH_CONSTANT
op1_type =>
op2_type => CONST
result_type =>
op1 =>
op2 => NULL
result =>
-----------------------------------------------------------------------------
line => 0
opcode => ZEND_IS_EQUAL
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 41153792
opcode => ZEND_IS_EQUAL
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 3
opcode => ZEND_NOP
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 0
opcode => ZEND_IS_EQUAL
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 1866690388
opcode => ZEND_GOTO
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 1315271791
opcode => ZEND_FETCH_OBJ_UNSET
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 0
opcode => ZEND_NOP
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 0
opcode => ZEND_NOP
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 17
opcode => ZEND_ADD
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 17
opcode => ZEND_TICKS
op1_type =>
op2_type => CONST
result_type =>
op1 =>
op2 => [UNKNOWN]
result =>
-----------------------------------------------------------------------------
line => 115
opcode => ZEND_ASSIGN_MUL
op1_type => CONST
op2_type =>
result_type =>
op1 => [UNKNOWN]
op2 =>
result =>
-----------------------------------------------------------------------------
line => 25
opcode => ZEND_NEW
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 41
opcode => ZEND_TICKS
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 0
opcode => ZEND_NOP
op1_type => VAR
op2_type => CONST
result_type =>
op1 => $16
op2 => [UNKNOWN]
result =>
-----------------------------------------------------------------------------
line => 0
opcode => ZEND_NOP
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 17
opcode => ZEND_TICKS
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 33
opcode => ZEND_NOP
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 0
opcode => ZEND_NOP
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 0
opcode => ZEND_NOP
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 2010775553
opcode => ZEND_ADD
op1_type =>
op2_type => CONST
result_type =>
op1 =>
op2 => [ARRAY]
result =>
-----------------------------------------------------------------------------
line => 25
opcode => ZEND_CASE
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 0
opcode => ZEND_NOP
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 17
opcode => ZEND_ISSET_ISEMPTY_DIM_OBJ
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 25
opcode => ZEND_ISSET_ISEMPTY_DIM_OBJ
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 41156136
opcode => ZEND_ASSIGN_MUL
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 2010775558
opcode => ZEND_NOP
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 0
opcode => ZEND_NOP
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 0
opcode => ZEND_IS_EQUAL
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 33584238
opcode => UNDEF
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 0
opcode => ZEND_NOP
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 2010775558
opcode => ZEND_NOP
op1_type =>
op2_type => CONST
result_type =>
op1 =>
op2 => [UNKNOWN]
result =>
-----------------------------------------------------------------------------
line => 2010775553
opcode => ZEND_IS_EQUAL
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 41156709
opcode => ZEND_IS_EQUAL
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 =>
result =>
-----------------------------------------------------------------------------
line => 8
opcode => ZEND_SR
op1_type => CONST
op2_type =>
result_type =>
op1 => NULL
op2 =>
result =>
-----------------------------------------------------------------------------
line => 0
opcode => ZEND_NOP
op1_type =>
op2_type =>
result_type =>
op1 =>
op2 => <?php
 
UNDEF OP:    255    1:U:1907660    2:U:43064200    >U:3672    ;0   
UNDEF OP:array(7) {
  ["opcode"]=>
  int(118)
  ["result"]=>
  array(1) {
    ["op_type"]=>
    int(41153416)
  }
  ["op1"]=>
  array(3) {
    ["op_type"]=>
    int(2)
    ["var"]=>
    int(77890724)
    ["EA.type"]=>
    int(41091186)
  }
  ["op2"]=>
  array(2) {
    ["op_type"]=>
    int(1)
    ["constant"]=>
    UNKNOWN:0
  }
  ["extended_value"]=>
  int(17)
  ["lineno"]=>
  int(17)
  ["line"]=>
  int(4)
}
Обратите внимание
UNDEF OP: 255 1:U:1907660 2:U:43064200 >U:3672 ;0
в самом конце опкод убийца :D

UPD: 20 окт 2012

255 опкод побежден
Для просмотра ссылки Войди или Зарегистрируйся

Просьба протестить от и до
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху