bzImage解压缩

bzImage诚如其名是big image的意思,不是压缩的image。

这里解压,采取的是半解压方式。

BzImage可能有两种,一种只有小量kernel,一种是小量kernel+initramfs。我解压缩针对initramfs

bzImage的头部有些验证码,所以解压缩的时候需要去掉。

对于bzip2压缩的initramfs,参考1

对于gunzip压缩的initramfs,参考2

我使用的是gunzip的bzImage

处理如下

1 找到压缩的头部

od -h -A d bzImage | grep --color -m 3 -A 1 -i 8b1f

结果:

0014928 838d d650 03a6 e0ff 8b1f 0008 feb8 571d
0014944 0302 fdec 607b 551c f8fd ef71 d2e6 bd26
--
0029792 e585 fd1b 6fc1 8b1f fb38 676c ad47 56f3
0029808 9b44 ee5b 9592 33b6 2ca2 24e2 ba65 b0d2
--
0080480 543e 5981 3302 d578 32a9 fa04 9441 8b1f
0080496 9bf4 2d72 e16f affc c751 ec97 e519 e677

注意0014936的位置有个8b1f 0008,这是gzip压缩的标记

结果:发现了压缩标记在14936字节

2 解压缩

dd if=BZIMAGE.INS bs=1 skip=14936 | gunzip > vmlinux.bin

结果:得到未压缩的vmlinux.bin,他压缩了就是bzImage.

file vmlinux.bin发现是ELF。这个里面包含了initramfs.tar.gz

3 找到压缩的头部

[root@localhost share]# od -h -A d vmlinux.bin | grep --color -m 3 -A 1 -i "8b1f 0008"
13385728 8b1f 0008 faa2 571d 0302 9ab4 700f c753
13385744 c099 649f 8419 2263 ce5d 9569 a79e 2479
^C

4 解压缩成为initramfs
[root@localhost share]# dd if=vmlinux.bin bs=1 skip=13385728 | gunzip > initramfs.cpio


参考

1 http://gentoo-en.vfose.ru/wiki/Initramfs

文中提到

Dismantling the Kernel

You can skip this step if your initramfs is a separate cpio archive already. Otherwise, you'll have to get the built-in cpio archive out of the kernel image. To do that, you have to dismantle it, which isn't easy, since the kernel image is a combination of boot sector and compressed archive itself. It also depends on the compression you are using for your kernel and for your initramfs. For simplicity, this example assumes bzip2 - however, the principle is the same for other compression methods.

First, you have to search for the compression signature in the kernel image. For bzip2, this is BZh. For gzip, you can use $'\x1F\x8B\x08'. You can also use app-misc/binwalk to find offsets of compression signatures in files.

grep -a -b --only-matching BZh bzImage

For me, this prints 12888:BZh, so the offset is 12888 bytes. Now you can extract the kernel image:

dd if=bzImage bs=1 skip=12888 | bunzip2 > Image

Now, you have the uncompressed kernel image. Somewhere within this image resides the compressed initramfs archive, so just iterate the previous process to find it.

grep -a -b --only-matching BZh Image

For me, this prints 171424:BZh, so the offset is 171424 bytes this time. Now you can extract the initramfs cpio archive:

dd if=Image bs=1 skip=171424 | bunzip2 > initramfs.cpio

If you want to verify that you actually got a cpio archive from that, use file:

file initramfs.cpio

Extracting the cpio archive

If your initramfs cpio archive was a separate file, you have to uncompress it first.

gunzip initramfs.cpio.gz

To extract the uncompressed initramfs.cpio, you can do so with the following command. Please note that this overwrites files in the directory you're currently in:

cpio -i -d -H newc --no-absolute-filenames < initramfs.cpio

With this, you should have successfully recovered your initramfs structure.


2

http://zhidao.baidu.com/link?url=hbydMhtPHdU_uo7Ii4nHYxNGXLvyZJiZX-dMpYYwEaScfPoY-DXB2MGgYCJFF3fdhzS3tmsXoNB090N-Pm702boAvVbAPdLnKzH6nf84zrq

文中提到

  #! /bin/sh
    set -x
    #
    # 一般gzip压缩包的magic值为0x8b1f后跟0x0008,或者0x0808。
    # 这里就是要找出这个偏移。
    # 119116,就是这个偏移,这个偏移在不同的bzImage里是不同的,所以,这里需要手动调整一下。
    # 解压后的文件即vmlinux.bin
    od -h -A d bzImage | grep --color -m 3 -A 1 -i 8b1f
    dd if=bzImage bs=1 skip=11916 | gunzip > vmlinux.bin
    # 调用我写的一个python脚本,生成gnu linker script。
    ./genlds.py > vmlinux.elf.lds
    # 构造 ELF 信息,结果文件为vmlinux.elf
    ld -m elf_x86_64 --format binary --oformat elf64-x86-64 -T vmlinux.elf.lds vmlinux.bin -o vmlinux.elf
    # 如果是32位系统,可以用以下命令
    #ld -m elf_i386 --format binary --oformat elf32-i386 -T vmlinux.elf.lds vmlinux.bin -o vmlinux.elf
    # 删除在上一步生成的多余符号。
    objcopy --strip-symbol _binary_vmlinux

你可能感兴趣的:(bzImage解压缩)