定位 XZ 流的结尾
Posted
技术标签:
【中文标题】定位 XZ 流的结尾【英文标题】:Locate the end of an XZ stream 【发布时间】:2017-07-07 18:08:05 【问题描述】:我目前正在尝试提取嵌入在内核映像中的初始 RAM 文件系统,对其进行修改,然后用它重新打包内核映像。你可以搜索 GitHub 并找到几个这样做的项目here。我对这些脚本的问题是它们非常具体,或者变成了我无法与我正在使用的内核映像一起使用的硬代码值,或者它们很难进行逆向工程。我正在使用的内核映像使用 XZ 压缩内核和 GZip 压缩初始 RAM 文件系统 CPIO 存档。通过查找特定字符串很容易找到 GZip 流的结尾,而那些 GitHub 项目似乎需要知道这些流的确切结尾。
我可以像这样提取内核的压缩部分:
offset=$(cat zImage | grep -aob $'\xFD\x37\x7A\x58\x5A\x00' | cut -d ":" -f 1 | sed -n 2p)
dd bs=1 skip=$offset if=zImage | xzcat > Image
然后我可以像这样从Image
提取初始 RAM 文件系统 CPIO 存档:
offset=$(cat "$1" | grep -aob $'\x1F\x8B\x08' | cut -d ":" -f 1 | sed -n 2p)
dd bs=1 skip=$offset if=Image | zcat > initramfs.cpio
现在,通过阅读那些 GitHub 脚本,似乎必须知道压缩流的结束地址。如何在 shell 脚本中找到 XZ 流的结尾?
【问题讨论】:
【参考方案1】:xz 文件或流的大小在 xz 标头的 Unpadded Size
字段中进行编码。Unpadded size
字段表示块的大小不包括 Block Padding
字段。
即未填充大小 = size-of(块头 + 压缩数据 + CRC 字段)
获取大小的一种快速方法是使用xz tool 本身,如下所示:
xz --robot --list <xz-file-or-stream> | cut -f 4 | sed -n 2p
参考:xz file-format。
注意:未填充大小使用 xz 文件格式规范的第 1.2 节多字节整数中描述的编码存储。
该值绝不能为零;使用 Blocks 的当前结构,Unpadded Size
字段的实际最小值为 5。
实现说明:由于Block Padding字段的大小不包含在Unpadded Size中,计算一个Stream的总大小或者做随机读取需要计算实际大小将未填充大小四舍五入到下一个四的倍数。
【讨论】:
以上是关于定位 XZ 流的结尾的主要内容,如果未能解决你的问题,请参考以下文章