/* * ===================================================================================== * * Filename: cpbtool.c * * Description: 一個分解酷派刷機文件.cpb文件的程序 * * Version: 1.0 * Created: 2013年05月07日 18時55分53秒 * Revision: none * Compiler: clang * * Author: linkscue (scue), * Organization: 不告訴你。 * * ===================================================================================== */ #include <stdio.h> #include <stdlib.h> #define u8 unsigned char #define u32 unsigned int #define u16 unsigned short typedef struct { u8 cp_magic[4]; /* coolpad file magic */ u8 cp_version[32]; /* coolpad head version */ u8 model[32]; /* coolpad phone model */ u8 flag_p2[16]; /* alway is P2 string */ u8 version[64]; /* phone version or rom name */ u8 file_form[256]; /* where the rom come from */ u8 information[12]; /* some information, but unkown */ u32 image_offset; /* entrance offset of image */ u32 cpb_filesize; /* the size of whole cpb file */ u8 reverse[128]; /* never use, remain for future */ u32 checksum; /* here maybe is a checksum */ } cpb_head; typedef struct { /* 76 bytes */ u8 filename[64]; /* image filename */ u32 image_offset; /* image offset */ u32 image_size; /* image filesize */ u32 checksum; /* here maybe is a checksum */ } image_t; //分解文件函數; void splitFile(char *file){ FILE *fd = NULL; FILE *ft = NULL; int i=0,imagecount=0; cpb_head header; image_t images[10]; printf("\n"); printf("Welcome to use unpackcpb tool by scue@ATX(bbs.anzhi.com), 2013-05-09, weibo.com/scue.\n"); printf("\n"); if ( (fd=fopen(file,"rb")) == NULL ) { /* 打開文件進行操作 */ printf ( "Extract cpb file, open %s failure!\n", file ); exit(1); } fread(&header, sizeof(header), 1, fd); for ( i=0; ( ftell(fd) < (header.image_offset) ); i++ ){ fread(&images[i], sizeof(image_t), 1, fd); imagecount++; } //開始解壓數據; int size=0,n=0,count=0,offset=0; unsigned char imagename[32]=""; unsigned char buffer[4]=""; /* 創建緩沖區 */ for( i=0; i < imagecount; i++ ){ strncpy(imagename, images[i].filename, sizeof(imagename)); /*----------------------------------------------------------------------------- * 從這里開始,不同的酷派手機, * 可能會被穿插入一部分未知的字節數,要視情況對offset的值進行修改, * 提示一點,所有的Android手機,boot.img的MAGIC必須是‘ANDROID!’。 *-----------------------------------------------------------------------------*/ offset=images[i].image_offset; size=images[i].image_size; if ( size != 0 ) { if ( ( ft=fopen(imagename,"wb") ) == NULL ){ printf("Extract cpb file, open %s failure!\n",imagename); } fseek( fd, offset, SEEK_SET); /* 跳轉至數據段 */ printf("Extract: %-15s offset: 0x%08x size: %d\n",imagename, offset, size); n=0;count=0; while ( count < size ) { n = fread(buffer,1, sizeof(buffer), fd); fwrite(buffer, n, 1, ft); count+=n; } } } fclose(fd); // printf("Extract cpb file done!\n"); } /* * === FUNCTION ====================================================================== * Name: main * Description: 僅分解.cpb文件,不含重新制作.cpb文件的部分 * 在一些酷派手機固件中,官方會把文件結尾的一部分內容,穿插至cpb文件中 * 穿插的部分字節不確定,所以要視不同的酷派手機固件重寫這個cpbtool.c程序 * ===================================================================================== */ int main ( int argc, char *argv[] ) { if (argc==1) { printf("usage:%s cpb file.\n", argv[0]); exit(0); } // printf("argc is %d\n",argc); char *cpb; cpb=argv[1]; splitFile(cpb); return EXIT_SUCCESS; }
注:cpb文件組成結構是經過反復對比與測試得到的,分析工具:bless,測試平台:Linux。