PDA

Просмотр полной версии : Изучение протокола игры


FreePVP)))
29.09.2012, 22:33
Доброго времени суток.
Из названия темы понятно, что речь пойдет о разработке OOG бота
1. Настройка сниффера
Прежде чем начать изучать трафик, надо видеть его структуру
Для этого будем использовать сниффер, перехватчик пакетов
Сниффер - Pandora's Box(сниффер на основе прокси-сервера)
Прокси-клиент - Любой, но я использую Proxifier
Скачать Pandora's Box ([Ссылки могут видеть только зарегистрированные и активированные пользователи]) | VT ([Ссылки могут видеть только зарегистрированные и активированные пользователи] 7e58f1f484adb7/analysis/1348921223/)


Options -> Proxy Settings

Add
Address = 127.0.0.1
Port = 30000 (по умолчанию используется в пандоре)
Protocol = SOCKS Version 4
Ok
Отмечаем галочкой созданную настройку

[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Options -> Proxification Rules

Выбираем второй кружочек
Add
Название выбираем удобное для вас.
Добавляем Application (указываем путь к elementclient.exe)
Port Range = 29000
Ok
Отмечаем галочкой созданную настройку

[Ссылки могут видеть только зарегистрированные и активированные пользователи]
Процесс

Запускаем Pandora's Box
Включаем Proxy
Запускаем PW



2. Структура пакета
Все пакеты отправляются в формате:

CUInt32 Type;
CUInt32 Length;
BYTE[Length] Buffer;

Type - тип пакета(например: 0x01, 0x03)
Length - длина буфера с данными
Buffer - данные(например логин и хеш логина с паролем)

internal uint ReadCUInt32()
{
byte code = ReadByte();
switch (code & 0xE0)
{
case 0xE0:
return BitConverter.ToUInt32(ReadArray(4, true), 0);
case 0xC0:
byte[] bt = ReadArray(3, true);
return BitConverter.ToUInt32(new byte[] { bt[2], bt[1], bt[0], code }, 0) & 0x1FFFFFFF;
case 0x80:
case 0xA0:
return (uint)(BitConverter.ToUInt16(new byte[] { ReadByte(), code }, 0) & 0x3FFF);
}
return (uint)code;
}

internal DataStream WriteCUInt32(uint value)
{
if (value <= 0x7F)
{
WriteByte((byte)value);
return this;
}
if (value <= 0x3FFF)
{
byte[] bt = BitConverter.GetBytes((ushort)(value + 0x8000));
WriteArray(bt, true);
return this;
}
if (value <= 0x1FFFFFFF)
{
byte[] bt = BitConverter.GetBytes((uint)(value + 0xC0000000));
WriteArray(bt, true);
return this;
}
if (value <= 0xFFFFFFFF)
{
List<byte> bt = new List<byte>();
bt.Add(0xE0);
byte[] arrbt = BitConverter.GetBytes((uint)value);
bt.AddRange(arrbt);
WriteArray(bt.ToArray(), true);
return this;
}
return this;
}

3. "Упаковка, шифрация, создание ключей" или "Входим на аккаунт"
Как известно, все серверные пакеты после 0x02 S2C(Server to Client) шифруются и пакуются, а клиентские пакеты только шифруются
Для шифрации используется алгоритм RC4 ([Ссылки могут видеть только зарегистрированные и активированные пользователи])
Для упаковки - MPPC ([Ссылки могут видеть только зарегистрированные и активированные пользователи])

using System;

namespace OOGLibrary.Cryptography
{
class RC4
{
public RC4()
{
for (int i = 0; i < 256; i++)
m_Table[i] = Convert.ToByte(i);
m_Shift1 = 0;
m_Shift2 = 0;
}

public void Shuffle(byte[] Key)
{
byte Shift = 0;
for (int i = 0; i < 256; i++)
{
byte A = Key[i % 16];
Shift += (byte)(A + m_Table[i]);

byte B = m_Table[i];
m_Table[i] = m_Table[Shift];
m_Table[Shift] = B;
}
}

public byte Encode(byte InPacket)
{
m_Shift1++;
byte A = m_Table[m_Shift1];
m_Shift2 += A;
byte B = m_Table[m_Shift2];
m_Table[m_Shift2] = A;
m_Table[m_Shift1] = B;
byte C = (byte)(A + B);
byte D = m_Table[C];
return (byte)(InPacket ^ D);
}

private byte m_Shift1;
private byte m_Shift2;
private byte[] m_Table = new byte[256];
}
}


using System;
using System.Collections.Generic;

namespace OOGLibrary.Cryptography
{
class Unpack
{
UInt32 m_Code1;
UInt32 m_Code2;
UInt32 m_Stage;
UInt32 m_Shift;
byte m_PackedOffset;
readonly List<byte> m_Packed = new List<byte>();
readonly List<byte> m_Unpacked = new List<byte>();


public Unpack()
{
m_PackedOffset = 0;
m_Stage = 0;
}

bool HasBits(UInt32 Count)
{
return (m_Packed.Count * 8 - m_PackedOffset) >= Count;
}

public List<byte> AddByte(byte InB)
{
m_Packed.Add(InB);
var UnpackedChunk = new List<byte>();

for (; ; )
{
if (m_Stage == 0)
{
if (HasBits(4))
{
if (GetPackedBits(1) == 0)
{
// 0-xxxxxxx
m_Code1 = 1;
m_Stage = 1;
continue;
}
else
{
if (GetPackedBits(1) == 0)
{
// 10-xxxxxxx
m_Code1 = 2;
m_Stage = 1;
continue;
}
else
{
if (GetPackedBits(1) == 0)
{
// 110-xxxxxxxxxxxxx-*
m_Code1 = 3;
m_Stage = 1;
continue;
}
else
{
if (GetPackedBits(1) == 0)
{
// 1110-xxxxxxxx-*
m_Code1 = 4;
m_Stage = 1;
continue;
}
else
{
// 1111-xxxxxx-*
m_Code1 = 5;
m_Stage = 1;
continue;
}
}
}
}
}
else
break;
}
else if (m_Stage == 1)
{
if (m_Code1 == 1)
{
if (HasBits(7))
{
byte OutB = (byte)(GetPackedBits(7));
UnpackedChunk.Add(OutB);
m_Unpacked.Add(OutB);
m_Stage = 0;
continue;
}
else
break;
}
else if (m_Code1 == 2)
{
if (HasBits(7))
{
byte OutB = (byte)((GetPackedBits(7)) | 0x80);
UnpackedChunk.Add(OutB);
m_Unpacked.Add(OutB);
m_Stage = 0;
continue;
}
else
break;
}
else if (m_Code1 == 3)
{
if (HasBits(13))
{
m_Shift = GetPackedBits(13) + 0x140;
m_Stage = 2;
continue;
}
else
break;
}
else if (m_Code1 == 4)
{
if (HasBits(8))
{
m_Shift = GetPackedBits(8) + 0x40;
m_Stage = 2;
continue;
}
else
break;
}
else if (m_Code1 == 5)
{
if (HasBits(6))
{
m_Shift = GetPackedBits(6);
m_Stage = 2;
continue;
}
else
break;
}
}
else if (m_Stage == 2)
{
if (m_Shift == 0)
{
// Guess !!!
if (m_PackedOffset != 0)
{
m_PackedOffset = 0;
//m_Packed.PopFront();
m_Packed.RemoveAt(0);
}
m_Stage = 0;
continue;
}
m_Code2 = 0;
m_Stage = 3;
continue;
}
else if (m_Stage == 3)
{
if (HasBits(1))
{
if (GetPackedBits(1) == 0)
{
m_Stage = 4;
continue;
}
else
{
m_Code2++;
continue;
}
}
else
break;
}
else if (m_Stage == 4)
{
UInt32 CopySize = 0;
if (m_Code2 == 0)
CopySize = 3;
else
{
UInt32 Sz = m_Code2 + 1;
if (HasBits(Sz))
CopySize = GetPackedBits(Sz) + (UInt32)(1 << ((Int32)Sz));
else
break;
}

Copy(m_Shift, CopySize, ref UnpackedChunk);
m_Stage = 0;
continue;
}
}
return UnpackedChunk;
}








void Notify(string Msg)
{
//Log.L(Msg);
}

void Copy(UInt32 Shift, UInt32 Size, ref List<byte> UnpackedChunk)
{
for (UInt32 i = 0; i < Size; i++)
{
var PIndex = m_Unpacked.Count - Shift;
if (PIndex < 0)
Notify("Unpack error");
else
{
byte B = m_Unpacked[(Int32)PIndex];
m_Unpacked.Add(B);
UnpackedChunk.Add(B);
}
}
}

UInt32 GetPackedBits(UInt32 BitCount)
{
if (BitCount > 16)
return 0;

if (!HasBits(BitCount))
Notify("Unpack bit stream overflow");

UInt32 AlBitCount = BitCount + m_PackedOffset;
UInt32 AlByteCount = (AlBitCount + 7) / 8;

UInt32 V = 0;
for (UInt32 i = 0; i < AlByteCount; i++)
V |= (UInt32)(m_Packed[(Int32)i]) << (Int32)(24 - i * 8);
V <<= m_PackedOffset;
V >>= (Int32)(32 - BitCount);

m_PackedOffset += (byte)BitCount;
Int32 FreeBytes = m_PackedOffset / 8;
if (FreeBytes != 0)
{
//m_Packed.PopFront(FreeBytes);
m_Packed.RemoveRange(0, FreeBytes);
}
m_PackedOffset %= 8;

return V;
}
}

}

Теперь по порядку

S2C <- 0x01 ServerInfo
C2S -> 0x03 LogginAnnounce
S2C <- 0x02 SMKey
C2S -> 0x02 CMKey



byte KeyLen;
byte[KeyLen] Key;
byte AuthType;
byte[4] ServerVersion;
byte Bonus;

// Интересный факт: в ключе (Key) хранятся данные о бонусах и нагрузке на сервер
Key - ключ, который мы будем использовать для генерации хеша



byte LoginLength;
AString Login;
byte HashLen;
byte[HashLen] Hash;
byte 0x00;

Login - Логин, как вы уже поняли
Hash - хеш в формате HMACMD5(Key){MD5{login+password}};
Hash и Login так же используются при создании ключей RC4



byte EncHashLen;
byte[EncKeyLen] EncHash;
byte Force;

0x02 SMKey - тот самый пакет, после которого клиент начинает шифровать трафик, а сервер паковать алгоритмом MPPC и шифровать
EncHash - хеш, который нужен для создания ключа для RC4, который в свою очередь используется для шифрации трафика
Этот ключ генерируется следующим образом - HMACMD5(Login){Hash + EncHash}
Hash - тот самый хеш из 0x03 LogginAnnounce



byte DecHashLen;
byte[DecKeyLen] DecHash;
byte Force;

DecHash - Рандомный хеш, с помощью которого, как я уже описывал чуть выше, генерируется ключ для RC4, которым клиент будет расшифровывать трафик
Force - флаг(Усиленный вход)
Этот пакет, как и все последующие, шифруется


Задавайте вопросы, пишите замечания

Скачать Pandora's Box ([Ссылки могут видеть только зарегистрированные и активированные пользователи]) | VT ([Ссылки могут видеть только зарегистрированные и активированные пользователи] 7e58f1f484adb7/analysis/1348921223/)
Скачать PacketDeclaration.xml ([Ссылки могут видеть только зарегистрированные и активированные пользователи])

7_ON
02.10.2012, 12:05
:question:
Options -> Proxy SettingsAdd
Address = 127.0.0.1
Port = 30000 (по умолчанию используется в пандоре)
Protocol = SOCKS Version 4
Ok
Отмечаем галочкой созданную настройку

38045

krukovis
02.10.2012, 15:21
7_ON, это вопрос или дополнение или... ?

FreePVP)))
02.10.2012, 21:11
7_ON, не трогайте настройки пандоры, если не знаете, что они значат

