2016-12-07 15 views
1

Мне нужна помощь в определении следующей техники. Это длинное чтение, поэтому попробуйте следовать. Мой вопрос в том, является ли это известным стандартом, имеет ли он имя, может ли кто-либо связать или увидеть это раньше. В чем польза. Также, если вы задаетесь вопросом, это связано с пакетом, захваченным в давно забытой онлайн-игре 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. Это заявленный истинный размер пакета.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~

Эта формула была проверена на 20 000 последующих пакетов, и она работает. Но зачем идти по всем этим проблемам, чтобы указать размер сообщения, которое следует? Я думал, что это форма шифрования, но остальная часть сообщения не зашифрована вообще. Формула понятна, но я не вижу преимущества.Я думаю, что, возможно, это способ оптимизировать размер пакета, передав число больше 255, используя только один байт, но это сохраняет только один байт, а другой байт дает максимальное значение 65 535, поэтому почему бы не выбрасывать другой байт в поток байтов. Я уверен, что один дополнительный байт не будет иметь большого влияния на сеть, так что может быть целью. Я думал, что, возможно, кто-то еще увидит то, что отсутствует или связано с каким-то документированным стандартом, протоколом, шаблоном, техникой или чем-то, что где-то документировано.

Кроме того, я не беру на себя ответственность за выяснение формулы выше, что было сделано другим членом команды.

+1

Я думаю, что возможно, что у второго байта есть требование, чтобы бит 7 всегда устанавливался (по какой-либо причине, например, обратной совместимостью). При обработке длины бит 7 необходимо очистить сначала с помощью AND 0x7F или 128 вычесть из считанного значения байта (128 = 2 ** 7). Похоже, что длина пакета кодируется в байте1 [3: 0]: byte2 [6: 0], предоставляя счетчик в 11 бит. Минимальная длина, по-видимому, вычитается, чтобы максимизировать возможные значения длины, которые могут быть закодированы; длина кодирования находится в [15,15 * 128 + 127 + 15] = [15,2062]. – njuffa

+0

Было бы полезно опубликовать еще несколько примеров: «Класс» всегда равен минимальному размеру? Есть ли пример с байтом5 бит7 == 0? Есть ли пример с байтом6 low nibble non-zero? – AShelly

ответ

0

Мое лучшее предположение заключается в том, что приемник использует некоторую форму кодирования 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];
Но я не могу думать о какой-либо причине, чтобы построить его таким образом.