10-04-2011, 01:20 AM
Скрипт, который декодирует файлы клиента (RSA и gzip). Аналог l2encdec.
В интернете описания алгоритма не нашел, поэтому пришлось разбираться самому (плюс искать ключи). Ставил хуки на gmpz_powm и gmpz_export в libgmp-3, смотрел что передает и получает l2encdec.
В интернете описания алгоритма не нашел, поэтому пришлось разбираться самому (плюс искать ключи). Ставил хуки на gmpz_powm и gmpz_export в libgmp-3, смотрел что передает и получает l2encdec.
PHP код:
<?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);
?>