Media Centers Based on Wyplayer/Firmware

From Wikibooks, open books for an open world
< Media Centers Based on Wyplayer
Jump to: navigation, search

Firmware files allow users to update this multimedia disks. Are distributed by each multimedia disk manufacturer and seem to be NOT interchangeable / compatible between different (brand) devices.

Firmware file format[edit]

Updating method[edit]

Firmware file reverse engineer landmarks[edit]

  • Knowing .wup file structure (Done)
  • Knowing .wup file parts format (XML and Kernel, software not yet)
  • Knowing .wup file each part function (Pending)
  • Update one device with other device firmare (Pending)
  • Generate our own "kernel" and install in device (Pending)
  • Generate our own "software" and install in device (Pending)
  • Knowing the encryption key used in software part inside update.wup for each device (Pending)
  • Getting access to device intending to obtain more info while working (Pending)

Internal structure of .wup file[edit]

XML Code[edit]

Example:

<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>

Kernel file[edit]

Depending on the file command output (available in *nix based systems) the kernel file is like:

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

Looking inside in code[edit]

In source code provided by wyplay exists one uboot-<version> folder Trying to guess how is compiled, inside uboot we found board folder and inside this one a sub-folder called wyplay, that may be the especifications needed to compile uboot for the different wyplay motherboards.

  • Reviewing Makefile found in the main folder uboot-<version>, a different (entrada) can be found for the different wyplay boards. We are trying to configure and compile for wymdbox_config (wyplayer multimedia box) that we understand is what corresponds to this multimedia disks.
  • The Make fails cause lack of SH4 compiler (¿?) That seems to be the processor architecture of multimedia disks. (Especification: http://lars.nocrew.org/computers/processors/SuperH/sh4cpu_sh1.pdf).
  • toolchain has been compiled for crossed-compilation for this architecture: http://wiki.debian.org/SH4/CrossToolchain
  • u-boot has been compiled for the wymdbox.
  • Apparently the firmware kernel file includes u-boot and kernel.

Analyzing kernel file[edit]

Header magic number (0x270519) of this file shows that is u-boot type. By analyzing the rest of the file you found in offset 352 a gzip file (at least in reviewed files until now) that can be extracted with command:

dd if=kernel.bin bs=352 skip=1 | gzip -d > kernel.ucompressed

By analizing this uncompressed file we found inside (at least in majority of firmwares) two other compressed files. One of them seem to be the kernel configuration file and the other one the initramfs.cpio required during compilation (if required parameter is established).

A new script has been created to find and decompress gzip files inside other files. As input needs the file/files in which you want to find the gzip file (as input you can use something like kernel1.2*)

#!/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 "Looking inside file $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 "False gzip in $OFFSET."
            rm $OUT_DIR/$FILE\_$loop\_$OFFSET.uncomp
        else
            echo "Generating gzip file: $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 "End of search"
done

In this case can be used to obtain gzip file from kernel file or used to obtain gzip files inside decompressed files extracted from kernel. In order to clarify all this stuff, file hierarchy is shown below:

update.wup (use extraction script)

header (include kernel file size in last 4 bytes)
kernel (use gzip extraction script)
kernel.uncomp (use gzip extraction script)
config (gonfig file for kernel compilation)
initramfs.cpio (needed file for compilation)
middle (include software file size in last 4 bytes)
software
footer
infoxml (xml information about update.wup file and device)


Note: There is a project called Tribbox. A mediacenter with similar especifications to ours (al least the processor) with info about mounting OS, etc. Can be useful: http://www.tribbox.com/

Software file[edit]

To date, we don't know exactly the format of software system, knowing that 'file' command gives "data" as output for this file. Guess that it is a squahfs file system and in addition is encrypted with aes-cbc-plain coding with 128 bits key. Probably image is decrypted by dm-crypt interface of kernel linux.

By joining all the discovers made, a script has been created which, from software file obtained from firmware file (extraction script) (wup) and other file with possible password list, tries to decrypt and know the underlying file system. Known problems:

  • We're not sure of encrypting system used, thats why we're hitting out blindly.
  • The script gives us a lot of false positive results, since always system is decrypted. The fact that determines if has been successful or not is the output of file, we should expect something like squashfs filesystem or any thing like that.

Below, just a didactic code as an decrypting example in linux file systems and full partitions. We take no responsibility of use. Review before use is recommended.

#! /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
 
#Verifiying syntax of script call
if [ $# -lt 2 ]
then
  echo -e  "Wrong call."
  echo -e  "ej: $0 <software_file wup> <password_list_file>"
  exit
fi
 
SOFTWARE_FILE=$1
PASSWORDS_FILE=$2
 
#Setting up device /dev/loop0 to select software file
losetup /dev/loop0 $SOFTWARE_FILE
 
#For each password
for passwd in `cat $PASSWORDS_FILE`
do
    #echo "Trying password $passwd..."
    #Mapping device /dev/loop0 with encrypted password as aes-cbc-plain 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
 
    #Sometimes problems because it keep going on mapping the one before, and tries to "un-map" and map again
    if [ ! $? -eq 0 ]
    then
        dmsetup remove decripted
        #echo -e "\tTrying again password $passwd..."
        echo $passwd | cryptsetup -c aes-cbc-plain  -s 128 -b `blockdev --getsize /dev/loop0` create decripted /dev/loop0
    fi
 
    #Small sample file is created with the begining of the decrypted partition
    dd if=/dev/mapper/decripted of=sample.img count=100 bs=1 2> /dev/null
 
    #Verifiying file type. If succesful, we should expect squashfs filesystem or something like that
    TYPE=`file sample.img | grep -v "sample.img: data"`
    if [ $? -eq 0 ]
    then
        echo "Decrypted as \"$TYPE\" with password $passwd"
    fi
 
    #Trying to despam (?) /dev/loop0 de /dev/mapper/decripted
    cryptsetup remove decripted 2> /dev/null
    dmsetup remove decripted 2> /dev/null
    #Wait 1 sec
    sleep 1
done
 
#Delete association between software_file and /dev/loop0
losetup -d /dev/loop0

Extraction script[edit]

This script in bash/shell scripting allows to obtain from one firmware update file (.wup), the corresponding files of kernel, software and XML information. It is completely GPL and we take no resposibility on its use. Whoever interested in functionality or effects must analyze it. Of course, any improvement, suggestion or contribution will be appreciated.

To date, we obtain six files from .wup update file. The main files are kernel and software, infoxml has limited interest, and the other files (header_bytes, middle_bytes and footer_bytes) are the bytes without identity in different parts of the file. Has been made like that so that joining all the files we could obtain a new original file without losing information.

header_bytes # kernel # middle_bytes # software # footer_bytes # infoxml

This script has been sucessfully tested on the last update files of MediaTitan, ZoltarTv and Wyplayer.


#! /bin/bash
# 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
 
 
#File needed as input parameter
if [ $# -lt 1 ]
then
  echo -e  "Wrong call."
  echo -e  "ej: $0 <update_file.wup>"
  exit
fi
 
FILE=$1
#Obtaining XML info and storing in file
echo -e  "Analyzing file $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 total lines. Root section begins at line $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  "\tXML info obtained from firmware version $VERSION: $XML_FILE"
 
 
 
#Kernel information
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`
 
#Software file information
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  "\tKernel section in the XML. Version:$KERNEL_VERSION, Size: $KERNEL_SIZE, Checksum: $KERNEL_SIGNATURE."
echo -e  "\tSoftware section in the XML. Size: $SOFTWARE_SIZE, Checksum: $SOFTWARE_SIGNATURE."
 
echo -e  "Looking for kernel and software files offset..."
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  "\tKernel found between bytes $KERNEL_OFFSET and $( expr $KERNEL_OFFSET + $KERNEL_SIZE )."
echo -e  "\tSoftware found between bytes $SOFTWARE_OFFSET and $( expr $SOFTWARE_OFFSET + $SOFTWARE_SIZE )."
 
echo -e  "Extracting header bytes..."
dd if=$FILE of=$HEADER_BYTES_FILE bs=1 count=$HEADER_BYTES 2> /dev/null
echo -e  "\tHeader file ($HEADER_BYTES_FILE) extracted."
 
echo -e  "Extracting kernel file..."
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  "\t $DIFF bytes pending for extract"
  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  "\tKernel file ($KERNEL_FILE) extracted succesfully"
else
  echo -e  "ERROR: Kernel file ($KERNEL_FILE) failed"
fi
 
echo -e  "Extracting middle bytes..."
dd if=$FILE of=$MIDDLE_BYTES_FILE bs=1 count=$MIDDLE_BYTES skip=`expr $HEADER_BYTES + $KERNEL_SIZE` 2> /dev/null
echo -e  "\tMiddle bytes file ($MIDDLE_BYTES_FILE) extracted."
 
echo -e  "Extracting software file..."
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  "\t $DIFF bytes pending for extract"
  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  "\tSoftware file ($SOFTWARE_FILE) extracted succesfully"
else
  echo -e  "ERROR: Software file ($SOFTWARE_FILE) failed"
fi
 
echo -e  "Extracting footer bytes..."
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  "\tFooter bytes file ($FOOTER_BYTES_FILE) extracted."
 
kill `pidof dd` 2> /dev/null

Updating a device with other device (brand) device[edit]

One of the problems found is that one device can not be updated with a different device (brand) firmware file. It seems to be that the reason is that each device has one indentifier and, in addition, the "software" part of firmware file is encrypted in different way for each device.

If this was simply like that, would be theoretically possible to create a firmware for a device with modified kernel part, and even so, update would be allowed. With each one of the 6 parts included in a update file, a new one would be built as the mixture of some different firmware files.

Script for mixing firmware files[edit]

To test the concept of mixing the contents of two firmware files a script has been created able to generate a new .wup file from two diferent files. Script disassembles each of the two original (just if disassembled parts are not available in folder) and offers a number of possible combinations. This can be interesting for verifying if any of those combinations allows us to update our device. As a general rule, from all options offered by the script, we're interested in those that mixes one part from a different device and the rest from our device. And more specifically the one that takes the kernel of another ant the rest of our own device. Generated files has not been tested yet, so we recommend caution in using them.

IMPORTANT: To run this script you need to change the value of variable EXTRACT_PROGRAM and set the path to extraction script.

The operation is simple:

wup_mix <update_file1> <update_file2>
#! /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 to extraction script
EXTRACT_PROGRAM=<PATH_TO_EXTRACTION_SCRIPT>/extract_xml
 
if [ ! -f $EXTRACT_PROGRAM ]
then
    echo "You must set variable EXTRACT_PROGRAM to extraction script path"
fi
 
#File is needed as input parameter
if [ $# -lt 2 ]
then
  echo -e  "Wrong call."
  echo -e  "ej: $0 <update_file_1.wup> <update_file_2.wup>"
  exit
fi
 
UPDATE_FILE1=$1
UPDATE_FILE2=$2
 
if [ $UPDATE_FILE1 == $UPDATE_FILE2 ]
then
    echo "Files can not have same name even in different folders."
    echo "Try to rename one of them (ej. mv update.wup update1.wup)."
    exit
fi
 
 
echo -e  "Checking if mixture of files is possible."
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 "Both update files are of same version. Must be from two different versions to be mixed."
    rm $UPDATE_FILE1.xml
    rm $UPDATE_FILE2.xml
    exit
else
    echo "Ok."
fi
 
rm $UPDATE_FILE1.xml
rm $UPDATE_FILE2.xml
 
bash $EXTRACT_PROGRAM $UPDATE_FILE1
bash $EXTRACT_PROGRAM $UPDATE_FILE2
 
echo "Type number of operation to do:"
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 "Creating mixed file..."
      touch $NEW_NAME
      for part in $( seq 0 `expr ${#PARTS[*]} - 1` )
      do
          echo -e "\tAdding ${PARTS[$part]} to new file $NEW_NAME..."
          dd if=${PARTS[$part]} of=$NEW_NAME bs=1 seek=`du -b $NEW_NAME | cut -f1` 2>/dev/null
      done
      echo "Done."
      break
done


Generating own "kernel" and installing in device[edit]

SH4 toolchain for crossed compiling from 386 32 bits. Download and decompress in opt: http://www.megaupload.com/?d=HSV19P40

Generating own "software" and installing in device[edit]

SH4 toolchain for crossed compiling from 386 32 bits. Download and decompress in opt: http://www.megaupload.com/?d=HSV19P40

Telnet access to device[edit]

In order to get telnet access to device is mandatory to modify one file in HD. For that, you need to get out HD from device and plug to PC to get access. Any linux distribution will allow access to HD and modify that file, even a Ubuntu Live cd or any other distribution.

The file to modify is located in partition 1 (JFS). To mount it, execute this commands:

(note: sda must be changed to fit your partition data and all commands must be executed as root, i.e. by adding "sudo" before command)


$ mkdir /mnt/sda1
$ jfs_fsck /dev/sda1
$ mount /dev/sda1 /mnt/sda1

Once mounted, we must edit "local_conf.py" file by adding lines below at the end of file:

import os

os.system('telnetd -l /bin/ash')

Now we dismount partition ( umount /mnt/sda1 ) and plug HD in device again.

From now we should have telnet access to device: (if is connected to network, obviously)

$ telnet device_ip
Wybox Release Branch 1.3.15 (Future is Now!)
/ $

To date, we have tested this procedure succesfully to versions below:

                Works                 Don't works
Media Titan:  7983 and previous        7989
Zoltar TV:    7891 and previous        7909
Wyplayer:          8399?               8418                      
Mediatec:          ?                   ?

Firmware file links[edit]

O2Media ZoltarTV[edit]

Conceptronic MediaTitan[edit]

  CMT2D (non 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
  CMT2DW (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[edit]