Lo hice y lo entendí

El blog de Vicente Navarro
01 feb

Desempaquetando el firmware de móviles y tablets Android de Samsung

Acabo de aterrizar en el mundo Android con un móvil y una tablet de Samsung. Es increíble la cantidad de movimiento que hay con las roms personalizadas… ¡Quién tuviera más un poco más de tiempo!

De momento, aún no me he decidido a probar nada “no oficial” hasta que entienda un poco mejor cómo funciona todo, pero sí que me he atrevido a probar a actualizar con el firmware oficial de otro país (Instalar Jelly Bean [4.1.1][OFICIAL][P5110XXCLK7]). Cuando he visto que el fichero del firmware era un fichero .tar.md5, no he podido resistirme a desempaquetarlo e intentar entender qué hay dentro.

Lo primero que uno se pregunta es que qué es eso de .tar.md5. Pues es simplemente un fichero tar con formato “ustar” (POSIX.1-1988) al que le añadirmos al final un md5sum de sí mismo (How to make an Odin flashable .tar from .img):

$ tar -H ustar -c image_1 [image_2 ...] > your_odin_package.tar
$ md5sum -t your_odin_package.tar >> your_odin_package.tar
$ mv your_odin_package.tar your_odin_package.tar.md5

La siguiente pregunta sería: ¿cómo podemos verificar la integridad de un fichero .tar.md5?

Podemos ver que el resultado del md5sum está claramente visible al final del fichero:

$ tail -c 100 P5110XXCLK7_P5110OXACLK7_HOME.tar.md5 | hexdump -C -v
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000020  65 63 39 66 61 34 62 31  38 66 64 31 36 35 38 63  |ec9fa4b18fd1658c|
00000030  62 30 61 36 65 39 62 31  63 62 39 66 66 32 62 63  |b0a6e9b1cb9ff2bc|
00000040  20 20 50 35 31 31 30 58  58 43 4c 4b 37 5f 50 35  |  P5110XXCLK7_P5|
00000050  31 31 30 4f 58 41 43 4c  4b 37 5f 48 4f 4d 45 2e  |110OXACLK7_HOME.|
00000060  74 61 72 0a                                       |tar.|
00000064

Sabiendo que la longitud de un hash MD5 es 128-bits (32 dígitos hexadecimales), el tamaño del nombre del fichero y que el md5sum deja dos espacios entre el hash MD5 y el nombre y añade un fin de línea (0x0a), podemos extraer el fichero .md5 leyendo sólo los últimos “32(MD5)+2(espacios)+1(0x0a)-4(.md5)+nombre del fichero” caracteres:

$ FICHERO_FIRMWARE=P5110XXCLK7_P5110OXACLK7_HOME.tar.md5
$ tail -c $(( $( echo -n $FICHERO_FIRMWARE | wc -c )+32+2+1-4 )) $FICHERO_FIRMWARE
ec9fa4b18fd1658cb0a6e9b1cb9ff2bc  P5110XXCLK7_P5110OXACLK7_HOME.tar

y verificar la integridad del fichero leyendo todo el fichero menos la parte del md5sum:

$ head -c -$(( $( echo -n $FICHERO_FIRMWARE | wc -c )+32+2+1-4 )) $FICHERO_FIRMWARE | md5sum
ec9fa4b18fd1658cb0a6e9b1cb9ff2bc  -

Una vez verificada la integridad del fichero, se desempaqueta como cualquier otro fichero tar:

$ tar xvf P5110XXCLK7_P5110OXACLK7_HOME.tar.md5
Sbl.bin
boot.img
cache.img
hidden.img
recovery.img
system.img

El fichero Sbl.bin es el Secondary Bootloader, del que se suele hablar a menudo en los foros de XDA Developers (por ejemplo: [LISTING] Firmware with Fixed (OS X Compatible) Secondary Bootloader (Sbl.bin)). El artículo “The Android boot process from power on” es una buena referencia para entender cómo es el proceso de arranque de Android.

El resto de ficheros .img son imágenes de las particiones de Android (Android Partitions Explained: boot, system, recovery, data, cache & misc).

Los ficheros boot.img y recovery.img contienen el kernel Linux y un initrd para arrancar el sistema. boot.img es el principal y recovery.img se usa para arrancar en modo recovery (en las tablets Samsung, suele ser arrancar con el botón de Power y el de “volumen abajo” apretados y en los móviles Samsung, suele ser arrancar con el botón de Power, Home y el de “volumen arriba” apretados).

