Unpacking UPDATE.APP

Discussion specific to Huawei Ascend G600 / Honor+ (U8950-1, U8950-51, U8950N-1, U8950D, C8950D, T8950)

Unpacking UPDATE.APP

Postby Dopi » Sun Apr 21, 2013 12:51 pm

I found an interesting post on the modaco forum. It shows a perl script that was initially written for U8220 to unpack the Huawei UPDATE.APP and split it into several files containing e.g. the kernel and the root and rescue filesystems. The updated script extracts the UPDATE.APP file for U8800Pro. I tried this script and it also works for the U8950 ( Ascend G600 ) and U8951 ( Ascend G510 ) UPDATE.APP files.

Below is the script I used:
Code: Select all
#!/usr/bin/perl
######################################################################
#
#   File          : split_update.pl
#   Author(s)     : McSpoon and others
#   Description   : Unpack a Huawei  'UPDATE.APP' file.                 
#
#   Last Modified : 07/07/2012
#
######################################################################

use strict;
use warnings;

my %fileHash=(   "\x00\x00\x00\x10","appsboot.mbn",
      "\x00\x00\x00\x20","file25.mbn",
      "\x00\x00\x00\x30","userdata.img",
      "\x00\x00\x00\xB0","cust.ext3.img",
      "\x00\x00\x00\x00","system.img",
      "\x00\x00\x00\x50","userdata.img",
      "\x00\x00\x00\x40","recovery.img",
      "\x00\x00\x00\x70","cust.img",
      "\x00\x00\x00\x80","AMSSMBN.img",
      "\x00\x00\x00\xC0","file11.mbn",
      "\x00\x00\x00\xD0","file08.mbn",
      "\x00\x00\x00\xE0","file05.mbn",
      "\x00\x00\x00\xF0","file04.mbn",
      "\x00\x00\x00\xF1","file07.mbn",
      "\x00\x00\x00\xF2","splash.raw565",
      "\x00\x00\x00\xF3","file01.mbn",
      "\x00\x00\x00\xF4","file02.mbn",
      "\x00\x00\x00\xF5","file14.mbn",
      "\x00\x00\x00\xF6","boot_versions.txt",
      "\x00\x00\x00\xF7","upgradable_versions.txt",
      "\x00\x00\x00\xF8","file09.mbn",
      "\x00\x00\x00\xF9","version.txt",
      "\x00\x00\x00\xFA","file20.mbn",
      "\x00\x00\x00\xFB","appsboothd.mbn",
      "\x00\x00\x00\xFC","boot.img",
      "\x00\x00\x00\xFD","file16.mbn",
      "\x00\x00\x00\xFE","file18.mbn",
      "\x00\x00\x00\xFF","file21.mbn",
   );


my $unknown_count=0;

# Turn on print flushing.
$|++;

# Unsigned integers are 4 bytes.
use constant UINT_SIZE => 4;

# If a filename wasn't specified on the commmand line then
# assume the file to be unpacked is called "UPDATE.APP".
my $FILENAME = undef;
if ($#ARGV == -1) {
   $FILENAME = "UPDATE.APP";
}
else {
   $FILENAME = $ARGV[0];
}

open(INFILE, $FILENAME) or die "Cannot open $FILENAME: $!\n";
binmode INFILE;

# Skip the first 92 bytes, they're blank.
#seek(INFILE, 92, 0);

# We'll dump the files into a folder called "output".
my $fileLoc=0;
my $BASEPATH = "output/";
mkdir $BASEPATH;

while (!eof(INFILE))
{
   $fileLoc=&find_next_file($fileLoc);
   seek(INFILE, $fileLoc, 0);
   $fileLoc=&dump_file();
}

close INFILE;


# Find the next file block in the main file
sub find_next_file
{
   my ($_fileLoc) = @_;
   my $_buffer = undef;
   my $_skipped=0;

   read(INFILE, $_buffer, UINT_SIZE);
   while ($_buffer ne "\x55\xAA\x5A\xA5" && !eof(INFILE))
   {
      read(INFILE, $_buffer, UINT_SIZE);
      $_skipped+=UINT_SIZE;
   }

   return($_fileLoc + $_skipped);
}

