我正在解压缩相机固件文件,其中包含我可以正确分割和验证的各个部分。该文件中的一个部分另外按LZSS格式压缩,如此处所述,我无法确定其正确格式的查找字节。 (或单个8192字节块,不过您想查看),然后跟随压缩数据。

压缩数据以标志字节开头,其标志位(从LSB开始)指示哪个接下来的字节将被复制(位设置),哪些字节是查找信息(位未设置)。查找信息由2字节/ 16位组成,我正在寻求帮助以解码其确切格式。

我已经知道:


MSB将index包含到查找缓冲区中
LSB包含查找的length,即从给定索引处的查找缓冲区中复制的字节数
length至少为3位
实际查找长度为length + 3(因为3是有意义的最小长度,例如2的位指示长度等于5字节的实际查找长度)

我怀疑:


查找长度为3或4位(在我可以手动解码的数据中,虽然没有发现需要4位的长度)
查找为3位或4位,索引应为13位或12位。 12位使查找缓冲区的大小为4096字节,13位使缓冲区的大小为8192,它对应于顶部的未压缩数据块,并且可能是缓冲区的初始数据。
00675CCE开始:

00675CC0  65 0D 0A 0D FD 0A 33 C0 3C 68 74 6D 6C 3E FF 3C  e...ý.3À<html>ÿ<
00675CD0  68 65 61 64 3E 3C 74 BF 69 74 6C 65 3E 34 40 C0  head><t¿itle>4@À
00675CE0  42 FF 61 64 20 52 65 71 75 65 6F 73 74 3C 2F 5F  Bÿad Requeost</_
00675CF0  C3 3C 2F 59 C3 6F 62 6F 64 79 57 C0 31 3E 69 CA  Ã</YÃobodyWÀ1>iÊ
00675D00  FE 8A C0 3C 70 3E 59 6F 75 72 FF 20 62 72 6F 77  þŠÀ<p>Yourÿ brow


解码序列:

00675CCE FF: read 8 bytes ("<head><t")
00675CD7 BF: read 6 bytes ("itle>4")
             lookup 40C0 -> read 3 bytes @ ? index ("00 ")
             read 1 byte  ("B")
00675CE0 FF: read 8 bytes ("ad Reque")
00675CEA 6F: read 4 bytes ("st</")
             lookup 5FC3 -> read 6 bytes @ ? index ("title>")
             read 2 bytes ("</")
             lookup 59C3 -> read 6 bytes @ ? index ("head><")
00675CF5 6F: read 4 bytes ("body")
             ...             


解码结果:

00000000  3C 68 65 61 64 3E 3C 74 69 74 6C 65 3E 34 30 30  <head><title>400
00000010  20 42 61 64 20 52 65 71 75 65 73 74 3C 2F 74 69   Bad Request</ti
00000020  74 6C 65 3E 3C 2F 68 65 61 64 3E 3C 62 6F 64 79  tle></head><body


现在让我们看一下最后两个查找及其可能的解码:

0x5FC3 = 0101111111000011b
         0101111111000 011 -> index 3064, length 6 (3 + 3 per above rule)
         010111111100 0011 -> index 1532, length 6

0x59C3 = 0101100111000011b
         0101100111000 011 -> index 2872, length 6
         010110011100 0011 -> index 1436, length 6


我专门选择了此示例,因为这两个查询仅返回了几个字节。在解码后的输出/查找缓冲区中,0x5FC3回溯23个字节,0x59C3回溯38个字节。长度绝对正确,但是索引编号对我来说没有意义。无论我采用哪种缓冲区大小,或者无论索引是从缓冲区的前面还是后面开始,或者甚至是区分字节序,数字都不合适。我假设由于仅回溯了几个字节,查找索引应该位于缓冲区的上边缘或下边缘。同样,由于它们在压缩数据和查找数据中都相邻,因此它们的索引应该非常接近。

所以问题是,如何正确解释查找索引,或者假设它们正确,查找缓冲区如何工作,因为在这种情况下它不能成为标准的循环缓冲区。

ps:如果有人感兴趣,YI M1和Fujifilm X-A10相机将使用有问题的固件格式。固件解压缩程序的当前状态可在GitHub上找到。

更新2:
找到证据表明查找长度至少需要4位。还弄清楚了查找字节是以大端顺序存储的(好像上次尝试时我犯了一个错误)。在链接代码存储库中进行设置后,我注意到许多查找都偏离了709字节,因此我添加了初始查找缓冲区写偏移709,现在我可以正确解码大部分数据,包括上面的示例。其他部分似乎还需要另一个偏移量,因此仍然可以解决。

更新3:
通过分析查找偏移量的变化位置,我注意到较长的0x00字节序列,如果将数据压缩,显然不会出现。仔细观察它们,结果发现它们是2048字节对齐的填充,而压缩数据段又由几个子段组成。一旦将它们拆分并分别解压缩,就解决了更改缓冲区查找偏移量的问题。因此,最后似乎LZSS算法的工作原理与我上面已发布的链接完全相同。谜题不是压缩本身,而是文件结构。与此相关的问题还有很多,一旦完成,我将发布更详细的答案。

评论

仅检查解压缩代码在做什么可能会更容易。找到了吗?

我假定代码也是压缩数据的一部分,因为其他固件部分仅包含资源,booboo和分区表。但是它可能在前8192个未压缩字节中,因此谢谢您的提示!我也尚未确定体系结构……您听说过“ EV9x”(“ / XC_ODM / sdk / SDK_selfcheck / src / EV9x_DevEnv”)吗?

固件包含“ ARM926”字符串,指向armv5te体系结构。相对较新的可处理4K H.264视频的相机是否可以基于使用了十年的处理器?

ARM926实际上具有用于加速类似DSP的代码的特殊指令(即armv5te中的e),但大多数处理可能是在专用硬件模块中完成的,而CPU仅处理UI和任务管理。

#1 楼

正如我对问题的更新中已经描述的那样,事实证明压缩算法是具有12位查找索引和4位查找长度的标准LZSS算法。它们只是以意外的方式存储(翻转的字节)。

从以下示例中进行询问:以下内容:

0x5FC3 = 0 1 0 1 1 1 1 1 1 1 0 0 0 0 1 1 b
         <-------------> <-----> <----->
         7             0 11    8 3     0 (bit indices)
             index        index  length


因此,在缓冲区位置3167处查找是6个字节。缓冲区位置是绝对的,并且始终从“物理”缓冲区索引0开始,不是

观察到怪异且变化的查找索引偏移的原因是


数据包含多个独立的压缩段,拆分后,给出了恒定的缓冲区偏移量
我仍然必须应用缓冲区偏移量才能正确解压缩,这可能是由于某些我尚未确定的数据头或初始化数据所致,但这超出了此范围问题