El método de omisión de bloque cpio dado no funciona de manera confiable. Eso se debe a que las imágenes initrd que estaba obteniendo no tenían ambos archivos concatenados en un límite de 512 bytes.
En su lugar, haz esto:
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
Use el último número (21136) que no está en un límite de 512 bytes para mí:
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
Si conoces tu initrd.img
consta de un archivo cpio sin comprimir seguido de un archivo cpio comprimido gz, puede usar lo siguiente para extraer todos los archivos (de ambos archivos) en su directorio de trabajo actual (probado en bash):
(cpio -id; zcat | cpio -id) < /path/to/initrd.img
La línea de comando anterior pasa el contenido de initrd.img
como entrada estándar en una subcapa que ejecuta los dos comandos cpio -id
y zcat | cpio -id
secuencialmente. El primer comando (cpio -id
) termina una vez que ha leído todos los datos pertenecientes al primer archivo cpio. El contenido restante luego se pasa a zcat | cpio -id
, que descomprime y desempaqueta el segundo archivo.
Resulta que el initrd generado por la compilación en vivo de Debian (y, para mi sorpresa, aceptado por el kernel) es en realidad la concatenación de dos imágenes:
- un archivo CPIO que contiene actualizaciones de microcódigo que se aplicarán en el procesador;
- un archivo cpio comprimido con gzip, que en realidad contiene el árbol de archivos initrd (con los directorios /etc /bin /sbin /dev ... que se esperaban).
Al extraer el initrd.img original, directamente de la salida de compilación en vivo, obtuve esta salida:
$cpio -idv ../initrd.img
kernel
kernel/x86
kernel/x86/microcode
kernel/x86/microcode/GenuineIntel.bin
896 blocks
Lo que significa que la extracción de cpio terminó después de analizar 896 bloques de 512 bytes cada uno. Pero el initrd.img original era mucho más grande que 896*512 =458752B =448 KB:
$ls -liah initrd.img
3933924 -r--r--r-- 1 root root 21M Oct 21 10:05 initrd.img
Entonces, la imagen initrd real que estaba buscando se agregó justo después del primer archivo cpio (el que contiene las actualizaciones del microcódigo) y se podía acceder usando dd:
$dd if=initrd.img of=myActualInitrdImage.img.gz bs=512 skip=896