1

我目前正在尝试提取嵌入在内核映像中的初始 RAM 文件系统,对其进行修改,然后用它重新打包内核映像。您可以搜索 GitHub 并在此处找到几个执行此操作的项目。我对这些脚本的问题是它们非常具体,或者变成了我无法与我正在使用的内核映像一起使用的硬代码值,或者它们很难进行逆向工程。我正在使用的内核映像使用 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

然后我可以像这样提取初始 RAM 文件系统 CPIO 存档Image

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 流的结尾?

4

1 回答 1

1

xz 文件或流的大小Unpadded Size在 xz 标头内的字段中进行编码。
Unpadded size字段表示不包括Block Padding字段的块的大小。

ie Unpadded Size = size-of(Block Header + Compressed Data + CRC fields)


一种快速获取大小的方法是使用xz工具本身,如下所示:

xz --robot --list <xz-file-or-stream> | cut -f 4 | sed -n 2p

参考:xz 文件格式


注意:未填充大小使用xz 文件格式规范的第 1.2 节多字节整数中描述的编码存储。该值绝不能为零;使用 Blocks 的当前结构,field 的实际最小值Unpadded Size是 5。

实现说明:由于块填充字段的大小不包含在未填充大小中,因此计算流的总大小或进行随机访问读取需要通过将未填充大小四舍五入到下一个四的倍数来计算块的实际大小.

于 2017-07-08T12:39:20.377 回答