• 新版飞信聊天记录逆向分析全过程


    自学逆向有段时间了,今天来一帖!

    直接进入正题:

    安装飞信,登录飞信,制造一点聊天记录。
    在 C:Users\%用户名%DocumentsFetion"飞信号" 路径下发现了一个文件 V5_History.dat (可以在飞信设置里面点击打开历史记录文件位置直接过去)
    看名称就知道啦,飞信数据库文件就是这货。
    UE打开观察此文件,一看就知道肯定经过加密的。不做多的解释
    <ignore_js_op>
    打开飞信主目录,观察飞信目录中的dll。
    看dll名称,猜测消息记录处理的dll,飞信主目录内发现目录 DataHistory,目录中有个History.dll,猜测这货是处理历史记录的dll
    于是打开OD,OD打开Fetion.exe,ALT+E 跟随History.dll,大概喵了几眼,然后CTRL+N查看模块中的名称,
    发现一个_FhOpenDB,看名称就知道这是干嘛的了,根据OD显示,此函数出自Fhlib.dll,于是用 eXeScope 查看此dll的导入导出信息
    在导入信息中发现导入了ADVAIP.DLL(非常重要!!!!),此DLL是Windows自带的加密算法库,于是打开 IDA Pro,准备开始分心Fhlib.dll.
    在Import表里面发现了 CryptCreateHash、CryptHashData、CryptDeriveKey、CryptDestroyHash等很显眼的函数!!
    感觉告诉我,这就是解码部分,
    于是逆向了这部分代码,完成过后用OD跟踪,确定这几个函数的可变参数内容,哈哈,最重要的生产hash和key的密钥居然是飞信号,立刻打开VS写代码,
    一举成功,成功将V5_History.dat解码,用UE打开观察解码后的文件,我艹!!文件签名好熟悉,这不是我常用的 sqlite3 么?而sqlite3是个轻量级小型开源数据库。
    接着用数据库可视化查看工具查看数据库内容,聊天记录一览无遗。破解成功。
    附上代码!!!

    [C++] 纯文本查看 复制代码
    01 * - 将解密的数据库文件放入系统临时目录
    02 */
    03 int IS_FetionV5History::DeCryptFetionDB()
    04 {
    05 HCRYPTPROV hProv = NULL;
    06 HCRYPTHASH hHash = NULL;
    07 LPCTSTR lpszPwd = (LPCTSTR)szFetionNum;//密码,飞信号
    08 HCRYPTKEY hKey = NULL;
    09  
    10 CryptAcquireContext(&hProv, 0, "Microsoft Enhanced Cryptographic Provider v1.0", 1, 0xF0000000);
    11 CryptCreateHash(hProv,0x8004,0,0,&hHash);
    12 CryptHashData(hHash,(const BYTE *)lpszPwd,strlen((const char *)lpszPwd),0);
    13 CryptDeriveKey(hProv,0x6801,hHash,0,&hKey);
    14 CryptDestroyHash(hHash);
    15  
    16 /**************************************************************/
    17 HANDLE pInFile,pOutFile;//文件句柄
    18 DWORD dwReadLen = 0x400 ,dwReadSize ,dwWriteSize;//想要读取的数据长度;实际读取文件大小;实际写入数据
    19  
    20 {//打开源文件
    21 pInFile = ::CreateFile(strEvidencePath.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING,
    22 FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_READONLY, NULL); //用这个函数比OpenFile好
    23 if( pInFile == INVALID_HANDLE_VALUE)
    24 {
    25 CloseHandle(pInFile); //一定注意在函数退出之前对句柄进行释放。
    26 return -1;
    27 }
    28 }
    29 {//打开写入文件
    30 pOutFile = ::CreateFile(strDstPath.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
    31 FILE_ATTRIBUTE_NORMAL, NULL); //用这个函数比OpenFile好
    32 if( pOutFile == INVALID_HANDLE_VALUE)
    33 {
    34 CloseHandle(pOutFile); //一定注意在函数退出之前对句柄进行释放。
    35 return -1;
    36 }
    37 }
    38 /**************************************************************/
    39 BYTE szBuf[0x400 + 1] = {0}; //__in__out 输入加密内容,输出解密后内容
    40  
    41 //循环读取文件
    42 do
    43 {
    44 ReadFile(pInFile, szBuf, dwReadLen, &dwReadSize, NULL);
    45  
    46 if (dwReadLen < dwReadSize)
    47 CryptDecrypt(hKey,0,TRUE,0,szBuf,&dwReadLen);
    48 else
    49 CryptDecrypt(hKey,0,TRUE,0,szBuf,&dwReadSize);
    50 //写入文件
    51 WriteFile(pOutFile,szBuf,dwReadSize,&dwWriteSize,NULL);
    52  
    53 memset(szBuf,0,0x400 + 1);
    54 }while( dwReadSize == dwReadLen);
    55  
    56 CloseHandle(pInFile);
    57 CloseHandle(pOutFile);
    58 return 0;
    59 }//DeCryptFetionDB()

    https://www.0xaa55.com/forum.php?mod=viewthread&tid=1787&extra=page%3D1

  • 相关阅读:
    OI中的小智慧
    洛谷 P2335 SDOI 2005 毒瘤 位图(也补上注释了)
    洛谷P4779 Dijkstra 模板
    洛谷 P1156 垃圾陷阱 谈论剪枝,非满分
    8/14考试 JWG
    一个好消息 JWG
    刷水题(一) JWG
    C语言运算符优先级从没像现在这样深刻体会
    cron 备忘
    CentOS
  • 原文地址:https://www.cnblogs.com/findumars/p/5558031.html
Copyright © 2020-2023  润新知