PDA

Просмотр полной версии : Разбор защиты на lineage.ru


Deadly
07.01.2014, 16:26
Не знаю на всех ли серверах у них одинаковая защита(думаю что да), конкретно смотрел на х10 новом сервере, админы не сильно заморачивались), защита разбита на 2 подпункта 1 - dll которая кодирует пакеты отправки приема и длл которая отслеживает память, (вызывается из той же длл Cliexd.dll), сегодня разберем только защиту начинающуюся на гейм сервере (которая со 2 пакета) защита идет так : "оригинальный пакет"> стандартная шифрация > накрутка сервера вот эту "накрутку" и разберем;)


1300C399 8B4D E8 MOV ECX,DWORD PTR SS:[EBP-0x18] переносит в ecx стек с 0)
1300C39C 83C1 01 ADD ECX,0x1 доб 1
1300C39F 894D E8 MOV DWORD PTR SS:[EBP-0x18],ECX закидываем в стек 1
1300C3A2 8B55 E8 MOV EDX,DWORD PTR SS:[EBP-0x18] переносим в edx 1
1300C3A5 3B55 10 CMP EDX,DWORD PTR SS:[EBP+0x10] сравниваем значение стека с edx(щетчик если равно выйдем из цикла)
1300C3A8 7D 41 JGE SHORT CliExt.1300C3EB переход при равно(выйдет из секции шифровки)
1300C3AA A1 28080313 MOV EAX,DWORD PTR DS:[0x13030828] перем в eax 1
1300C3AF 25 07000080 AND EAX,0x80000007 лог операция с eax и 2147483655(фактически округляет до 7 цифр(0-7)
1300C3B4 79 05 JNS SHORT CliExt.1300C3BB если рез операции отр переходим
1300C3B6 48 DEC EAX
1300C3B7 83C8 F8 OR EAX,0xFFFFFFF8
1300C3BA 40 INC EAX
1300C3BB C1E0 05 SHL EAX,0x5 лог сдвиг eax влево на 5(умножение на 2 в 5(32))
1300C3BE 8B4D E8 MOV ECX,DWORD PTR SS:[EBP-0x18] переносим в ecx значение из стека(1)
1300C3C1 81E1 1F000080 AND ECX,0x8000001F выполняем над ecx and(фактически округляем число до 32)
1300C3C7 79 05 JNS SHORT CliExt.1300C3CE
1300C3C9 49 DEC ECX
1300C3CA 83C9 E0 OR ECX,0xFFFFFFE0
1300C3CD 41 INC ECX
1300C3CE 0FB69408 30080>MOVZX EDX,BYTE PTR DS:[EAX+ECX+0x1303083> складывает ecx +eax + магическое число 318965808 и помещает его в edx(2 посл)
1300C3D6 8B45 08 MOV EAX,DWORD PTR SS:[EBP+0x8] помещает в еах адрес начала ключа
1300C3D9 0345 E8 ADD EAX,DWORD PTR SS:[EBP-0x18] помещаем в edx начало ключа
1300C3DC 0FB608 MOVZX ECX,BYTE PTR DS:[EAX] добавляем номер текущего байта шифровки
1300C3DF 31D1 XOR ECX,EDX хорит с edx
1300C3E1 8B55 08 MOV EDX,DWORD PTR SS:[EBP+0x8] перемеает в edx начальное значение ключа
1300C3E4 0355 E8 ADD EDX,DWORD PTR SS:[EBP-0x18] добавляет к edx текущий номер байта ключа
1300C3E7 880A MOV BYTE PTR DS:[EDX],CL переписывает его
1300C3E9 ^EB AE JMP SHORT CliExt.1300C399 на 27 пунктов вверх к следующему байту

зы где 1 имеется ввиду 1 байт ключа(2 по щету)

wimax
08.01.2014, 02:10
с чего вы взяли что идет накрутка шифрации а не ие замена?

Deadly
08.01.2014, 03:08
с чего вы взяли что идет накрутка шифрации а не ие замена?

посмотрел) замена идет только от логин сервера там да, даже вызов ws2 свой)

