首页
社区
课程
招聘
[原创]wx新版本(after4.0)数据库key逆向
发表于: 2025-7-25 17:47 2977

[原创]wx新版本(after4.0)数据库key逆向

2025-7-25 17:47
2977

1、 前提

已知wx使用的是 wcdb,这是一个基于 SQLite 和 SQLCipher的数据库框架。阅读其源码,可以定位到一个函数setCipherKey,这是用来设置数据库key的。

void Database::setCipherKey(const UnsafeData& cipherKey, int cipherPageSize, CipherVersion cipherVersion)

{

    if (cipherKey.size() > 0) {

        m_innerDatabase->setConfig(

        CipherConfigName,

        std::static_pointer_cast<Config>(std::make_shared<CipherConfig>(

        cipherKey, cipherPageSize, cipherVersion)),

        Configs::Priority::Highest);

    } else {

        m_innerDatabase->removeConfig(CipherConfigName);

    }

}




UnSafeData 核心成员变量如下所示,这里作者猜测m_buffer指针指向内容就是key。

class UnsafeData {

protected:

    unsigned char *m_buffer;

    size_t m_size;

};



有几种方式可以获取这个key。
1. hook setCipherKey函数,解析cipherkey参数即可得到key,比较简单。
2. 通过key的来源反推key生成算法,难度较高。