# Unpack a file block and output the payload to a file.
sub dump_file {
    my $buffer = undef;
    my $outfilename = undef;
    my $fileSeq;
    my $calculatedcrc = undef;
    my $sourcecrc = undef;
    my $fileChecksum;

    # Verify the identifier matches.
    read(INFILE, $buffer, UINT_SIZE); # Packet Identifier
    unless ($buffer eq "\x55\xAA\x5A\xA5") { die "Unrecognised file format. Wrong identifier.\n"; }
    read(INFILE, $buffer, UINT_SIZE); # Packet Length.
    my ($headerLength) = unpack("V", $buffer);
    read(INFILE, $buffer, 4);         # Always 1
    read(INFILE, $buffer, 8);         # Hardware ID
    read(INFILE, $fileSeq, 4);        # File Sequence
    if (exists($fileHash{$fileSeq})) {
   $outfilename=$fileHash{$fileSeq};
    } else {
   $outfilename="unknown_file.$unknown_count";
   $unknown_count++;
    }
   
    read(INFILE, $buffer, UINT_SIZE); # Data file length
    my ($dataLength) = unpack("V", $buffer);
    read(INFILE, $buffer, 16);        # File date
    read(INFILE, $buffer, 16);        # File time
    read(INFILE, $buffer, 16);        # The word INPUT ?
    read(INFILE, $buffer, 16);        # Blank
    read(INFILE, $buffer, 2);         # Checksum of the header maybe?
    read(INFILE, $buffer, 2);         # Always 1?
    read(INFILE, $buffer, 2);         # Blank

   
   
    # Dump the payload.
    read(INFILE, $buffer, $dataLength);
    open(OUTFILE, ">$BASEPATH$outfilename") or die "Unable to create $outfilename: $!\n";
    binmode OUTFILE;
    print OUTFILE $buffer;
    close OUTFILE;

   
   
    # Ensure we finish on a 4 byte boundary alignment.
    my $remainder = UINT_SIZE - (tell(INFILE) % UINT_SIZE);
    if ($remainder < UINT_SIZE) {
       # We can ignore the remaining padding.
       read(INFILE, $buffer, $remainder);
    }
   
    return (tell(INFILE));
}

sub hexdump ()
{
        my $num=0;
        my $i;
        my $rhs;
        my $lhs;
        my ($buf) = @_;
        my $ret_str="";

        foreach $i ($buf =~ m/./gs)
        {
                # This loop is to process each character at a time.
                #
                $lhs .= sprintf(" %02X",ord($i));

                if ($i =~ m/[ -~]/)
                {
                        $rhs .= $i;
                }
                else
                {
                        $rhs .= ".";
                }

                $num++;
                if (($num % 16) == 0)
                {
                        $ret_str.=sprintf("%-50s %s\n",$lhs,$rhs);
                        $lhs="";
                        $rhs="";
                }
        }
        if (($num % 16) != 0)
        {
                $ret_str.=sprintf("%-50s %s\n",$lhs,$rhs);
        }

   return ($ret_str);
}
       
sub slimhexdump ()
{
        my $i;
        my ($buf) = @_;
        my $ret_str="";

        foreach $i ($buf =~ m/./gs)
        {
                # This loop is to process each character at a time.
                #
                $ret_str .= sprintf("%02X",ord($i));
        }

   return ($ret_str);
}
       


The usage is quite simple. Just launch it with the perl command and the name of the UPDATE.APP file as an argument.

Code: Select all
perl split_update.pl UPDATE.APP


With this I hope to use the G510 Jelly Bean ROM files for the G600.

Cheers,
Dopi
Ad banners support the JetDroid forum. Please consider clicking them once in a while.
User avatar
Dopi
Dev Team
Dev Team
 
Posts: 926
Joined: Sun Aug 22, 2010 9:47 pm

Advertisement

Return to Huawei Ascend G600 Honor+ (U8950, C8950, T8950)

Who is online

Users browsing this forum: No registered users and 1 guest

  • Advertisement
cron