wimax
11.01.2014, 20:38
логин сервер использует свой алгоритм шифрации и я ищо не разу не встречал чтоб его меняли а вот гейм уже другой разговор там скорей всего замена шифрации

Deadly
11.01.2014, 23:17
интересно но не очень конечно могли бы и по солидней сделать) даже огг подцепил(на логин серве там есть шифрация причем не хилая с использованием сторонней программы(shild.bin) вот исходники с шарпа кто захочет тоже написать уже все разжовано)

foreach (string s in "47 78 E1 77 51 36 FB 68 03 E1 EA 2C CF E6 98 0C 4D AD C6 34 11 A4 2B 0F CA 86 A7 30 86 42 CA 7B 77 2A 41 66 3C D9 60 02 F9 76 75 AD 41 AD EE 2C 13 28 2D E8 14 BC F2 2C 1F 34 4C 25 51 DE EB 51 D0 BE C9 63 62 99 03 14 F5 B5 DB F2 61 81 C7 C7 63 07 58 76 15 47 1E F4 08 7B 23 7A 12 59 3E 3A 19 33 C3 CC E9 3C DD E7 56 B7 1C 41 9D 60 70 34 83 B9 39 4B 03 B8 8A 04 EB 67 4E 0D 77 E1 73 58 15 6A C7 24 8A E5 B8 72 88 7A 7B 07 E7 A7 FD 6D C0 98 08 03 53 EF E4 9E 39 E9 3A DB B7 0F 05 81 99 33 AF 1B 79 2B 1E 4A 00 E2 8A DA C0 28 53 14 70 E4 41 5A 04 31 9A B2 67 DE 91 14 99 DE 38 29 7D 3D 9F 7F 7E 03 63 B0 36 C2 1E 7A 2C 12 17 72 F1 C4 B0 3D 9C 29 E6 D5 F7 06 56 06 5E B9 14 6D A2 29 03 55 DC CF A5 90 AF CB 53 CC B2 02 B3 81 A7 4B 65 BA 2A EB CA 47 6D 0A C4 2E DB 6C 6F 1B".Split(' '))
{
Keycli[index] = Convert.ToByte(s, 16);
index++;
}
byte[] keys = { 0x58, 0xF0, 0xDD, 0xBF, 0x6E, 0x39, 0x86, 0xCC, 0xC8, 0x27, 0x93, 0x01, 0xA1, 0x6C, 0x31, 0x97 };
byte[] keyc = { 0x58, 0xF0, 0xDD, 0xBF, 0x6E, 0x39, 0x86, 0xCC, 0xC8, 0x27, 0x93, 0x01, 0xA1, 0x6C, 0x31, 0x97 };
byte[] keycc = { 0x58, 0xF0, 0xDD, 0xBF, 0x6E, 0x39, 0x86, 0xCC, 0xC8, 0x27, 0x93, 0x01, 0xA1, 0x6C, 0x31, 0x97 };
byte[] keyds = {0xC8, 0x27, 0x93, 0x01, 0xA1, 0x6C, 0x31, 0x97 };
byte[] keydc = {0xC8, 0x27, 0x93, 0x01, 0xA1, 0x6C, 0x31, 0x97 };
byte[] keydcc = { 0xC8, 0x27, 0x93, 0x01, 0xA1, 0x6C, 0x31, 0x97 };
int size;
int numpcksr = 0;
int numpckcl = 0;
int lensum = 0;
byte[] dsend = new byte[4];
Console.WriteLine("Все компоненты инициализированы запуск скрипта");
while (true)
{

while (nsgsin.DataAvailable)
{
nsgsin.Read(buf, 0, 2);
temp = (buf[0] + buf[1] * 256);

size = 0;
while (size != temp - 2) { size += nsgsin.Read(buf, size + 2, temp - size - 2); }
if (numpckcl == 0)
{
Console.WriteLine(BitConverter.ToString(buf, 2, temp - 2).Replace('-', ' '));
nsgsout.Write(buf, 0, temp);
numpckcl++;
continue;
}

BitConverter.GetBytes((UInt16)(temp + 4)).CopyTo(buf, 0);


/* for (int i = 2; i < temp; ++i)
{
buf[i] = Convert.ToByte(buf[i] ^ Keycli[((numpckcl % 8 * 32) + ((i - 2) % 32))]);
}*/

byte temp1 = 0;

for (int i = 2; i < temp; i++)
{
byte temp2 = buf[i];
buf[i] = Convert.ToByte((temp2 ^ (keycc[(i - 2) % 16]) ^ temp1));
temp1 = temp2;
}

Console.WriteLine(numpckcl);
if (buf[0] == 0xF)
{
buf[2] = 0x5; buf[3] = 0x3; buf[4] = 0; buf[5] = 0; buf[6] = 0; buf[7] = 0; buf[8] = 0;
buf[9] = 0; buf[10] = 0;

}

temp += 4;

Crypt_Lineage.CryptEnd(ref buf, temp - 6, numpckcl, ref lensum, dsend);



log.WriteLine();
log.WriteLine(numpckcl+"client");
log.WriteLine();
for (int i = 0; i < temp; i++)
{
log.Write(buf[i].ToString("x") + " ");

}
log.WriteLine();
log.WriteLine();



/*Console.WriteLine(BitConverter.ToString(buf, 2, temp - 2).Replace('-', ' '));*/
/*Console.WriteLine(BitConverter.ToString(keyc, 0, 16).Replace('-', ' '));*/
Console.WriteLine();

temp1 = 0;
for (int i = 2; i < temp; i++)
{
byte temp2 = buf[i];
buf[i] = Convert.ToByte((buf[i] ^ (keyc[(i - 2) % 16]) ^ temp1));
temp1 = buf[i];
}

for (int i = 2; i < temp; ++i)
{
buf[i] = Convert.ToByte(buf[i] ^ Keycli[((numpckcl % 8 * 32) + ((i - 2) % 32))]);
}
keydc = BitConverter.GetBytes(BitConverter.ToInt64(keydc, 0) + temp-2);
keydcc = BitConverter.GetBytes(BitConverter.ToInt64(keydcc, 0) + temp-6);
keydcc.CopyTo(keycc, 8);
keydc.CopyTo(keyc, 8);
nsgsout.Write(buf, 0, temp);
numpckcl++;
}
/////////////////////////////////////////////////////////////////////////////
Thread.Sleep(10);
while (nsgsout.DataAvailable)// отправка на клиент
{



size = nsgsout.Read(buf, 0, 2);

temp = (buf[0] + buf[1] * 256);
size = 0;

while (size != temp-2){size += nsgsout.Read(buf, size + 2, temp - size-2);}

if (numpcksr == 0)
{
for (int i = 4; i < 12; i++)
{
keys[i - 4] = buf[i];
}
nsgsin.Write(buf, 0, temp);
keys.CopyTo(keyc,0);
keys.CopyTo(keycc, 0);

numpcksr++;
continue;
}

byte temp1 = 0;
for (int i = 2; i < temp; i++)
{
byte temp2 = buf[i];
buf[i] = Convert.ToByte((temp2 ^ (keys[(i - 2) % 16]) ^ temp1));
temp1 = temp2;
}
///////////////////////////////////////////////

////////////////////////////////////////////////
/* log.WriteLine();
log.WriteLine(numpcksr);

for (int i = 0; i < temp; i++)
{
log.Write(buf[i].ToString("x") + " ");

}
log.WriteLine();
log.WriteLine();*/
// if (buf[2] == 0x7f) buf[2]=0x00;

Console.WriteLine("SRV PCK <<"+numpcksr);
Console.WriteLine(BitConverter.ToString(buf,2,temp-2).Replace('-', ' '));

Console.WriteLine();
temp1 = 0;
for (int i = 2; i < temp; i++)
{
byte temp2 = buf[i];
buf[i] = Convert.ToByte((buf[i] ^ (keys[(i - 2) % 16]) ^ temp1));
temp1 = buf[i];
}

keyds=BitConverter.GetBytes(BitConverter.ToInt64(k eyds, 0) + temp-2);
keyds.CopyTo(keys, 8);

nsgsin.Write(buf, 0, temp);
numpcksr++;

}

}




