首页 > 解决方案 > 找出字节内容

问题描述

我正在处理一个包含多个流的复合文件。我很沮丧如何弄清楚每个流的内容。我不知道这些字节是文本还是 mp3 或视频。例如:有没有办法理解这些字节是什么类型的数据?

b'\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x0bz\xcc\xc9\xc8\xc0\xc0\x00\xc2?\x82\x1e<\x0ec\xbc*8\x19\xc8i\xb3W_\x0b\x14bH\x00\xb2-\x99\x18\x18\xfe\x03\x01\x88\xcf\xc0\x01\xc4\xe1\x0c\xf9\x0cE\x0c\xd9\x0c\xc5\x0c\xa9\x0c%\x0c\x86`\xcd \x0c\x020\x1a\x00\x00\x00\xff\xff\x02\x080\x00\x96L~\x89W\x00\x00\x00\x00\x80(\\B\xefI;\x9e}p\xfe\x1a\xb2\x9b>(\x81\x86/=\xc9xH0:Pwb\xb7\xdck-\xd2F\x04\xd7co'

标签: streambytemp3

解决方案


是的,需要弄清楚每个流的内容。除了不可靠的扩展名之外,这个星球上的每个文件都有一个签名。它可能被删除或错误添加。

那么签名是什么?

在计算中,文件签名是用于识别或验证文件内容的数据。特别是,它可能指:

  • 文件幻数:文件中用于识别文件格式的字节;通常是一个短的字节序列(大多数是 2-4 个字节长)放在文件的开头;查看文件签名列表

  • 文件校验和或更一般地是对文件内容的哈希函数的结果:用于验证文件内容完整性的数据,通常用于防止传输错误或恶意攻击。签名可以包含在文件的末尾或单独的文件中。

我使用幻数来定义我从维基百科复制的幻数术语

计算机编程中,幻数一词有多种含义。它可以指以下一项或多项:

  • 具有无法解释的含义或多次出现的唯一值,可以(最好)用命名常量替换
  • 用于标识文件格式或协议的常量数值或文本值;对于文件,请参阅文件签名列表
  • 不太可能被误认为其他含义的独特的唯一值(例如,全局唯一标识符

在第二点,它是一个特定的字节序列,比如

PNG (89 50 4E 47 0D 0A 1A 0A) 

或者

BMP (42 4D)

那么如何知道每个文件的幻数呢?

在这篇文章“使用 PowerShell 调查文件签名”中,我们发现作者创建了一个很棒的 power shell 函数来获取幻数,他还提到了一个工具,我从他的文章中复制了这个

PowerShell V5 引入了Format-Hex,它可以提供一种替代方法来读取文件并显示十六进制和 ASCII 值以确定幻数。

form Format-Hex help 我正在复制这个描述

Format-Hex cmdlet 将文件或其他输入显示为十六进制值。要确定字符与输出的偏移量,请将行最左侧的数字与该字符列顶部的数字相加。

此 cmdlet 可以帮助您确定损坏文件或可能没有文件扩展名的文件的文件类型。运行此 cmdlet,然后检查结果以获取文件信息。

这个工具也非常适合获取文件的幻数。这是一个例子 在此处输入图像描述

另一个工具是在线十六进制编辑器,但刚开始我不明白如何使用它。

现在我们得到了神奇的数字,但是如何知道什么类型的数据或者那个文件或流? 这是最好的问题。幸运的是,这些幻数有很多数据库。让我列出一些

  1. 文件签名
  2. 文件签名表
  3. 文件签名列表

例如,第一个数据库具有搜索功能。只需输入不带空格的幻数并搜索

在此处输入图像描述

之后你可能会发现。是的,可能。您很有可能无法直接找到相关文件类型。

我遇到了这个问题,并通过针对特定类型的签名测试流来解决它。就像我在流中搜索的 PNG

def GetPngStartingOffset(arr):

    #targted magic Number for png (89 50 4E 47 0D 0A 1A 0A)
    markerFound = False
    startingOffset = 0
    previousValue = 0
    arraylength = range(0, len(arr) -1) 

    for i in arraylength:
        currentValue = arr[i]
        if (currentValue == 137):   # 0x89  
            markerFound = True
            startingOffset = i
            previousValue = currentValue
            continue

        if currentValue == 80:  # 0x50
            if (markerFound and (previousValue == 137)):
                previousValue = currentValue
                continue
            markerFound = False

        elif currentValue == 78:   # 0x4E
            if (markerFound and (previousValue == 80)):
                previousValue = currentValue
                continue
            markerFound = False

        elif currentValue == 71:   # 0x47
            if (markerFound and (previousValue == 78)):
                previousValue = currentValue
                continue
            markerFound = False

        elif currentValue == 13:   # 0x0D
            if (markerFound and (previousValue == 71)):
                previousValue = currentValue
                continue
            markerFound = False

        elif currentValue == 10:   # 0x0A
            if (markerFound and (previousValue == 26)):
                return startingOffset
            if (markerFound and (previousValue == 13)):
                previousValue = currentValue
                continue
            markerFound = False

        elif currentValue == 26:   # 0x1A
            if (markerFound and (previousValue == 10)):
                previousValue = currentValue
                continue
            markerFound = False
    return 0

一旦这个函数找到了幻数 在此处输入图像描述

我拆分流并保存 png 文件

    arr = stream.read()
    a = list(arr)
    B = a[GetPngStartingOffset(a):len(a)]
    bytesString = bytes(B)
    image = Image.open(io.BytesIO(bytesString))
    image.show()

最后,这不是端到端的解决方案,而是一种找出流内容的方法 感谢您的阅读,感谢@Robert Columbia 的耐心等待


推荐阅读