Il metodo cpio block skip fornito non funziona in modo affidabile. Questo perché le immagini initrd che stavo ottenendo io stesso non avevano entrambi gli archivi concatenati su un limite di 512 byte.
Invece, fai questo:
apt-get install binwalk
legolas [mc]# binwalk initrd.img
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"
376 0x178 ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode/GenuineIntel.bin", file name length: "0x00000026", file size: "0x00005000"
21004 0x520C ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
21136 0x5290 gzip compressed data, from Unix, last modified: Sat Feb 28 09:46:24 2015
Usa l'ultimo numero (21136) che per me non è su un limite di 512 byte:
legolas [mc]# dd if=initrd.img bs=21136 skip=1 | gunzip | cpio -tdv | head
drwxr-xr-x 1 root root 0 Feb 28 09:46 .
drwxr-xr-x 1 root root 0 Feb 28 09:46 bin
-rwxr-xr-x 1 root root 554424 Dec 17 2011 bin/busybox
lrwxrwxrwx 1 root root 7 Feb 28 09:46 bin/sh -> busybox
-rwxr-xr-x 1 root root 111288 Sep 23 2011 bin/loadkeys
-rwxr-xr-x 1 root root 2800 Aug 19 2013 bin/cat
-rwxr-xr-x 1 root root 856 Aug 19 2013 bin/chroot
-rwxr-xr-x 1 root root 5224 Aug 19 2013 bin/cpio
-rwxr-xr-x 1 root root 3936 Aug 19 2013 bin/dd
-rwxr-xr-x 1 root root 984 Aug 19 2013 bin/dmesg
Se conosci il tuo initrd.img
consiste in un archivio cpio non compresso seguito da un archivio cpio compresso con gz, è possibile utilizzare quanto segue per estrarre tutti i file (da entrambi gli archivi) nella directory di lavoro corrente (testato in bash):
(cpio -id; zcat | cpio -id) < /path/to/initrd.img
La suddetta riga di comando passa il contenuto di initrd.img
come input standard in una subshell che esegue i due comandi cpio -id
e zcat | cpio -id
sequenzialmente. Il primo comando (cpio -id
) termina dopo aver letto tutti i dati appartenenti al primo archivio cpio. Il contenuto rimanente viene quindi passato a zcat | cpio -id
, che decomprime e scompatta il secondo archivio.
Si scopre che l'initrd generato dalla live-build di Debian (e con mia sorpresa, accettato dal kernel) è in realtà la concatenazione di due immagini:
- un archivio CPIO contenente gli aggiornamenti del microcodice da applicare sul processore;
- un archivio cpio compresso con gzip, che in realtà contiene l'albero dei file initrd (con le directory /etc /bin /sbin /dev ... previste).
Dopo aver estratto l'originale initrd.img, direttamente dall'output live-build, ho ottenuto questo output:
$cpio -idv ../initrd.img
kernel
kernel/x86
kernel/x86/microcode
kernel/x86/microcode/GenuineIntel.bin
896 blocks
Ciò significa che l'estrazione cpio è terminata dopo aver analizzato 896 blocchi di 512 byte ciascuno. Ma l'originale initrd.img era molto più grande di 896*512 =458752B =448 KB :
$ls -liah initrd.img
3933924 -r--r--r-- 1 root root 21M Oct 21 10:05 initrd.img
Quindi l'immagine initrd effettiva che stavo cercando è stata aggiunta subito dopo il primo archivio cpio (quello contenente gli aggiornamenti del microcodice) e vi si poteva accedere usando dd:
$dd if=initrd.img of=myActualInitrdImage.img.gz bs=512 skip=896