7_ON
03.10.2012, 17:36
Может я чего то не понимаю... Скачал архив с Pandora's Box, открываю гайд по ее настройке и собственно вопрос: где те кнопки и пункты меню? Или эта не та версия или ... Можно поподробнее описать настройку Pandora's Box

FreePVP)))
03.10.2012, 19:01
7_ON,
[Ссылки могут видеть только зарегистрированные и активированные пользователи]

gudvin7771
05.10.2012, 14:23
Поясните, что надо отправлять в пакете C02? Я его формирую так: беру EncHash из S02, HMACMD5 хеш из C03, логин. На их основе делаю RC4 ключ = HMACMD5(хеш из С03 + EncHash).ComputeHash(Login). Затем пишу в пакет опкод 0х02, длину пакета, длину ключа, полученный RC4 ключ и 0х00. Отправляю и сервер молчит. Слышал, что нужно уже сам пакет C02 зашифровать, так вот, его шифровать с помощью RC4? И на основе какого ключа тогда? И что именно шифровать - чисто пакет, или все полностью вместе с опкодом/длиной пакета и т.д.

FreePVP)))
05.10.2012, 16:54
gudvin7771, [Ссылки могут видеть только зарегистрированные и активированные пользователи] 1%86%D0%B8%D0%B8.194/
В будущем юзайте поиск

