世界杯主办国

1、前言 最近想整理下照片(回忆 ^ _ ^ 怀旧),以前也知道在微信pc端聊天时,图片、视频、文档等文件会缓存在一个目录下(电脑微信→左下角三条杠→设置→文件管理),点击按钮“打开文件夹”快速访问,文件基本都存储在“FileStorage”文件夹中,本文重点在于解密“Image”文件夹中被加密的dat文件。 2、工具介绍 使用VS2010 MFC编写,支持选择单个文件转换及选择文件夹批量转换,一般都是选择目录/路径/文件夹进行批量转换。【注】在Windows XP下软件打开失败。 (1)工具界面截图

(2)阿里云盘链接:下载 提取码: i5j9 3、分析 在网上搜索相关资料时了解到,电脑端微信对接收到的图片中的每一个字节进行了异或加密计算(即异或某一个固定值,这个值不知道,需要尝试计算反推出来),再将转换后的字节存储在以dat为后缀名的文件中,至此图片被加密了,无法直接双击查看图片,失去了它本身的色彩。 (1)异或原理:异或百度百科 我们所常见的jpg、png、bmp、gif等格式图片都有其固定的存储方式(如jpg格式图片以FF D8开头),可以使用文本编辑器Notepad++打开图片,然后点击编辑器上方工具栏最后面的“H”,即以十六进制展示文件内容,如下图所示:

(2)解密代码:打开dat文件→读取数据→判断文件类型→异或解密→写入数据到新文件

//可扩展并使用数据结构存储

#define JPG1 0xFF

#define JPG2 0xD8

#define PNG1 0x89

#define PNG2 0x50

#define BMP1 0x42

#define BMP2 0x4D

#define GIF1 0x47

#define GIF2 0x49

//代码可优化(sXor作为加密key值是唯一的,成功一次即可计算出key值,后续解密时无需反推计算)

bool DecryptDatFile(CString &strEncrypt, CString &strDecrypt)

{

string strInPath = strEncrypt.GetString();

string strOutPath = strDecrypt.GetString();

//以二进制方式打开文件

FILE* fp;//文件指针

if((fp=fopen(strInPath.c_str(), "rb")) == NULL)

{

//MessageBox("dat文件打开失败,请检查路径及文件", "提示", MB_ICONWARNING);

return false;

}

//获取图像数据总长度

fseek(fp, 0, SEEK_END);

int nLength = ftell(fp);

rewind(fp);

//根据图像数据长度分配内存buffer

char *pImgBuffer = (char*)malloc(nLength * sizeof(char));

fread(pImgBuffer, nLength, 1, fp);//将图像数据读入buffer

fclose(fp);

//判断图片类型,并获取异或值

short sXor = 0;

short sFirst = pImgBuffer[0];

short sSecond = pImgBuffer[1];

//CString strType;

if((sFirst ^ JPG1) == (sSecond ^ JPG2))//jpg

{

sXor = sFirst ^ JPG1;

strOutPath += ".jpg";

//strType = "jpg格式";

}

else if((sFirst ^ PNG1) == (sSecond ^ PNG2))//png

{

sXor = sFirst ^ PNG1;

strOutPath += ".png";

//strType = "png格式";

}

else if((sFirst ^ GIF1) == (sSecond ^ GIF2))//gif

{

sXor = sFirst ^ GIF1;

strOutPath += ".gif";

//strType = "gif格式";

}

else if((sFirst ^ BMP1) == (sSecond ^ BMP2))//bmp

{

sXor = sFirst ^ BMP1;

strOutPath += ".bmp";

//strType = "bmp格式";

}

else

{

//MessageBox("dat文件识别失败", "提示", MB_OK);

free(pImgBuffer);

return false;

}

//异或解密

for(int i=0; i

{

pImgBuffer[i] ^= sXor;

}

//以二进制方式写入文件

if((fp=fopen(strOutPath.c_str(), "wb")) == NULL)

{

//MessageBox("解密文件保存失败,请检查路径", "提示", MB_ICONWARNING);

free(pImgBuffer);

return false;

}

fwrite(pImgBuffer, nLength, 1, fp);//从buffer中写数据到fp指向的文件中

fclose(fp);//关闭文件指针

free(pImgBuffer);//释放buffer内存

return true;

}