MTK手机软件是一个二进制的BIN文件,最近一段时间来,很多人都在动BIN文件的脑筋,希望通过直接修改BIN达到修改软件的目的.有人写了资源提取工具,有人写了直接修改手机语言的工具,总之MTK平台售后服务工具层出不穷.于是常常被别人请教这些工具是怎么实现的.这倒让我有些为难了,简单一些来说,他们都是靠分析BIN得操作的.不过面对一大堆混乱的字符,要分析他们可不是一件容易的事.一般来说,由于二进制文件在生成的过程中编译系统对他们执行了一些对齐的操作,而我们通常使用的编辑软件都只能一个一个字节的把文件内容如实显示出来,他可不管这个字节是和那个字节对齐还是和别的字节合成有意义的字符,所以即使你定义的字串常量,也有可能在你所使用的编辑器里变成你不认识的东东.这就给我们解析BIN文件造成很大的麻烦.所幸这个麻烦并不是不可克服的.
下面一个例子,只是简单的讲解一下如何从BIN文件里提取图片资源.通过这个例子,我们就可以大至了解到BIN文件的解析过程.我使用的方法是解析BIN文件的第一件武器"特征码".由于MTK对BMP文件做了特殊处理以提高显示效率,而我又懒得去写PBM文件转BMP的函数,所以我这个软件从BIN提取的BMP文件可能有不少是不能显示或者显示不对的,这部分仅仅给大家参考吧.(对于BMP与PBM以及其他图片资源的有不理解的,可以详细了解我的其他有关MTK资源的博文)
关于特征码我再说一下,就是GIF和BMP及JPG是不同的图像文件,他们的文件结构不同,扩展名不同,所以在BIN文件里表现的特征是不同的.通过这些特征,我们就可以把他们从BIN文件里挖出来.如下,是这三种文件的特征码,不理解的可以使用UE打开一个图片文件看看.
const unsigned char BMP_HEAD[2] = {0x42,0x4D}; const unsigned char GIF_HEAD[6] = {0x47,0x49,0x46,0x38,0x39,0x61}; const unsigned char JPG_HEAD1[4] = {0xff,0xd8,0xff,0xe1}; const unsigned char JPG_HEAD2[4] = {0xff,0xd8,0xff,0xe0}; 函数实现如下,由于整个过程已经写出,所以不再过多讲解:
#include <stdio.h> #include <stdlib.h> #include <string.h>
const unsigned char BMP_HEAD[2] = {0x42,0x4D}; const unsigned char GIF_HEAD[6] = {0x47,0x49,0x46,0x38,0x39,0x61}; const unsigned char JPG_HEAD1[4] = {0xff,0xd8,0xff,0xe1}; const unsigned char JPG_HEAD2[4] = {0xff,0xd8,0xff,0xe0};
int main(int argc, char* argv[]) { long i,j; char ch; FILE *pBF; FILE *pPicF; long bmp_file_len = 0; long jpg_file_len = 0; long gif_file_len = 0; char filename[10]; int bmp_index,jpg_index,gif_index; unsigned char *buffer; long len; int is_pic = 0; printf( "欢迎使用CSDN网站懒人制作的BIN文件图片资源提取器!/n" ); system("pause"); // mkdir("F://pic"); system("md F://pic//bmp"); system("md F://pic//gif"); system("md F://pic//jpg"); if( (pBF = fopen( "f://my.bin", "rb+" )) == NULL ) { printf( "没有找到可以使用的BIN文件!/n" ); return 0; }
fseek(pBF,0,SEEK_END); len=ftell(pBF); fseek(pBF,0,SEEK_SET);
buffer = (unsigned char *)malloc((len+1)*sizeof(char));
ch = fgetc( pBF ); for(i=0; i < len+1; i++ ) { buffer[i] = (char)ch; ch = fgetc( pBF ); } //提取gif i = 0; gif_index = 0; while(i++ < len+1) { if(buffer[i] == GIF_HEAD[0]&&buffer[i+1] == GIF_HEAD[1]&&buffer[i+2] == GIF_HEAD[2] &&(buffer[i+3] == GIF_HEAD[3]&&buffer[i+4] == GIF_HEAD[4])&&buffer[i+5] == GIF_HEAD[5]) { for(j=0; j<1024*500; j++) { if(buffer[i+j]==0&&buffer[i+j+1]==0x3B) { is_pic =1; bmp_file_len = j; for(j = 1; j<1024; j++) { if(buffer[i+bmp_file_len+j] == GIF_HEAD[0]&&buffer[i+bmp_file_len+j+1] == GIF_HEAD[1]&&buffer[i+bmp_file_len+j+2] == GIF_HEAD[2]) { is_pic = 1; break; } if(buffer[i+bmp_file_len+j]==0&&buffer[i+bmp_file_len+j] ==0x3B) { is_pic = 2; break; } } if(is_pic>1) bmp_file_len = bmp_file_len+j; break; } } if(is_pic>=1) { sprintf(filename,"F://pic//gif//%d.gif",gif_index); printf("find gif %d.gif/n/n", gif_index); pPicF = fopen(filename,"wb+"); for(j=0; j<bmp_file_len+2; j++) { fputc(buffer[i+j],pPicF); } fclose(pPicF); gif_index++; i = i+bmp_file_len-1; } is_pic =0; } } i = 0; //bmp bmp_index = 0; while(i++ < len+1) { if(buffer[i] == BMP_HEAD[0]&&buffer[i+1] == BMP_HEAD[1]) { for(j=0; j<1024*500; j++) { if(buffer[i+j]==0 && buffer[i+j+1]==0x38) { is_pic =1; bmp_file_len = j; for(j = 1; j<1024; j++) { if(buffer[i+bmp_file_len+j] == BMP_HEAD[0]&&buffer[i+bmp_file_len+j+1] == BMP_HEAD[1]) { is_pic = 1; break; } if(buffer[i+bmp_file_len+j]==0&&buffer[i+bmp_file_len+j] ==0x3B) { is_pic = 2; break; } } if(is_pic>1) bmp_file_len = bmp_file_len+j; break; } } if(is_pic>=1) { sprintf(filename,"F://pic//bmp//%d.bmp",bmp_index); printf("find bmp %d.bmp/n/n", bmp_index); pPicF = fopen(filename,"wb+"); for(j=0; j<bmp_file_len+2; j++) { fputc(buffer[i+j],pPicF); } fclose(pPicF); bmp_index++; i = i+bmp_file_len-1; } is_pic =0; } } //jpg i = 0; jpg_index = 0; while(i++ < len+1) { if((buffer[i] == JPG_HEAD1[0]&&buffer[i+1] == JPG_HEAD1[1]&&buffer[i+2] == JPG_HEAD1[2]&&buffer[i+3] == JPG_HEAD1[3])|| (buffer[i] == JPG_HEAD2[0]&&buffer[i+1] == JPG_HEAD2[1]&&buffer[i+2] == JPG_HEAD2[2]&&buffer[i+3] == JPG_HEAD2[3])) { for(j=0; j<1024*500; j++) { if(buffer[i+j]==0 && buffer[i+j+1]==0x38) { is_pic =1; bmp_file_len = j; for(j = 1; j<1024; j++) { if(buffer[i+bmp_file_len+j] == JPG_HEAD1[0]&&buffer[i+bmp_file_len+j+1] == JPG_HEAD1[1]&& buffer[i+bmp_file_len+j+2] == JPG_HEAD1[2]&&buffer[i+bmp_file_len+j+3] == JPG_HEAD1[3]) { is_pic = 1; break; } if(buffer[i+bmp_file_len+j]==0&&buffer[i+bmp_file_len+j] ==0x3B) { is_pic = 2; break; } } if(is_pic>1) bmp_file_len = bmp_file_len+j; break; } } if(is_pic>=1) { sprintf(filename,"F://pic//jpg//%d.jpg",jpg_index); printf("find jpg %d.jpg/n/n", jpg_index); pPicF = fopen(filename,"wb+"); for(j=0; j<bmp_file_len+2; j++) { fputc(buffer[i+j],pPicF); } fclose(pPicF); jpg_index++; i = i+bmp_file_len-1; } is_pic =0; } } free(buffer); return 0; } |