gudvin7771
05.10.2012, 23:45
И все же, нагуглился как следует, пвлаб изучил все что можно было, везде только "угадай сам". Ну скажите, что я делаю не так при формировании C0x02:

class Packet_C02
{
public static byte[] Create(byte[] S01, byte[] S02, string log, string pass)
{
byte[] bLogin = Encoding.ASCII.GetBytes(log);
byte[] bPass = Encoding.ASCII.GetBytes(pass);
byte[] EncHash = Bytes.ReadBytes(S02, 3, 16);
byte[] key_from_S01 = Bytes.ReadBytes(S01, 3, 16);
byte[] bLogPass = Bytes.ConcatBytes(bLogin, bPass); // функция аналог встроенной конкатинации, 100% рабочая.
MD5 md5 = MD5.Create();
byte[] hashHMAC = new HMACMD5(md5.ComputeHash(bLogPass)).ComputeHash(key _from_S01);
md5.Clear();
byte[] RC4_key = new HMACMD5(Bytes.ConcatBytes(hashHMAC, EncHash)).ComputeHash(bLogin);
RC4 encoder = new RC4(EncHash); // RC4 алгоритм 100% рабочий.
byte[] itog = encoder.Encode(RC4_key);
List<byte> result = new List<byte>();
result.AddRange(new byte[] { 0x02, (byte)(2 + itog.Length), (byte)(itog.Length) });
result.AddRange(itog);
byte[] buf = new byte[1];
buf[0] = 0x00;
result.AddRange(buf);
return result.ToArray();
}

FreePVP)))
06.10.2012, 00:13
Вот мой старый класс для генерации ключей
using System.Text;
using System.Security.Cryptography;

