├── Readme.md ├── shot.png └── unpackapp.c /Readme.md: -------------------------------------------------------------------------------- 1 | About 2 | ===== 3 | 4 | A tool for unpack huawei app file. 5 | 6 | HOW-TO 7 | ====== 8 | 9 | gcc unpackapp.c -o unpackapp 10 | unpackapp 11 | 12 | Shot 13 | ==== 14 | ![Shot](https://github.com/scue/unpackapp/raw/master/shot.png) 15 | -------------------------------------------------------------------------------- /shot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scue/unpackapp/fd4ef8cc026b90e00d7a26f10055db8d00f5f60c/shot.png -------------------------------------------------------------------------------- /unpackapp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ===================================================================================== 3 | * 4 | * Filename: unpack.c 5 | * 6 | * Description: A tool for unpack huawei *.app file. 7 | * 8 | * Version: 1.0 9 | * Created: 2013年03月28日 22时34分52秒 10 | * Revision: none 11 | * Compiler: gcc 12 | * 13 | * Author: linkscue (scue), 14 | * Organization: 15 | * 16 | * ===================================================================================== 17 | */ 18 | 19 | 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #define u8 unsigned char 27 | #define u32 unsigned int 28 | #define u16 unsigned short 29 | #define BUFFER_SIZE 4096 30 | 31 | typedef struct _image 32 | { 33 | // u32 magic 34 | u32 packet_size; 35 | u32 flag; 36 | char hardware[8]; 37 | u32 filetype; 38 | u32 data_size; 39 | char date[16]; 40 | char time[16]; 41 | char filename[32]; 42 | // u8 other[packet_size-92] 43 | } image; 44 | 45 | // 字符串真实长度 46 | int realStrlen(char *string){ 47 | int i=0; 48 | char ch=0; 49 | while ( (ch = *(string + i)) != '\xFF' ) { 50 | i++; 51 | } 52 | return i; 53 | } 54 | 55 | // 去掉字符串尾部 \xFF 56 | void trim_str(char *string){ 57 | char tmpstr[128]=""; 58 | strncpy(tmpstr, string, realStrlen(string)); 59 | strcpy(string, tmpstr); 60 | } 61 | 62 | // 字符串大写转换小写 63 | void str_tolower(char *string){ 64 | int i=0; 65 | for (i = 0; i < strlen(string); ++i) { 66 | string[i]=tolower(string[i]); 67 | } 68 | } 69 | 70 | // 重命名镜像文件 71 | void rename_imgfname(char *filename, int number){ 72 | // 针对MTK, 它们所有Image名字都是INPUT 73 | char tmp[32]=""; 74 | if ( strcmp(filename,"INPUT") == 0 ) { 75 | sprintf(tmp, "output_%02d.img", number); 76 | strcpy(filename, tmp); 77 | } 78 | // 针对普通机型 79 | else { 80 | str_tolower(filename); 81 | snprintf(tmp, sizeof(tmp)-1, "%s.img", filename); 82 | strcpy(filename, tmp); 83 | } 84 | } 85 | 86 | // 欢迎信息 87 | void hello(){ 88 | printf("\n"); 89 | printf("Welcome to use linkscue unpackapp tool!\n"); 90 | } 91 | 92 | int main ( int argc, char *argv[] ) 93 | { 94 | hello(); 95 | if (argc == 1) { 96 | printf("\n"); 97 | printf("usage: %s unpack.app\n", argv[0]); 98 | exit(0); 99 | } 100 | 101 | // 文件 102 | char *file; /* app文件 */ 103 | FILE *fp,*fd; 104 | 105 | // 镜像信息 106 | u32 magic=0xa55aaa55; 107 | image img; 108 | int other_size=0; 109 | 110 | u32 tmp; /* for compare magic */ 111 | int number=1; /* for MTK only */ 112 | u8 buffer[BUFFER_SIZE]; /* for read image file */ 113 | int fp_start=0; /* for image file start point */ 114 | int i=0, count; 115 | 116 | file=argv[1]; 117 | if ( (fp=fopen(file,"rb")) == NULL) { 118 | printf("open file %s failure!\n",file); 119 | exit(1); 120 | } 121 | printf("\n"); 122 | while (!feof(fp)) { 123 | fread( &tmp, 1, sizeof(tmp), fp ); 124 | if (tmp == magic) { 125 | memset(&img, 0, sizeof(img)); 126 | fp_start=(ftell(fp)-4); 127 | 128 | // 读取镜像相关信息 129 | fread( &img, 1, sizeof(img), fp ); 130 | other_size=( img.packet_size - 92 ); 131 | 132 | // 字符串处理 133 | trim_str(img.hardware); 134 | trim_str(img.filename); 135 | rename_imgfname(img.filename, number); 136 | 137 | printf("At: 0x%08x hw: %s size: %-10d time: %s_%s --> %s\n", 138 | fp_start, img.hardware, img.data_size, img.date, img.time, img.filename); 139 | 140 | // 写入镜像文件 141 | fseek(fp, other_size, SEEK_CUR); 142 | if ((fd=fopen(img.filename,"wb"))==NULL) { 143 | printf("open %s to write data failure!\n", img.filename); 144 | fseek(fp, sizeof(image), SEEK_CUR); 145 | continue; 146 | } 147 | for (i = 0; i < img.data_size/BUFFER_SIZE; ++i) { /* 1. read image main */ 148 | if (feof(fp)) /* if the end of file, break! */ 149 | break; 150 | count = fread(buffer, 1, BUFFER_SIZE, fp); 151 | fwrite(buffer, 1 , count, fd); 152 | } 153 | int tail_data_size=img.data_size%BUFFER_SIZE; 154 | if ( tail_data_size != 0) { /* 2. read image tail data */ 155 | count = fread(buffer, 1, tail_data_size, fp); 156 | fwrite(buffer, 1 , count, fd); 157 | } 158 | fclose(fd); 159 | 160 | // 移动文件,使之以4字节对齐 161 | fseek(fp, (fp_start+(img.data_size/sizeof(magic))*sizeof(magic)) , SEEK_SET); 162 | number++; 163 | } 164 | } 165 | fclose(fp); 166 | return EXIT_SUCCESS; 167 | } 168 | --------------------------------------------------------------------------------