2017-07-07 68 views
1

我目前正试图提取嵌入在内核映像中的初始RAM文件系统,对其进行修改并用它重新打包内核映像。您可以搜索GitHub并找到几个执行此操作的项目here。我对这些脚本的问题是它们非常具体,或者是硬编码值,我无法使用我正在使用的内核映像,或者它们很难进行反向工程。我正在使用的内核映像使用XZ压缩内核,并使用GZip压缩初始RAM文件系统CPIO存档。 GZip流的结束通过查找特定的字符串很容易找到,这些GitHub项目似乎需要知道这些流的确切结束。找到XZ流的结尾

我能够提取的内核像这样的压缩部分:

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字段。

未填充尺寸 =大小的(块首+压缩数据+ CRC字段)


一个快速的方法得到尺寸如下使用xz tool本身:

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

参考:xz file-format


注:未填充尺寸是使用在节在xz文件格式规范的1.2多字节整数描述的编码存储起来。 该值必须不能为零;根据当前的块结构,Unpadded Size字段的实际最小值为5。

实现注意事项:因为该块填充字段的大小不包括在未填补的大小,计算流的总规模或做随机访问读取需要计算由块的实际大小四舍五入Unpadded大小可达四倍的下一个倍数。