吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 43983|回复: 148
收起左侧

[原创] PC版XX数据库解密详细教程

    [复制链接]
newxccg 发表于 2019-5-12 21:36
本帖最后由 Kido 于 2019-6-6 18:11 编辑

【 原创文章,转载请注明出处。 】
       在电子取证过程中,也会遇到提取PC版微信数据的情况,看雪、52破解和CSDN等网上的PC版微信数据库破解文章实在是太简略了,大多数只有结果没有过程。经过反复试验终于成功解密了数据库,现在把详细过程记录下来,希望大家不要继续在已经解决的问题上过度浪费时间,以便更投入地研究尚未解决的问题。通过查阅资料得知,与安卓手机版微信的7位密码不同,PC版微信的密码是32字节(64位),加密算法没有说明,但是可以通过OllyDbg工具从内存中获取到这个密码,然后通过一段C++代码进行解密。
       首先下载OllyDbg 2.01汉化版,我用的版本如下图所示:
ollydbg2.png
       运行OllyDbg,然后运行PC版微信(需要下载客户端的,不是网页版)。先不要点击登录按钮。
微信登录.jpg
       切换到Ollydbg界面:
ollydbg菜单.png
       点击文件菜单,选择“附加”,在弹出的对话框中找到名称为WeChat的进程,其窗口名称为“登录”。然后点击“附加”。
附加微信.png
       附加成功后OllyDbg开始加载,成功加载后可以看到最上面OllyDbg后面有WeChat.exe的字样:
附加成功.png
       在查看菜单中选择“可执行模块”:
可执行模块.png
       找到名称为WeChatWin的模块,双击选中。为了方便观察,在窗口菜单中选择水平平铺。在CPU窗口标题栏可以看到“模块WeChatWin”字样。
水平平铺后CPU窗口.png
       在插件中选择“StrFinder字符查找”中的“查找ASCII字符串”(注意如果下载的OllyDbg版本不对,可能没有相关插件,因此一定要找对版本),要稍微等一会儿,会出现搜索结果的窗口。
插件查找ASCII字符串.png
       在此窗口点击鼠标右键,选择“Find”,在搜索框中输入“DBFactory::encryptDB”。
查找encryptDB.png
       会自动定位在第一处,但我们需要的是第二处,即“encryptDB %s DBKey can’t be null”下面这一处。可以用鼠标点击滚动条向下,找到第二处,用鼠标双击此处。
定位字符串.png
       在CPU窗口中可以看到已经定位到了相应的位置。用鼠标点击滚动条向下翻。
找到断点.png
       下面第六行应该是TEST EDX,EDX,就是用来比对密码的汇编语言代码。在最前面地址位置(本文中是0F9712BA)双击设置断点(设置断点成功则地址会被标红,而且可以在断点窗口中看到设置成功的断点)
       点击“运行”按钮(或者在调试菜单中选择“运行”),这时寄存器窗口中的EDX的值应该是00000000。
       切换到微信登录页面,点击登录,然后到手机端确认登录。这是OllyDbg界面中的数据不断滚动,直到EDX不再为全0并且各个窗口内容停止滚动为止。
寄存器.png
       在EDX的值上面点击鼠标右键,在弹出的菜单里面选择“数据窗口中跟随”,则数据窗口中显示的就是EDX的内容。
