重新打包嵌入式 initramfs

逆向工程 linux 垃圾桶
2021-07-01 02:35:39

我想修改嵌入在内核 bzImage 中的 initramfs 中的一些 init 脚本。我知道我可以通过不更改任何文件的大小来修改它们(例如,通过注释掉行,并在必要时删除字母或添加注释以平衡事情。)

理想情况下,我想从 zImage 中删除 xz 文件。解压它。修改cpio,然后重新压缩,然后DD回zImage。我希望通过不更改任何文件的大小,这会起作用。虽然我很欣赏它可能并不那么容易。因此,我们将不胜感激。

另外,我在内核映像上运行了 binwalk,它看起来像这样:


十进制十六进制描述
-------------------------------------------------- ------------------------------
0 0x0 Microsoft 可执行文件,可移植 (PE)
16817 0x41B1 xz 压缩数据
7297600 0x6F5A40 xz 压缩数据
7299230 0x6F609E Unix 路径:/x86/boot/compressed/kaslr_64.c!?
7483729 0x723151 DER格式的证书(x509 v3),头部长度:4,序列长度:762

现在。我还在文件上运行 Binwalk -e,它能够成功提取 xz 档案,并将其中至少一个 (0x41B1) 解压缩到一个 .cpio 文件中,我已经验证该文件包含 initramfs。但是我遇到的几个问题对我来说没有意义:

  1. binwalk 提取的“xz”文件大小为 7468247。然而,如果你减去上面两个 xz 文件之间的偏移量,你会得到 7280783。为什么会有不同?

  2. 当我尝试对 binwalk 提取的 .xz 文件运行 xz -d 时,我收到一条消息“压缩数据已损坏”。如果我对 binwalk 提取的 XZ 文件进行十六进制转储,它似乎没有与顶部的 XZ 文件关联的魔术字节。那么 binwalk 在正确提取 XZ 文件方面有何不同?binwalk 提取的究竟是什么,因为它似乎不是有效的 XZ 文件(至少根据 XZ 实用程序)?

  3. 当我在 Binwalk 提取的 CPIO 文件上运行 xz_wrap 脚本(包含在 linux 内核中)(或我尝试过的任何其他 XZ 选项)时——无论我做什么——我都无法获得 xz 文件生成与 binwalk 从 zImage 提取的原始 .xz 文件完全相同的文件。任何人都可以解释这个或我可以做些什么来生成完全相同的 XZ 存档?

我确信内核正在使用“CONFIG_HAVE_KERNEL_XZ=y”,因为我已经能够提取那么多。虽然我会注意到在 Binwalk 中启用了一些调试后,我可以看到它正在使用它的 lzma 解压缩器来解压缩从内核映像中提取的 XZ 文件。

这里有什么建议吗?我当然不是要重新发明轮子。因此,如果其他人想出了将 initramfs 重新打包到 x86 内核中的方法,我会很感兴趣。我也愿意在这里接受任何其他建议。

2个回答

谢谢指点。至少 xz.txt 回答了我的一个问题,这就是 XZ util 无法解压缩的原因。虽然我仍然不认为binwalk提取的是内核make过程生成的确切XZ文件。更多关于下面的内容。

内核是启用 UEFI 的内核,所以我猜第一个 PE 映像是 EFI 存根。

我正在处理的特定版本是 4.19.36。

我查看了 Makefile.lib。如果我理解正确,这是为 XZKERN 运行的命令:


cmd_xzkern = (cat $(filter-out FORCE,$^) | \
    sh $(srctree)/scripts/xz_wrap.sh && \
    $(call size_append, $(filter-out FORCE,$^))) > $@ || \
    (rm -f $@ ; 假)

换句话说:

猫 CPIO 文件 | xz_​​wrap.sh && size_append(CPIOFile) > output.xz

如果我们查看 xz_wrap.sh,它似乎是针对 X86 平台执行此操作的


xz --check=crc32 --x86 --lzma2=,dict=32MiB

因此,在我的场景中,如果我运行以下命令,我应该能够生成一个与通过 Binwalk 提取的文件非常接近的 XZ 文件(附加的大小长度除外):

猫41B1 | xz --check=crc32 --x86 --lzma2=,dict=32MiB > 41B1.xz

但是本场景生成的文件比原文件小20KB。

现在有趣的是,当我对原始文件进行 hexdump 时,我可以看到有大量的 0x00 填充,甚至还嵌入了一些字符串(这当然很奇怪,因为它是一个 XZ 文件)。这让我觉得binwalk提取的东西不完全是make过程中生成的XZ文件。

此外,如果其他人想破解,这里是内核映像的链接:

https://ufile.io/pjkx79e4

编辑:我还补充说,我不确定 xzmisc 是正确的运行命令。但无论如何,它会生成比原始文件更大的 XZ 文件。

对基于 5.5.13 稳定内核源代码的问题进行粗略检查后发现,几分钟内就发现使用了一个被调用的特殊程序xzkern摘自scripts/Makefile.lib

# XZ
# ---------------------------------------------------------------------------
# Use xzkern to compress the kernel image and xzmisc to compress other things.
#
# xzkern uses a big LZMA2 dictionary since it doesn't increase memory usage
# of the kernel decompressor. A BCJ filter is used if it is available for
# the target architecture. xzkern also appends uncompressed size of the data
# using size_append. The .xz format has the size information available at
# the end of the file too, but it's in more complex format and it's good to
# avoid changing the part of the boot code that reads the uncompressed size.
# Note that the bytes added by size_append will make the xz tool think that
# the file is corrupt. This is expected.
#
# xzmisc doesn't use size_append, so it can be used to create normal .xz
# files. xzmisc uses smaller LZMA2 dictionary than xzkern, because a very
# big dictionary would increase the memory usage too much in the multi-call
# decompression mode. A BCJ filter isn't used either.

我将此作为社区维基发布,因为它不是一个正确的答案,但对于仅发表评论来说太大了。

此外,您可以Documentation/xz.txt在内核源代码树中找到详细信息

无论哪种方式,它看起来都好像您正在寻找xzmisc或者(但不太可能)xzkern

此外,鉴于 binwalk 报告 PE 文件格式,我想知道这是否是一些与 UEFI 相关的图像。更多细节将有助于给出明确的答案。

但这应该有助于解决一些已知的难题。