Ambos ficheros están en formato Android Boot Images. Podemos desempaquetar dicho formato con abootimg o con el script del artículo Extracting, Editing and Re-Packing boot.img in Windows. Si nos decidimos por esta última opción, obtenemos los mencionados ficheros y las opciones de arranque que se le han de pasar al kernel:

$ ./split_bootimg.pl boot.img
Page size: 2048 (0x00000800)
Kernel size: 4385112 (0x0042e958)
Ramdisk size: 485026 (0x000766a2)
Second size: 0 (0x00000000)
Board name:
Command line: console=ttyO2,115200n8 mem=1024M androidboot.console=ttyO2 vram=20M omapfb.vram=0:16M androidboot.carrier=wifi
Writing boot.img-kernel ... complete.
Writing boot.img-ramdisk.gz ... complete.

$ ./split_bootimg.pl recovery.img
Page size: 2048 (0x00000800)
Kernel size: 4385112 (0x0042e958)
Ramdisk size: 1195680 (0x00123ea0)
Second size: 0 (0x00000000)
Board name:
Command line: console=ttyO2,115200n8 mem=1024M androidboot.console=ttyO2 vram=20M omapfb.vram=0:16M androidboot.carrier=wifi
Writing recovery.img-kernel ... complete.
Writing recovery.img-ramdisk.gz ... complete.

Los kernels de ambos ficheros son idénticos:

# md5sum boot.img-kernel recovery.img-kernel
89d3f9249d218e10e08f9b947188a76a  boot.img-kernel
89d3f9249d218e10e08f9b947188a76a  recovery.img-kernel

pero los initrd, no. Como es habitual en los initrd de los sistemas Linux de escritorio, es posible desempaquetarlos con “cpio -i -v” (o “cpio -t -v” si sólo queremos ver los ficheros que llevan):

gzip -d -c boot.img-ramdisk.gz | cpio -i -v
gzip -d -c recovery.img-ramdisk.gz | cpio -i -v

y veremos que más o menos llevan los mismos ficheros; con la particularidad de que el recovery.img-ramdisk.gz lleva además las típicas imágenes que componen la animación de cuando Android se está actualizando:

Android actualizándose

Finalmente, los ficheros cache.img, hidden.img y system.img son imágenes sparse de sistemas de ficheros ext4. Podemos convertirlas a imágenes normales con la utilidad simg2img (ver [REF] Unpacking and repacking stock rom .img files):

$ /tmp/ext4_utils/simg2img system.img system_normal.img

y ya montarla en modo loopback:

# mount -t ext4 -o loop system2.img /mnt/loop/

# ll /mnt/loop/
total 72
drwxr-xr-x  2 root root  8192 Nov 22 14:27 app
drwxr-xr-x  2 root 2000  4096 Nov 22 14:27 bin
-rw-r--r--  1 root root  2781 Nov 22 14:27 build.prop
drwxr-xr-x  2 root root  4096 Nov 22 14:27 cameradata
drwxr-xr-x 11 root root  4096 Nov 22 14:36 etc
drwxr-xr-x  2 root root  4096 Nov 22 14:27 fonts
drwxr-xr-x  2 root root  4096 Nov 22 14:27 framework
drwxr-xr-x  2 root root  4096 Nov 22 14:27 hdic
drwxr-xr-x  9 root root 12288 Nov 22 14:36 lib
drwxr-xr-x  4 root root  4096 Nov 22 14:27 media
drwxr-xr-x  4 root root  4096 Nov 22 14:27 tts
drwxr-xr-x  8 root root  4096 Nov 22 14:27 usr
drwxr-xr-x  8 root 2000  4096 Nov 22 14:36 vendor
drwxr-xr-x  4 root root  4096 Nov 22 14:27 vsc
drwxr-xr-x  2 root 2000  4096 Nov 22 14:27 xbin

Y en este punto, hemos conseguido acceso a todos los ficheros del firmware. Qué hacer ahora con ellos es otra, muy larga, historia…

Actualización 28/2/2013: He descubierto un interesante documento muy similar a esta entrada: HOWTO: Unpack, Edit, and Re-Pack Boot Images

:wq!

Entradas relacionadas

2 Comentarios a “Desempaquetando el firmware de móviles y tablets Android de Samsung”

Tema LHYLE09, creado por Vicente Navarro