и еще на окончание(типо хеш функции к каждому пакету дописывается)


lensum++;
uint sumbyte;
if (lensum % 2 == 1) sumbyte = 0x98786756; else sumbyte = 0x13243546;
for (int i = 0; i < len; i++) sumbyte += data[i+2];

/*Console.WriteLine(BitConverter.ToString(BitConver ter.GetBytes(sumbyte)).Replace('-', ' '));*/

/*Console.WriteLine(BitConverter.ToString(BitConver ter.GetBytes(sumbyte)).Replace('-', ' '));*/
dsend = BitConverter.GetBytes(sumbyte);
/* Console.WriteLine("lensum: " + BitConverter.ToString(BitConverter.GetBytes(lensum )).Replace('-', ' '));*/
for (int i = 0; i < 4; i++)
{

dsend[i] += (byte)(0x4b);
/* Console.Write("dsend[i] += (0x4b): {0:X}", dsend[i]);*/
dsend[i] *= (byte)(len + lensum + i);
/* Console.WriteLine(" dsend[i] *= (byte)(len + lensum + i) {0:X} = {1:X}", len + lensum + i, dsend[i]);*/
}
/* Console.WriteLine("lensum+len "+BitConverter.ToString(BitConverter.GetBytes(lensu m + len)).Replace('-', ' '));*/
sumbyte = BitConverter.ToUInt32(dsend, 0) + (uint)(lensum + len);

