1

我需要帮助识别以下技术。是一个冗长的阅读所以请尝试跟随。我的问题是,如果这是一个已知的标准,它是否有名字,任何人都可以联系或看到这个。有什么好处。另外,如果您想知道,这与在一个早已被遗忘的在线 PS2 游戏中捕获的数据包有关,我是一个试图将其带回的团队的一员。

请注意,这不是 ip 协议所描述的大小,此大小表示与实际有效负载一起使用,它是供客户端和服务器使用的。以下阅读描述了如何表示消息的大小。~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~

真正的数据包长度是 94 字节长。这些是在所有 ip 协议内容之后的有效负载数据上的字节 5-6 [CF E0]。另外,请注意,我们必须将这两个字节解释为小端格式。因此,我们应该将这两个字节视为

[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 的最大值,所以为什么不抛出另一个字节进入字节流。我确信一个额外的字节不会对网络产生很大的影响,那么目的可能是什么。我想也许其他人会看到缺少的东西或与某种记录在案的标准、协议、模式有关的东西,

另外,我不认为上面的公式是由另一个团队成员完成的。

4

1 回答 1

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;
}  

另一种可能性是 byte[5] 是有符号的,并且长度是由重建的,
(int8_t)byte[5] + 128*((byte[6]&0xF)+1) + minlen[byte[6]>>4];
但我想不出任何理由以这种方式构造它。

于 2016-12-14T22:55:24.477 回答