[SCRIPT] Декодирование файлов клиента (аналог l2encdec)

Тема в разделе "Веб скрипты (WEB)", создана пользователем root, 1 окт 2014.

  1. root

    root Administrator Команда форума Administrator Moderator Developers Team

    Регистрация:
    23 авг 2014
    Сообщения:
    254
    Симпатии:
    58
    Баллы:
    11
    Скрипт, который декодирует файлы клиента (RSA и gzip). Аналог l2encdec.
    В интернете описания алгоритма не нашел, поэтому пришлось разбираться самому (плюс искать ключи). Ставил хуки на gmpz_powm и gmpz_export в libgmp-3, смотрел что передает и получает l2encdec.

    Не уверен, что правильно выбрал раздел. Возможно, надо было опубликовать в разделе "клиенты".
    Код:
    <?php 
    
    
    /** 
     * L2 file decoder (4 october 2011). 
     * @author Hint aka Ilya 
     */ 
    
    
    function decode($filename, $original = true) 
    { 
      $file = @file_get_contents($filename); 
      if (!$file) return false; 
      if (strlen($file) < 28 + 128) return false; 
      $head = mb_convert_encoding(substr($file, 0, 28), 'UTF-8', 'UTF-16LE'); 
      if ($head != 'Lineage2Ver413') return false; 
       
      $blocks = intval((strlen($file) - 28) / 128); 
      if ($blocks < 1) return false; 
       
      $size = $blocks * 128; 
    
    
      $file = substr($file, 28, $size); 
       
      if ($original) 
      { 
        $s = base64_decode('l985hHLd9zfvCgzRfo0XLw/vFmGjiorh1ugpvBxuTDz8GSkt2p75AXXkbnOUoYhQtkF9A75u6idNPtHd5bXXvecswKC3HQNghlVjOIF5OgLJpn2e8rRet8CNS+MpCDzkUOaPeGe2dJMU1AUR0JvFdEVRuqhqidw4Ej3BZo/XLYM='); 
        $key = gmp_init('0x' . bin2hex($s)); 
        $exp = gmp_init('0x35'); 
      } 
      else 
      { 
        $s = base64_decode('dbTW3lwBZUQGihrPElhp9D0uCfxVuLHiiVVtr5uHV2NVk0RiiLNlPaHOkch7saXBjxYyNJXFXX1ywIkKg/ab/R/ZQ06xwC8+Rnnt+kMwkxkHASnCZ8hWBNh7tluuIF3jcHrx0hCIgau1Z8Oz0GmuZ8OkxqOqk9JkE9TGYJSuIDk='); 
        $key = gmp_init('0x' . bin2hex($s)); 
        $exp = gmp_init('0x1d'); 
      } 
       
      $data = ''; 
      for ($i = 0; $i < $blocks; ++$i) 
      { 
        $block = substr($file, $i * 128, 128); 
        $res = gmp_powm('0x' . bin2hex($block), $exp, $key); 
        if (!is_resource($res)) return false; 
        $hex = gmp_strval($res, 16); 
        if (strlen($hex) != 250) return false; 
        $s = pack('H*' , $hex); 
         
        $size = ord($s[0]); 
        if ($size > strlen($s) - 1) return false; 
         
        if ($size != 0x7c) 
        { 
          $p = strlen($s) - $size; 
          while ($p > 2 && $s[$p - 1] != "\0") --$p; 
          $s = substr($s, $p, $size); 
        } 
        else 
        { 
          $s = substr($s, -$size); 
        }     
        $data .= $s; 
      } 
    
    
      $a = unpack('L', $data); 
      if (!is_array($a) || !isset($a[1])) return false; 
       
      $size = intval($a[1]); 
      $data = substr($data, 4); 
      $result = gzuncompress($data); 
      if (strlen($result) != $size) return false; 
       
      return $result; 
    } 
    
    
    // Example 
    $s = decode('l2.ini', true); 
    if ($s === false) die('Error!'); 
    file_put_contents('dec-l2.ini', $s); 
    ?>