EDX值.png
       图示中从0B946A80(这个数值是变化的,不但每台电脑不同,每次调试也可能完全不同)到0B946A9F共32个字节就是微信的加密密码,本图中就是:“53E9BFB23B724195A2BC6EB5BFEB0610DC2164756B9B4279BA32157639A40BB1”
      一共32个字节,共64位。
       得到这个之后,就可以关闭OllyDbg了,微信也会自动被关闭。
       接下来就是解密过程。在看雪、52破解等多个论坛中都有相关的C++源码,开始企图使用Dev-C++或者C-Free等轻量级IDE进行编译,也使用过Visual C++ 6.0绿色精简版,结果多次尝试出现各种错误,反复失败,最终不得已使用Visual Studio,并对代码进行了一定的修正,终于调试成功。正好Visual Studio 2019刚刚发布直接到官方网站下载了社区版。
       根据查到的资料,需要先安装openssl,为了省事直接下载了最新的Win64OpenSSL-1_1_1b,安装后发现各种报错,继续查找资料发现原来sqlcipher使用的是低版本的openssl,之后找到了一个Win64OpenSSL-1_0_2r也报错,最后发现还是官方这个直接解压缩的版本靠谱:https://www.openssl.org/source/openssl-1.0.2r.tar.gz
       把压缩包直接解压到任意目录,比如c:\openssl-1.0.2r
       启动Visual Studio 2019社区版(估计Visual Studio 2008以后的都应该可以,懒得找就直接官网下载最新的吧)
       在启动界面右下方选择“创建新项目”
创建新项目.png
       滚动下拉条,在窗口中选择C++控制台应用:
控制台应用.png
       给项目随便起个名字,选择保存位置:
项目名称.png
       然后点击“创建”,即可完成新项目创建。生成默认的Hello World代码:
默认代码.png
       先要做好项目的基础配置,之前调试失败主要问题就出在这里了。
       在项目菜单中最下面选择项目属性“dewechat属性”(这个跟设置的项目名称一致)
属性页.png
       对话框最左上角的配置后面,可以选择配置的是Debug模式还是Release模式(Release模式不包含调试信息,编译完成的exe文件更小一些,但如果是自己用,这两个模式没有区别,配置了哪个,后面就要用哪个模式编译,否则会报错)
       先选择C/C++下面的“常规”选项:
cpp常规.png
       右边第一条是“附加包含目录”,点击右侧空白处。在下拉框里选择“编辑…”,在对话框中点击四个图标按钮最左侧的“新行”按钮,会生成一个空白行,点击右侧的“…”:
附加包含.png
       在弹出的对话框里选择刚刚安装的openssl目录(本文是c:\openssl-1.0.2r)中的include目录。
包含目录.png
     设置完成后如下:
包含设置完毕.png
       然后选择左侧“链接器”下面的“常规”:
链接器常规.png
       在中间位置,有一个“附加库目录”,点击右侧空白处,选择openssl目录下的lib目录,设置完成后如下:
附加库完成.png
       最后点击链接器下面的“输入”:
输入附加依赖项.png
       右侧最上面有“附加依赖项”,默认已经有一些系统库,点击右侧内容,选择“编辑…”
依赖库完成.png
       这个没有增加新行的按钮,只能手工录入或者拷贝文件名进去,需要增加上图所示的两个库名称。       设置完成后如下:
依赖库设置好.png
       现在所有的设置都OK了,可以把代码放进来编译了。       由于太多网站转载,而且很多有错漏,已经搞不清原始代码是哪位大神写的了,其中有一些已经被废弃的代码,根据系统报错提示进行了替换,另外做了一个主要的变化就是之前的代码是把数据库名写在变量中,但由于需要解密很多库,为了灵活,改为输入参数的方法,即在运行时带参数运行或者根据提示输入需要解密的数据库文件名。
[C++] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using namespace std;
#include <Windows.h>
#include <iostream>
#include <openssl/rand.h>
#include <openssl/evp.h>
#include <openssl/aes.h>
#include <openssl/hmac.h>
 
#undef _UNICODE
#define SQLITE_FILE_HEADER "SQLite format 3"
#define IV_SIZE 16
#define HMAC_SHA1_SIZE 20
#define KEY_SIZE 32
 
#define SL3SIGNLEN 20
 