namespace OOGLibrary.Cryptography
{
class MD5Hash
{
byte[] Hash = new byte[16];
byte[] Login = new byte[16];
public byte[] GetHash(string login, string password, byte[] key)
{
byte[] loginBytes = Encoding.ASCII.GetBytes(login);
byte[] pwdBytes = Encoding.ASCII.GetBytes(password);
Login = loginBytes;
MD5 md = MD5.Create();
byte[] loginWithPasswordBytes = new byte[loginBytes.Length + pwdBytes.Length];
for (int i = 0; i < loginBytes.Length; i++)
loginWithPasswordBytes[i] = loginBytes[i];
for (int i = 0; i < pwdBytes.Length; i++)
loginWithPasswordBytes[i + loginBytes.Length] = pwdBytes[i];
byte[] hash = new HMACMD5(md.ComputeHash(loginWithPasswordBytes)).Co mputeHash(key);
Hash = hash;
return hash;
}
public byte[] GetKey(byte[] key)
{
byte[] nhash = new byte[key.Length + Hash.Length];
for (int i = 0; i < Hash.Length; i++) nhash[i] = Hash[i];
for (int i = 0; i < key.Length; i++) nhash[i + Hash.Length] = key[i];

byte[] hash = new HMACMD5(Login).ComputeHash(nhash);
return hash;
}
}
}

С02
using System;
using System.Collections.Generic;
using System.Text;

namespace OOGLibrary.IO.PacketBase.Client
{
public class CMKeyC02 : DataStream, IClientPacket
{
internal byte[] ServerKey { get; private set; }
internal byte[] ClientKey { get; private set; }
public bool Force { get; private set; }
public CMKeyC02(Server.SMKeyS02 key, bool force)
{
ServerKey = key.Key;
ClientKey = new byte[16]; new Random().NextBytes(ClientKey);
Force = force;
}
public DataStream Serialize()
{
Type = 0x02;
WriteData(ClientKey);
Write(Force);
return this;
}
}
}

