从 MS-DOS 可执行文件中提取 zImage

逆向工程 linux 核心
2021-06-12 23:56:53

我有一个带有以下幻数的 aarch64 内核映像:

root@localhost:/# cat msImage|xxd -l4  
00000000: 4d5a 0091                                MZ..

root@localhost:/# file msImage 
msImage: MS-DOS executable, MZ for MS-DOS

是否可以从中提取可引导的 zImage?并提取 aarch64 elf 二进制文件?如何?

1个回答

AArch64 Linux 内核的整体格式可以在https://www.kernel.org/doc/Documentation/arm64/booting.txt 中找到

特别注意(强调我的):

AArch64 内核当前不提供解压缩器,因此如果使用压缩的 Image 目标(例如 Image.gz),则需要由引导加载程序执行解压缩(gzip 等)。对于未实现此要求的引导加载程序,可以使用未压缩的 Image 目标。

事实上,我从 Linaro下载了一个示例图像,其标题与第 4 节中的结构相匹配,即图像未压缩。

标头的十六进制转储:

0000000000: 4D 5A 00 91 57 00 00 14 │ 00 00 08 00 00 00 00 00  MZ.............
0000000010: 00 70 A8 00 00 00 00 00 │ 00 00 00 00 00 00 00 00  ...............
0000000020: 00 00 00 00 00 00 00 00 │ 00 00 00 00 00 00 00 00  ...............
0000000030: 00 00 00 00 00 00 00 00 │ 41 52 4D 64 40 00 00 00  ........ARMd@...

您可以magic在偏移量 0x38(0x644d5241或“ARM\x64”作为文本)看到该字段

显示的“MS-DOS 可执行文件”文本file是一个红鲱鱼:整个图像格式实际上是可移植可执行文件 (PE),它必须以MZ签名开头Linux 内核采用了一些技巧,使其看起来像一个有效的 PE 文件,以便它可以由符合 UEFI 的固件启动

没有要提取的“elf bibnary”,因为内核已链接到 PE 文件格式并且不再包含任何 ELF 标头。如果您想反汇编它,只需将其反汇编为原始 AArch64 二进制文件(例如将-bbinary -maarch64标志传递给 ARM objdump)——第二条指令将跳转到真正的入口点:

0000 4D 5A 00 91    ADD             X13, X18, #0x16
0004 57 00 00 14    B               stext

arch/arm64/kernel/head.S有关更多详细信息,请参阅内核源代码)。