Рейтинг темы:
  • 0 Голос(ов) - 0 в среднем
  • 1
  • 2
  • 3
  • 4
  • 5
Структура, крипт и декрипт Tcp и Udp пакетов
#1
Крипт и декрипт

Клиент Piercing Blow криптует пакеты (и не только) методом сдвига бит. Методы крипта и декрипта можно без усилий получить из i3BaseDx_Cli.dll.

[SRC="csharp"]public static void Shift(byte[] buffer, int bits)
{
int length = buffer.Length;
byte first = buffer[0];
byte current;

for (int i = 0; i < length; i++)
{
if (i >= (length - 1))
{
current = first;
}
else
{
current = buffer[i + 1];
}

buffer[i] = (byte)(current >> (8 - bits) | (buffer[i] << bits));
}
}

public static void Unshift(byte[] buffer, int bits)
{
int length = buffer.Length;
byte last = buffer[length - 1];
byte current;

for (int i = length - 1; (i & 0x80000000) == 0; i--)
{
if (i <= 0)
{
current = last;
}
else
{
current = buffer[i - 1];
}

buffer[i] = (byte)(current << (8 - bits) | buffer[i] >> bits);
}
}
[/SRC]


Tcp пакеты

Структура клиентского Tcp пакета:

[SRC="csharp"]class TcpPacket
{
ushort Length { get; set; }
ushort Opcode { get; set; }
byte[] Data { get; set; }
}
[/SRC]


При этом размер пакета не криптуется, а комбинируется с флагом 0x8000.

[SRC="csharp"]ushort length =| 0x8000
[/SRC]


Таким образом, при получении пакета от клиента, нам нужно получить размер данных, это делается так:

[SRC="csharp"]int length = BitConverter.ToUInt16(_buffer, 0) & 0x7FFF;
[/SRC]


В размере пакета не учтён размер опкода, поэтому с буффера нужно получить на 2 байта больше полученной длины.

[SRC="csharp"]byte[] buffer = new byte[length + 2];
Buffer.BlockCopy(_buffer, 2, buffer, 0, buffer.Length);

Unshift(buffer, _bits);
[/SRC]


Сам сдвиг рассчитывается следующим образом:

[SRC="csharp"]// Id - идентификатор текущего соединения.
_bits = Id % 7 + 1;
[/SRC]


В ответ сервер отправляет не криптованные данные, структура которых ничем не отличается от клиентских.

Udp пакеты

Piercing Blow, Point Blank и Project Blackout для обмена данными между игроками использует одноранговую сеть P2P.

Структура Udp пакета

[SRC="csharp"]public class UdpPacket
{
public byte Id { get; set; }
public byte Slot { get; set; }
public float Time { get; set; }
public byte Session { get; set; }
public ushort Length { get; set; }
public byte[] Data { get; set; }
}
[/SRC]


Первые 13 байт* в которые входят Id, Slot, Time, Session, Length - не криптованы, это касается как клиентских, так и серверных пакетов. Data же криптована всё тем же сдвигом бит, только для получения сдвига используется длина пакета:

[SRC="csharp"]int bits = length % 6 + 1;
[/SRC]


*длина заголовка Udp пакета может меняться от версии к версии.


Так же, изучите тему с чего начать написание BattleServer в режиме Relay, чтобы применить полученные знания на деле.

Есть вопросы или дополнения - велком.
Ответ
#2
PROGRAMMATOR, Первые 13 байт пропускать надо верно? Потом остаток что осталось % 6 + 1; Верно??
Ответ
#3
Да, можно изменить метод Unshift:

[SRC="csharp"]public static void Unshift(byte[] buffer, int start, int bits)
{
int length = buffer.Length - start;

// ...
}
[/SRC]


И использовать:

[SRC="csharp"]Unshift(buffer, 13, length % 6 + 1);
[/SRC]
Ответ
#4
PROGRAMMATOR,
Можешь помочь с наброском удп сервера?

и еще проблема, когда срезаю верхушку 13 байт, как получить длину пакета, если до среза они в разброс идут
может второй ид пакета придти, а длина другого(
Ответ
#5
Enfern;416891 Написал:если до среза они в разброс идут
может второй ид пакета придти, а длина другого(

В Udp, пакеты, могут прийти в разном порядке, например приходит более старая версия PosRotation. Но чтобы приходил пакет с "чужой" длиной... nichoci

Длина пакета в заголовке, там же структуру я описал. Именно её берёте для получения битового сдвига packet.Length % 6 + 1.
Ответ
#6
PROGRAMMATOR,

Код:
[SRC="csharp"]    
// Temp получает с Receive ...........
int Length = BitConverter.ToUInt16(Temp, 7) & 0x7FFF;
Unshift(Temp, 13, Length % 6 + 1);
HandlePacket(Temp);[/SRC]

Я тебя верно понял?
Ответ
#7
Да, только & 0x7FFF там не нужно, это относится к Tcp.
Ответ
#8
PROGRAMMATOR, как мне получить теперь опкод?
Если я расшифровал, дальше даже длина пакета не отображается в чем проблема?
Если не сложно, объясни сколько он всего примерно оп кодов шлет, потому что первые 13 байт они изменились полностью.
Ответ
#9
А не должны они меняться. 13 байт - это заголовок пакета, он не шифрован.
Ответ
#10
Enfern,
1. Пишешь структуру.
2. Пропускаешь по структуре (13) байт.
3. Расшифровываешь Длина пакета % 6 + 1
4. В итоге у тебя получится, 13 байт не кодированных, дата расшифрованная.
Ответ


Возможно похожие темы ...
Тема Автор Ответы Просмотры Последний пост
  Список серверных пакетов PROGRAMMATOR 82 38,250 01-24-2020, 09:13 PM
Последний пост: Pyotr
  Список серверных пакетов [PB] Awiion 22 12,848 02-24-2019, 04:59 PM
Последний пост: bmzproject
  Структура PROTOCOL_BASE_GET_SCHANNELLIST_ACK BallDev 3 1,634 05-21-2016, 06:25 PM
Последний пост: PROGRAMMATOR
  Структура PROTOCOL_INVENTORY_USE_ITEM_ACK BallDev 0 945 05-06-2016, 12:36 PM
Последний пост: BallDev
  Структура PROTOCOL_BASE_GET_MYINFO_ACK BallDev 6 1,985 05-03-2016, 04:48 AM
Последний пост: crayonnet
  Структура PROTOCOL_ROOM_GET_SLOTINFO_ACK Empert 1 1,548 04-01-2016, 09:25 AM
Последний пост: PROGRAMMATOR
  [Piercing Blow] Структура PROTOCOL_BASE_GET_SYSTEM_INFO_ACK BallDev 2 2,054 03-28-2016, 08:32 PM
Последний пост: BallDev
  Структура PROTOCOL_LOGIN_ACK Sojang 15 3,932 01-20-2016, 01:02 AM
Последний пост: PROGRAMMATOR

Перейти к форуму:


Пользователи, просматривающие эту тему: 1 Гость(ей)