/*
* =====================================================================================
*
* 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[]; /* coolpad file magic */
u8 cp_version[]; /* coolpad head version */
u8 model[]; /* coolpad phone model */
u8 flag_p2[]; /* alway is P2 string */
u8 version[]; /* phone version or rom name */
u8 file_form[]; /* where the rom come from */
u8 information[]; /* some information, but unkown */
u32 image_offset; /* entrance offset of image */
u32 cpb_filesize; /* the size of whole cpb file */
u8 reverse[]; /* never use, remain for future */
u32 checksum; /* here maybe is a checksum */
} cpb_head; typedef struct { /* 76 bytes */
u8 filename[]; /* 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=,imagecount=;
cpb_head header;
image_t images[];
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();
} fread(&header, sizeof(header), , fd);
for ( i=; ( ftell(fd) < (header.image_offset) ); i++ ){
fread(&images[i], sizeof(image_t), , fd);
imagecount++;
}
//开始解压数据;
int size=,n=,count=,offset=;
unsigned char imagename[]="";
unsigned char buffer[]=""; /* 创建缓冲区 */
for( i=; 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 != ) {
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=;count=;
while ( count < size ) {
n = fread(buffer,, sizeof(buffer), fd);
fwrite(buffer, n, , 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==) {
printf("usage:%s cpb file.\n", argv[]);
exit();
} // printf("argc is %d\n",argc);
char *cpb;
cpb=argv[];
splitFile(cpb); return EXIT_SUCCESS;
}
注:cpb文件组成结构是经过反复对比与测试得到的,分析工具:bless,测试平台:Linux。