重新创建 lzma 存档(非流式传输)

逆向工程 固件 文件格式 开箱 嵌入式 包装工
2021-06-27 15:52:43

我正在反转 Dlink 相机固件 ( dcs5000l_v1.03.05.bin),并且能够dd通过lzma -d lzma_data.lzma. 我希望能够从提取的文件中重新创建 lzma 存档,然后再对其进行修改。问题是,我无法重新创建确切的 lzma 文件。

第 1 期

当我尝试重新压缩提取的数据时,我能够通过以下方式获得正确的属性(字节0x5d)和字典大小(0x02000000

lzma -8 -z decompressed_data

,但数据是流式传输的,因此标头确实包含0xFFFF...而不是未压缩的大小(0x6b660a,在交换字节序中0x0a666b)。

下面是lzma开头的原始数据和我的recreation的对比:

原来的

00000000: 5d00 0000 020a 666b 0000 0000 0000 006f ].....fk..o

娱乐

00000000: 5d00 0000 02ff ffff ffff ffff ff00 006f ]........o

从我读到的内容来看,只有当 lzma 工具从 stdin 获取数据时才应压缩数据流,但在我的情况下,我将完整文件提供给该工具,并希望将未压缩的大小写入标头。我不知道我的相机是否可以处理流式模式并想创建非流式 lzma 数据。

有什么想法我可以强迫吗?

第二期

除此之外,我还遇到了重新创建的 lzma 有效负载不同的问题。从 position 开始0000 00B0,lzma 压缩数据开始不同:

原来的

000000b0: 2d7b 73cd 13f6 1621 2ea9 ea09 20f1 8a47 -{s....!.....G
000000c0:0c5a 53cc d87f d893 45a2 5196 8960 84dd .ZS.....EQ....

娱乐

000000b0: 2d7b 73cd 13f6 1621 2ea9 ea09 20f1 8a4a -{s....!.....J
000000c0: 4634 378a ac21 efd9 c3e2 3ada 4744 a347 F47.......:.GD.G

压缩的 lzma 档案的大小在原始文件(大小:4522684 字节)和重新创建的文件(大小:4521221 字节)之间也有所不同。据我了解,流式与非流式问题不应该影响实际的压缩数据,只需在末尾附加一个 5 或 6 字节的流结束标记。因此,即使我有正确的属性和字典大小,lzma 压缩数据在我的娱乐中也不同,并且大小不同。

你知道为什么会这样吗,如果我能解决它?

2个回答

很难确定,但可能您使用的库版本或压缩参数与原始程序不同。相同的数据可能由不同的压缩流表示,因此它们可以随着使压缩更加优化的新版本或当您调整某些参数(例如压缩级别)而改变。一般来说,只要解压后的数据相同,压缩流中的细微差别应该无关紧要。

正如 Igor 所说,您正在使用的 lzma 压缩存档很可能是使用较旧的库版本生成的。如果您使用系统的内置lzma命令重新压缩文件,您可能无法获得正确的输出,因为它可能只是别名为xz --format=lzma. 请参阅您系统的手册页以确认xzlzma确认。如果lzma确实别名为xz,则它使用 XZ Utils 来压缩您的存档,它使用 LZMA SDK 的更高版本。

您可以尝试使用基于 LZMA SDK 4.32 的LZMA Utils ( https://tukaani.org/lzma/ )。简单地:

  1. 克隆他们的 git 存储库
git clone https://git.tukaani.org/lzma.git
  1. autogen.sh在项目的根目录中运行(确保安装所需的依赖项,如automakelibtoolize
  2. 运行新生成的configureshell脚本
  3. 运行make编译程序
  4. 可以运行make install,但此时,您应该lzma<Project Root>/src/lzma/. 您可以直接从此目录运行可执行文件,而无需更改系统lzma配置。

(这些说明也在INSTALL项目根目录下文件中,但是第一次看还是比较难理解的,为了方便,我在这里破译了。)

你应该能够通过运行以下命令来压缩你的文件,假设in是你的输入文件,out.lzma是你的输出文件,~/lzma/src/lzma/lzma是你编译的lzma二进制文件:

~/lzma/src/lzma/lzma -9 -c -z in >out.lzma

我建议在尝试压缩修改后的文件之前尝试重新压缩未修改的提取文件以验证此方法是否有效,以防万一。