Discos multimedia basados en Wyplayer/Firmware
Los ficheros de firmware son los que permiten al usuario actualizar éstos discos multimedia. Los suministran las casa que que venden cada dispositivo y parece que no son compatibles los de un dispositivo con los de otro.
Formato de los ficheros firmware
editarMétodo de actualización
editarHitos en la ingeniería inversa de los ficheros de firmware
editar- Conocer la estructura de los fichero .wup (Hecho)
- Conocer el formato de las partes del fichero .wup (XML y Kernel, queda el software)
- Conocer la funcionalidad de cada parte del fichero .wup (Pendiente)
- Actualizar los dispositivos con el firmware de otro dispositivo. (Pendiente)
- Generar "kernel" propio e instalarlo en los dispositivos. (Pendiente)
- Generar "software" propio e instalarlo en los dispositivos. (Pendiente)
- Intentar obtener las clave que encripta la parte del software de los update.wup para cada dispositivo. (Pendiente)
- Acceder al dispositivo para obtener más información durante su funcionamiento. (Pendiente)
Estructura interna de los ficheros wup
editarCódigo XML
editarEjemplo:
<root>
<specVersion>
<major>1</major>
<minor>1</minor>
</specVersion>
<update>
<version>001.002.00014.0000007929</version>
<displayName>Grab'n'GO Wireless Media Titan</displayName>
<description>-----</description>
<target>WBD000930AA</target>
<targetList>
<target>WBD000930AB</target>
</targetList>
<level>0</level>
<provider>-----</provider>
<generationDatetime>2009-02-09T10:22:13+0100Z</generationDatetime>
<uri>announce</uri>
<signature/>
<partList>
<part>
<id>1</id>
<displayName>Kernel</displayName>
<version>2.6.17.14.617</version>
<type>kernel</type>
<uri>kernel</uri>
<compression>none</compression>
<parent>1</parent>
<generationDatetime>2009-02-09T10:22:09+0100Z</generationDatetime>
<uncompressedSize>1962745</uncompressedSize>
<signature>ddbeb13f573a12c880b1d971ff25949b</signature>
</part>
<part>
<id>2</id>
<displayName>Software</displayName>
<version>001.002.00014.0000007929</version>
<type>core</type>
<uri>core</uri>
<compression>none</compression>
<parent>2</parent>
<generationDatetime>2009-02-09T10:22:09+0100Z</generationDatetime>
<uncompressedSize>121692160</uncompressedSize>
<signature>1afb31cdc482ce22c1ae0406ee55161f</signature>
</part>
</partList>
</update>
</root>
Fichero de kernel
editarSegún la salida del comando file (existente en sistemas basados en *nix) el fichero de kernel es de tipo:
System:$ file kernel2.6.17.14.617_1.2.14.7929.bin
kernel2.6.17.14.617_1.2.14.7929.bin: u-boot/PPCBoot image
Investigando el código
editarEn el código fuente suministrado por wyplay existe el directorio uboot-<version> Investigando un poco como se complila, en uboot se ha encontrado que en el directorio board hay un sub-directorio llamado wyplay, que parecen ser las especificaciones necesarias para compilar el u-boot para las distintas placas bases de wyplay.
- Al revisar el Makefile que se encuetra en el directorio princial uboot-<version> se puede encontrar una entrada para diferentes "boards" de wyplay.
Se está intentando configurar y compilar para wymdbox_config (wyplayer multimedia box) que se entiende que es la que corresponde con los estos discos.
- El make falla porque falta el compilador para SH4 (¿?). Este aarece que puede ser el tipo de arquitectura del procesador que llevan los discos multimedia (Especificación: http://lars.nocrew.org/computers/processors/SuperH/sh4cpu_sh1.pdf).
- Se ha compilado un toolchain para la compilación cruzada para esta arquitectura: http://wiki.debian.org/SH4/CrossToolchain
- Se ha compilado el u-boot para la wymdbox.
- Parece ser que el fichero kernel de los firmwares está compuesto por el u-boot y el propio kernel.
Analizando el fichero kernel
editarEl magic number en la cabecera (0x270519) de este fichero indica que es del tipo u-boot. Si se analiza el resto del fichero se encuentra en el offset 352 (al menos de los analizados hasta ahora un fichero gzip, que se puede extraer con el comando:
dd if=kernel.bin bs=352 skip=1 | gzip -d > kernel.ucompressed
Si se analiza este fichero que se ha descomprimido, se encuentra que dentro del mismo hay (al menos en la mayoría de los firmwares) otros dos ficheros comprimidos. Uno parece ser el fichero de configuración del kernel y el otro el initramfs.cpio también requerido durante la compilación (si se establece el parámetro correspondiente).
Se ha creado un nuevo script para buscar y descomprimir ficheros gzip dentro de otros ficheros. Como entrada necesita el o los ficheros (puede utilizarse algo como kernel1.2* como entrada) en los que se desean buscar fichero gzip.
#!/bin/bash
# search_gzip
# Copyright (C) 2008, 2009, 20010
# Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Original Author: Orensbruli (Esteban Martinena Guerrero)
# Current Version: 0.1
PATTERN=1f8b0800
P_LEFT=`echo $PATTERN | cut -b1`
P_RIGHT=`echo $PATTERN | cut -b2-`
for FILE in $@
do
loop=1
OFFSET=$(expr `xxd -p $FILE | tr -d '\n' | sed -e "s/$P_LEFT\($P_RIGHT\)/p\1/g" | cut -d'p' -f1-$loop | wc -c` / 2)
LAST_OFFSET="_"
OUT_DIR=uncompressed
if [ ! -d $OUT_DIR ]
then
mkdir $OUT_DIR
fi
echo "Buscando en el fichero $FILE..."
while [ ! $OFFSET == $LAST_OFFSET ]
do
dd if=$FILE bs=1 skip=$OFFSET 2>/dev/null | gzip -dc 2>/dev/null > $OUT_DIR/$FILE\_$loop\_$OFFSET.uncomp
if [ $? -eq 1 ]
then
echo "Falso gzip en $OFFSET."
rm $OUT_DIR/$FILE\_$loop\_$OFFSET.uncomp
else
echo "Generado fichero gzip: $OUT_DIR/$FILE\\_$loop\\_$OFFSET.uncomp"
fi
loop=$(expr $loop + 1)
LAST_OFFSET=$OFFSET
OFFSET=$(expr `xxd -p $FILE | tr -d '\n' | sed -e 's/1f8b/pqrs/g' | cut -d'p' -f1-$loop | wc -c` / 2)
done
echo "Fin de la búsqueda"
done
En éste caso concreto. Se puede utilizar tanto para obtener el gzip de los ficheros de kernel, como para los ficheros gzip que están en los ficheros descomprimidos obtenidos del kernel. Para clarificar todo esto se expone a continuación la jerarquía de ficheros que se tiene ahora mismo:
update.wup (aplicar el script de extracción)
- header (contiene el tamaño del fichero de kernel en sus últimos 4 bytes)
- kernel (aplicar script de extracción de gzip)
- kernel.uncomp (aplicar script de extracción de gzip)
- config (fichero de configuración para la compilación del kernel)
- initramfs.cpio (fichero necesario también en la compilación)
- kernel.uncomp (aplicar script de extracción de gzip)
- middle (contiene el tamaño del fichero de software en sus últimos 4 bytes)
- software
- footer
- infoxml (información xml sobre el fichero update.wup y su dispositivo)
Notas: Hay un proyecto llamado tribbox de un media center con características similares a los nuestros (al menos el procesador) y con información de como montar el sistema operativo/etc. Puede ser util: http://www.tribbox.com/
Fichero de software
editarHasta el momento no se sabe exactamente cual es el formato del sistema de software, ya que el comando file da como salida para dicho fichero "data". Se conjetura que es un sistema de ficheros squashfs y que además está encriptado con un cifrado aes-cbc-plain usando una clave de 128 bits. Probablemente, la imagen es desencriptada por la interfaz dm-crypt del kernel Linux.
A partir de todas las conjeturas que se han ido haciendo, se ha creado un script que dado un fichero de software obtenido de un fichero de firmware (script de extracción) (wup) y otro fichero con una lista de contraseñas, intenta desencriptar y determinar el sistema de ficheros que hay subyacente. Hay varios problemas:
- No se está completamente seguro del sistema que se está utilizando para encriptar, por lo que se están dando palos de ciego.
- El script da muchos falsos positivos, ya que siempre se desencripta el sistema. Lo único que determina si ha sido correcto o no es la salida de file, de la que cabría esperar que fuera algo como squashfs filesystem o similar.
Este es solo un código didáctico y a modo de ejemplo de desencriptación en sistemas Linux de ficheros y particiones completas. Cada cual es responsable del uso que hace de él. Se recomienda revisarlo antes de hacerlo funcionar.
#! /bin/bash
# soft_decrypt
# Copyright (C) 2008, 2009, 20010
# Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Original Author: Orensbruli (Esteban Martinena Guerrero)
# Current Version: 0.1
#Se comprueba la sintaxis de la llamada al script
if [ $# -lt 2 ]
then
echo -e "Llamada incorrecta."
echo -e "ej: $0 <fichero_software wup> <fichero_lista_passwords>"
exit
fi
SOFTWARE_FILE=$1
PASSWORDS_FILE=$2
#Se configura el disposifivo /dev/loop0 para que apunte al fichero de software
losetup /dev/loop0 $SOFTWARE_FILE
#Para cada contraseña
for passwd in `cat $PASSWORDS_FILE`
do
#echo "Probando la contraseña $passwd..."
#Se mapea el dispositivo /dev/loop0 con la contraseña encriptada como aes-cbc-plain de 128 bits e /dev/mapper/decripted
echo $passwd | cryptsetup -c aes-cbc-plain -s 128 -b `blockdev --getsize /dev/loop0` create decripted /dev/loop0 2>/dev/null
#A veces da problemas porque sigue mapeado el anterior, se reintenta "desmapear" y mapear de nuevo
if [ ! $? -eq 0 ]
then
dmsetup remove decripted
#echo -e "\tProbando de nuevo la contraseña $passwd..."
echo $passwd | cryptsetup -c aes-cbc-plain -s 128 -b `blockdev --getsize /dev/loop0` create decripted /dev/loop0
fi
#Se crea un pequeño fichero de muestra con el comienzo de la partición desencriptada
dd if=/dev/mapper/decripted of=sample.img count=100 bs=1 2> /dev/null
#Se comprueba el tipo de fichero. Si fuera lo que esperamo debria poner squashfs filesystem o similar
TYPE=`file sample.img | grep -v "sample.img: data"`
if [ $? -eq 0 ]
then
echo "Desencriptado como \"$TYPE\" con la contraseña $passwd"
fi
#Se intenta despamear /dev/loop0 de /dev/mapper/decripted
cryptsetup remove decripted 2> /dev/null
dmsetup remove decripted 2> /dev/null
#Se espera 1 segundo
sleep 1
done
#Se elimina la asociación del fichero_software y /dev/loop0
losetup -d /dev/loop0
Script de extracción
editarEste script en bash/shell script permite obtener de un fichero de actualización de firmware (.wup) los ficheros correspondientes al kernel, el software y la información XML. Es completamente GPL y no hay responsabilidad ninguna sobre su uso. Quien tenga dudas sobre su funcionamiento o sus acciones que lo analice. Por supuesto, cualquier mejora, sugerencia o aportación será bienvenida.
Actualmente obtiene 6 ficheros a partir del fichero de actualización wup. Los principales son los de kernel y software, de cierto interés el infoxml y el resto (header_bytes, middle_bytes y footer_bytes) son los bytes que quedan sin identificar en distintas partes del fichero. Se ha hecho así para que uniendo todos los ficheros se obtega de nuevo el fichero original sin perder información.
header_bytes # kernel # middle_bytes # software # footer_bytes # infoxml
El script se ha probado con éxito en los últimos ficheros de actualización de MediaTitan, ZoltarTv y Wyplayer.
#! /bin/sbash
# wup_extract
# Copyright (C) 2008, 2009, 20010
# Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Original Author: Orensbruli (Esteban Martinena Guerrero)
# Current Version: 0.2
#Es necesario el fichero como parametro de entrada
if [ $# -lt 1 ]
then
echo -e "Llamada incorrecta."
echo -e "ej: $0 <fichero_actualizacion.wup>"
exit
fi
FILE=$1
#Obtenemos la información XML y la almacenamos en un fichero
echo -e "Analizando el fichero $FILE."
FILE_SIZE=`du -b $FILE | cut -f1`
LINEAS=`wc -l $FILE | cut -d' ' -f1`
ROOT_BEGIN=`grep -a -n -u "root" $FILE | head -n1 | cut -d':' -f1`
echo -e "\t$LINEAS líneas totales. La sección root comienza en la línea $ROOT_BEGIN."
TAIL=`expr $LINEAS - $ROOT_BEGIN + 1`
tail -n $TAIL $FILE > $FILE.xml
VERSION=`cat $FILE.xml | grep version | head -n1 | cut -d'>' -f 2 | cut -d'<' -f1 | sed -e 's/^0*//' | sed -e 's/\.0*/./g'`
XML_FILE=infoxml\_$VERSION.xml
mv $FILE.xml $XML_FILE
echo -e "\tObtenida información XML del firmware $VERSION: $XML_FILE"
#Información del kernel
KERNEL_VERSION=`cat $XML_FILE | grep -A 9 "<id>1" | grep version | head -n1 | cut -d'>' -f 2 | cut -d'<' -f1`
KERNEL_SIZE=`cat $XML_FILE | grep -A 9 "<id>1" | grep uncompressedSize | head -n1 | cut -d'>' -f 2 | cut -d'<' -f1`
KERNEL_FILE=kernel$KERNEL_VERSION\_$VERSION.bin
KERNEL_SIGNATURE=`cat $XML_FILE | grep -A 9 "<id>1" | grep signature | head -n1 | cut -d'>' -f 2 | cut -d'<' -f1`
#Información del fichero de software
SOFTWARE_FILE=software_$VERSION.bin
SOFTWARE_SIZE=`cat $XML_FILE | grep -A 9 "<id>2" | grep uncompressedSize | head -n1 | cut -d'>' -f 2 | cut -d'<' -f1`
SOFTWARE_SIGNATURE=`cat $XML_FILE | grep -A 9 "<id>2" | grep signature | head -n1 | cut -d'>' -f 2 | cut -d'<' -f1`
echo -e "\tSección kernel en el XML. Version:$KERNEL_VERSION, Tamaño: $KERNEL_SIZE, Checksum: $KERNEL_SIGNATURE."
echo -e "\tSección software en el XML. Tamaño: $SOFTWARE_SIZE, Checksum: $SOFTWARE_SIGNATURE."
echo -e "Buscando offset de los ficheros kernel y software..."
for KERNEL_OFFSET in `seq 1 200`
do
dd if=$FILE of=$KERNEL_FILE bs=1 count=200 skip=$KERNEL_OFFSET 2> /dev/null
file $KERNEL_FILE | grep "u-boot/PPCBoot image" > /dev/null
if [ $? -eq 0 ]
then
break
else
echo -e "\t$KERNEL_OFFSET"
fi
done
HEADER_BYTES=$KERNEL_OFFSET
HEADER_BYTES_FILE=header_bytes_$VERSION.bin
MIDDLE_BYTES=10
MIDDLE_BYTES_FILE=middle_bytes_$VERSION.bin
SOFTWARE_OFFSET=`expr $HEADER_BYTES + $KERNEL_SIZE + 10`
FOOTER_BYTES=`expr $(expr $(du -b $FILE | cut -f1)) - $(expr $HEADER_BYTES + $KERNEL_SIZE + $MIDDLE_BYTES + $SOFTWARE_SIZE) - $(expr $(du -b $XML_FILE | cut -f1))`
FOOTER_BYTES_FILE=footer_bytes_$VERSION.bin
echo -e "\tEl kernel se encuentra entre los bytes $KERNEL_OFFSET y $( expr $KERNEL_OFFSET + $KERNEL_SIZE )."
echo -e "\tEl software se encuentra entre los bytes $SOFTWARE_OFFSET y $( expr $SOFTWARE_OFFSET + $SOFTWARE_SIZE )."
echo -e "Extrayendo bytes de la cabecera..."
dd if=$FILE of=$HEADER_BYTES_FILE bs=1 count=$HEADER_BYTES 2> /dev/null
echo -e "\tFichero de cabecera ($HEADER_BYTES_FILE) extraido."
echo -e "Extrayendo fichero de kernel..."
touch $SOFTWARE_FILE
dd if=$FILE of=$KERNEL_FILE bs=1 count=$KERNEL_SIZE skip=$KERNEL_OFFSET 2> /dev/null&
DIFF=`expr $KERNEL_SIZE - $( du -b $KERNEL_FILE | cut -f1 )`
while [ ! $DIFF -eq 0 ]
do
echo -e "\tQuedan $DIFF bytes por extraer"
sleep 5
DIFF=`expr $KERNEL_SIZE - $( du -b $KERNEL_FILE | cut -f1 )`
done
KERNEL_FILE_TYPE=`file $KERNEL_FILE`
MD5SUM=`md5sum $KERNEL_FILE | cut -d' ' -f1`
if [ $MD5SUM == $KERNEL_SIGNATURE ]
then
echo -e "\tFichero de kernel ($KERNEL_FILE) extraido y correcto"
else
echo -e "ERROR: Fichero de kernel ($KERNEL_FILE) incorrecto"
fi
echo -e "Extrayendo bytes del medio..."
dd if=$FILE of=$MIDDLE_BYTES_FILE bs=1 count=$MIDDLE_BYTES skip=`expr $HEADER_BYTES + $KERNEL_SIZE` 2> /dev/null
echo -e "\tFichero de bytes del medio ($MIDDLE_BYTES_FILE) extraido."
echo -e "Extrayendo fichero de software..."
touch $SOFTWARE_FILE
dd if=$FILE of=$SOFTWARE_FILE bs=1 count=$SOFTWARE_SIZE skip=$SOFTWARE_OFFSET 2> /dev/null&
DIFF=`expr $SOFTWARE_SIZE - $( du -b $SOFTWARE_FILE | cut -f1)`
while [ ! $DIFF -eq 0 ]
do
echo -e "\tQuedan $DIFF bytes por extraer"
sleep 5
DIFF=`expr $SOFTWARE_SIZE - $( du -b $SOFTWARE_FILE | cut -f1)`
done
SOFTWARE_FILE_TYPE=`file $SOFTWARE_FILE`
MD5SUM=`md5sum $SOFTWARE_FILE | cut -d' ' -f1`
if [ $MD5SUM == $SOFTWARE_SIGNATURE ]
then
echo -e "\tFichero de software ($SOFTWARE_FILE) extraido y correcto"
else
echo -e "ERROR: Fichero de software ($SOFTWARE_FILE) incorrecto"
fi
echo -e "Extrayendo bytes del final..."
dd if=$FILE of=$FOOTER_BYTES_FILE bs=1 count=$FOOTER_BYTES skip=`expr $HEADER_BYTES + $KERNEL_SIZE + $MIDDLE_BYTES + $SOFTWARE_SIZE` 2> /dev/null
echo -e "\tFichero de bytes del final ($FOOTER_BYTES_FILE) extraido."
kill `pidof dd` 2> /dev/null
Actualizar un dispositivo con el firmware de otro
editarUno de los problemas que se están encontrando es que no se puede utilizar un firmware de uno de los dispositivos en otro dispositivo distinto. Parece ser que el motivo es que cada dispositivo tiene un identificador y además que la parte de "software" del fichero firmware está encriptada de forma distinta para cada dispositivo.
Si esto fuera simplemente así, sería teóricamente posible crear un firmware para un dispositivo al que se le cambiara la parte de kernel y aún así permitiría la actualización. Teniendo cada uno de los 6 trozos de un fichero de actualización podría construirse uno como la mezcla de varios ficheros firmware distintos.
Nota: esto no parece posible. Se ha probado un kernel de Wyplayer en un CMT2DW, escribiéndolo directamente con un comando dd, y el dispositivo no arranca. (minukab. 9-3-2010)
Script para mezclar ficheros de firmware
editarPara probar este concepto de mezclar el contenido de dos ficheros de firmware se ha creado un script capaz de generar un nuevo fichero .wup a partir de otros dos distintos. Para ello, descompone cada uno de los dos originales (si todavía no se encuentran descompuestos en el directorio) y ofrece una serie de posibles combinaciones. Esto puede ser interesante para comprobar si alguna de ellas nos permite actualizar nuestro dispositivo. Por regla general, de todas las opciones que ofrece el script, pueden interesar aquellas que mezclan una parte de un dispositivo ajeno y el resto lo toman del propio. Y más concretamente la que toma el kernel de otro y el resto del propio. Todavía no se han puesto a pruebas los ficheros generados por este script, por lo que se recomienda cautela a la hora de utilizarlos.
IMPORTANTE: Para que el script funcione hay que cambiar el valor de la variable EXTRACT_PROGRAM y establecer la ruta completa al script de extracción.
El funcionamiento es sencillo:
wup_mix <fichero_actualización1> <fichero_de_actualización2>
#! /bin/bash
# wup_mix
# Copyright (C) 2008, 2009, 20010
# Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Original Author: Orensbruli (Esteban Martinena Guerrero)
# Current Version: 0.1
#PATH al script de extracción
EXTRACT_PROGRAM=<PATH_COMPLETO_AL_SCRIPT_DE_EXTRACCION>/extract_xml
if [ ! -f $EXTRACT_PROGRAM ]
then
echo "Debe establecer la variable EXTRACT_PROGRAM a la ruta completa donde se encuntra el script de extracción"
fi
#Es necesario el fichero como parametro de entrada
if [ $# -lt 2 ]
then
echo -e "Llamada incorrecta."
echo -e "ej: $0 <fichero_actualizacion_1.wup> <fichero_actualizacion_2.wup>"
exit
fi
UPDATE_FILE1=$1
UPDATE_FILE2=$2
if [ $UPDATE_FILE1 == $UPDATE_FILE2 ]
then
echo "No se pueden llamar igual los dos ficheros aunque estén en diferentes directorios."
echo "Intente renombrar uno de ellos (ej. mv update.wup update1.wup)."
exit
fi
echo -e "Comprobando si se puede hacer la mezcla de los dos ficheros."
UPDATE_FILE1_SIZE=`du -b $UPDATE_FILE1 | cut -f1`
LINEAS1=`wc -l $UPDATE_FILE1 | cut -d' ' -f1`
ROOT_BEGIN1=`grep -a -n -u "root" $UPDATE_FILE1 | head -n1 | cut -d':' -f1`
TAIL1=`expr $LINEAS1 - $ROOT_BEGIN1 + 1`
tail -n $TAIL1 $UPDATE_FILE1 > $UPDATE_FILE1.xml
VERSION1=`cat $UPDATE_FILE1.xml | grep version | head -n1 | cut -d'>' -f 2 | cut -d'<' -f1 | sed -e 's/^0*//' | sed -e 's/\.0*/./g'`
UPDATE_FILE2_SIZE=`du -b $UPDATE_FILE2 | cut -f1`
LINEAS2=`wc -l $UPDATE_FILE2 | cut -d' ' -f1`
ROOT_BEGIN2=`grep -a -n -u "root" $UPDATE_FILE2 | head -n1 | cut -d':' -f1`
TAIL2=`expr $LINEAS2 - $ROOT_BEGIN2 + 1`
tail -n $TAIL2 $UPDATE_FILE2 > $UPDATE_FILE2.xml
VERSION2=`cat $UPDATE_FILE2.xml | grep version | head -n1 | cut -d'>' -f 2 | cut -d'<' -f1 | sed -e 's/^0*//' | sed -e 's/\.0*/./g'`
DATE_KERNEL1=`cat $UPDATE_FILE1.xml | grep -i generationDatetime | tail -n2 | head -n1 | cut -d'>' -f 2 | cut -d'<' -f1`
DATE_KERNEL2=`cat $UPDATE_FILE2.xml | grep -i generationDatetime | tail -n2 | head -n1 | cut -d'>' -f 2 | cut -d'<' -f1`
DATE_SOFTWARE1=`cat $UPDATE_FILE1.xml | grep -i generationDatetime | tail -n1 | cut -d'>' -f 2 | cut -d'<' -f1`
DATE_SOFTWARE2=`cat $UPDATE_FILE2.xml | grep -i generationDatetime | tail -n1 | cut -d'>' -f 2 | cut -d'<' -f1`
SIGNATURE_KERNEL1=`cat $UPDATE_FILE1.xml | grep -i signature | tail -n2 | head -n1 | cut -d'>' -f 2 | cut -d'<' -f1`
SIGNATURE_KERNEL2=`cat $UPDATE_FILE2.xml | grep -i signature | tail -n2 | head -n1 | cut -d'>' -f 2 | cut -d'<' -f1`
SIGNATURE_SOFTWARE1=`cat $UPDATE_FILE1.xml | grep -i signature | tail -n1 | cut -d'>' -f 2 | cut -d'<' -f1`
SIGNATURE_SOFTWARE2=`cat $UPDATE_FILE2.xml | grep -i signature | tail -n1 | cut -d'>' -f 2 | cut -d'<' -f1`
SIZE_KERNEL1=`cat $UPDATE_FILE1.xml | grep -i uncompressedSize | tail -n2 | head -n1 | cut -d'>' -f 2 | cut -d'<' -f1`
SIZE_KERNEL2=`cat $UPDATE_FILE2.xml | grep -i uncompressedSize | tail -n2 | head -n1 | cut -d'>' -f 2 | cut -d'<' -f1`
SIZE_SOFTWARE1=`cat $UPDATE_FILE1.xml | grep -i uncompressedSize | tail -n1 | cut -d'>' -f 2 | cut -d'<' -f1`
SIZE_SOFTWARE2=`cat $UPDATE_FILE2.xml | grep -i uncompressedSize | tail -n1 | cut -d'>' -f 2 | cut -d'<' -f1`
NAME1=`cat $UPDATE_FILE1.xml | grep -i displayName | head -n1| cut -d'>' -f 2 | cut -d'<' -f1`
NAME2=`cat $UPDATE_FILE2.xml | grep -i displayName | head -n1| cut -d'>' -f 2 | cut -d'<' -f1`
if [ $VERSION1 == $VERSION2 ]
then
echo "Los dos ficheros de actualización son de la misma versión. Deben ser de versiones distintas para poder mezclarlos."
rm $UPDATE_FILE1.xml
rm $UPDATE_FILE2.xml
exit
else
echo "Correcto."
fi
rm $UPDATE_FILE1.xml
rm $UPDATE_FILE2.xml
bash $EXTRACT_PROGRAM $UPDATE_FILE1
bash $EXTRACT_PROGRAM $UPDATE_FILE2
echo "Introduzca el número correspondiente a la operación a realizar:"
select OPCION in cabecera$NAME1$VERSION1+resto$NAME2$VERSION2 kernel$NAME1$VERSION1+resto$NAME2$VERSION2 middle$NAME1$VERSION1+resto$NAME2$VERSION2 software$NAME1$VERSION1+resto$NAME2$VERSION2 footer$NAME1$VERSION1+resto$NAME2$VERSION2 xml$NAME1$VERSION1+resto$NAME2$VERSION2 cabecera$NAME2$VERSION2+resto$NAME1$VERSION1 kernel$NAME2$VERSION2+resto$NAME1$VERSION1 middle$NAME2$VERSION2+resto$NAME1$VERSION1 software$NAME2$VERSION2+resto$NAME1$VERSION1 footer$NAME2$VERSION2+resto$NAME1$VERSION1 xml$NAME2$VERSION2+resto$NAME1$VERSION1
do
NEW_NAME=$OPCION.wup
case $OPCION in
cabecera$NAME1$VERSION1+Resto$NAME2$VERSION2)
PARTS[0]=`ls -1 header_bytes*$VERSION1.bin | head -n1`
PARTS[1]=`ls -1 kernel*$VERSION2.bin | head -n1`
PARTS[2]=`ls -1 middle_bytes*$VERSION2.bin | head -n1`
PARTS[3]=`ls -1 software*$VERSION2.bin | head -n1`
PARTS[4]=`ls -1 footer_bytes*$VERSION2.bin | head -n1`
PARTS[5]=`ls -1 infoxml*$VERSION2.xml | head -n1`
;;
cabecera$NAME2$VERSION2+resto$NAME1$VERSION1)
PARTS[0]=`ls -1 header_bytes*$VERSION2.bin | head -n1`
PARTS[1]=`ls -1 kernel*$VERSION1.bin | head -n1`
PARTS[2]=`ls -1 middle_bytes*$VERSION1.bin | head -n1`
PARTS[3]=`ls -1 software*$VERSION1.bin | head -n1`
PARTS[4]=`ls -1 footer_bytes*$VERSION1.bin | head -n1`
PARTS[5]=`ls -1 infoxml*$VERSION1.xml | head -n1`
;;
kernel$NAME1$VERSION1+resto$NAME2$VERSION2)
PARTS[0]=`ls -1 header_bytes*$VERSION2.bin | head -n1`
PARTS[1]=`ls -1 kernel*$VERSION1.bin | head -n1`
PARTS[2]=`ls -1 middle_bytes*$VERSION2.bin | head -n1`
PARTS[3]=`ls -1 software*$VERSION2.bin | head -n1`
PARTS[4]=`ls -1 footer_bytes*$VERSION2.bin | head -n1`
PARTS[5]=`ls -1 infoxml*$VERSION2.xml | head -n1`
cp ${PARTS[5]} ${PARTS[5]}.aux
PARTS[5]=${PARTS[5]}.aux
sed -i -e "s/$SIZE_KERNEL2/$SIZE_KERNEL1/g" -e "s/$SIGNATURE_KERNEL2/$SIGNATURE_KERNEL1/g" -e "s/$DATE_KERNEL2/$DATE_KERNEL1/g" ${PARTS[5]}
;;
kernel$NAME2$VERSION2+resto$NAME1$VERSION1)
PARTS[0]=`ls -1 header_bytes*$VERSION1.bin | head -n1`
PARTS[1]=`ls -1 kernel*$VERSION2.bin | head -n1`
PARTS[2]=`ls -1 middle_bytes*$VERSION1.bin | head -n1`
PARTS[3]=`ls -1 software*$VERSION1.bin | head -n1`
PARTS[4]=`ls -1 footer_bytes*$VERSION1.bin | head -n1`
PARTS[5]=`ls -1 infoxml*$VERSION1.xml | head -n1`
cp ${PARTS[5]} ${PARTS[5]}.aux
PARTS[5]=${PARTS[5]}.aux
sed -i -e "s/$SIZE_KERNEL1/$SIZE_KERNEL2/g" -e "s/$SIGNATURE_KERNEL1/$SIGNATURE_KERNEL2/g" -e "s/$DATE_KERNEL1/$DATE_KERNEL2/g" ${PARTS[5]}
;;
middle$NAME1$VERSION1+resto$NAME2$VERSION2)
PARTS[0]=`ls -1 header_bytes*$VERSION2.bin | head -n1`
PARTS[1]=`ls -1 kernel*$VERSION2.bin | head -n1`
PARTS[2]=`ls -1 middle_bytes*$VERSION1.bin | head -n1`
PARTS[3]=`ls -1 software*$VERSION2.bin | head -n1`
PARTS[4]=`ls -1 footer_bytes*$VERSION2.bin | head -n1`
PARTS[5]=`ls -1 infoxml*$VERSION2.xml | head -n1`
;;
middle$NAME2$VERSION2+resto$NAME1$VERSION1)
PARTS[0]=`ls -1 header_bytes*$VERSION1.bin | head -n1`
PARTS[1]=`ls -1 kernel*$VERSION1.bin | head -n1`
PARTS[2]=`ls -1 middle_bytes*$VERSION2.bin | head -n1`
PARTS[3]=`ls -1 software*$VERSION1.bin | head -n1`
PARTS[4]=`ls -1 footer_bytes*$VERSION1.bin | head -n1`
PARTS[5]=`ls -1 infoxml*$VERSION1.xml | head -n1`
;;
software$NAME1$VERSION1+resto$NAME2$VERSION2)
PARTS[0]=`ls -1 header_bytes*$VERSION2.bin | head -n1`
PARTS[1]=`ls -1 kernel*$VERSION2.bin | head -n1`
PARTS[2]=`ls -1 middle_bytes*$VERSION2.bin | head -n1`
PARTS[3]=`ls -1 software*$VERSION1.bin | head -n1`
PARTS[4]=`ls -1 footer_bytes*$VERSION2.bin | head -n1`
PARTS[5]=`ls -1 infoxml*$VERSION2.xml | head -n1`
cp ${PARTS[5]} ${PARTS[5]}.aux
PARTS[5]=${PARTS[5]}.aux
sed -i -e "s/$SIZE_SOFTWARE2/$SIZE_SOFTWARE1/g" -e "s/$SIGNATURE_SOFTWARE2/$SIGNATURE_SOFTWARE1/g" -e "s/$DATE_SOFTWARE2/$DATE_SOFTWARE1/g" ${PARTS[5]}
;;
software$NAME2$VERSION2+resto$NAME1$VERSION1)
PARTS[0]=`ls -1 header_bytes*$VERSION1.bin | head -n1`
PARTS[1]=`ls -1 kernel*$VERSION1.bin | head -n1`
PARTS[2]=`ls -1 middle_bytes*$VERSION1.bin | head -n1`
PARTS[3]=`ls -1 software*$VERSION2.bin | head -n1`
PARTS[4]=`ls -1 footer_bytes*$VERSION1.bin | head -n1`
PARTS[5]=`ls -1 infoxml*$VERSION1.xml | head -n1`
cp ${PARTS[5]} ${PARTS[5]}.aux
PARTS[5]=${PARTS[5]}.aux
sed -i -e "s/$SIZE_SOFTWARE1/$SIZE_SOFTWARE2/g" -e "s/$SIGNATURE_SOFTWARE1/$SIGNATURE_SOFTWARE2/g" -e "s/$DATE_SOFTWARE1/$DATE_SOFTWARE2/g" ${PARTS[5]}
;;
footer$NAME1$VERSION1+resto$NAME2$VERSION2)
PARTS[0]=`ls -1 header_bytes*$VERSION2.bin | head -n1`
PARTS[1]=`ls -1 kernel*$VERSION2.bin | head -n1`
PARTS[2]=`ls -1 middle_bytes*$VERSION2.bin | head -n1`
PARTS[3]=`ls -1 software*$VERSION2.bin | head -n1`
PARTS[4]=`ls -1 footer_bytes*$VERSION1.bin | head -n1`
PARTS[5]=`ls -1 infoxml*$VERSION2.xml | head -n1`
;;
footer$NAME2$VERSION2+resto$NAME1$VERSION1)
PARTS[0]=`ls -1 header_bytes*$VERSION1.bin | head -n1`
PARTS[1]=`ls -1 kernel*$VERSION1.bin | head -n1`
PARTS[2]=`ls -1 middle_bytes*$VERSION1.bin | head -n1`
PARTS[3]=`ls -1 software*$VERSION1.bin | head -n1`
PARTS[4]=`ls -1 footer_bytes*$VERSION2.bin | head -n1`
PARTS[5]=`ls -1 infoxml*$VERSION1.xml | head -n1`
;;
xml$NAME1$VERSION1+resto$NAME2$VERSION2)
PARTS[0]=`ls -1 header_bytes*$VERSION2.bin | head -n1`
PARTS[1]=`ls -1 kernel*$VERSION2.bin | head -n1`
PARTS[2]=`ls -1 middle_bytes*$VERSION2.bin | head -n1`
PARTS[3]=`ls -1 software*$VERSION2.bin | head -n1`
PARTS[4]=`ls -1 footer_bytes*$VERSION2.bin | head -n1`
PARTS[5]=`ls -1 infoxml*$VERSION1.xml | head -n1`
;;
xml$NAME2$VERSION2+resto$NAME1$VERSION1)
PARTS[0]=`ls -1 header_bytes*$VERSION1.bin | head -n1`
PARTS[1]=`ls -1 kernel*$VERSION1.bin | head -n1`
PARTS[2]=`ls -1 middle_bytes*$VERSION1.bin | head -n1`
PARTS[3]=`ls -1 software*$VERSION1.bin | head -n1`
PARTS[4]=`ls -1 footer_bytes*$VERSION1.bin | head -n1`
PARTS[5]=`ls -1 infoxml*$VERSION2.xml | head -n1`
;;
*)
continue
;;
esac
echo "Creando fichero mixto..."
touch $NEW_NAME
for part in $( seq 0 `expr ${#PARTS[*]} - 1` )
do
echo -e "\tAñadiendo ${PARTS[$part]} al nuevo fichero $NEW_NAME..."
dd if=${PARTS[$part]} of=$NEW_NAME bs=1 seek=`du -b $NEW_NAME | cut -f1` 2>/dev/null
done
echo "Hecho."
break
done
Generar "kernel" propio e instalarlo en los dispositivos
editarSH4 toolchain para compilación cruzada desde 386 de 32 bits. Descargar y descomprimir en opt: http://www.megaupload.com/?d=HSV19P40
Generar "software" propio e instalarlo en los dispositivos
editarSH4 toolchain para compilación cruzada desde 386 de 32 bits. Descargar y descomprimir en opt: http://www.megaupload.com/?d=HSV19P40
Acceso Telnet al dispositivo
editarPara tener acceso telnet al dispositivo es necesario modificar un fichero del disco duro. Para ello será necesario sacar el disco duro y conectarlo a un PC para poder acceder a él. Para acceder al disco y poder modificar el archivo necesitamos una distro linux cualquiera. Si no se dispone de ella se puede usar un live cd de Ubuntu o cualquier otra distribución.
El archivo a modificar se encuentra en la partición 1 que es JFS. Para montarla se deben ejecutar esto comandos:
(nota: sda se debe sustituir por lo que corresponda)
$ sudo mkdir /mnt/sda1 $ sudo jfs_fsck /dev/sda1 $ sudo mount /dev/sda1 /mnt/sda1
Una vez la tenemos montada debemos modificar el archivo "local_conf.py". Abrimos el fichero con gedit (o kedit desde kde):
$ sudo gedit /mnt/sda1/local_conf.py
y añadimos las siguientes líneas al final (ojo con el "-l", es una L y no un Uno):
import os os.system('telnetd -l /bin/ash')
Una vez hecho esto desmontamos la partición ( umount /mnt/sda1 ) y ya podemos volver a montar el disco duro en el reproductor.
A partir de este momento ya deberiamos tener acceso telnet al dispositivo: (si está conectado a la red, obviamente)
$ telnet ip_del_reproductor Wybox Release Branch 1.3.15 (Future is Now!) / $
De momento, se ha comprobado que este procedimiento es valido para las siguientes versiones:
Funciona No funciona Media Titan: 7983 y anteriores 7989 Zoltar TV: 7891 y anteriores 7909 Wyplayer: 8399, 8379 y ¿anteriores? 8418 Mediatec: ? ?
Enlaces a ficheros de firmware
editarO2Media ZoltarTV
editar- Septiembre 2009 (1.3.17.7947 - 17 Septiembre 2009): http://www.zoltartv.com/firmware/Sep-17-2009/update.zip
- Junio 2009: http://www.zoltartv.com/firmware/Junio-16-2009/update.zip
- Mayo 2009 (1.3.15.7891 - 27 Mayo 2009): http://www.zoltartv.com/firmware/Mayo-27-2009/update.zip
- Febrero 2009 (1.2.14.7866 - 02 de Febrero 2009): http://www.zoltartv.com/firmware/Febrero-02-2009/update.zip
Conceptronic MediaTitan
editarPara el CMT2D (sin Wi-Fi): http://download.conceptronic.net/GrabnGo/CMT2D_CMT2DW/CMT2D_FW_UPD_v1.3.15.7989_(1.3R6).zip http://download.conceptronic.net/GrabnGo/CMT2D_CMT2DW/CMT2D_FW_UPD_v1.3.15.7984_(1.3R5).zip http://download.conceptronic.net/GrabnGo/CMT2D_CMT2DW/CMT2D_FW_UPD_v1.3.15.7983_(1.3R4).zip http://download.conceptronic.net/GrabnGo/CMT2D_CMT2DW/CMT2D_FW_UPD_v1.3.15.7963_BETA.zip http://download.conceptronic.net/GrabnGo/CMT2D_CMT2DW/CMT2D_FW_UPD_v1.2.14.7929.ZIP http://download.conceptronic.net/GrabnGo/CMT2D_CMT2DW/CMT2D_FW_UPD_v1.2.14.7926.zip http://download.conceptronic.net/GrabnGo/CMT2D_CMT2DW/CMT2D_FW_UPD_v1.1.13.7870.ZIP http://download.conceptronic.net/GrabnGo/CMT2D_CMT2DW/CMT2D_FW_v1.1.13.7860.ZIP
Para el CMT2DW (con Wi-Fi): http://download.conceptronic.net/GrabnGo/CMT2D_CMT2DW/CMT2DW_FW_UPD_v1.3.15.7989_(1.3R6).zip http://download.conceptronic.net/GrabnGo/CMT2D_CMT2DW/CMT2DW_FW_UPD_v1.3.15.7983_(1.3R4).zip http://download.conceptronic.net/GrabnGo/CMT2D_CMT2DW/CMT2DW_FW_UPD_v1.3.15.7963_BETA.zip http://download.conceptronic.net/GrabnGo/CMT2D_CMT2DW/CMT2DW_FW_UPD_v1.2.14.7929.ZIP http://download.conceptronic.net/GrabnGo/CMT2D_CMT2DW/CMT2DW_FW_UPD_v1.2.14.7926.zip http://download.conceptronic.net/GrabnGo/CMT2D_CMT2DW/CMT2DW_FW_UPD_v1.1.13.7870.ZIP http://download.conceptronic.net/GrabnGo/CMT2D_CMT2DW/CMT2DW_FW_v1.1.13.7860.ZIP
Wyplayer
editar- Septiembre 09: http://www.wyplayer.com/downloads/Wyplayer/wup/1.3.17.8530.zip
- Agosto 09: http://www.wyplayer.com/downloads/Wyplayer/wup/1.3.16.8498.zip
--- ya no aparecen en la web oficial aunque siguen funcionando:
- Junio 09: http://www.wyplayer.com/downloads/Wyplayer/1.3.15.8418_11.06.09/version-1.3.15.8418_1.3.15.8418_110609.zip
- Mayo 09: http://www.wyplayer.com/downloads/Wyplayer/1.3.15.8399_13.05.09/version-1.3.15.8399_1.3.15.8399_130509.zip
- Abril . 09: http://www.wyplayer.com/downloads/Wyplayer/1.3.15.8379_20.04.09/version-1.3.15.8379_1.3.15.8379_200409.wup