为什么80%的码农都做不了架构师?>>>   

此前入手了部酷派8730L,无奈搜遍整个互联网寻求ROOT的方法以及用了各种ROOT工具均以失败告终。于是决定研究下酷派的CPB升级文件:4.3.066.P3.140417.8730L.CPB。以为解包出来改改某个文件再封包,然后刷机可以解决ROOT的问题(后来事实证明太天真啦,CDS这个升级工具根本就没法用,让我机器变砖头的机会都不给),于是下载个cpb解包封包工具试下,没想到又失败了。没办法只能参考找到的部分cpb文件格式资料,自己写解包封包工具。OD动态调试CDS升级工具(版本:V4.29_140116_01),发现cpb文件验证过程在dChkData.dll中完成,研究一番,写了个自己的CPB解包封包工具,代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <direct.h>
#include <stddef.h>typedef char int8 ;
typedef unsigned char uint8 ;
typedef short int16 ;
typedef unsigned short uint16 ;
typedef int int32 ;
typedef unsigned int uint32 ;
typedef __int64 int64 ;
typedef unsigned __int64 uint64 ;typedef struct tagCPBHEADER
{char cp_magic[2] ;     //'CP'uint8 cp_version[2] ;   //CPB文件版本uint16 correct[6] ;        //12字节校正用 uint8 unknown[32] ;       //未知32字节char model[32] ;        //适用的手机型号,如"8730L" char hardVersion[16] ;  //适用的硬件版本号,如"P3"char version[64] ;     //适用的版本号,如"4.3.066.P3.140417.8730L"char romFrom[256] ;     //uint32 imgHdrEndPos ;     //Image Header停止的位置,这样就能确定Image Header大小uint8 reverse[128] ;     //保留uint32 checkSum ;       //校验和(CRC16)
}CPBHEADER, *LPCPBHEADER ;typedef struct tagIMAGEHEADER
{char fileName[64] ;uint32 imageOffset ;uint32 imageSize ;uint32 checkSum ;//CRC16
}IMAGEHEADER, *LPIMAGEHEADER;const uint16 CRC16Tab[256] =
{0x0000L, 0x1021L, 0x2042L, 0x3063L,0x4084L, 0x50a5L, 0x60c6L, 0x70e7L,0x8108L, 0x9129L, 0xa14aL, 0xb16bL,0xc18cL, 0xd1adL, 0xe1ceL, 0xf1efL,0x1231L, 0x0210L, 0x3273L, 0x2252L,0x52b5L, 0x4294L, 0x72f7L, 0x62d6L,0x9339L, 0x8318L, 0xb37bL, 0xa35aL,0xd3bdL, 0xc39cL, 0xf3ffL, 0xe3deL,0x2462L, 0x3443L, 0x0420L, 0x1401L,0x64e6L, 0x74c7L, 0x44a4L, 0x5485L,0xa56aL, 0xb54bL, 0x8528L, 0x9509L,0xe5eeL, 0xf5cfL, 0xc5acL, 0xd58dL,0x3653L, 0x2672L, 0x1611L, 0x0630L,0x76d7L, 0x66f6L, 0x5695L, 0x46b4L,0xb75bL, 0xa77aL, 0x9719L, 0x8738L,0xf7dfL, 0xe7feL, 0xd79dL, 0xc7bcL,0x48c4L, 0x58e5L, 0x6886L, 0x78a7L,0x0840L, 0x1861L, 0x2802L, 0x3823L,0xc9ccL, 0xd9edL, 0xe98eL, 0xf9afL,0x8948L, 0x9969L, 0xa90aL, 0xb92bL,0x5af5L, 0x4ad4L, 0x7ab7L, 0x6a96L,0x1a71L, 0x0a50L, 0x3a33L, 0x2a12L,0xdbfdL, 0xcbdcL, 0xfbbfL, 0xeb9eL,0x9b79L, 0x8b58L, 0xbb3bL, 0xab1aL,0x6ca6L, 0x7c87L, 0x4ce4L, 0x5cc5L,0x2c22L, 0x3c03L, 0x0c60L, 0x1c41L,0xedaeL, 0xfd8fL, 0xcdecL, 0xddcdL,0xad2aL, 0xbd0bL, 0x8d68L, 0x9d49L,0x7e97L, 0x6eb6L, 0x5ed5L, 0x4ef4L,0x3e13L, 0x2e32L, 0x1e51L, 0x0e70L,0xff9fL, 0xefbeL, 0xdfddL, 0xcffcL,0xbf1bL, 0xaf3aL, 0x9f59L, 0x8f78L,0x9188L, 0x81a9L, 0xb1caL, 0xa1ebL,0xd10cL, 0xc12dL, 0xf14eL, 0xe16fL,0x1080L, 0x00a1L, 0x30c2L, 0x20e3L,0x5004L, 0x4025L, 0x7046L, 0x6067L,0x83b9L, 0x9398L, 0xa3fbL, 0xb3daL,0xc33dL, 0xd31cL, 0xe37fL, 0xf35eL,0x02b1L, 0x1290L, 0x22f3L, 0x32d2L,0x4235L, 0x5214L, 0x6277L, 0x7256L,0xb5eaL, 0xa5cbL, 0x95a8L, 0x8589L,0xf56eL, 0xe54fL, 0xd52cL, 0xc50dL,0x34e2L, 0x24c3L, 0x14a0L, 0x0481L,0x7466L, 0x6447L, 0x5424L, 0x4405L,0xa7dbL, 0xb7faL, 0x8799L, 0x97b8L,0xe75fL, 0xf77eL, 0xc71dL, 0xd73cL,0x26d3L, 0x36f2L, 0x0691L, 0x16b0L,0x6657L, 0x7676L, 0x4615L, 0x5634L,0xd94cL, 0xc96dL, 0xf90eL, 0xe92fL,0x99c8L, 0x89e9L, 0xb98aL, 0xa9abL,0x5844L, 0x4865L, 0x7806L, 0x6827L,0x18c0L, 0x08e1L, 0x3882L, 0x28a3L,0xcb7dL, 0xdb5cL, 0xeb3fL, 0xfb1eL,0x8bf9L, 0x9bd8L, 0xabbbL, 0xbb9aL,0x4a75L, 0x5a54L, 0x6a37L, 0x7a16L,0x0af1L, 0x1ad0L, 0x2ab3L, 0x3a92L,0xfd2eL, 0xed0fL, 0xdd6cL, 0xcd4dL,0xbdaaL, 0xad8bL, 0x9de8L, 0x8dc9L,0x7c26L, 0x6c07L, 0x5c64L, 0x4c45L,0x3ca2L, 0x2c83L, 0x1ce0L, 0x0cc1L,0xef1fL, 0xff3eL, 0xcf5dL, 0xdf7cL,0xaf9bL, 0xbfbaL, 0x8fd9L, 0x9ff8L,0x6e17L, 0x7e36L, 0x4e55L, 0x5e74L,0x2e93L, 0x3eb2L, 0x0ed1L, 0x1ef0L
};uint32 CRC16(const uint8 *pData, uint32 nSize, uint32 uiCrc)
{uint32 i;for (i=0; i<nSize; i++)uiCrc = (uiCrc << 8) ^ (uint16)CRC16Tab[(uint8)(uiCrc >> 8) ^ pData[i]];return uiCrc ;
}int32 MkdirRecursive( char* path )
{char *p, ch;if( access( path, 0 ) == 0 )return 0;for( p=path; *p; p++ ){if( p>path && ((*p == '/') || (*p == '\\')) ){ch = *p ;*p = 0;if( access( path, 0 ) != 0 ){if( mkdir( path ) != 0 )return -1;}*p = ch ;}}return mkdir( path );
}void usage(void)
{printf("本工具限用于酷派CPB1.7版本。即cpb文件头4字节为\"CP\\x01\\x07\"。\n") ;printf("usage: cpbtool.exe\n""  [-l <CPB文件> <列表文件>]\n\t#列出CPB的所有文件为列表文件。\n""  [-u <CPB文件> <路径>]\n\t#解压CPB文件到指定目录。\n""  [-p <型号> <硬件版本> <版本号> <路径> <列表文件> <CPB文件>]\n\t#打包指定目录下的文件为CPB包。\n") ;printf("Ex: cpbtool.exe -l ex.cpb list.txt\n") ;printf("    cpbtool.exe -u ex.cpb .\\8730L\n") ;printf("    cpbtool.exe -p 8730L P3 4.3.066.P3.140417.8730L .\\8730L list.txt new.cpb\n") ;
}void PrintCpbHeader(LPCPBHEADER pHdr)
{char buf[512] ;printf("CPB文件版本:%d.%d\n", pHdr->cp_version[0], pHdr->cp_version[1]) ;strncpy(buf, pHdr->model, sizeof(buf)) ;printf("适用的手机型号:%s\n", buf) ;strncpy(buf, pHdr->hardVersion, sizeof(buf)) ;printf("适用的硬件版本号:%s\n", buf) ;strncpy(buf, pHdr->version, sizeof(buf)) ;printf("适用的版本号:%s\n", buf) ;printf("映像文件头大小:%u,每个76字节,共%u个。\n", pHdr->imgHdrEndPos-sizeof(CPBHEADER), (pHdr->imgHdrEndPos-sizeof(CPBHEADER)) / sizeof(IMAGEHEADER)) ;printf("校验和:0x%08X\n\n", pHdr->checkSum) ;
}void CreateListFile(const char *lpszCpb, const char *lpszList)
{FILE *fcpb = NULL ;FILE *flst = NULL ;CPBHEADER cpbHdr ;LPIMAGEHEADER pImgHdr = NULL ;size_t sz ;uint32 nImgSize, nImgCount, i ;fcpb = fopen(lpszCpb, "rb") ;if (fcpb == NULL){printf("打开文件“%s”失败!\n", lpszCpb) ;return 0 ;}sz = fread(&cpbHdr, sizeof(cpbHdr), 1, fcpb);if(sz != 1 || cpbHdr.cp_magic[0] != 'C' || cpbHdr.cp_magic[1] != 'P' ||cpbHdr.imgHdrEndPos < sizeof(cpbHdr)){fclose(fcpb) ;printf("不是有效的CPB文件!\n") ;return 0;}if(cpbHdr.cp_version[0] != 0x01 || cpbHdr.cp_version[1] != 0x07){printf("本工具限用于酷派CPB1.7版本。即cpb文件头4字节为\"CP\\x01\\x07\"。\n") ;return ;}PrintCpbHeader(&cpbHdr) ;nImgSize = cpbHdr.imgHdrEndPos - sizeof(CPBHEADER) ;nImgCount = (cpbHdr.imgHdrEndPos - sizeof(CPBHEADER)) / sizeof(IMAGEHEADER) ;pImgHdr = (LPIMAGEHEADER)malloc(nImgSize) ;if(pImgHdr == NULL){fclose(fcpb) ;printf("分配内存%u字节失败,可能是文件不合法!\n", nImgSize) ;return 0 ;}sz = fread(pImgHdr, nImgSize, 1, fcpb) ;if(sz != 1){free(pImgHdr) ;fclose(fcpb) ;printf("不是有效的CPB文件!\n") ;return 0 ;}flst = fopen(lpszList, "w") ;if(flst != NULL){for(i=0; i<nImgCount; i++)fprintf(flst, "%s\n", pImgHdr[i].fileName) ;fclose(flst) ;printf("列表文件‘%s’创建成功!\n", lpszList) ;}elseprintf("列表文件‘%s’创建失败!\n", lpszList) ;free(pImgHdr) ;fclose(fcpb) ;return 0 ;
}void PrintfImageHeader(LPIMAGEHEADER pImgHdr)
{char buf[128] ;strncpy(buf, pImgHdr->fileName, sizeof(buf)) ;printf("文件名:%s\n", buf) ;printf("偏移:0x%08X\n", pImgHdr->imageOffset) ;printf("大小:0x%08X(%u)\n", pImgHdr->imageSize, pImgHdr->imageSize) ;printf("校验和:0x%08X\n", pImgHdr->checkSum) ;
}void ImageHeaderCorrectPosSize(LPIMAGEHEADER pImgHdr, int32 idx, uint32 uiCorrect)
{uint32 iPos, nSize, iTemp ;uint8 bt1, bt2, bt3, bt4 ;bt1 = (uint8)idx + (uint8)uiCorrect ;bt2 = (uint8)idx + (uint8)(uiCorrect >> 8) ;bt3 = (uint8)idx + (uint8)(uiCorrect >> 16) ;bt4 = (uint8)idx + (uint8)(uiCorrect >> 24) ;iPos = pImgHdr->imageOffset ;nSize = pImgHdr->imageSize ;iPos = (uint8)(bt3 ^ iPos) | (uint16)((uint8)(bt4 ^ (uint8)(iPos >> 8)) << 8) | (((uint8)(bt1 ^ ((uint32)iPos >> 16)) | (uint16)((uint8)(bt2 ^ (uint8)(iPos >> 24)) << 8)) << 16);iTemp = (uint8)(bt3 ^ nSize);nSize = iTemp | (uint16)((uint8)(bt4 ^ (uint8)(nSize >> 8)) << 8) | (((uint8)(bt1 ^ ((uint32)nSize >> 16)) | (uint16)((uint8)(bt2 ^ (uint8)(nSize >> 24)) << 8)) << 16);pImgHdr->imageOffset = iPos ;pImgHdr->imageSize = nSize ;
}void DumpFile(FILE *fcpb, const char *lpszPath, LPIMAGEHEADER pImgHdrs, uint32 nImgCount)
{FILE *fImg ;char szFile[512] ;uint8 *pBuf ;uint32 i, iBufSize, nLen, uiCrc = 0;if(pImgHdrs == NULL) return ;iBufSize = 1024 * 1024 ; //1MiBpBuf = (uint8 *)malloc(iBufSize) ;if(pBuf == NULL){printf("DumpFile 分配内存失败!\n") ;return ;}for(i=0; i<nImgCount; i++){PrintfImageHeader(&pImgHdrs[i]) ;if(pImgHdrs[i].imageSize == 0) continue ;if(fseek(fcpb, pImgHdrs[i].imageOffset, SEEK_SET) != 0){printf("生成文件“%s”失败!原CPB文件无法定位到:0x%08X\n\n", pImgHdrs[i].fileName, pImgHdrs[i].imageOffset) ;continue ;}sprintf(szFile, "%s%s", lpszPath, pImgHdrs[i].fileName) ;fImg = fopen(szFile, "wb") ;if(fImg == NULL){printf("创建文件‘%s’失败!\n", szFile) ;continue ;}for(nLen=0, uiCrc=0; (nLen+iBufSize)<=pImgHdrs[i].imageSize; nLen+=iBufSize){if(fread(pBuf, iBufSize, 1, fcpb) != 1){printf("生成文件“%s”失败!原CPB文件有误!\n\n", pImgHdrs[i].fileName) ;break ;}uiCrc = CRC16(pBuf, iBufSize, uiCrc) ;fwrite(pBuf, iBufSize, 1, fImg) ;}nLen = pImgHdrs[i].imageSize - nLen ;if(nLen > 0){if(fread(pBuf, nLen, 1, fcpb) == 1){uiCrc = CRC16(pBuf, nLen, uiCrc) ;fwrite(pBuf, nLen, 1, fImg) ;}elseprintf("生成文件“%s”失败!原CPB文件有误!\n\n", pImgHdrs[i].fileName) ;}fclose(fImg) ;if(uiCrc != pImgHdrs[i].checkSum)printf("校验失败!生成的文件“%s”非法!原CPB文件有误!\n\n", pImgHdrs[i].fileName) ;elseprintf("文件“%s”创建成功!\n\n", pImgHdrs[i].fileName) ;}free(pBuf) ;
}void UnpackCpb(const char *lpszCpb, const char *lpszPath)
{FILE *fcpb = NULL;CPBHEADER cpbHdr ;LPIMAGEHEADER pImgHdr = NULL ;size_t sz ;uint32 nImgSize, nImgCount, i, uiCrc, uiCorrect ;uint64 uiVal64 ;char szPath[264] ;if(lpszPath == NULL || lpszPath[0]=='\0'){printf("无效目录!\n") ;return ;}strncpy(szPath, lpszPath, sizeof(szPath)) ;if(MkdirRecursive(szPath) != 0){printf("创建目录‘%s’失败!\n", lpszPath) ;return ;}sz = strlen(szPath) ;if(szPath[sz-1] != '/' && szPath[sz-1] != '\\'){szPath[sz] = '\\' ;szPath[sz+1] = '\0' ;}fcpb = fopen(lpszCpb, "rb") ;if (fcpb == NULL){printf("打开文件“%s”失败!\n", lpszCpb) ;return ;}sz = fread(&cpbHdr, sizeof(cpbHdr), 1, fcpb);if(sz != 1 || cpbHdr.cp_magic[0] != 'C' || cpbHdr.cp_magic[1] != 'P' ||cpbHdr.imgHdrEndPos < sizeof(cpbHdr)){fclose(fcpb) ;printf("不是有效的CPB文件!\n") ;return ;}if(cpbHdr.cp_version[0] != 0x01 || cpbHdr.cp_version[1] != 0x07){printf("本工具限用于酷派CPB1.7版本。即cpb文件头4字节为\"CP\\x01\\x07\"。\n") ;return ;}uiCorrect = 0 ;for(i=0; i<6; i++)uiCorrect += cpbHdr.correct[i] ;uiVal64 = (uint64)0x66666667 * uiCorrect ;uiCorrect = (uint32)((int32)(uiVal64 >> 32)) >> 1 ;uiCorrect = (uint16)((uiCorrect >> 31) + uiCorrect) ;uiCorrect = (uiCorrect-cpbHdr.correct[3]) | ((uiCorrect-cpbHdr.correct[4]) << 16) ;uiCrc = CRC16((uint8 *)&cpbHdr, sizeof(cpbHdr)-4, 0) ;PrintCpbHeader(&cpbHdr) ;nImgSize = cpbHdr.imgHdrEndPos - sizeof(CPBHEADER) ;nImgCount = (cpbHdr.imgHdrEndPos - sizeof(CPBHEADER)) / sizeof(IMAGEHEADER) ;pImgHdr = (LPIMAGEHEADER)malloc(nImgSize) ;if(pImgHdr == NULL){fclose(fcpb) ;printf("分配内存%u字节失败,可能是文件不合法!\n", nImgSize) ;return ;}sz = fread(pImgHdr, nImgSize, 1, fcpb) ;if(sz != 1){free(pImgHdr) ;fclose(fcpb) ;printf("不是有效的CPB文件!\n") ;return ;}for(i=0; i<nImgCount; i++){ImageHeaderCorrectPosSize(&pImgHdr[i], i, uiCorrect);uiCrc = CRC16((uint8 *)&pImgHdr[i], sizeof(IMAGEHEADER), uiCrc) ;}uiCrc += cpbHdr.cp_version[1] ;if(uiCrc != cpbHdr.checkSum){free(pImgHdr) ;fclose(fcpb) ;printf("校验失败!期望的CPB校验值:0x%.8X,实际值:0x%.8X\n",cpbHdr.checkSum, uiCrc) ;return ;}DumpFile(fcpb, szPath, pImgHdr, nImgCount) ;free(pImgHdr) ;fclose(fcpb) ;return ;
}void TrimCRLF(char *str)
{int32 nLen ;nLen = strlen(str) - 1 ;for(; nLen>=0; nLen--){if(str[nLen]=='\r' || str[nLen]=='\n')str[nLen] = '\0' ;elsebreak ;}
}void InitCpbHeader(LPCPBHEADER pCpbHdr, const char *lpszModel, const char *lpszHardVer,const char *lpszVersion, const char *lpszFrom)
{uint16 arrCorrect[6] = {0x005C, 0x0836, 0x0828, 0x083A, 0x0809, 0x0825} ;uint8 unknown[33] = "\x55\x35\x25\x27\x28\x59\x2D\x11\x32\x2D\x24\x3D\x5B\x2B\x3F\x11""\x0C\x16\x07\x01\x11\x16\x10\x03\x06\x13\x03\x1C\x01\x06\x00\x00" ;memset(pCpbHdr, 0, sizeof(CPBHEADER)) ;pCpbHdr->cp_magic[0] = 'C' ;pCpbHdr->cp_magic[1] = 'P' ;pCpbHdr->cp_version[0] = 0x01 ;pCpbHdr->cp_version[1] = 0x07 ;memcpy(pCpbHdr->correct, arrCorrect, sizeof(arrCorrect)) ;memcpy(pCpbHdr->unknown, unknown, sizeof(pCpbHdr->unknown)) ;strncpy(pCpbHdr->model, lpszModel, sizeof(pCpbHdr->model)) ;strncpy(pCpbHdr->hardVersion, lpszHardVer, sizeof(pCpbHdr->hardVersion)) ;strncpy(pCpbHdr->version, lpszVersion, sizeof(pCpbHdr->version)) ;strncpy(pCpbHdr->romFrom, lpszFrom, sizeof(pCpbHdr->romFrom)) ;
}uint32 WriteImageHeaders(FILE *fcpb, LPIMAGEHEADER pImgHdrs, int32 nCount, uint32 uiCorrect, uint32 uiCrc)
{uint32 uiOffset, uiSize ;int32 i ;for(i=0; i<nCount; i++){uiOffset = pImgHdrs[i].imageOffset ;uiSize = pImgHdrs[i].imageSize ;uiCrc = CRC16(&pImgHdrs[i], sizeof(IMAGEHEADER), uiCrc) ;ImageHeaderCorrectPosSize(&pImgHdrs[i], i, uiCorrect) ;fwrite(&pImgHdrs[i], sizeof(IMAGEHEADER), 1, fcpb) ;pImgHdrs[i].imageOffset = uiOffset ;pImgHdrs[i].imageSize = uiSize ;}return uiCrc ;
}void WriteImages(FILE *fcpb, FILE *fImgs[], LPIMAGEHEADER pImgHdrs, int32 nCount)
{int32 i ;uint32 iBufSize, nLen, uiCrc ;uint8 *pBuf ;iBufSize = 1024 * 1024 ; //1MiBpBuf = (uint8 *)malloc(iBufSize) ;if(pBuf == NULL){printf("写入映像文件时,申请1MiB内存失败!\n") ;exit(1) ;return ;}for(i=0; i<nCount; i++){printf("写入‘%s’文件...\n", pImgHdrs[i].fileName) ;uiCrc = 0 ;for(nLen=0; (nLen+iBufSize)<=pImgHdrs[i].imageSize; nLen+=iBufSize){fread(pBuf, iBufSize, 1, fImgs[i]) ;uiCrc = CRC16(pBuf, iBufSize, uiCrc) ;fwrite(pBuf, iBufSize, 1, fcpb) ;}nLen = pImgHdrs[i].imageSize - nLen ;if(nLen > 0){fread(pBuf, nLen, 1, fImgs[i]) ;uiCrc = CRC16(pBuf, nLen, uiCrc) ;fwrite(pBuf, nLen, 1, fcpb) ;}pImgHdrs[i].checkSum = uiCrc ;}free(pBuf) ;
}void PackCpb(LPCPBHEADER pCpbHdr, const char *lpszPath, const char *lpszList, const char *lpszCpb)
{
#define MAX_IMG 500FILE *flst = NULL ;FILE *fcpb = NULL ;FILE *fImgs[MAX_IMG] ;char szPath[260], szFile[512] ;LPIMAGEHEADER pImgHdr = NULL ;int32 i, nCount ;uint32 uiCrc, uiCorrect, uiSize ;uint64 uiVal64 ;if(lpszPath == NULL || lpszPath[0]=='\0' || access(lpszPath, 0) != 0){printf("‘%s’无效目录!\n", lpszPath) ;return ;}strncpy(szPath, lpszPath, sizeof(szPath)) ;uiSize = strlen(szPath) ;if(szPath[uiSize-1] != '/' && szPath[uiSize-1] != '\\'){szPath[uiSize] = '\\' ;szPath[uiSize+1] = '\0' ;}//在此之前确保已经调用InitCpbHeader函数 uiCorrect = 0 ;for(i=0; i<6; i++)uiCorrect += pCpbHdr->correct[i] ;uiVal64 = (uint64)0x66666667 * uiCorrect ;uiCorrect = (uint32)((int32)(uiVal64 >> 32)) >> 1 ;uiCorrect = (uint16)((uiCorrect >> 31) + uiCorrect) ;uiCorrect = (uiCorrect-pCpbHdr->correct[3]) | ((uiCorrect-pCpbHdr->correct[4]) << 16) ;if(access( lpszPath, 0 ) != 0){printf("路径‘%s’无法访问!\n", lpszPath) ;return ;}flst = fopen(lpszList, "r") ;if(flst == NULL){printf("列表文件‘%s’打开失败!\n", lpszList) ;return ;}fcpb = fopen(lpszCpb, "wb") ;if(fcpb == NULL){fclose(flst) ;printf("创建文件‘%s’失败!\n", lpszCpb) ;return ;}pImgHdr = malloc(sizeof(IMAGEHEADER) * MAX_IMG) ;if(pImgHdr == NULL){fclose(flst) ;fclose(fcpb) ;printf("申请映像头内存失败!\n") ;return ;}for(nCount=0; nCount<MAX_IMG && fgets(pImgHdr[nCount].fileName, sizeof(pImgHdr[nCount].fileName)-1, flst); ){TrimCRLF(pImgHdr[nCount].fileName) ;sprintf(szFile, "%s%s", szPath, pImgHdr[nCount].fileName) ;fImgs[nCount] = fopen(szFile, "rb") ;if(fImgs[nCount]){if(fseek(fImgs[nCount], 0, SEEK_END) != 0){printf("文件‘%s’定位失败!\n", szFile) ;continue ;}pImgHdr[nCount].imageOffset += sizeof(IMAGEHEADER) ;pImgHdr[nCount].imageSize = ftell(fImgs[nCount]) ;if((int32)pImgHdr[nCount].imageSize == -1){printf("获取文件‘%s’大小失败!\n", szFile) ;continue ;}fseek(fImgs[nCount], 0, SEEK_SET) ;nCount++ ;}else printf("文件‘%s’打开失败!\n", szFile) ;}pCpbHdr->imgHdrEndPos = sizeof(CPBHEADER) + nCount * sizeof(IMAGEHEADER) ;uiCrc = CRC16((uint8 *)pCpbHdr, sizeof(CPBHEADER)-4, 0) ;fwrite(pCpbHdr, sizeof(CPBHEADER), 1, fcpb) ; //写入头fwrite(pImgHdr, sizeof(IMAGEHEADER)*nCount, 1, fcpb) ; //写入映像文件头 WriteImages(fcpb, fImgs, pImgHdr, nCount) ;fseek(fcpb, sizeof(CPBHEADER), SEEK_SET) ;uiCrc = WriteImageHeaders(fcpb, pImgHdr, nCount, uiCorrect, uiCrc) ;uiCrc += pCpbHdr->cp_version[1] ;fseek(fcpb, offsetof(CPBHEADER, checkSum), SEEK_SET) ;fwrite(&uiCrc, 4, 1, fcpb) ;for(i=0; i<nCount; i++)fclose(fImgs[i]) ;free(pImgHdr) ;fclose(flst) ;fclose(fcpb) ;
}int main(int argc, char *argv[])
{char *lpszCpb = NULL ;char *lpszPath = NULL ;char *lpszList = NULL ;char *lpszModel = NULL ;char *lpszHardVer = NULL ;char *lpszVersion = NULL ;CPBHEADER cpbHdr ;if(argc < 4){usage() ;return 0 ;}switch(argv[1][1]){case 'l':case 'L':lpszCpb = argv[2] ;lpszList = argv[3] ;CreateListFile(lpszCpb, lpszList) ;break ;case 'u':case 'U':lpszCpb = argv[2] ;lpszPath = argv[3] ;UnpackCpb(lpszCpb, lpszPath) ;break ;case 'p':case 'P':if(argc < 8){usage() ;return 0 ;}lpszModel = argv[2] ;lpszHardVer = argv[3] ;lpszVersion = argv[4] ;lpszPath = argv[5] ;lpszList = argv[6] ;lpszCpb = argv[7] ;InitCpbHeader(&cpbHdr, lpszModel, lpszHardVer, lpszVersion, "D:\\image") ;PackCpb(&cpbHdr, lpszPath, lpszList, lpszCpb) ;break ;default:usage() ;return 0 ;}return 0 ;
}