Создание классов RC4
CMKeyC02 key = (CMKeyC02)ds;
Crypt.CreateEnc(md5.GetKey(key.ServerKey));
Crypt.CreateDec(md5.GetKey(key.ClientKey));

Sinyss
10.10.2012, 01:19
Вот мой старый класс для генерации ключей
После обновления поменялась схема авторизации, старый алгоритм больше не работает....

FreePVP)))
10.10.2012, 07:28
Sinyss, что там за обновление такое/horror
Добавились всего 5 байт, а алгоритмы те же

Nek1t
10.10.2012, 07:47
FreePVP))), можно узнать, что за класс у вас такой DataStream? Это аналог вортовского CPWPacketStream или же что-то другое?

FreePVP)))
10.10.2012, 15:39
Nek1t, CPWPacket, не?

Nek1t
10.10.2012, 15:41
Nek1t, CPWPacket, не?

Хм. И правда. Сразу не приметил.

Jok3r666
12.10.2012, 15:11
Sinyss, что там за обновление такое/horror
Добавились всего 5 байт, а алгоритмы те же

кто нить разобрался что за 5 байт?
У меня всегда 00 ff ff ff ff

--------------------------

Еще вопрос:
Подскажите пожалуйста
Вот я получаю ключ в пакете SM 0x02
Далее я должен послать серверу CM 0x02 в зашифрованом RC4 виде.
Подойдет любая реализация RC4?

Jok3r666
20.10.2012, 12:14
Разобрался.

7_ON
27.10.2012, 13:54
Кто нибудь подскажет в чем может быть дело?
Сервер на мой пакет 0x02(cm_key) отвечает 0x04(cm_loginsuccess), т.е. с ним все нормально. Пакет 0x04 расшифровываю серверным ключиком, распаковываю, данные со снифером (Pandora Box) сходятся. Т.е. формат получаю такой:

Opcode Byte //Опкод 0x04
PacketLen Byte //Длина пакета в байтах
AccountKey dword (4 bytes) //Идентификатор аккаунта
Далее неизвестные данные

Выдергиваю этот AccountKey, формирую 0x52, шифрую его RC4 тем же ключом, что и шифровал пакет для отправки 0x02(cm_key), но вот сервер на него не отвечает(
RC4 enc = new RC4(Connection.ClientKey);
List<byte> result = enc.Encode(send, send.Count);
Вот в чем вопрос, для шифрования клиентских пакетов после 0x02(cm_key) используется тот же ключ, что и для 0x02 (cm_key) или тут что то другое?

Разобрался, Спасибо FreePVP)))

AHTOLLlKA
11.12.2012, 21:26
поделитесь MPPC на делфях ^^

vogel
12.12.2012, 22:38
Сам напиши

tianddu
04.03.2013, 12:57
Вот в чем вопрос, для шифрования клиентских пакетов после 0x02(cm_key) используется тот же ключ, что и для 0x02 (cm_key) или тут что то другое?

Разобрался, Спасибо FreePVP)))
мне вот тоже не понятно, CMKey и SMKey содежат ключи, для шифрования, они задаются только один раз при логине? и еще вопрос про
DecHash - Рандомный хеш, с помощью которого, как я уже описывал чуть выше, генерируется ключ для RC4, которым клиент будет расшифровывать трафик
совсем рандомный хоть все нули?/okay

tianddu
17.04.2013, 18:16
List<byte> Send2 = new List<byte>();
byte[] EncHash = new byte[0x10];
for (int i = 0; i < 0x10; i++)
EncHash[i] = buf[i + 3];
RC4Key = RC4_key(loginbt, hash, EncHash);
byte[] DecHash = new byte[0x10];
Random r = new Random();
for (int i = 0; i < DecHash.Length; i++)
DecHash[i] = Convert.ToByte(r.Next(0, 255));
Send2.Add(0x12);
Send2.AddRange(DecHash);
Send2.Insert(0, (byte)Send2.Count);
Send2.Insert(0, 0x02);

RC4_Testing.RC4 encoder = new RC4_Testing.RC4(RC4Key);
byte[] result = encoder.Encode(Send2.ToArray(), Send2.ToArray().Length);

