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

注:本文所有图片保存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

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 华为固件工具Linux是一种用于解包华为设备固件的工具,它可以在Linux操作系统上运行。使用该工具可以将华为设备的固件成各个组件,方便进行修改和定制。该工具通常用于开发者和技术人员进行设备定制和优化。 ### 回答2: 华为固件工具linux是一个非常实用的解工具,可以用于对华为设备上的固件进行解操作。它主要是由华为的开发团队所设计和开发的,可以在linux系统上进行使用。 华为固件工具linux可以帮助用户快速地解包华为设备上的固件,拆分出其中的各个文件和模块,并对其进行修改、添加或删除操作。这对于华为设备的开发和维护来说非常重要,可以极大地提高开发效率和节省开发成本。 华为固件工具linux可以支持多种华为设备,括路由器、交换机、存储设备等。它的具体功能括:解固件、打固件、拆分镜像、生成驱动程序等。这些功能能够满足用户对华为设备开发和维护需求的各种操作。 同时,华为固件工具linux还具有可扩展性和灵活性,用户可以根据自己的需要对其进行自定义配置和打操作,以满足各种个性化需求。此外,它的界面简单易用,操作流程简单明了,适合各个层次的用户进行操作。 总之,华为固件工具linux是一个非常实用和强大的解工具,能够满足华为设备的开发和维护需求。它的功能强大、易于使用,对提高华为设备开发效率和降低开发成本具有重要意义。 ### 回答3: 华为固件工具linux是一款用于解包华为设备固件的软件,它可以帮助技术人员分析固件文件,获取有用的信息并进行相关的操作。华为固件工具支持在Linux系统下使用,兼容多种不同版本的Linux系统,例如:Ubuntu、CentOS、Debian等。 使用华为固件工具linux,我们可以对华为设备进行固件升级、修复等操作,保证设备的安全性和稳定性。同时,该工具也为网络技术人员提供了一个重要的分析和检测工具,在网络安全评估、设备调试、性能优化等方面都有广泛应用。 华为固件工具linux具有以下优点: 1. 简便易用:该软件支持多种操作系统平台,安装及使用都非常方便。技术人员只需下载相应的软件,按照软件安装说明即可完成安装。 2. 功能齐全:华为固件工具linux支持华为设备固件的解、打、提取、还原、修改等操作,可以帮助技术人员更好地进行设备的维护和管理工作。 3. 安全可靠:华为固件工具linux遵循安全原则,确保技术人员的相关操作不会破坏设备,避免对用户造成损失。同时,也保护用户的设备不受来自互联网的攻击和侵害。 总之,华为固件工具linux是一款不可或缺的网络技术工具,在网络设备管理、安全评估、调试优化等方面都有广泛应用和重要作用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值