Sharppcap: '.'символы вместо пробелов с методом printHex () - PullRequest
0 голосов
/ 03 декабря 2018

Я успешно разбираю файлы .pcap с помощью библиотеки SharpPcap.

Цель - извлечь данные XML из пакетов TCP / HTTP.Для этого я использую приведенный ниже код (удалены нулевые проверки, чтобы сделать его более читабельным):

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();

Перемещая в сторону шестнадцатеричные значения и начальные строки, я могу извлечь XMLданные из переменной rawData вместе с неожиданным побочным эффектом.

Вместо пробелов .PrintHex() возвращает '.'символы:

Вместо:

<xml>Only text here</xml>

Я получаю это:

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

Я не делаю никаких странных замен или преобразований байтов.Вышеуказанное поведение - это именно то, что .PrintHex() возвращает.

  • Это случайно не ожидаемый результат?
  • И что более важно ... Как это можно исправить или предотвратить?(имея в виду, что действительное «.» от преобразованного «.» нельзя отличить)

Версии библиотеки:

  • .NETFramework :> 4.5.2

  • Pcapsharp : 4.2.0

Ответы [ 2 ]

0 голосов
/ 09 декабря 2018

Это может быть полезно для других, поэтому я публикую свое окончательное решение (основанное на принятом ответе).

Дополнительные функции:

  • Использование компоновщика строк для повышения производительности
  • Включая символы новой строки

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

}
0 голосов
/ 07 декабря 2018

Попробуйте использовать метод переопределения 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 останутся без изменений, остальные будут заменены на . (включая space, что составляет 32 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
    }
}
...