/*RC4_Testing.RC4 decoder = new RC4_Testing.RC4(key);
byte[] decryptedBytes = decoder.Decode(result, result.Length);
string decryptedString = ASCIIEncoding.ASCII.GetString(decryptedBytes);*/

skt.Send(result);
continue;
формируется пакет но почему то пандора не показывает что пакет отправлен...

CSharp
22.04.2013, 19:26
Вопрос по распаковке и расшифровке: сначала расшифровка, потом распаковка? Распаковывать нужно только само тело пакета, не трогая 1 и 2 байты? И запаковывать также только тело, а зашифровывать все целиком? И почему при использовании алгоритма MPPC вылетает исключение выхода за границы массива? Даже начинает казаться, что оба варианта MPPC в паблике которые, имеют намеренные ошибки, чтобы ничего не работало специально. И я бы сам написал MPPC по стандарту RFC, но ведь в пв "немного измененная" версия, и ведь хрен поймешь, где и насколько сильно он изменен.

N00bSa1b0t
22.04.2013, 21:42
сначала расшифровка, потом распаковка
Именно.

Распаковывать нужно только само тело пакета, не трогая 1 и 2 байты
Расшифровка и распаковка идет всего трафика полностью.

И запаковывать также только тело, а зашифровывать все целиком
Запаковывать ничего не надо. Трафик от клиента лишь зашифрован. Да, шифруем все целиком.

оба варианта MPPC в паблике которые, имеют намеренные ошибки
Бред. Код в этой теме почти рабочий (за исключением вроде как неверного пакета входа). Реализация MPPC и RC4 рабочие.

Единственно что - MPPC в этой теме имеет утечку памяти, но это не так критично)

CSharp
22.04.2013, 21:59
Так, ладно, с MPPC разобрался, спасибо. Один вопросик - что за байты после основного пакета? Например у того же 0х4 в конце FF FF FF FF 00 00 00 00 00 00 00 00 и еще 2-5 байтов рандомных, хотя в пандоре этот рандомный конец не отображается. Это мусор?

Добавлено через 53 минуты

Единственно что - MPPC в этой теме имеет утечку памяти, но это не так критично)

Откуда утечка? В данном коде MPPC же нет неуправляемого кода, сборщик мусора сам все чистит, это же C#.

N00bSa1b0t
24.04.2013, 12:05
основного пакета
А что такое основной пакет?)

Откуда утечка? В данном коде MPPC же нет неуправляемого кода, сборщик мусора сам все чистит, это же C#.
Если посмотреть код MPPC, то видно что в список m_Unpacked идет добавление байт, однако никогда нет удаления. Соответственно, чем больше работает программа, тем больше место в памяти он отожрет :)

CSharp
24.04.2013, 17:50
По поводу буфера MPPC. Я обнаружил, что пакеты должны распаковываться в строгой последовательности друг за другом по мере поступления, ибо учитывается значение буфера. Он имеет размер 8192 байта. Но ведь весь трафик игры не 8 кб, тогда в каких случая буфер нужно сбрасывать?

Kitsune
24.04.2013, 20:17
CSharp, буфер 8кб, значит надо оставлять последние 8кб.

wajskopf
26.07.2013, 01:27
Подскажите структуру пакета 0x52. А то сервер мне в ответ молчит.
Вот этот вариант правильный?
[ 1] 52 // тип
[ 1] 00 // размер
[ 4] xx xx xx xx // Account ID
[ 4] 00 00 00 00 // Хз что, но обычно нули
[ 4] 00 00 00 01 // Номер слота (начиная с нуля)

Smertig
26.07.2013, 03:29
[ 1] 52 // тип
[ 1] 00 // размер
[ 4] xx xx xx xx // Account ID
[ 4] 00 00 00 00 // Хз что, но обычно нули
[ 4] 00 00 00 01 // Номер слота (начиная с нуля)
Тип 52, размер 0С, дальше айди акка 4 байта и 8 нулей. В последующих пакетах меняется только номер слота (последняя цифра пакета)
520CXXXXXXXX00000000