lensum += len;
BitConverter.GetBytes(sumbyte).CopyTo(data, len + 2);
Console.WriteLine(BitConverter.ToString(data, 2, len+4).Replace('-', ' '));
Console.WriteLine("dsend " + BitConverter.ToString(BitConverter.GetBytes(sumbyt e)).Replace('-', ' '));

/* Console.WriteLine(BitConverter.ToString(data, 2, len + 4).Replace('-', ' '));*/


кому надо сделают думаю

St1mul
12.01.2014, 22:01
Я раньше тоже исходники смотрел, только ссрЕксперт, который обычно на хф5 стоит, там по аналогии есть массив. Я пытался вручную проделать все это, однако вот оказалось, что массив для каждого сервера разный

Deadly
13.01.2014, 09:30
Я раньше тоже исходники смотрел, только ссрЕксперт, который обычно на хф5 стоит, там по аналогии есть массив. Я пытался вручную проделать все это, однако вот оказалось, что массив для каждого сервера разный

Конечно разный, это единственное что меняется, в чем сделать, чтобы он из памяти длл сам подгружался), адрес у него всегда одинаковый.

Opoi4
06.02.2014, 21:59
в итоге есть рабочий l2phx под этот сервер?)

Magistic
10.06.2014, 13:14
Deadly, я так понимаю ты защиту на этом сервере обошел? или у тебя только общие наброски?

На днях начал ковырять сервер Arion x5, пока просматриваю логин сервер, и из нестандартных пакетов есть только RequestAuthLogin (0x00), там после RSA ключа идет еще 36 байт данных, и плюс в конце пакета дописывается дополнительная информация (какие-то хэши, название компа, имя пользователя, системная папка).
Самое интересное, что почему-то и RSA, и BF ключи от сервера приходят одинаковые.

Deadly
15.06.2014, 14:30
привет, нет уже данный способ не работает, был выложен полноценный бот, работал долго около месяцев потом обновили защиту, время не было смотреть, что там да и желания тратить время за бесплатно( сейчас есть бот под averia.ws

Magistic
16.07.2014, 10:59
Deadly, если это не великий секрет, можешь вкратце рассказать, чем занимался shield.exe? Потому что я от него почти никакой сетевой активности не вижу (только проверку файлов делает), а вот сервак как-то проверяет его работоспособность.

Altar123
05.08.2014, 21:09
Deadly, привет, можно с тобой связвть в скайпе или по почте для расшифрации сервера л2, заплачу:D

Magistic
11.08.2014, 16:17
Deadly, привет, можно с тобой связвть в скайпе или по почте для расшифрации сервера л2, заплачу:DИ сколько народ готов платить за обход защиты? :)