3. 还有这种通过内存扫描的方式。(a48K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1j5H3P5r3I4S2L8X3g2Q4x3V1k6%4k6h3y4Z5j5i4c8Q4x3X3c8V1N6h3#2H3i4K6u0V1M7Y4y4Q4c8f1k6Q4b7V1y4Q4z5o6V1`.

作者尝试了前两种方法,第一种简单实现,第二种方法定位到了key生成算法的位置,但是能力有限没有把该算法逆向出来(望各位大佬赐教)

这里主要讲解逆向思路,以及第一种方式的实现。


2、正式分析

1. 定位setCipherKey的地址

wx的功能基本都在Weixin.dll这个dll里面,用ida打开这个dll,由于是没有符号的(废话,当然没符号),所以没法直接搜索到setCipherKey。


但是在setCipherKey中有一行代码是 

m_innerDatabase->removeConfig(CipherConfigName);

而CipherConfigName参数是一个全局字符串。

WCDBLiteralStringDefine(CipherConfigName, "com.Tencent.WCDB.Config.Cipher");

这时候我们可以搜索字符串定位到CipherConfigName的地址。

(ps : 如果CipherConfigName的字符串被混淆了也没关系,运行时还是会恢复的,用CheatEngien在进程中查找字符串,也能定位CipherConfigName)


然后根据CipherConfigName来查找它的引用。


对于反汇编的伪代码和源代码可以初步定位到setCipherKey。


2.  动态调试setCipherKey

x64dbg附加到wx,先不要登录,不然不会触发setCipherKey了。setCipherKey处下个断点,然后登录。

由于setCipherKey是个成员函数,所以第一个参数cipherKey对应寄存器是rdx,而不是rcx。rdx处地址如图所示,可以看到rdx+0x10处是0x20,也就是cipherKey->m_size。那么rdx+0x8就是cipherKey->m_buffer


跳转到cipherKey->m_buffer指向地址,这0x20个字节就是key。


拿这个key去打开数据库验证一下,验证通过,ok,得到key。


3. 工程化

1. 注入

注入就不多说了,自行查找。


2. 获取setCipherKey地址

由于setCipherKey是一个比较基础和底层的库,改动的可能性比较小,且有全局唯一性,因此我们完全可以通过特征码定位该函数。
注意,匹配特征码的时候要将地址相关的做模糊匹配,否则会匹配失败。且匹配的时候建议只匹配代码节,减少匹配时间。


3. hook setCipherKey

这个也没啥好说的,detours。(注意下重入就行)


4. 根据得到的key即可读取数据库内容。


作者将用到的一些偏工具性的代码放到了0e7K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6K6L8s2A6J5j5i4W2Q4x3V1k6T1K9h3&6S2M7X3q4&6i4K6g2X3M7s2u0G2K9X3g2U0N6q4!0q4c8W2!0n7b7#2)9^5b7#2!0q4y4W2)9&6b7#2)9^5z5h3W2F1K9X3g2U0N6q4!0q4x3#2)9^5x3q4)9^5x3h3S2G2L8$3E0Q4c8e0y4Q4z5o6m8Q4z5o6q4E0k6h3#2G2M7Y4W2Q4c8e0N6Q4z5f1u0Q4b7U0S2Q4c8e0g2Q4z5o6g2Q4b7U0y4Q4c8e0N6Q4z5f1q4Q4z5o6c8Q4c8e0g2Q4z5p5q4Q4z5f1k6Q4c8e0S2Q4z5o6y4Q4b7V1c8Q4c8f1k6Q4b7V1y4Q4z5p5y4Q4c8e0g2Q4z5p5k6Q4b7f1k6Q4c8e0c8Q4b7V1g2Q4z5f1u0Q4c8e0g2Q4z5p5k6Q4z5o6u0Q4c8e0S2Q4z5o6m8Q4z5o6y4Q4c8e0y4Q4z5o6m8Q4z5o6t1`.


4. 其他

作者通过setCipherKey一层一层往上找,基本定位到了generatekey函数,还有一些全局变量,加/解密时候需要调用的表。但是意义不大,因为这个生成key所需的数据应该没存在本地,而是通过网络请求获取的,所以逆向出算法也没用,还是要通过hook的方式去做。如果各位大佬有什么高见,可以指点一下。


微信数据库相关的信息:ec2K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1j5H3P5r3I4S2L8X3g2Q4x3V1k6%4k6h3y4Z5j5i4c8Q4x3X3c8V1N6h3#2H3i4K6u0V1M7Y4y4Q4x3V1k6T1L8r3!0T1i4K6u0r3N6U0c8Q4x3V1k6V1L8$3y4K6i4K6u0r3N6$3g2U0K9r3q4@1i4K6g2X3y4q4)9#2k6U0m8Q4y4h3j5H3i4K6g2X3x3U0k6Q4y4h3k6@1j5h3u0D9k6g2)9#2k6Y4y4@1M7Y4g2U0N6q4)9J5k6h3#2V1
不过这个不是100%准,比如只查message_.db是不行的,还要和message_fts.db关联。后续有时间的话,且如果大家有兴趣的话考虑聊天记录这块整一下。


所用工具:IDA、x64dbg、CheatEngine
引用:
    d61K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6f1k6h3&6U0k6h3&6@1i4K6u0r3N6$3y4V1j5R3`.`.

    9daK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6K6L8s2A6J5j5i4W2Q4x3V1k6T1K9h3&6S2M7X3q4&6i4K6g2X3M7s2u0G2K9X3g2U0N6l9`.`.
    264K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1j5H3P5r3I4S2L8X3g2Q4x3V1k6%4k6h3y4Z5j5i4c8Q4x3X3c8V1N6h3#2H3i4K6u0V1M7Y4x3`.


4. 免责声明


本文只供研究和学习,作者不对任何滥用行为负责。使用者应自行承担风险。!

本文只供研究和学习,作者不对任何滥用行为负责。使用者应自行承担风险。!

本文只供研究和学习,作者不对任何滥用行为负责。使用者应自行承担风险。!


重要的事情说三遍!!!



[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

最后于 2025-7-30 07:21 被小周学习站编辑 ,原因:
收藏
免费 47
支持
分享
最新回复 (18)
雪    币: 293
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
666
2025-7-25 18:10
0
雪    币: 1708
活跃值: (2157)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
看看主题内容
2025-7-25 18:27
0
雪    币: 7
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
感谢分享
2025-7-25 19:59
0
雪    币: 200
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
感谢分享
2025-7-27 18:21
0
雪    币: 35
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
感谢分享
2025-7-27 20:09
0
雪    币: 31227
活跃值: (1218)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
感谢分享
2025-7-27 21:20
0
雪    币: 3831
活跃值: (510)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
感谢分享
2025-7-28 11:48
0
雪    币: 2790
活跃值: (5612)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
9
感谢分享
2025-7-28 13:15
0
雪    币: 217
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
感谢分享
2025-7-28 17:07
0
雪    币: 13
活跃值: (2847)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
感谢分享
2025-7-28 22:27
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
x64dbg附加微信4.0.6.26闪退,请问博主调试的是哪个版本的微信,或者x64dbg用了什么插件?非常感谢
2025-7-29 12:15
0
雪    币: 2708
活跃值: (7351)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
谢谢分享
2025-7-29 13:21
0
雪    币: 14
活跃值: (1089)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
wx_王宁 x64dbg附加微信4.0.6.26闪退,请问博主调试的是哪个版本的微信,或者x64dbg用了什么插件?非常感谢
我是调试的4.0.5.18版本
2025-7-29 16:17
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
谢谢分享
2025-7-29 17:42
0
雪    币: 213
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
16
谢谢分享
2025-7-29 18:28
0
雪    币: 1547
活跃值: (4398)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
好了,知道了,下个版本把字符串特征改掉
2025-7-30 09:54
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
18
小周学习站 我是调试的4.0.5.18版本
谢谢,是x64dbg插件引起的,所有插件删除就没问题了
2025-8-4 22:36
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
可以相互交流下,在微信4早期的版本,它的key存储在wx内存里,可是在后面的版本,已经改正了,把密钥做了异或处理,存在了内存中,所以你在内存中搜不到。
两者在同一个对象之中,挨着很近,没有去验证是否为同一个字段,它异或的值是硬编码写在代码段,找到两者,异或一下就行。
2025-11-22 09:59
0
游客
登录 | 注册 方可回帖
返回