需要帮助识别位操作技术

Posted

技术标签:

【中文标题】需要帮助识别位操作技术【英文标题】:Need help identifying a bit manipulation technique 【发布时间】:2016-12-07 17:08:44 【问题描述】:

我需要帮助识别以下技术。是一个冗长的阅读所以请尝试跟随。我的问题是,如果这是一个已知的标准,它是否有名字,任何人都可以联系或看到这个。有什么好处。另外,如果您想知道,这与在一个早已被遗忘的在线 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 字节。 这导致了以下从第 5 和第 6 字节数据包头中提取数据包长度的方法。首先请注意,我们之前已确定数据包类别为 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 的最大值,所以为什么不抛出另一个字节进入字节流。我确信一个额外的字节不会对网络产生很大的影响,那么目的可能是什么。我想也许其他人会看到缺少的东西或与某种记录在案的标准、协议、模式、技术或某处记录的东西有关。

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

【问题讨论】:

我认为第二个字节可能要求必须始终设置第 7 位(无论出于何种原因,例如向后兼容性)。处理长度时,需要先用 AND 0x7F 清除第 7 位,或者必须从读取的字节值中减去 128(128 = 2**7)。看起来数据包长度以 byte1[3:0]:byte2[6:0] 编码,提供 11 位字节数。可能会减去最小长度,以便最大化可以编码的可能长度值;可编码长度为 [15,15*128+127+15] = [15,2062]。 再贴几个例子会很有用:“类”总是等于最小大小吗?有没有 byte5 bit7 == 0 的例子?有 byte6 低半字节非零的例子吗? 【参考方案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]&amp;0xF)+1) + minlen[byte[6]&gt;&gt;4];重构 但是我想不出任何理由来这样构建它。

【讨论】:

以上是关于需要帮助识别位操作技术的主要内容,如果未能解决你的问题,请参考以下文章

win32位操作系统java包不能运行

32位操作系统与64位操作系统内存比较

32位、64位操作系统有什么区别?

图像识别

国民技术 NS3300 配件认证身份识别安全芯片

国民技术 NS3300 配件认证身份识别安全芯片