0

我正在使用 SharpPcap 库成功解析“.pcap”文件。

目标是从 TCP/HTTP 数据包中检索 XML 数据。为了做到这一点,我使用下面的代码(删除空检查,使其更具可读性):

Packet packet = Packet.ParsePacket(eventArguments.Packet.LinkLayerType, eventArguments.Packet.Data);
EthernetPacket ethernetPacket = ((EthernetPacket)packet);

IpPacket ipPacket = (IpPacket)packet.Extract(typeof(IpPacket));

TcpPacket tcpPacket = (TcpPacket)packet.Extract(typeof(TcpPacket));

string rawData = tcpPacket.PrintHex();

移动,除了十六进制值和初始行,我能够从rawData变量中提取 XML 数据,以及意外的副作用。

返回的不是空格,而是.PrintHex()'.' 人物:

代替:

<xml>Only text here</xml>

我得到这个:

<xml>Only.text.here</xml>

我没有做任何奇怪的替换或字节转换。上述行为正是.PrintHex()返回的结果。

  • 这是否是预期的结果?
  • 更重要的是……如何解决或防止这种情况?(请记住,无法区分有效的 '.' 和转换后的 '.')

库版本:

  • .NET 框架:> 4.5.2

  • Pcapsharp:4.2.0

4

2 回答 2

1

尝试使用ToString()似乎完全符合您期望的方法的覆盖。

或者,如果这不起作用,请自行实施public string PrintHex()Packet如果您查看反编译的代码,这就是您的问题:

    if ((int) bytes[index - 1] < 33 || (int) bytes[index - 1] > 126)
      str2 += ".";
    else
      str2 += Encoding.ASCII.GetString(new byte[1]
      {
        bytes[index - 1]
      });

只有dec代码在 33 到 126 之间的字符将保持不变,其余的将替换为.(包括space32 http://www.asciitable.com/)。而且由于BytesHighPerformance.Bytes是公开的,您可以按照这些思路轻松编写自己的扩展方法。

TcpPacket tcpPacket = (TcpPacket)packet.Extract(typeof(TcpPacket));
string rawData = tcpPacket.CustomPrintHex();

public static class Extensions
{
    public static string CustomPrintHex(this TcpPacket self)
    {
        byte[] bytes = self.BytesHighPerformance.Bytes;

        // copy / paste of `PrintHex()` with your custom conversion
    }
}
于 2018-12-07T06:53:31.667 回答
0

它可能对其他人有帮助,所以我发布了我的最终解决方案(基于接受的答案)。

附加的功能:

  • 利用字符串生成器提高性能
  • 包括换行符

public class TcpPacketCustom: TcpPacket
{
    public static int AsciiRangeMin { get; } = 32;
    public static int AsciiRangeMax { get; } = 126;
    public static HashSet<int> AdditionalAsciiCodes { get; } = new HashSet<int> { 10, 13 }; //ascii codes of carriage and new line

    public TcpPacketCustom(ByteArraySegment byteArraySegment) : base(byteArraySegment) { }

    public new string PrintHex()
    {
        StringBuilder stringBuilder = new StringBuilder();
        foreach (byte b in this.BytesHighPerformance.Bytes)
        {
            int asciiCode = (int)b;
            if ( ((asciiCode < AsciiRangeMin) || (asciiCode > AsciiRangeMax)) && !AdditionalAsciiCodes.Contains(asciiCode) )
            {
                stringBuilder.Append(".");
            }
            else
            {
                stringBuilder.Append(Encoding.ASCII.GetString(new byte[1] { b }));
            }
        }
        return stringBuilder.ToString();
    }

}
于 2018-12-09T20:00:24.953 回答