vmlinuz を解凍するための 1f 8b 08 00
お題「vmlinuz を解凍して vmlinux を取りだそう」。
環境は Mandriva Linux 2010.0。
Traditionally, when creating a bootable kernel image, the kernel is also compressed using the zlib algorithm, or since Linux 2.6.30[1], using LZMA or BZIP2, which requires a very small decompression stub to be included in the resulting image.
vmlinuz は gzip で圧縮されていることが知られています。Kernel 2.6.30 以降は LZMA か BZIP2 が使われていることもあるらしいですが、結論から言うと今回のは gzip。
ただし、ただの gzip 圧縮というわけではなく、16進数ダンプやらなにやらして確認して、ようやく解凍できました。
普通に gunzip を試みる
普通に gunzip を試してみます。
kei@frederica ~ $ gunzip /boot/vmlinuz-2.6.31.12-desktop-1mnb gzip: /boot/vmlinuz-2.6.31.12-desktop-1mnb: unknown suffix -- ignored
gunzip は拡張子を見るプログラムだったみたいですよ。
拡張子をつけて改めて。
kei@frederica ~ $ cp /boot/vmlinuz-2.6.31.12-desktop-1mnb ./vmlinuz.gz kei@frederica ~ $ gunzip ./vmlinuz.gz gzip: ./vmlinuz.gz: not in gzip format
!? gzip じゃねーよとおこられます。
ちなみにこのあと、BZIP2 や LZMA を試しても同様に撃沈。
16進数ダンプして gzip ヘッダーを確認する
od (8進数ダンプツール) にオプションをつけて16進数出力して確認してみます。
od -A d -t x1 /boot/vmlinuz-2.6.31.12-desktop-1mnb > vmlinuz.dump
-A d で表示されるオフセットの基数は10進数に。
-t x1 で16進数出力に。
gzip のヘッダーは「1f 8b 08 00」。なんか頭にいないんですけど。
0015952 c7 c1 c0 16 2c 00 48 c1 e9 03 fd f3 48 a5 fc 5e 0015968 48 8d 83 20 d8 2b 00 ff e0 1f 8b 08 00 d8 a0 5e 0015984 4b 02 03 ec fd 0b 7c 14 d5 fd f8 ff cf e6 02 41
ファイルに落として確認するのは面倒ですので、grep に渡すだけでいいです。
kei@frederica ~ $ od -A d -t x1 /boot/vmlinuz-2.6.31.12-desktop-1mnb | grep '1f 8b 08 00' 0015968 48 8d 83 20 d8 2b 00 ff e0 1f 8b 08 00 d8 a0 5e
gzip ヘッダーの開始バイト位置を確認する
0015968 48 8d 83 20 d8 2b 00 ff e0 1f 8b 08 00 d8 a0 5e
15968 から数えて 1f は 15968 + 9 = 15977。
つまりここまでスキップしてから gzip として解凍すれば、解凍できるはず。
dd でバイトスキップして zcat に渡す
dd でインプットファイルに /boot/vmlinuz-2.6.31.12-desktop-1mnb を食べさせて、ブロックサイズを1で 15977 個スキップします (0 から数えるから)。
kei@frederica ~ $ dd if=/boot/vmlinuz-2.6.31.12-desktop-1mnb bs=1 skip=15977 | zcat > vmlinux gzip: stdin: decompression OK, trailing garbage ignored
「decompression OK」!
strings で vmlinux を参照
無事解凍できましたが、当然バイナリ。
でも、Kernel version とかの文字列が含まれているはずです。
kei@frederica ~ $ strings vmlinux | grep "Linux version" Linux version 2.6.31.12-desktop-1mnb (qateam@titan.mandriva.com) (gcc version 4.4.1 (GCC) ) #1 SMP Tue Jan 26 02:59:07 EST 2010
とれたー!
結論
vmlinuz は gzip ヘッダーが頭にいないので、dd でスキップして解凍しましょう。
ちなみに fedora 8 の xen kernel は拡張子を .gz にしたうえで gunzip したら普通に解凍できたり。xen kernel は単純な gzip なのかなー。



odして目的の文字列が同じ行にあったのでgrepで見つかりましたが、
もし2行にわたっていたら上の方法では見つけられないので、もう一工夫必要がありますね。
ですねー。
まあ今回は od でとりあえずってかんじですけど、自前でダンプ+位置の確認をするスクリプトを書けば問題ない気もするので、スクリプト書いて「vmlinuz 解凍ソフトウェア」という名目で公開するとかアリかも。
解凍の需要があるのかって話からですね、はい。