完整的下载地址:这里

转载于:https://my.oschina.net/osbin/blog/266431

酷派CPB升级文件封包解包相关推荐

  1. APK文件的解包打包和修改

    相信每位玩机的人对APK文件都不陌生.你可能每天都与APK文件打交道,无论是安装和卸载有用的应用工具.插件.好玩的游戏等等...你可曾知道这些每天都伴随着你的APK文件是什么吗?怎样对它们作些修改呢? ...

  2. 【游戏杂记】.xp3文件的解包

    .xp3文件的解包 在RPG游戏中,如果想提取图片音乐等资源,需要对文件进行解包 链接:https://pan.baidu.com/s/1LhyerbiMy2nJCwZ4AK6cQA?pwd=5422 ...

  3. 【游戏杂记】Rgss3a文件的解包

    Rgss3a文件的解包 在RPG游戏中,如果想提取图片音乐等资源,需要对文件进行解包 这里是解包工具的链接 链接:https://pan.baidu.com/s/1-UKyetIHGsw1ibOHFL ...

  4. linux 如何打包分区文件,Linux基础------文件打包解包---tar命令,文件压缩解压---命令gzip,vim编辑器创建和编辑正文件,磁盘分区/格式化,软/硬链接...

    作业一: 1)将用户信息数据库文件和组信息数据库文件纵向合并为一个文件/1.txt(覆盖) cat /etc/passwd /etc/group > /1.txt 2)将用户信息数据库文件和用户 ...

  5. 怎么解压linux ext4文件,ext4解包和重新打包

    有的官方包用的是.img.ext4格式,要用Linux解包 以下用Ubuntu做例子讲解打包解包方法 也可以用相同的原理修改EXT4文件系统的.img 1.需要: Ubuntu操作系统 http:// ...

  6. Java解析银联报文_中国银联8583报文(JAVA)封包/解包/位图 相关操作源代码

    一:IS08583包介绍: ISO8583包(简称8583包)是一个国际标准的包格式,最多由128个字段域组成,每个域都有统一的规定,并有定长与变长之分. 8583包前面一段为位图,用来确定包的字段域 ...

  7. 数据封包解包协议之TCP封包解包

    数据封包协议规定:整个数据包包含2字节长度信息+数据包体.2字节长度信息包含本身着2字节.如:数据体是(abcdefg)7个字节,整体封包就是09abcdefg,总共是9个字节的协议 1.netbus ...

  8. JAVA包装类及自动封包解包示例代码

    在学习上是一个知识点,但不知如何与实际串起来... 悲哀,真是悲哀!!! 代码: 1 public class Wrapper { 2 public static void main(String[] ...

  9. Linux文件打包及压缩、解包及解压

    目录 前言 什么是压缩? tar的介绍与使用 简介 打包压缩文件 打包文件(不压缩) gzip压缩类型压缩文件 bzip压缩类型压缩文件 xzip压缩类型压缩文件 解包解压文件 简介 解压缩(解压到当 ...

最新文章

  1. Docker学习(3)——安装部署过程及简单应用
  2. Sniffer Pro 教程
  3. python多维数据post给php_使用Python中的POST将数据发送到PHP
  4. 云服务器软件运行出错,云服务器程序运行中出现木马
  5. iOS开发之导航栏(navigationController)透明化
  6. Glide 4.x之ModelLoader简单分析
  7. nyoj 628 小媛在努力= =(水)
  8. 离散数学(五)上课复习笔记(无向图的连通性、有向图、欧拉图、哈密顿图、二部图、平面图)
  9. cmd命令行中文显示乱码
  10. 【vtk实例】平面切割
  11. ipa在线安装搭建_在线安装IPA 文件和视频下载
  12. PC发卡机器人 v1.0
  13. java.util之ArrayList使用
  14. 【计算思维题】少儿编程 蓝桥杯青少组计算思维题真题及解析第2套
  15. 社会各界送别“国医大师”邓铁涛
  16. 网易杭研易盾实习心得
  17. mysql mybatis 不等于号写法
  18. 索尼摄像机V1C语言设置,索尼摄像机随机软件(Picture package) v1.8官方版
  19. TMC2130-TA/LA电机驱动芯片对比DRV8880、DRV8846、DRV8886
  20. python手写字体程序_深度学习---手写字体识别程序分析(python)

热门文章

  1. 一级计算机视频教学百度网盘,2019年一级造价工程师教学视频百度云网盘分享...
  2. vue-cli -- epub电子书
  3. pycharm 输入中文变成繁体字的解决方法
  4. 程序员幸福感拉满:一键为代码自动生成注释的工具,拿走不谢!
  5. wordpress自动发布_如何在WordPress中跟踪发布想法
  6. 巧用springboot微服务搭建一个网站
  7. Gbase 8a 修改 max_user_processes 参数不生效
  8. Java开发 - 公共字段的自动填充
  9. TIPTOP ERP上线-财务端辅导讲义
  10. 用IDEA详解Spring中的IoC和DI(挺透彻的,点进来看看吧)