Нужна помощь в определении техники манипуляции
Мне нужна помощь в определении следующей техники. Это длительное чтение, поэтому, пожалуйста, попробуйте следовать. У меня вопрос, является ли это известным стандартом, имеет ли оно название, может кто-нибудь связать или видел это раньше. В чем выгода. Также, если вам интересно, это связано с пакетом, захваченным в давно забытой онлайн-игре для PS2, и я являюсь частью команды, которая пытается вернуть его.
Обратите внимание, что это не тот размер, который описан в протоколе ip. Это представление размера не учитывает фактическую полезную нагрузку и предназначено для использования клиентом и сервером. В следующем прочтении описывается, как представляется размер сообщения. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
Истинная длина пакета составляет 94 байта. Это байты 5-6 [CF E0] в данных полезной нагрузки после всего содержимого протокола ip. Также обратите внимание, что мы должны интерпретировать эти два байта как в формате с прямым порядком байтов. Таким образом, мы должны думать об этих двух байтах как
[E0 CF] Мы определяем класс пакета из этих двух байтов, беря первый кусочек (4 бита) первого байта. В данном конкретном случае это просто 0xE. Затем мы идентифицировали бы этот пакет как имеющий класс пакета 0xE. Это было определено как пакетный класс инициатора сеанса.
Теперь для определения длины пакета по оставшемуся клеву и второму байту. Сначала мы конвертируем второй байт в десятичный, мы получаем 0xCF = 207. Разница между этим значением и фактической длиной составляет 207-94=113 байтов. Первоначально я знал, что этот байт пропорционален длине пакета, но просто имеет некоторое смещение. Я не был уверен, откуда пришло это смещение. Кроме того, это смещение, казалось, изменилось для разных пакетов. Требовалось больше изучения.
В конце концов я обнаружил, что у каждого класса пакетов было разное смещение. Поэтому мне нужно было исследовать только пакеты в одном и том же классе пакетов, чтобы выяснить смещение для этого класса пакетов. При этом я составил таблицу всех сообщенных длин (в байте 5) и сравнил ее с фактической длиной пакета. Я обнаружил, что
почти все сообщенные длины пакетов в байте 5 были больше, чем 0x80=128. второй полубайт в другом байте работал как тип множителя для длины пакета, чтобы каждый класс пакета имел ассоциированную минимальную длину пакета и максимальную длину пакета, которые могли бы быть представлены. Для исследуемого класса пакетов 0xC минимальный размер пакета составлял 18 байт, а максимальный размер пакета составлял примерно 10*128 +17 = 1297 байт. Это привело к следующему подходу для извлечения длины пакета из пятого и шестого байта заголовка пакета. Прежде всего обратите внимание, что ранее мы определили, что класс пакета равен 0xE, и что минимальный размер пакета, связанный с этим классом пакета, составляет 15 байтов. Теперь возьмем второй кусочек первого байта [0xE0] = 0 в этом случае и умножим его на 128 байтов 0*128 = 0 байтов. Теперь добавьте это ко второму байту [0xCF] = 207 в этом случае и вычтите 128. Таким образом, 0 + 207 - 128 = 79. Теперь нам нужно добавить минимальный размер пакета для этого класса пакетов 0xE = 15-байтовый минимальный размер пакета, Итак (0*128)+(207-128) -15 = 94. Это сообщенный истинный размер пакета.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
Эта формула была проверена на 20000 последующих пакетов, и она работает. Но зачем проходить через все эти неприятности, просто чтобы указать размер следующего сообщения? Я думал, что это была форма шифрования, но остальная часть сообщения вообще не зашифрована. Формула понятна, но я не вижу выгоды. Я думаю, что, возможно, это способ оптимизировать размер пакета, передавая число больше 255, используя только один байт, но это экономит мне ровно один байт, бросая другой байт, выдает значение Max 65 535, так почему бы не бросить еще один байт в поток байтов. Я уверен, что один дополнительный байт не окажет большого влияния на сеть, так что может быть целью. Я думал, что, возможно, кто-то еще увидит, что отсутствует или связано с каким-то документированным стандартом, протоколом, шаблоном, техникой или чем-то, что где-то задокументировано.
Кроме того, я не беру кредит на то, чтобы выяснить формулу выше, что было сделано другим членом команды.
1 ответ
Мое лучшее предположение состоит в том, что приемник использует некоторую форму кодирования base128 переменной длины, такую как LEB128.
Но в этом случае отправитель, зная, что фактический максимальный размер помещается в 11 битах, вынуждает кодировку использовать 2 байта и перегружает верхний фрагмент для "класса". Это делает размер заголовка и время постройки постоянными. И получатель может просто замаскировать класс и запустить его через стандартный декодер.
Послать:
len -= minlen[class]
byte[5]=(len&0x7F)|0x80;
byte[6]=(len>>7)|(class<<4);
Получать:
class = byte[6]>>4;
byte[6]&=0xF;
len = decode(&byte[5]) + minlen[class];
где:
int decode(byte* data) {
int v=*data&0x7F;
while (*data & 0x80) {
data++;
v+=*data&0x7F;
}
return v;
}
Еще одна возможность состоит в том, что байт [5] подписан, а длина восстанавливается(int8_t)byte[5] + 128*((byte[6]&0xF)+1) + minlen[byte[6]>>4];
Но я не могу думать ни о какой причине, чтобы построить это таким образом.