〖Android〗酷派手機固件.cpb文件的分解程序


/*
 * =====================================================================================
 *
 *       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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM