2021/02/13

dracutで作られたinitrd・initramfsからのデータ取り出し

古いinitrd・initramfsでは、lsinitrdで中のファイルを見たり、取り出したりできていた。しかし、最近のものは中身を見ることができない。

Redhat系や、Gentooは、dracutコマンドでinitrd・initramfsが作成されるのだが、dracutコマンドで作成されたものが見れないっぽい。lsinitrdコマンドは、dracutパッケージ自体が提供しているにも関わらず。

結論から言うと、dracutパッケージに含まれるskipcpioを通すことで、lsinitrdコマンドで扱えるようになる。こんな感じ。

# /usr/lib/dracut/skipcpio initrd.lz > initrd.skipcpio.lz
# cd output_dir
# lsinitrd --unpack ../initrd64.skipcpio1.lz


skipcpioを通す前のファイルをlsinitrdするとこんな感じ。Early CPIO imageに続くdracut modulesの中身が、Early CPIO imageと同じような内容(CPU microcode)になっている。

# lsinitrd initrd.lz
initrd in UEFI: : 37M
========================================================================
Early CPIO image
========================================================================
drwxr-xr-x   3 root     root            0 May 24  2018 .
drwxr-xr-x   3 root     root            0 May 24  2018 kernel
drwxr-xr-x   3 root     root            0 May 24  2018 kernel/x86
drwxr-xr-x   2 root     root            0 May 24  2018 kernel/x86/microcode
-rw-r--r--   1 root     root        27434 May 24  2018 kernel/x86/microcode/AuthenticAMD.bin
========================================================================
Version:

Arguments:
dracut modules:
========================================================================
drwxr-xr-x   2 root     root            0 Jan 17 23:44 kernel
drwxr-xr-x   2 root     root            0 Jan 17 23:44 kernel/x86
drwxr-xr-x   2 root     root            0 Jan 17 23:44 kernel/x86/microcode
-rw-r--r--   1 root     root      3460096 Jan 17 23:44 kernel/x86/microcode/GenuineIntel.bin
========================================================================


skipcpioを通したあとのファイルをlsinitrdすると、先程のdracut modulesに入っていた部分がEarly CPIO imagenの部分に来ており、dracut modulesの中にinitrdの中身が来ている。

# lsinitrd initrd64.skipcpio1.lz
initrd in UEFI: : 37M
========================================================================
Early CPIO image
========================================================================
drwxr-xr-x   2 root     root            0 Jan 17 23:44 kernel
drwxr-xr-x   2 root     root            0 Jan 17 23:44 kernel/x86
drwxr-xr-x   2 root     root            0 Jan 17 23:44 kernel/x86/microcode
-rw-r--r--   1 root     root      3460096 Jan 17 23:44 kernel/x86/microcode/GenuineIntel.bin
========================================================================
Version:

Arguments:
dracut modules:
========================================================================
drwxr-xr-x  12 root     root            0 Jan 17 23:44 .
drwxr-xr-x   2 root     root            0 Jan 17 23:44 bin
-rwxr-xr-x  91 root     root            0 Mar  9  2020 bin/[
-rwxr-xr-x  91 root     root            0 Mar  9  2020 bin/[[
-rwxr-xr-x  91 root     root            0 Mar  9  2020 bin/acpid
-rwxr-xr-x  91 root     root            0 Mar  9  2020 bin/ash
-rwxr-xr-x  91 root     root            0 Mar  9  2020 bin/awk
-rwxr-xr-x  91 root     root            0 Mar  9  2020 bin/basename
-rwxr-xr-x  91 root     root            0 Mar  9  2020 bin/blockdev
~以下省略~

なぜmicrocodeが2個あるのかは調べていないが、一応解決はした。以下は参考まで。Gentooではdracutはsys-kernel/dracutでインストールできる。lsinitrdでファイルを展開するときには--unpackをつけて実行するが、lsinitrdを使わずともこんな感じで展開することもできる。(skipcpioやlsinitrdはパイプでの入力を受け付けてくれず、毎回ファイル名で指定しないとだめなようなので、それらを使わない方法を考える。)

# /usr/lib/dracut/skipcpio initrd.skipcpio1.lz | xz -d | cpio -idmv -D output_dir

xzコマンドの-dは解凍、cpioコマンドの-i -d -m -v -Dはそれぞれ、標準入力の入力を展開、展開時に必要となるディレクトリを作成、ファイルの作成日時を保持、処理したファイルを表示、展開先先ディレクトリを意味する。 ちなみに、initrdの中身をskipcpioしていったときのファイルは以下のような感じ。CPIOで2回アーカイブされたLZMA圧縮ファイルだった。Gzipの場合もあるだろうけど。

# file initrd.lz
initrd.lz: ASCII cpio archive (SVR4 with no CRC)

# /usr/lib/dracut/skipcpio initrd.lz > initrd64.skipcpio.lz

# file initrd.skipcpio.lz
initrd.skipcpio.lz: ASCII cpio archive (SVR4 with no CRC)

# /usr/lib/dracut/skipcpio initrd.skipcpio.lz > initrd.skipcpio.skipcpio.lz

# file initrd.skipcpio.skipcpio.lz
initrd.skipcpio.skipcpio.lz: LZMA compressed data, streamed

app-misc/binwalkパッケージのbinwalkを使うと、こんな感じ。まずはもともとのinitrd。

# binwalk initrd.lz

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             ASCII cpio archive (SVR4 with no CRC), file name: ".", file name length: "0x00000002", file size: "0x00000000"
112           0x70            ASCII cpio archive (SVR4 with no CRC), file name: "kernel", file name length: "0x00000007", file size: "0x00000000"
232           0xE8            ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86", file name length: "0x0000000B", file size: "0x00000000"
356           0x164           ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode", file name length: "0x00000015", file size: "0x00000000"
488           0x1E8           ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode/AuthenticAMD.bin", file name length: "0x00000026", file size: "0x00006B2A"
28072         0x6DA8          ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
28672         0x7000          ASCII cpio archive (SVR4 with no CRC), file name: "kernel", file name length: "0x00000007", file size: "0x00000000"
28792         0x7078          ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86", file name length: "0x0000000B", file size: "0x00000000"
28916         0x70F4          ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode", file name length: "0x00000015", file size: "0x00000000"
29200         0x7210          Intel x86 or x64 microcode, sig 0x000006f2, pf_mask 0x20, 2010-10-02, rev 0x005c, size 4096
33296         0x8210          Intel x86 or x64 microcode, sig 0x000006f2, pf_mask 0x01, 2010-10-02, rev 0x005d, size 4096
37392         0x9210          Intel x86 or x64 microcode, sig 0x000006f6, pf_mask 0x04, 2010-10-01, rev 0x00d2, size 4096
~同じような行が続くので、中略~
2917904       0x2C8610        Intel x86 or x64 microcode, sig 0x000906ed, pf_mask 0x22, 2020-05-24, rev 0x00de, size 103424
3021328       0x2E1A10        Intel x86 or x64 microcode, sig 0x000a0652, pf_mask 0x20, 2020-07-08, rev 0x00e0, size 93184
3114512       0x2F8610        Intel x86 or x64 microcode, sig 0x000a0653, pf_mask 0x22, 2020-07-08, rev 0x00e0, size 94208
3208720       0x30F610        Intel x86 or x64 microcode, sig 0x000a0655, pf_mask 0x22, 2020-07-08, rev 0x00e0, size 93184
3301904       0x326210        Intel x86 or x64 microcode, sig 0x000a0660, pf_mask 0x80, 2020-07-08, rev 0x00e0, size 94208
3396112       0x33D210        Intel x86 or x64 microcode, sig 0x000a0661, pf_mask 0x80, 2020-07-02, rev 0x00e0, size 93184
3489296       0x353E10        ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
3489792       0x354000        LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: -1 bytes
7950832       0x7951F0        MPEG transport stream data


skipcpioを1回かけたinitrdはこんな感じ。オリジナルのinitrdのbinwalk出力で"TRAILER!!!"と書かれた行までがなくなっているのが分かる。

# binwalk initrd.skipcpio.lz

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             ASCII cpio archive (SVR4 with no CRC), file name: "kernel", file name length: "0x00000007", file size: "0x00000000"
120           0x78            ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86", file name length: "0x0000000B", file size: "0x00000000"
244           0xF4            ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode", file name length: "0x00000015", file size: "0x00000000"
528           0x210           Intel x86 or x64 microcode, sig 0x000006f2, pf_mask 0x20, 2010-10-02, rev 0x005c, size 4096
4624          0x1210          Intel x86 or x64 microcode, sig 0x000006f2, pf_mask 0x01, 2010-10-02, rev 0x005d, size 4096
8720          0x2210          Intel x86 or x64 microcode, sig 0x000006f6, pf_mask 0x04, 2010-10-01, rev 0x00d2, size 4096
12816         0x3210          Intel x86 or x64 microcode, sig 0x000006f6, pf_mask 0x20, 2010-10-01, rev 0x00d1, size 4096
~同じような行が続くので、中略~
2785808       0x2A8210        Intel x86 or x64 microcode, sig 0x000906ec, pf_mask 0x22, 2020-06-03, rev 0x00de, size 103424
2889232       0x2C1610        Intel x86 or x64 microcode, sig 0x000906ed, pf_mask 0x22, 2020-05-24, rev 0x00de, size 103424
2992656       0x2DAA10        Intel x86 or x64 microcode, sig 0x000a0652, pf_mask 0x20, 2020-07-08, rev 0x00e0, size 93184
3085840       0x2F1610        Intel x86 or x64 microcode, sig 0x000a0653, pf_mask 0x22, 2020-07-08, rev 0x00e0, size 94208
3180048       0x308610        Intel x86 or x64 microcode, sig 0x000a0655, pf_mask 0x22, 2020-07-08, rev 0x00e0, size 93184
3273232       0x31F210        Intel x86 or x64 microcode, sig 0x000a0660, pf_mask 0x80, 2020-07-08, rev 0x00e0, size 94208
3367440       0x336210        Intel x86 or x64 microcode, sig 0x000a0661, pf_mask 0x80, 2020-07-02, rev 0x00e0, size 93184
3460624       0x34CE10        ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
3461120       0x34D000        LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: -1 bytes
7922160       0x78E1F0        MPEG transport stream data

skipcpioを2回かけたファイルはこんな感じ。上記同様に、"TRAILER!!!"の行までがなくなっている。

# binwalk initrd.skipcpio.skipcpio.lz

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: -1 bytes
4461040       0x4411F0        MPEG transport stream data

binwalkで特定したデータの場所を利用すると、skipcpioがやっているのと同じようなことができる。"TRAILER!!!"の次の行のDECIMALの数字+1までを切り落とすと、目的とするデータが取り出せる。

# tail -c +28672 initrd.lz | file -
/dev/stdin: data

# tail -c +28673 initrd.lz | file -
/dev/stdin: ASCII cpio archive (SVR4 with no CRC)

# tail -c +28674 initrd.lz | file -
/dev/stdin: data

# tail -c +28673 initrd.lz | openssl sha1
(stdin)= f8831c9233b18d5ed92835681e5fc9711b87df07

# openssl sha1 initrd.skipcpio.lz
SHA1(initrd64.skipcpio1.lz)= f8831c9233b18d5ed92835681e5fc9711b87df07

skipcpioと同じ出力。このデータをファイルに落としてlsinitrdコマンドを使ってファイルを取り出すことができる。なお、気をつけないといけないのは、"TRAILER!!!"の行のDECIMAL値+1でもfileコマンドの出力がcpio archiveになる点。当然ながら意図したものとは別ファイル。

# tail -c +28072 initrd.lz | file -
/dev/stdin: data

# tail -c +28073 initrd.lz | file -
/dev/stdin: ASCII cpio archive (SVR4 with no CRC)

# tail -c +28074 initrd.lz | file -
/dev/stdin: data

# tail -c +28073 initrd.lz | openssl sha1
(stdin)= 9f4de978de23e905a737097b43b9452e3eaf6290

lsinitrdを使わずに一気に展開するには、2つめの"TRAILER!!!"の次の行にあるLZMA compressed dataの行のDECIMAL値+1まで切り落とす。

# tail -c +3489793 initrd.lz | file -
/dev/stdin: LZMA compressed data, streamed

# tail -c +3489793 initrd.lz | openssl sha1
(stdin)= 3ce27552d7adc8a2421ac2ee8655f8f310b1eeae

# openssl sha1 initrd.skipcpio.skipcpio.lz
SHA1(initrd.skipcpio.skipcpio.lz)= 3ce27552d7adc8a2421ac2ee8655f8f310b1eeae

これを使うと、一気にinitrdを展開できる

# cd outputdir/
# tail -c +3489793 ../initrd.lz | xz -d | cpio -idmv -D output_dir


0 件のコメント:

コメントを投稿