#ifndef ANDROID_WECHAT
#define DEFAULT_PAGESIZE 4096       //4048数据 + 16IV + 20 HMAC + 12
#define DEFAULT_ITER 64000
#else
#define NO_USE_HMAC_SHA1
#define DEFAULT_PAGESIZE 1024
#define DEFAULT_ITER 4000
#endif
//pc端密码是经过OllyDbg得到的32位pass。
unsigned char pass[] = { 0x53,0xE9,0xBF,0xB2,0x3B,0x72,0x41,0x95,0xA2,0xBC,0x6E,0xB5,0xBF,0xEB,0x06,0x10,0xDC,0x21,0x64,0x75,0x6B,0x9B,0x42,0x79,0xBA,0x32,0x15,0x76,0x39,0xA4,0x0B,0xB1 };
char dbfilename[50];
int Decryptdb();
int CheckKey();
int CheckAESKey();
int main(int argc, char* argv[])
{
        if (argc >= 2)    //第二个参数argv[1]是文件名
                strcpy_s(dbfilename, argv[1]);  //复制   
                   //没有提供文件名,则提示用户输入
        else {
                cout << "请输入文件名:" << endl;
                cin >> dbfilename;
        }
        Decryptdb();
        return 0;
}
 
int Decryptdb()
{
        FILE* fpdb;
        fopen_s(&fpdb, dbfilename, "rb+");
        if (!fpdb)
        {
                printf("打开文件错!");
                getchar();
                return 0;
        }
        fseek(fpdb, 0, SEEK_END);
        long nFileSize = ftell(fpdb);
        fseek(fpdb, 0, SEEK_SET);
        unsigned char* pDbBuffer = new unsigned char[nFileSize];
        fread(pDbBuffer, 1, nFileSize, fpdb);
        fclose(fpdb);
 
        unsigned char salt[16] = { 0 };
        memcpy(salt, pDbBuffer, 16);
 
#ifndef NO_USE_HMAC_SHA1
        unsigned char mac_salt[16] = { 0 };
        memcpy(mac_salt, salt, 16);
        for (int i = 0; i < sizeof(salt); i++)
        {
                mac_salt[i] ^= 0x3a;
        }
#endif
 
        int reserve = IV_SIZE;      //校验码长度,PC端每4096字节有48字节
#ifndef NO_USE_HMAC_SHA1
        reserve += HMAC_SHA1_SIZE;
#endif
        reserve = ((reserve % AES_BLOCK_SIZE) == 0) ? reserve : ((reserve / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
 
        unsigned char key[KEY_SIZE] = { 0 };
        unsigned char mac_key[KEY_SIZE] = { 0 };
 
        OpenSSL_add_all_algorithms();
        PKCS5_PBKDF2_HMAC_SHA1((const char*)pass, sizeof(pass), salt, sizeof(salt), DEFAULT_ITER, sizeof(key), key);
#ifndef NO_USE_HMAC_SHA1
        PKCS5_PBKDF2_HMAC_SHA1((const char*)key, sizeof(key), mac_salt, sizeof(mac_salt), 2, sizeof(mac_key), mac_key);
#endif
 
        unsigned char* pTemp = pDbBuffer;
        unsigned char pDecryptPerPageBuffer[DEFAULT_PAGESIZE];
        int nPage = 1;
        int offset = 16;
        while (pTemp < pDbBuffer + nFileSize)
        {
                printf("解密数据页:%d/%d \n", nPage, nFileSize / DEFAULT_PAGESIZE);
 
#ifndef NO_USE_HMAC_SHA1
                unsigned char hash_mac[HMAC_SHA1_SIZE] = { 0 };
                unsigned int hash_len = 0;
                HMAC_CTX hctx;
                HMAC_CTX_init(&hctx);
                HMAC_Init_ex(&hctx, mac_key, sizeof(mac_key), EVP_sha1(), NULL);
                HMAC_Update(&hctx, pTemp + offset, DEFAULT_PAGESIZE - reserve - offset + IV_SIZE);
                HMAC_Update(&hctx, (const unsigned char*)& nPage, sizeof(nPage));
                HMAC_Final(&hctx, hash_mac, &hash_len);
                HMAC_CTX_cleanup(&hctx);
                if (0 != memcmp(hash_mac, pTemp + DEFAULT_PAGESIZE - reserve + IV_SIZE, sizeof(hash_mac)))
                {
                        printf("\n 哈希值错误! \n");
                        getchar();
                        return 0;
                }
#endif
                //
                if (nPage == 1)
                {
                        memcpy(pDecryptPerPageBuffer, SQLITE_FILE_HEADER, offset);
                }
 
                EVP_CIPHER_CTX* ectx = EVP_CIPHER_CTX_new();
                EVP_CipherInit_ex(ectx, EVP_get_cipherbyname("aes-256-cbc"), NULL, NULL, NULL, 0);
                EVP_CIPHER_CTX_set_padding(ectx, 0);
                EVP_CipherInit_ex(ectx, NULL, NULL, key, pTemp + (DEFAULT_PAGESIZE - reserve), 0);
 
                int nDecryptLen = 0;
                int nTotal = 0;
                EVP_CipherUpdate(ectx, pDecryptPerPageBuffer + offset, &nDecryptLen, pTemp + offset, DEFAULT_PAGESIZE - reserve - offset);
                nTotal = nDecryptLen;
                EVP_CipherFinal_ex(ectx, pDecryptPerPageBuffer + offset + nDecryptLen, &nDecryptLen);
                nTotal += nDecryptLen;
                EVP_CIPHER_CTX_free(ectx);
 
                memcpy(pDecryptPerPageBuffer + DEFAULT_PAGESIZE - reserve, pTemp + DEFAULT_PAGESIZE - reserve, reserve);
                char decFile[1024] = { 0 };
                sprintf_s(decFile, "dec_%s", dbfilename);
                FILE * fp;
                fopen_s(&fp, decFile, "ab+");
                {
                        fwrite(pDecryptPerPageBuffer, 1, DEFAULT_PAGESIZE, fp);
                        fclose(fp);
                }
 
                nPage++;
                offset = 0;
                pTemp += DEFAULT_PAGESIZE;
        }
        printf("\n 解密成功! \n");
        return 0;
}

       将之前默认的代码全部清除,将以上代码拷贝进去,保存。然后在工具条栏中选择是Debug还是Release模式,是x86还是x64(需要跟之前配置匹配,如果选了没配置的模式会报错。测试发现几个选项没有太大区别,建议默认),之后点击“本地windows调试器”(或者按F5键),如果前面的步骤操作都正确,应该可以完成编译并自动运行,弹出一个命令行窗口,提示需要输入文件名:

调试成功.png
       最下方显示了生成的exe文件路径,将这个文件拷贝到微信数据库所在的目录,一般是:C:\Users\Administrator\Documents\WeChat Files\********\Msg
       其中********位置为需要解密的微信id,目录内容如下:
微信数据库目录.png
       如果要解密ChatMsg.db,则在命令行窗口输入指令dewechat ChatMsg.db回车即可。
解密成功.png
       解密成功后,会在目录中生成de_ChatMsg.db,用sqlite数据库管理软件打开即可。
       本文主要是个验证过程,没有做什么突破工作,目前的解密只能算是半自动过程,密码算法部分的获得是下一步需要研究的内容,希望大家共同努力!
       作者:newx
【 原创文章,转载请注明出处。 】

openssl-include-lib.zip

643.16 KB, 下载次数: 666, 下载积分: 吾爱币 -1 CB

包含文件

免费评分

参与人数 51威望 +2 吾爱币 +54 热心值 +49 收起 理由
小云哥哥 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
xianr12 + 1 只看懂前面的,后面有点懵
愛你壹萬年 + 1 + 1 谢谢@Thanks!
臣本布衣 + 1 + 1 谢谢@Thanks!
deber + 1 + 1 谢谢@Thanks!
moon1981911 + 1 + 1 我很赞同!
崔万宇 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
kylinpapa + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
nauh + 1 + 1 谢谢@Thanks!
贝德曼 + 1 + 1 谢谢@Thanks!
luojinfang + 1 + 1 我很赞同!
Hmily + 2 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
cwjalsy + 1 + 1 谢谢@Thanks!
小小学生 + 1 + 1 这是一篇可以置顶加精的帖子
yozorano + 1 + 1 我很赞同!
Jixun069 + 1 + 1 用心讨论,共获提升!
freetan + 1 + 1 谢谢@Thanks!
xiaoqingren + 1 我很赞同!
abc220 + 1 + 1 谢谢@Thanks!
Ftimes + 2 火前留名
w蓝魔 + 1 + 1 用心讨论,共获提升!
笙若 + 1 + 1 谢谢@Thanks!
萌新与小白 + 1 + 1 热心回复!
红黑之橙 + 1 + 1 用心讨论,共获提升!
fanvalen + 1 + 1 热心回复!
zjjyl + 1 + 1 谢谢@Thanks!
N9loveyou + 1 + 1 谢谢@Thanks!
winderqy + 1 牛皮,支持!!
wcb0414 + 1 + 1 我很赞同!
conosc + 1 + 1 用心讨论,共获提升!
thepassion + 1 热心回复!
solsun + 1 + 1 用心讨论,共获提升!
x1aozeyuu + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
smk418 + 1 + 1 谢谢@Thanks!
毛新航 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
yunfeilu + 1 + 1 我很赞同!
马化腾之父 + 1 + 1 此为违规行为,请遵守论坛版规!
Monitor + 3 + 1 鼓励转贴优秀软件安全工具和文档!
cxyelu + 1 + 1 666,最喜欢技术贴!
少尉_lib + 1 + 1 我很赞同!
bigbirdl + 1 谢谢@Thanks!
ggbb6688 + 1 + 1 楼主厉害!支持一下!
j8250347 + 1 + 1 期待有成品出现;跨入了一大步;
海天一色001 + 1 + 1 谢谢@Thanks!
迷失自我 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
JuncoJet + 1 + 1 编译好的程序来一发
hongge + 1 + 1 热心回复!
忆江南 + 1 + 1 谢谢@Thanks!
wxue + 1 + 1 谢谢@Thanks!
我为52pojie狂 + 1 + 1 谢谢@Thanks!
砸七砸八 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

耳大啊飒飒的 发表于 2019-5-13 08:25
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈好东西

免费评分

参与人数 4吾爱币 -4 收起 理由
92013 -1 请勿灌水,提高回帖质量是每位会员应尽的义务!
lijie2love -1 请勿灌水,提高回帖质量是每位会员应尽的义务!
LeoSky -1 请勿灌水,提高回帖质量是每位会员应尽的义务!
adsllikk -1 请勿灌水,提高回帖质量是每位会员应尽的义务!

查看全部评分

weiya909 发表于 2019-5-15 00:21
无法定位序数2572于动态链接库LIBEAY32.DLL上 求解
SN1t2lO 发表于 2019-5-13 14:59
那些被废弃的代码不是真正废弃了,而是我用作搜索密钥的测试代码。当时有个坛友只要解密部分,所以实现代码没复制。int CheckKey();和int CheckAESKey();可以删除。这个代码的原始版本来自飘雪的大神。
gimisky 发表于 2019-5-12 22:26
图片都挂了,请更新一下图床,感谢楼主分享
zmolli775 发表于 2019-5-12 22:35
图片提示盗链被屏蔽了·请更新图床...
bjruiwangm 发表于 2019-5-12 22:48
学习了,大师的文章
 楼主| newxccg 发表于 2019-5-12 23:10
图片太多,重新上传了。感谢各位兄弟捧场。
Stillthekid 发表于 2019-5-13 01:55
楼主牛&#128046;
sutramusic 发表于 2019-5-13 01:55
厉害,基本看了一下,原理不懂,只能膜拜。
deadbeef 发表于 2019-5-13 02:09
请问为何链接下载来的openssl文件夹里没有lib文件夹?
lyghost 发表于 2019-5-13 07:19
很棒,过程很详细
小豆丁 发表于 2019-5-13 08:21
请问这个解密出来的数据是什么?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-4-15 16:13

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表