Disque dur multimédia Wyplayer/Firmware
Format des fichiers de firmware
modifierActualisation du firmware
modifierLes buts sur la connaissance du firmware
modifier- Connaitre la structure du fichier .wup (Fait)
- Connaitre les formats des parties du fichier .wup (XML et Kermel ok, reste le logiciel)
- Connaitre la fonctionnalité de chaque partie du fichier .wup (en cours...)
- Actualiser un boitier avec le firmware d'un de ses clones (en cours...)
- Générer son propre Kermel et l'installer dans le boitier (en cours...)
- Générer son propre logiciel et l'installer dans le boitier (en cours...)
- Obtenir la clé d'encryptage de la partie logiciel de chaque boitier (en cours...)
- Accéder au logiciel pour comprendre le fonctionnement du boitier (en cours...)
Structure du fichier .wup
modifierExemple: <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>
Infos sur le fichier Kermel
modifier- 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
Analyse du fichier Kermel
modifierLe nombre magique dans le kermel est (0x270519), il indique que le fichier est de type u-boot. Si on veut analyser le reste du fichier on va à l'offset 352 (on a analysé jusqu'à présent sous la forme d'un fichier gzip que l'on extrait avec la commande suivante:
dd if=kernel.bin bs=352 skip=1 | gzip -d > kernel.ucompressed
L'analyse de ce fichier décompressé montre qu'à l'intérieur il y a deux autres fichiers compressés. L'un permet la configuration du kermel, l'autre est l' l'initramfs.cpio .
Un nouveau script a été créé afin de décompresser un fichier gzip à l'intérieur d'un autre fichier.
#!/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 "En cherchant dans le fichier $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 "Faux gzip dans $OFFSET."
rm $OUT_DIR/$FILE\_$loop\_$OFFSET.uncomp
else
echo "Générer le fichier 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 recherche"
done
Dans ce cas concret, on peut obtenir le gzip contenu dans le fichier Kermel mais aussi les fichiers contenus dans le fichier Kermel décompressés. Pour clarifier, voilà comment se découpe le fichier:
- update.wup (applique le script d'extraction)
- header (contient le fichier Kermel dans ces 4 derniers bit)
- kernel (applique le script d'extraction du gzip)
- kernel.uncomp (applique le script d'extraction du gzip)
- config (fichier de configuration pour la compilation du kermel)
- initramfs.cpio (fichier nécessaire à la compilation)
- kernel.uncomp (applique le script d'extraction du gzip)
- middle (contient le fichier logiciel dans ces 4 derniers bit)
- software
- footer
- infoxml (information xml sur le fichierupdate.wup et le boitier)
Note: il y a un projet tribox avec des caractéristiques identiques au notre (même processeur) et ils ont pas mal d'infos sur le montage du système. Plus d'infos ici:http://www.tribbox.com/
Actualiser le firmware avec le firmware d'un autre boitier
modifierAujourd'hui il est impossible d'actualiser un clone par le firmware du wyplayer. Chaque boitier possède sa propre identification et la partie "logiciel" du firmware est cryptée de manière différente pour chaque boitier. En théorie, il serait possible de mélanger les firmwares entre eux afin de trouver un firmware alternatif. Il suffirait de prendre le kermel d'un boitier pour le mettre dans le firmware qui nous intéresse pour actualiser le boitier. On connait les 6 parties du firmware, il doit donc être possible de créer un firmware alternatif.
Script pour créer un firmware alternatif
modifierPour essayer de créer ce firmware alternatif, on a essayé de créer un script qui mélange les parties de 2 firmwares distincts afin de créer un fichier.wup valide pour actualiser le boitier. Toutes les combinaisons sont possibles, les fichiers créés par ce script n'étant pas tous testés, il est important de prendre des précautions avec cette actualisation.
IMPORTANT: pour que le script fonctionne, il faut changer la valeur de EXTRACT_PROGRAM et écrire la route pour le script d'extraction.
Le fonctionnement est simple:
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 le script d'extraction
EXTRACT_PROGRAM=<PATH_COMPLETO_AL_SCRIPT_DE_EXTRACCION>/extract_xml
if [ ! -f $EXTRACT_PROGRAM ]
then
echo "Etablir la variable EXTRACT_PROGRAM avec le chemin complet pour trouver le script d'extraction"
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