Skip to content

Instantly share code, notes, and snippets.

@janimo
Created April 18, 2013 13:35
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save janimo/5412727 to your computer and use it in GitHub Desktop.
Save janimo/5412727 to your computer and use it in GitHub Desktop.
Script to unpack Huawei UPDATE.APP Android firmware blobs
#!/usr/bin/perl
######################################################################
#
# File : split_updata.pl
# Author(s) : McSpoon
# Description : Unpack a Huawei U8220 'UPDATA.APP' file.
# http://pulse.modaco.com
#
# Last Modified : Thu 24 December 2009
# By : McSpoon
#
# Last Modified : Wed 18 June 2010
# By : ZeBadger (z e b a d g e r @ h o t m a i l . c o m)
# Comment : Added filename selection
#
# Last Modified : Wed 19 June 2010
# By : ZeBadger (z e b a d g e r @ h o t m a i l . c o m)
# Comment : Added CRC checking
#
######################################################################
use strict;
use warnings;
my $CRC_CHECK= -e "crc" && -x _;
my %fileHash=( "\x00\x00\x00\x00", "system.img",
"\x00\x00\x00\x10","appsboot.mbn",
"\x00\x00\x00\x20","file25.mbn",
"\x00\x00\x00\x30","testing.img",
"\x00\x00\x00\x40","recovery.img",
"\x00\x00\x00\x50","userdata.img",
"\x00\x00\x00\x70","unicom.img",
"\x00\x00\x00\xB0","FactoryImage.img",
"\x00\x00\x00\xC0","file11.mbn",
"\x00\x00\x00\xD0","amss.mbn",
"\x00\x00\x00\xE0","oemsbl.mbn",
"\x00\x00\x00\xE4","splash.raw565",
"\x00\x00\x00\xF0","file04.mbn", #oemsblhd.mbn?
"\x00\x00\x00\xF1","file07.mbn",
"\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",
"\x00\x00\x10\xF6","file22.txt",
);
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 under current directory.
my $FILENAME = undef;
if (@ARGV) {
$FILENAME = $ARGV[0];
}
else {
my @files = `ls`;
$FILENAME = $ARGV[0];
foreach (@files){
if(/updata.app/i){
$FILENAME=$_;
}
}
}
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);
#printf "fileLoc=%x\n",$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
#my ($temp)=unpack("V",$fileSeq);
#print "fileSeq=$temp\n";
if (exists($fileHash{$fileSeq})) {
$outfilename=$fileHash{$fileSeq};
} else {
$outfilename="unknown_file.$unknown_count";
printf "Unknown file %s found", slimhexdump($fileSeq);
$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
# Grab the checksum of the file
read(INFILE, $fileChecksum, $headerLength-98);
$sourcecrc=slimhexdump($fileChecksum);
# 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;
$calculatedcrc=`./crc $BASEPATH$outfilename` if $CRC_CHECK;
chomp($calculatedcrc) if $CRC_CHECK;
print STDOUT "Extracted $outfilename";
print "\n" if !$CRC_CHECK;
if($CRC_CHECK){
if ($calculatedcrc eq $sourcecrc)
{
print " - CRC Okay\n";
}
else
{
print " - ERROR: CRC did not match\n";
}
}
# 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);
}
@Alirezapcnerd
Copy link

Alirezapcnerd commented Apr 1, 2018

What type script is it? Should it change extension for this file?Is It bat file?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment