Linux 下解包华为固件包UPDATE.APP

本文提供了解析华为固件包UPDATE.APP的详细步骤,包括使用Perl脚本和C程序进行解包,并展示了Linux环境下解包与挂载的操作方法。通过实例指导如何从华为固件包中提取系统映像文件,适用于Android内核开发人员。

注:本文所有图片保存EverNote 印象笔记(www.yinxiang.com)当中, 如果有其帐号登录后即可查看全部图片。 如没有帐号可用e-mail >>点击注册免费印象笔记


Linux 下解包华为固件包UPDATE.APP

一.关于华为固件包

最近因为需要分析一个特殊的Apk,需要从华为固件升级包抽取出来。

下载后发现华为固件包有两种,一种标准的update.zip卡刷包,这个用标准recovery 升级。解压后从system/app 直接拷贝出相应的apk即可。
另外一种是华为自家包格式dlload格式,每个升级包含配置文件和单个数据文件UPDATE.APP

华为官方的固件全部用这个格式发布,但是这种格式没有公开,因为很简单,很早就被人破解了。

这里三篇是讲如何在Windows下使用perl脚本解出system.img进而抽出其中文件来,思路都是一样的.

《[GUIDE] How to extract Huawei firmware (update.app)》
http://forum.xda-developers.com/showthread.php?t=2315547
《华为mate官方固件update.app专用解包工具及教程 (转)》
http://cn.club.vmall.com/thread-78177-1-1.html
《华为官方固件解包教程...提前官方系统程序》
http://tieba.baidu.com/p/2734923332

二.解析脚本

这几个都是使用split_updata.pl这个perl脚本来解开包。实践发现update.app 实际上是多个img文件合并成的。一般有10个文件。

对比其中不同产品spl_update.pl中的system.img 在不同位置上,这也是造成同一个脚本解析华为不同产品的system.img不对的原因, 在第一篇教程中有一个识别分区image文件脚本
HuaweiFinder https://docs.google.com/file/d/0B5LJgOGBjYOBLWlKcC1sOHkzRzA/edit?usp=sharing ,但是我无法下载,实际操作发现,不用这么复杂,通常尺寸最大是userdata.img,华为改名为cust.img ,第二大就是system.img 这两个通常有50M上下,1-3M大小是boot.img 即内核格式。

这个可以用工具快速测试。

use strict;
use warnings;

# 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 "UPDATA.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 $BASEPATH = "output/";
mkdir $BASEPATH;

# These filenames are guessed. Feel free to correct.
&dump_file($BASEPATH."1.img");
&dump_file($BASEPATH."2.img");
&dump_file($BASEPATH."3.img");
&dump_file($BASEPATH."4.img");
&dump_file($BASEPATH."5.img");
&dump_file($BASEPATH."6.img");
&dump_file($BASEPATH."7.img"); # 40byte header
&dump_file($BASEPATH."8.img"); 
&dump_file($BASEPATH."9.img");
&dump_file($BASEPATH."10.img");
&dump_file($BASEPATH."11.img");
&dump_file($BASEPATH."12.img"); # 40byte header
&dump_file($BASEPATH."13.img");
&dump_file($BASEPATH."14.img"); # 40byte header

close INFILE;


# Unpack a file block and output the payload to a file.
sub dump_file {
    my ($outfilename) = @_;
    my $buffer = undef;

# Verify the identifier matches.
read(INFILE, $buffer, UINT_SIZE);
unless ($buffer eq "\x55\xAA\x5A\xA5") {
    die "Unrecognised file format. Wrong identifier.\n";
}

# Extract the packet length.
read(INFILE, $buffer, UINT_SIZE);
my ($packetLength) = unpack("V", $buffer);

# Ignore the next 16 bytes.
read(INFILE, $buffer, 16);

# Extract the length of the data file.
read(INFILE, $buffer, UINT_SIZE);
my ($dataLength) = unpack("V", $buffer);

# Ignore the rest of the packet. We've already read the first 28 bytes.
read(INFILE, $buffer, $packetLength-28);

# Dump the payload.
read(INFILE, $buffer, $dataLength);
open(OUTFILE, ">$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);
    }

    print STDOUT "Extracted $outfilename\n";
}    

不过我发现有一个C程序编译后也能达到同样效果

http://www.cnblogs.com/GentlemanMod/p/3272580.html
这里我修改一下源码,把itoa 改成snprintf,以便在linux可以编译通过

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAXLEN 10240