P.S. Когда я запоролся на этом пакете, оказалось, что неправильная реализация RC4 была, которая не учитывала предыдущие расшифровки. Грубо говоря:
X = RC4_Encode(123456)
Y = RC4_Encode(123456)
X не должен быть равен Y! (при последовательной расшифровке)

wajskopf
30.07.2013, 09:31
Как производится вызов RC4 из первого поста?
Как-то так?

$rc = new RC4(); //создание нового объекта
$rc->Shuffle($key);//передача ключа объекту

for ($i=0; $i<count($to_encode); $i++)//дешифровка последовательно каждого байта
{
$res []= $rc->Encode($to_encode[$i]);
}

Алгоритм правильный?

yurastelsfish
12.08.2013, 14:13
Хотелось бы увидеть пример правильного шифрования пакетов для сервера( ну и если можно то и расшифровки).
Или хотя бы отправки 0х02 C2S (c той же правильной шифровкой).

wajskopf
12.08.2013, 18:21
Хотелось бы увидеть пример правильного шифрования пакетов для сервера( ну и если можно то и расшифровки).
Или хотя бы отправки 0х02 C2S (c той же правильной шифровкой).
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
уже писали...

wajskopf
27.12.2013, 19:28
Помогите с переводом функции из MPPC на аутоит. Где ошибки могут быть? Меня смущает указатель ref List<byte> UnpackedChunk


Func Copy ($Shift, $Size, $UnpackedChunk) ;void Copy(UInt32 Shift, UInt32 Size, ref List<byte> UnpackedChunk)
For $i = 0 To $Size - 1 Step 1 ;for (UInt32 i = 0; i < Size; i++)
$PIndex = (StringLen($m_Unpacked)/2) - $Shift ;var PIndex = m_Unpacked.Count - Shift;
If $PIndex < 0 Then ;if (PIndex < 0)
MsgBox(64, "","Unpack error") ;Notify("Unpack error");
Else

$B = StringMid($m_Unpacked, Int(($PIndex * 2) - 1), 2) ;byte B = m_Unpacked[(Int32)PIndex];
$m_Unpacked &= $B ;m_Unpacked.Add(B);
$UnpackedChunk &= $B ;UnpackedChunk.Add(B);
EndIf
Next
EndFunc

ToRcH2565
28.12.2013, 17:31
Меня смущает указатель ref List<byte> UnpackedChunk
Это не указатель) а передача обьекта по ссылке.. т.е. в функцию передается ссылка на обьект, и при попытке записать будет идти запись в переданный обьект а не в его локальную копию(передача по значению).

wajskopf
04.01.2014, 10:46
Подскажите, как можно организовать проверку модулей MPPC и RC4. С виду все правильно работает. Начальные пакеты расшифровывает и распаковывает, но в ответ на 0x52 приходит всегда разный достаточно объемный пакет (не 0х8F как должно быть). Этот вот пакет при распаковке всегда выдает ошибку "MsgBox(16, "Error", "Unpack error")" в функции Copy из MPPC. Вот и не могу понять, что именно не правильно работает какой-либо из модулей, или пакет не правильно отправляю. Хотя, повторюсь, с виду все правильно...

ToRcH2565
05.01.2014, 16:55
RC4
Взять эталонный и проверить) удостоверится что в нем ошибки нет и после ковырять где же у вас в MPPC ошибка.
могу дать 2 файла, сжатые данные и не сжатые. делал по просьбе пишущих MPPC.... там около 8кб разархивированых данных. вход в мир есть вроде.

Vampire2015
12.09.2015, 13:52
Пробую разобраться с ООГ и хочу спросить об этом:

DecHash - Рандомный хеш, с помощью которого, как я уже описывал чуть выше, генерируется ключ для RC4, которым клиент будет расшифровывать трафик
Force - флаг(Усиленный вход)
Этот пакет, как и все последующие, шифруется
Если все последующие пакеты шифруются, то как их "читает" Пандора?
Ведь Она без всякой расшифровки корректно отображает данные

N00bSa1b0t
12.09.2015, 13:57
Если все последующие пакеты шифруются, то как их "читает" Пандора?
Ведь Она без всякой расшифровки корректно отображает данные
Она их расшифровывает :) Ваш кэп

jastyjj
04.10.2017, 00:24
Мне нужна помощь для протокола подключения к общему серверу.
При передаче соединения с общим сервером первый пакет, который вы получаете, является ServerInfo, как с обычным сервером. После этого вы отправляете ему пакет 0x451, который содержит некоторую базовую информацию, такую ​​как идентификатор персонажа на общем сервере и 32-байтовый токен входа. Байт входа в 32 байта, который вы получаете из последнего пакета, который вы получаете с обычного сервера после запроса перевода.

Сразу после этого второй пакет, который вы получаете с общего сервера, зашифрован, и я не знаю, как его расшифровать. Не было никакого пакета SMKey или CMKey, который предполагает, что вы используете EncHash / DecHash с обычного сервера. Я попытался использовать их как стандартные, но он не работал, тогда я попытался пересчитать ключ дешифрования / шифрования, используя ключ общего сервера в пакете ServerInfo для общего сервера, но это тоже не сработало.

У кого-нибудь есть идеи, куда идти отсюда? Я думаю, что единственными актуальными новыми данными будут 16-байтовый ключ в пакете ServerInfo с общим сервером и 32-байтовый токен входа, который вы используете для подключения к общему серверу. Как-то мне нужно сделать 16-разрядный ключ дешифрования от этого и то, что я получил от обычного сервера.

Есть идеи, как это решить? Прошу прощения, если этот текст трудно читать ... это на английском языке
I need help for the protocol of connecting to the shared server.
When you transfer connection to the shared server the first packet you receive is ServerInfo like with the normal server. After that you send it a packet 0x451 which contains some basic info like the character ID on the shared server and a 32-byte login token. The 32 byte login token you get from the last packet you get from the normal server after you request a transfer.

Immediately after that the 2nd packet you receive from the shared server is encrypted and I don't know how to decrypt it. There wasn't any SMKey or CMKey packet which suggests you use the EncHash / DecHash from the normal server. I tried using those as standard but it didn't work then I tried recalculating the decryption / encryption key using the shared server key in the shared server's ServerInfo packet but that didn't work either.

Does anyone have any ideas where to go from here? I think the only relevant new data would be the 16-byte Key in the shared server ServerInfo packet and the 32-byte login token you use to connect to the shared server. Somehow I need to make the 16-byte decryption key from that and what I alread had from the normal server.

Any ideas how to solve this?

JahGame
24.02.2018, 20:04
Помогите расшифровать протокол сервака
есть пакет а как перевести незнаю:sad:

[Ссылки могут видеть только зарегистрированные и активированные пользователи] GaD3khSzW3OqACfoSkLefZ91dwzPVSV6PXNnQFQ-V6vYLqFCvHTJxXFL1K-hp9KiaglSqWlOGVwn9xCpwSuE1lcthaMG8VBUxaP0G9KD18X6u __V0fOcuIYllNJM76pWQM3DQX-EFfiGMz-a6pNgJy0Vbl18YApUEgCY4t98VWeTLKfTc_R864DCVMD9b6o1F ohe6eDp-myM7Mi3CSmfZ6Idb9vAMplhFFIkf5obitqZQavfu9cZMFAdFyp 880r-WB2z-1aKbI9HJqn9zZLnJJnlgvmcsncRPMOz14QNZW8T-Mb3EkL4WbIYioSSQmHxUFHI54Hf1FjFb55kcF6h6GgyTGs0Rt_ eWlW81FCIRbfEqWoG6WUAEWHp2cxJA-X6MoPMRVuC8-VOjtNKd9jsKngnr8KJYywwA-8fPVmVx_sRWs-3IL7-W8SdD_QvvPw3sgHeohMpXll76HkPmDdqu65Igbc1hkOqAwydg0 gsTpoRqb5BONXK5OjIqGrj4yskCi0RsMGahci1u2sCq3ctmoka 1tiO0tiXmB7EC7DbtqAZtw5Ajs95M=w587-h442-no

Mizyki
14.03.2018, 16:56
Друзья, у меня лыжи не едут. Делаю всё точно так же, но до Пандоры пакеты не доходят, судя по всему. На 2 ПК пробовал - не получается. Расскажите, пожалуйста, подробнее как это все делается. Спасибо большое :)

Mizyki
17.03.2018, 12:41
Ап :(

Mizyki
28.03.2018, 14:55
Ап ап ап ап ап :(