【问题标题】:Wireshark unable to open btsnoop fileWireshark 无法打开 btsnoop 文件
【发布时间】:2020-12-12 17:48:34
【问题描述】:

我按照Bluetooth HCI snoop log not generated 的回答中的说明使用我的 Android 错误报告文件中的 btsnooz.py 创建了一个 btsnoop 文件。当我在 Wireshark 中打开生成的 btsnoop.log 文件时,我收到了错误 The file "btsnoop.log" isn't a capture file in a format Wireshark understands.

adb bugreport 是针对运行 Android 8.0.0 的 S7 Edge 完成的。

btsnoop.log 文件的副本可以在这里找到https://drive.google.com/file/d/1Y3544DrhPbI9YxktL6rSWkpAe-YeoPn4/view?usp=sharing

如何分析这个文件?

【问题讨论】:

    标签: bluetooth wireshark btsnoop


    【解决方案1】:

    虽然它不能完全回答问题,但也许它会帮助找到答案(我还不能评论)。您的跟踪以 FFFE6200740073006E006F006F007000 开头,其中 FFFE 看起来像 UTF-16LE BOM,然后进入“btsnoop”,并与零交错。我在运行过去安装在我的 W10x64 笔记本电脑上的“从下”python-2.7 脚本 btsnooz.py 时得到了确切的结果——就像这样: C:\python27-x64\python.exe btsnooz.py bugreport-2021-01-09-22-52-09.txt >bugreport.pcap

    然后我尝试像这样直接运行它,希望 W10 有一些自己的内置 python: .\btsnooz.py bugreport-2021-01-09-22-52-09.txt >bugreport.pcap

    并得到一个以“btsnoop”开头的文件,就像有效文件一样小两倍。尽管我遇到了不同的问题(Wireshark 只能解码前几个数据包),但它看起来向前迈出了一步,因为上面运行 btsnooz.py 的方法#1 似乎以某种方式损坏了输出文件。

    这是 btsnooz.py 应该从其代码中写入文件开头的内容,如下所示,因此其他任何内容都意味着脚本执行不正确: sys.stdout.write('btsnoop\x00\x00\x00\x00\x01\x00\x00\x03\xea')

    HTH...

    更新: 显然,python 脚本 btsnooz.py 暗示可在 Linux 上使用:刚刚在 Ubuntu 上使用 python v2.7 对其进行了验证,它产生了由 Wireshark 解析的正确跟踪,没有任何此类错误.在 Windows 上使用时,它似乎写入 0D0A 而不是每个 0A,导致上述 Wireshark 解析错误。在十六进制编辑器中用 0A 替换那些 0D0A “后退”修复了我的情况下的这些错误。

    【讨论】:

      【解决方案2】:

      我刚刚遇到了同样的问题,并设法修改 btsnooz.py 以在 Windows 上与 Python 3 一起正常工作(我也希望 Linux 等,因为我没有专门针对行尾做任何事情,只是编码等以匹配 Python 2 行为)。我还将它输出到当前目录中名为“btsnoop.log”的文件(覆盖任何可能已经存在的文件),而不是尝试写入标准输出。

      我在下面包含了我修改后的代码 - 只需将其保存为“btsnooz.py”并使用 Python 3 运行 python btsnooz.py <name of bugreport file>.txt

      #!/usr/bin/env python
      """
      This script extracts btsnooz content from bugreports and generates
      a valid btsnoop log file which can be viewed using standard tools
      like Wireshark.
      btsnooz is a custom format designed to be included in bugreports.
      It can be described as:
      base64 {
        file_header
        deflate {
          repeated {
            record_header
            record_data
          }
        }
      }
      where the file_header and record_header are modified versions of
      the btsnoop headers.
      """
      import base64
      import fileinput
      import struct
      import sys
      import zlib
      # Enumeration of the values the 'type' field can take in a btsnooz
      # header. These values come from the Bluetooth stack's internal
      # representation of packet types.
      TYPE_IN_EVT = 0x10
      TYPE_IN_ACL = 0x11
      TYPE_IN_SCO = 0x12
      TYPE_IN_ISO = 0x17
      TYPE_OUT_CMD = 0x20
      TYPE_OUT_ACL = 0x21
      TYPE_OUT_SCO = 0x22
      TYPE_OUT_ISO = 0x2d
      def type_to_direction(type):
          """
        Returns the inbound/outbound direction of a packet given its type.
        0 = sent packet
        1 = received packet
        """
          if type in [TYPE_IN_EVT, TYPE_IN_ACL, TYPE_IN_SCO, TYPE_IN_ISO]:
              return 1
          return 0
      def type_to_hci(type):
          """
        Returns the HCI type of a packet given its btsnooz type.
        """
          if type == TYPE_OUT_CMD:
              return '\x01'
          if type == TYPE_IN_ACL or type == TYPE_OUT_ACL:
              return '\x02'
          if type == TYPE_IN_SCO or type == TYPE_OUT_SCO:
              return '\x03'
          if type == TYPE_IN_EVT:
              return '\x04'
          if type == TYPE_IN_ISO or type == TYPE_OUT_ISO:
              return '\x05'
          raise RuntimeError("type_to_hci: unknown type (0x{:02x})".format(type))
      def decode_snooz(snooz):
          """
        Decodes all known versions of a btsnooz file into a btsnoop file.
        """
          version, last_timestamp_ms = struct.unpack_from('=bQ', snooz)
          if version != 1 and version != 2:
              sys.stderr.write('Unsupported btsnooz version: %s\n' % version)
              exit(1)
          # Oddly, the file header (9 bytes) is not compressed, but the rest is.
          decompressed = zlib.decompress(snooz[9:])
          fp.write('btsnoop\x00\x00\x00\x00\x01\x00\x00\x03\xea'.encode("latin-1"))
          if version == 1:
              decode_snooz_v1(decompressed, last_timestamp_ms)
          elif version == 2:
              decode_snooz_v2(decompressed, last_timestamp_ms)
      def decode_snooz_v1(decompressed, last_timestamp_ms):
          """
        Decodes btsnooz v1 files into a btsnoop file.
        """
          # An unfortunate consequence of the file format design: we have to do a
          # pass of the entire file to determine the timestamp of the first packet.
          first_timestamp_ms = last_timestamp_ms + 0x00dcddb30f2f8000
          offset = 0
          while offset < len(decompressed):
              length, delta_time_ms, type = struct.unpack_from('=HIb', decompressed, offset)
              offset += 7 + length - 1
              first_timestamp_ms -= delta_time_ms
          # Second pass does the actual writing out to stdout.
          offset = 0
          while offset < len(decompressed):
              length, delta_time_ms, type = struct.unpack_from('=HIb', decompressed, offset)
              first_timestamp_ms += delta_time_ms
              offset += 7
              fp.write(struct.pack('>II', length, length))
              fp.write(struct.pack('>II', type_to_direction(type), 0))
              fp.write(struct.pack('>II', (first_timestamp_ms >> 32), (first_timestamp_ms & 0xFFFFFFFF)))
              fp.write(type_to_hci(type).encode("latin-1"))
              fp.write(decompressed[offset:offset + length - 1])
              offset += length - 1
      def decode_snooz_v2(decompressed, last_timestamp_ms):
          """
        Decodes btsnooz v2 files into a btsnoop file.
        """
          # An unfortunate consequence of the file format design: we have to do a
          # pass of the entire file to determine the timestamp of the first packet.
          first_timestamp_ms = last_timestamp_ms + 0x00dcddb30f2f8000
          offset = 0
          while offset < len(decompressed):
              length, packet_length, delta_time_ms, snooz_type = struct.unpack_from('=HHIb', decompressed, offset)
              offset += 9 + length - 1
              first_timestamp_ms -= delta_time_ms
          # Second pass does the actual writing out to stdout.
          offset = 0
          while offset < len(decompressed):
              length, packet_length, delta_time_ms, snooz_type = struct.unpack_from('=HHIb', decompressed, offset)
              first_timestamp_ms += delta_time_ms
              offset += 9
              fp.write(struct.pack('>II', packet_length, length))
              fp.write(struct.pack('>II', type_to_direction(snooz_type), 0))
              fp.write(struct.pack('>II', (first_timestamp_ms >> 32), (first_timestamp_ms & 0xFFFFFFFF)))
              fp.write(type_to_hci(snooz_type).encode("latin-1"))
              fp.write(decompressed[offset:offset + length - 1])
              offset += length - 1
      fp = None
      def main():
          if len(sys.argv) > 2:
              sys.stderr.write('Usage: %s [bugreport]\n' % sys.argv[0])
              exit(1)
          iterator = fileinput.input(openhook=fileinput.hook_encoded("latin-1"))
          found = False
          base64_string = ""
          for line in iterator:
              if found:
                  if line.find('--- END:BTSNOOP_LOG_SUMMARY') != -1:
                      global fp
                      fp = open("btsnoop.log", "wb")
                      decode_snooz(base64.standard_b64decode(base64_string))
                      fp.close
                      sys.exit(0)
                  base64_string += line.strip()
              if line.find('--- BEGIN:BTSNOOP_LOG_SUMMARY') != -1:
                  found = True
          if not found:
              sys.stderr.write('No btsnooz section found in bugreport.\n')
              sys.exit(1)
      if __name__ == '__main__':
          main()
      

      【讨论】:

        猜你喜欢
        • 2011-03-26
        • 2019-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-09
        • 2018-11-30
        相关资源
        最近更新 更多