void usage();
int main(int argc,char *argv[])
{
    int count,packetLength,dataLength,olddataLength,datasum,line,remainder,*Length;
    char *FILENAME,*OUTNAME;
    char int2char[10];
    unsigned char buffer[MAXLEN];
    FILE *INFILE,*OUTFILE;

    //获取输入的参数
    if(argc == 1)
        FILENAME="UPDATE.APP";
    else
        FILENAME=argv[1];

    //用二进制打开输入文件
    if((INFILE = fopen(FILENAME, "rb")) == NULL) usage();

    //创建文件夹并进入目录
    mkdir("output");
    chdir("output");

    //跳过92空字节
    fseek(INFILE, 92, 0);

    for(count=1;INFILE != NULL;count++)
    {
        //判断是否为华为固件索引头
        fread(buffer, 4, 1, INFILE);
        if(buffer[0] != 0x55) break;
        if(buffer[1] != 0XAA) break;
        if(buffer[2] != 0x5A) break;
        if(buffer[3] != 0xA5) break;

        //获取头文件长度
        fread(buffer, 4, 1, INFILE);
        Length = (int *)buffer;
        packetLength=*Length;

        //跳过16字节
        fseek(INFILE, 16, 1);

        //获取内容长度
        fread(buffer, 4, 1, INFILE);
        Length = (int *) buffer;
        dataLength=*Length;

        //把整数和字符串连接并复制给文件名
        #itoa(count, int2char, 10);
      snprintf(int2char,sizeof(int2char),"%d",count);
        OUTNAME=strcat(int2char, ".img");

        //跳到头文件末尾
        fseek(INFILE, packetLength-28, 1);

        //创建文件
        if((OUTFILE = fopen(OUTNAME, "wb")) == NULL)
        {
            printf("Unrecognised file format. Wrong identifier.\n");
            return -1;
        } else printf("Extracted output/%s\n",OUTNAME);

        //把内容数据分成多个部分
        datasum=dataLength/MAXLEN;

        for(line=0;line <= datasum;line++)
        {
            //获取内容数据
            if(datasum == line)
                fread(buffer, dataLength % MAXLEN, 1, INFILE);
            else
            fread(buffer, MAXLEN, 1, INFILE);

            //输出文件
            if(datasum == line)
                fwrite(buffer, dataLength % MAXLEN, 1, OUTFILE);
            else
            fwrite(buffer, MAXLEN, 1, OUTFILE);
        }

        //关闭输出文件
        fclose(OUTFILE);

        //指针取整,4的倍数
        remainder = 4 - (ftell(INFILE) % 4);
        if (remainder < 4)
        {
            //进行填充剩余的字节
            fseek(INFILE, remainder, 1);
        }
    }
    //关闭输入文件
    fclose(INFILE);
    return 0;
}

void usage()
{
    //帮助函数
    printf("uasge: unpack_update.exe [UPDATE.APP|UPDATA.APP]\n");
    exit(0);
}

三.Linux下解包

前面教程都是因为windows下缺少必要工具perl解析器以及mount工具,才会如此大费周章,实际上Linux操作相当简单,只要传spl_update.pl 脚本即可。而且如果是一个专业的Android内核开发人员,用Linux比用windows机会更多吧。

  • 解包

    把spl_update.pl和UDPATE.APP放在一个目录下,执行
    perl spl_update.pl UPDATE.APP

  • 挂载操作system.img

    Linux下是可以用mount 直接把一个文件当成文件系统挂载的,假设3.img 是system.img格式,

直接用mount 命令
mount -t ext4 -o loop 3.img /mnt
以上命令把system.img 挂载到/mnt目录,打开这个目录/system的各种结构就是展示在你眼前!

Alt text

最后,如果你觉得印象笔记好用,请用这个链接注册一个吧,最好的跨平台笔记软件(Android/iOS/Mac/Windows/网页版),我也赚点印象分获得高级帐号,当我升级,你也同步升级 https://app.yinxiang.com/referral/Registration.action?uid=436771&sig=c8049c851d63432b15e096b5fb449dfb

非常威猛的官方固件UPDATE.APP解包打包工具(转自XDA论坛) Huawei Update Extractor After messing around a bit with the perl tools available for extracting Huawei update.app files, i got the idea to create an own (windows) tool. Requirements .Net Framework 3.5 Install Extract the content of the zip to a folder somewhere on your system. Execute HuaweiUpdateExtractor.exe I'm planning to create an installer sometime. Usage Press the browse (...) button and select an update.app file. Select a device or unknown and press on the open button. You'll see the content of the update.app file in the listview. Select one or more files and right click. Choose Extract selected from the context menu. Choose the ouput folder and press ok. Or just right click on the list and select Extract all, choose the output folder again and press ok. Press close on the extract window. You can sort the list on sequence, filename and size. Just press on the desired column header. Command line: HuaweiUpdateExtractor extract input output [profile] HuaweiUpdateExtractor repack input output profile Profile The profiles.xml file is used to identify the files in the update.app file. Every file in the update.app has a sequence or type, which is also shown in the list. Those sequences or types are used to identify the file/device partition. Example: system.img recovery.img baseband.img version.txt splash.raw565 boot.img cust.img userdata.img signature crc system.img cache.img cust.img userdata.img modemimage.img boot.img recovery.img signature crc - Root tag of the xml file. - Identifies a device - attribute name: name of the device - attribute author: author of the device - File root tag - Identifies a file - attribute sequence: sequence of the file in update.app - attribute type: type of the file in the update.app - attribute partition: destination partition on the device - attribute signature: used to identify the signature file - attribute checksum: used to identify the checksum file - value: file name You can add or edit devices. If you want them to integrate in newer version, pm 'em to me. I'm gonna make some auto update for the device file somewhere in the future Roadmap - You tell me ... Credits ZeBadger (zebadger@hotmail.com) for figuring out the file headers S34Qu4K3 for the P6 partition layout ngamyarthar for adding ALOT of devices! Changelog
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值