?>/script>'; } ?> [Odisea] ¿Generar imagen firmware desde los archivos binarios de las mtd? Widgets Magazine

Autor Tema: [Odisea] ¿Generar imagen firmware desde los archivos binarios de las mtd?  (Leído 12798 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado peperfus

  • ******
  • Mensajes: 251
Hola, la pregunta es algo friky, xD

No sé si se podrá, y en tal caso, ¿alguien sabe cómo generar un archivo imagen de firmware a partir de los archivos mtd? Para que se pueda flashear con el sysupgrade.
(No sé si será relativamente fácil o difícil)

Gracias.
« Última modificación: 20-01-2020, 17:41 (Lunes) por peperfus »

Desconectado danitool

  • ****
  • Mensajes: 78
Re:¿Generar imagen firmware desde los archivos binarios de las mtd?
« Respuesta #1 en: 16-01-2020, 11:26 (Jueves) »
Hola peperfus. En OpenWrt la partición linux es la que contiene el firmware. Por tanto basta con hacer un backup de la misma

Primero identificamos el número de la partición
Código: [Seleccionar]
# cat /proc/mtd
mtd0: 00020000 00010000 "CFE"
mtd1: 00136eb0 00010000 "kernel"
mtd2: 00d89050 00010000 "rootfs"
mtd3: 00b40000 00010000 "rootfs_data"
mtd4: 00ec0000 00010000 "linux"
mtd5: 00100000 00010000 "cal_data"
mtd6: 00020000 00010000 "nvram"

en este caso es mtd4, hacemos el backup:
Código: [Seleccionar]
dd if=/dev/mtd4 of=/tmp/fw_backup.bin
Esto debería ser válido para cualquier router, al menos en brcm63xx. En otros targets puede haber routers en los que esto deba hacerse de forma diferente.

Si además queremos hacer backup de los cambios hechos en el router, entonces hacemos lo mismo con rootfs_data. Para restaurar esta partición podemos usar el comando
Código: [Seleccionar]
mtd -r write /tmp/rootfs_data-backup.bin rootfs_data
Saludos
« Última modificación: 16-01-2020, 11:33 (Jueves) por danitool »

Desconectado peperfus

  • ******
  • Mensajes: 251
Re:¿Generar imagen firmware desde los archivos binarios de las mtd?
« Respuesta #2 en: 16-01-2020, 12:51 (Jueves) »
Ya, bueno. Esto más o menos ya lo conocía.
Lo que pregunto es el proceso inverso, pero para el firmware (la partición linux).
Quiero saber cómo restaurarla, o bien cómo convertirla a archivo válido para que sysupgrade lo flashee.
¿No hace falta nada? Es simplemente pasarle al sysupgrade el archivo de la mtd4 ?

Yo creo que no, porque el archivo imagen contiene todas las particiones...., o al menos las más importantes...
Me imagino que habrá que hacer algo así como unir los archivos mtd en uno sólo, por lo menos. Aunque me parece que será más complicado.
« Última modificación: 16-01-2020, 13:06 (Jueves) por peperfus »

Desconectado danitool

  • ****
  • Mensajes: 78
Re:¿Generar imagen firmware desde los archivos binarios de las mtd?
« Respuesta #3 en: 18-01-2020, 12:13 (Sábado) »
Hola peperfus. Tienes razón, hay que tener en cuenta que la partición linux incluye rootfs_data la cual puede impedir el sysupgrade, y desde luego con un firmware original o CFE directamente rechazaría la imagen.

La estructura del firmware Openwrt para Broadcom es fácil de entender. Primero hay un header de tamaño 0x100 bytes, luego está el kernel y a continuación rootfs.

rootfs empalma con rootfs_data a partir de una marca para alinear el sistema jffs2. la cual es en hexadecimal
Código: [Seleccionar]
DEADCODE
De forma habilidosa lo que hace el sistema de creación de firmwares de Openwrt es rellenar con ceros todo lo que hay después de rootfs hasta alinear el firmware con el tamaño de bloque, y colocar esa marca a continuación. Así que esa marca es el final del firmware. Esa marca es la que indica donde empezar a generar el jffs2 la primera vez que se inicia Openwrt, por tanto se borrará.

Entonces lo que debemos hacer es cortar cortar todo lo que sobra a la partición linux para obtener solo lo que es  firmware flasheable y colocar al final del mismo esa marca manualmente con editor hexadecimal. Aunque por supuesto podría automatizarse con comandos.

Para hacer el corte y colocar la marca tenemos que sacar la calculadora, si sabemo previamente el tamño de las particiones cuando Openwrt saca esa información en el dmesg al arrancar.
O bien usar el propio header del firmware, ahí está toda la información del tamaño. Para analizar el header en la wiki hay una pequeña utilidad.
https://openwrt.org/docs/techref/brcm63xx.imagetag
Compilamos la utilidad analyzetag mediante gcc
Código: [Seleccionar]
gcc analyzetag.c -o brcmanalyze
por ejemplo ejecutando sobre un firmware openwrt nos suelta esto
Código: [Seleccionar]
./brcmanalyze -t bc310 -i openwrt-brcm63xx-generic-squashfs-cfe.bin
Broadcom image analyzer - v0.1.0
Copyright (C) 2009 Daniel Dickinson
Tag Version: 6
Signature 1: Broadcom Corporatio
Signature 2: ver. 2.0
Chip ID: 63268
Board ID: 963167REF3
Bigendian: true
Image size: 0038ff04, 3735300
CFE Address: 00000000, 0
CFE Length: 00000000, 0
Flash Root Address: bfc10100, 3217096960
Flash Root Length: 001e15ac, 1971628
Flash Kernel Address: bfc10100, 3217096960
Flash Kernel Length: 001ae958, 1763672
Vendor information:
Image CRC: 5a0bbdc5   [Computed Value: 5a0bbdc5]
Rootfs CRC:             [Computed Value: 78117b80]
Image CRC from sections: 5a0bbdc5   [Computed Value: 68d41778]
Header CRC: 2a5bc89c   [Computed Value: 2a5bc89c]
Kernel CRC: 2188206c   [Computed Value: 2188206c]
Rootfs CRC: 807b1178   [Computed Value: 807b1178]

La información que nos interesa
Código: [Seleccionar]
Image size: 0038ff04, 3735300
a  0x0038ff04 le sumamos el propio tamaño del header, que como comenté son 0x100, y nos da el tamaño total. Ese es el tamaño que debemos cortar, y el último paso es colocar la marca DEADCODE en los últimos cuatro bytes,

Quedaría algo así al final del firmware
Código: [Seleccionar]
003F:FFC0 | 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00
003F:FFD0 | 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00
003F:FFE0 | 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00
003F:FFF0 | 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00
0040:0000 | DE AD C0 DE                                       
Hay que fijarse que la marca queda alineada para saber que lo estamos haciendo bien.


Otra opción interesante sería hacer un backup de la partición linux, y modificar el header para que incluya nuestro rootfs_data modificado. Esto lo dejo como deberes para casa
« Última modificación: 18-01-2020, 12:29 (Sábado) por danitool »

Desconectado peperfus

  • ******
  • Mensajes: 251
Re:¿Generar imagen firmware desde los archivos binarios de las mtd?
« Respuesta #4 en: 19-01-2020, 20:21 (Domingo) »
Redéu !!
Error: emoticono adecuado not found.

Vaya crack estás hecho.
Me pasarías el programita compilado y así lo intento?
El ejecutable supongo que lo podré poner en marcha en un debian virtual.

Edito: Mejor lo miro en el dmesg, más fácil y rápido.
(No tengo demasiada idea, pero veo viable conseguirlo con algo de ayuda)
¿Me echarías una mano en el proceso? Si lo conseguimos, el resultado será una imagen openwrt 19.07.0 para HG556a versión A; que actualmente no hay ninguna funcional en la web oficial de openwrt. Podría colgarla en Mega, por ejemplo para que se la baje quien quiera (y el mérito te lo dejaría 100% a ti  ^-^)

Gracias.

PD: A ver. Según tengo entendido, esto es lo que tengo que hacer:
Mirar el dmesg del openwrt 19.07.0 del router que sí me arranca. Mirar el tamaño de las particiones (en especial, supongo que la de linux)
Coger la copia de dicha partición y editarla con un editor hexadecimal. Por ejemplo, este.
Encontrar dónde acaba la parte firmware (esto será lo que necesite ayuda, supongo) y a partir de ahí, ponerle DEADCODE y desde ahí al final, quitarlo todo.

¿Correcto?
« Última modificación: 19-01-2020, 20:36 (Domingo) por peperfus »

Desconectado peperfus

  • ******
  • Mensajes: 251
Re:¿Generar imagen firmware desde los archivos binarios de las mtd?
« Respuesta #5 en: 19-01-2020, 20:41 (Domingo) »
Según el dmesg:
Código: [Seleccionar]
bla bla bla ....
[    0.734964] 2 bcm963xx-imagetag partitions found on MTD device linux
[    0.741566] Creating 2 MTD partitions on "linux":
[    0.746468] 0x000000000100-0x00000018d59c : "kernel"
[    0.754138] 0x00000018d59c-0x000000ec0000 : "rootfs"
[    0.761745] mtd: device 3 (rootfs) set to be root filesystem
[    0.767696] 1 squashfs-split partitions found on MTD device rootfs
[    0.774152] 0x000000420000-0x000000ec0000 : "rootfs_data"
[    0.782219] 0x000000ee0000-0x000000fe0000 : "cal_data"
[    0.790230] 0x000000fe0000-0x000001000000 : "nvram"
bla bla bla ....
Entiendo entonces que las particiones importantes son la de kernel y la de rootfs ?
O sea, que hay que ir a la posición 0x...ec0000, meterle ahí DEADCODE y borrar todo lo demás en adelante. ¿Es algo así? ¿Voy más o menos encaminado?
Gracias.
-------
Ok, me acabo de fijar en que rootfs_data termina igual que rootfs. Supongo que habrá que restarle a rootfs la parte de rootfs_data. Lo que no entiendo es por qué hay que sumarle el 100.
A todo esto y para aclararnos.... estoy suponiendo que el número de la izquierda es donde empieza la partición y el de la derecha, donde acaba, correcto??
Habría que restar: ec0000 - 42000, no?
El resultado sería la posición donde marcar el DEADCODE de mtd3. ¿Correcto? Y el resto hacia adelante, recortarlo.
« Última modificación: 20-01-2020, 12:49 (Lunes) por peperfus »

Desconectado peperfus

  • ******
  • Mensajes: 251
Re:¿Generar imagen firmware desde los archivos binarios de las mtd?
« Respuesta #6 en: 20-01-2020, 17:00 (Lunes) »
Buenas, aquí sigo intentando cositas en un mundo desconocido  ;D

De momento, esto es lo que he hecho: he descargado la imagen oficial de open 19 y he visto esto:
Así empieza:

Y así acaba, efectivamente con el deadc0de.


Sin embargo, el archivo que abro de la mtd4.... tiene mogollón de FF FF FF FF.... donde el oficial tiene ceros.
Se me ocurre ir a la posición 420000 y meterle el DEADC0DE; eso lo he conseguido hacer, y quitarle el resto desde ahí; pero en cambio, el principio no se parece en nada.... y no sé si debería insertar esa información.... (¿Eso es el header / la cabecera?)
En fin. Luego pongo más imágenes.
------

Y así es como empieza el archivo de la mtd4 (partición "linux"). En la imagen se ve tal cual, pero luego le añadí el DEADC0DE en la misma posición que la imagen oficial y quité el resto de bytes. Sin embargo, no sé qué tengo que hacer al principio del archivo... Voy a ver si copiando un poco....
(He intentado flashearlo con el DEADC0DE puesto pero me dice imagen no válida.)
Vamos a ver... algo estoy haciendo mal. Esto no tiene sentido. El principio del archivo de la mtd4 está lleno de FFFF...., desde la posición C hasta la posición 200000.

danitool, ¿me echas un cable?
« Última modificación: 20-01-2020, 18:06 (Lunes) por peperfus »

Desconectado Tki2000

  • Moderador
  • *
  • Mensajes: 2247
En una flash, el FF es que dichos bytes no están programados con ningún valor.
Una flash toda a "0" o virgen, se lee a FF.
En realidad borrar una flash, es ponerla toda a FF. Lo que programas al escribir son los 0s (ceros), y no los 1s (unos). Por eso hay que borrar la flash, o el bloque de flash, antes de escribir, porque lo único que puedes escribir son 0s (ceros). Y lo único que permite poner a 1 los bits es borrar bloques.
En una parte de la flash que no sea código ejecutable o datos almacenados, leer FF simplemente significa que los bytes no se han reprogramado después de haber sido borrados.
« Última modificación: 20-01-2020, 20:19 (Lunes) por Tki2000 »

Desconectado peperfus

  • ******
  • Mensajes: 251
Re:[Odisea] ¿Generar imagen firmware desde los archivos binarios de las mtd?
« Respuesta #8 en: 21-01-2020, 13:54 (Martes) »
Ok, gracias.

Seguiré haciendo pruebas y experimentos, a ver si tengo suerte y suena la campana.
Si consigo algo lo comentaré.

Desconectado danitool

  • ****
  • Mensajes: 78
Re:[Odisea] ¿Generar imagen firmware desde los archivos binarios de las mtd?
« Respuesta #9 en: 21-01-2020, 20:18 (Martes) »
Citar
vSe me ocurre ir a la posición 420000 y meterle el DEADC0DE; eso lo he conseguido hacer, y quitarle el resto desde ahí; pero en cambio, el principio no se parece en nada.... y no sé si debería insertar esa información.... (¿Eso es el header / la cabecera?)

la posición 0x420000 es donde empieza rootfs_data, que es donde acaba el firmware teóricamente, pero has de restarle el bootloader  que no va includido en el mismo. Lo raro de tu dmesg es que no se ve el bootloader por ninguna parte, entonces algo raro pasa..... Lo típico es que el tamaño de CFE sea de 0x20000. Es lo que habría que restar

Se me ocurre que, si lo que encuentras son FF FF FF FF en el backup entonces deberás retroceder hasta encontrar ceros que es donde empezó Openwrt a hacer operaciones de borrado, e insertar ahí el deadcode.

Pero lo suyo es leer la cabecera del firmware. Si abres unos cuantos firmwares "vírgenes" en el editor hexadecimal te darás cuenta como empieza esa cabecera. Lo más correcto es usar el analyzetag para que la lea, para que te dé la información exacta saber cuanto ocupa, y así evitas perderte entre los bytes.. Si metes más bytes de los que que informa la cabecera o cambias algún byte, dará un error de CRC. Ese CRC también va en la cabecera.

Desconectado peperfus

  • ******
  • Mensajes: 251
Re:[Odisea] ¿Generar imagen firmware desde los archivos binarios de las mtd?
« Respuesta #10 en: 24-01-2020, 10:58 (Viernes) »
No me termino de aclarar con esto, lo siento.
No soy capaz.

Si alguien quiere intentarlo por mí, estoy dispuesto a enviarle mi router y recogerlo (y pagar los gastos de envío de ida y vuelta), en aras del I+D. (España)
« Última modificación: 24-01-2020, 10:58 (Viernes) por peperfus »

Desconectado danitool

  • ****
  • Mensajes: 78
Re:[Odisea] ¿Generar imagen firmware desde los archivos binarios de las mtd?
« Respuesta #11 en: 26-01-2020, 12:28 (Domingo) »
No me termino de aclarar con esto, lo siento.
No soy capaz.

Si alguien quiere intentarlo por mí, estoy dispuesto a enviarle mi router y recogerlo (y pagar los gastos de envío de ida y vuelta), en aras del I+D. (España)

Para saber la longitud de kernel+rootfs resulta que el tamaño que sale por el dmesg es ya el real. No me había dado cuenta que esto cambió hace algún tiempo... en el pasado eran direcciones absolutas respecto al principio de la flash. El caso es que que no hay que calcular nada en teoría y 0x000000420000 es lo que hay que cortar de la partición linux.  Leer el header del firmware siempre es lo más fiable por estos motivos.

Si quieres pon aquí mismo un link del backup de la partición linux y extraigo el firmware si es posible.
« Última modificación: 26-01-2020, 12:35 (Domingo) por danitool »

Desconectado peperfus

  • ******
  • Mensajes: 251
Re:[Odisea] ¿Generar imagen firmware desde los archivos binarios de las mtd?
« Respuesta #12 en: 26-01-2020, 20:26 (Domingo) »
Ok, aquí está:

https://mega.nz/#!905m0YSS!nvLg8HrqPUTcZ7kpZlypp3ZkywSMnqmzGaRoNfK6IJI

Muchas gracias.

Edito: (El archivo estaba mal, no era ese  :P. El correcto está en mi siguiente post)
« Última modificación: 26-01-2020, 22:22 (Domingo) por peperfus »

Desconectado danitool

  • ****
  • Mensajes: 78
Re:[Odisea] ¿Generar imagen firmware desde los archivos binarios de las mtd?
« Respuesta #13 en: 26-01-2020, 22:15 (Domingo) »
Ok, aquí está:

https://mega.nz/#!905m0YSS!nvLg8HrqPUTcZ7kpZlypp3ZkywSMnqmzGaRoNfK6IJI

Muchas gracias.

El backup parece contener únicamente un sistema de ficheros jffs2. Tal vez no sea la partición correcta, y por la pinta parece rootfs_data. Cual es la salida del comando "cat /proc/mtd" ?

Desconectado peperfus

  • ******
  • Mensajes: 251
Re:[Odisea] ¿Generar imagen firmware desde los archivos binarios de las mtd?
« Respuesta #14 en: 26-01-2020, 22:19 (Domingo) »
Hola, lo acabo de ver.

Lo siento  :P, lo tenía mal, esa no es.  :P :P :P

Código: [Seleccionar]
root@OFICINA:~# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00020000 00020000 "CFE"
mtd1: 00ec0000 00020000 "linux"
mtd2: 0018d49c 00020000 "kernel"
mtd3: 00d32a64 00020000 "rootfs"
mtd4: 00aa0000 00020000 "rootfs_data"
mtd5: 00100000 00020000 "cal_data"
mtd6: 00020000 00020000 "nvram"

Esta es, la partición 1:
https://mega.nz/#!A4w2jabY!JpnCMNZdup_GMLTOEPMp4aE7OwBXRVmK6jNN6qrm0wU

Ahora veo que al abrirlo con el hexed.it se parece más al archivo de firmware.  ^-^
« Última modificación: 26-01-2020, 22:23 (Domingo) por peperfus »

Desconectado danitool

  • ****
  • Mensajes: 78
Re:[Odisea] ¿Generar imagen firmware desde los archivos binarios de las mtd?
« Respuesta #15 en: 26-01-2020, 22:36 (Domingo) »
Hola, lo acabo de ver.

Lo siento  :P, lo tenía mal, esa no es.  :P :P :P

Código: [Seleccionar]
root@OFICINA:~# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00020000 00020000 "CFE"
mtd1: 00ec0000 00020000 "linux"
mtd2: 0018d49c 00020000 "kernel"
mtd3: 00d32a64 00020000 "rootfs"
mtd4: 00aa0000 00020000 "rootfs_data"
mtd5: 00100000 00020000 "cal_data"
mtd6: 00020000 00020000 "nvram"

Esta es, la partición 1:
https://mega.nz/#!A4w2jabY!JpnCMNZdup_GMLTOEPMp4aE7OwBXRVmK6jNN6qrm0wU

Ahora veo que al abrirlo con el hexed.it se parece más al archivo de firmware.  ^-^

He cortado el firmware. Por lo visto el DEADCODE todavía estaba ahí, así que ha sido muy fácil. Pero como no lo he testeado, no sé si funciona correctamente.
https://drive.google.com/file/d/1fKcagBKJJfgXO1-HoXcKQCLWbRoI6Tpx/view?usp=sharing

Desconectado peperfus

  • ******
  • Mensajes: 251
Re:[Odisea] ¿Generar imagen firmware desde los archivos binarios de las mtd?
« Respuesta #16 en: 27-01-2020, 12:48 (Lunes) »
¡¡Gracias, danitool !!
Lo he flasheado y no ha funcionado.
Es muy curioso lo que pasa.

Explico: el caso es que la versión 19.07.0 de Openwrt falla en el arranque en los HG556a (A, B y C). Pero misteriosamente, tengo un HG556a que sí arranca con esa versión (llámalo Expediente X ???). Y quería pasarle una copia del firmware a otro HG556a (tengo 4 en total). Pero al hacerlo con tu copia extraída, no arranca.

Ahora me falta conectarle un cable serial y ver lo que pasa por consola, a ver si es el fallo "oficial" del arranque, o es por otra cosa. Cuando pueda voy a seguir haciendo pruebas y cuando lo vea, lo pongo por aquí, porque me parece interesante compartirlo.