maozhenyu 发表于 2021-2-14 18:48

撬开PC QQ的本地SQLite数据库(适用于Msg3.0.db等)

本帖最后由 maozhenyu 于 2021-3-7 00:47 编辑

*注意 本文于2月14日(1050z)发布于52pojie.cn;不允许转载。如果发现,追究侵权责任
检测到违规转载:https://www .y4f .net/375349.html 请立即删除


去年年底我发了一篇撬开MacQQ的本地SQLite数据库(适用于Msg3.0.db+)。有部分读者在下面询问相同的方法能不能在PC(Windows上使用)——答案当然是不行的。今天正好需要解开一个Windows下的QQ数据库文件,所以研究了一下,写了这篇文章。

在文章开始前,先做一下Q&A:
1. 打开本地QQ SQLite数据库的意义是什么?
主要是方便备份聊天记录,以及在极端情况下,如果QQ被封,只要先前备份过数据的key,那聊天记录依然可以提取,减少信息丢失带来的损失。
2. 这个方法会不会被不法分子利用窃取隐私?是不是可以用来盗取别人的聊天记录?
该DB文件密码由线上下发而来(具体原理是读取db的SQLite Header,然后发送sso_cryptsvr.0x12c包,从服务器上获得)。发包要求使用密码进行初步认证(wtlogin),因此没有该QQ号的密码,是不可能打开数据库文件的。(这里不考虑对于QQ程序的攻击引发的数据库密码泄露)

-------ZCZC 正文开始----------
本次分析过程使用的是新版的PC版QQ,聊天记录文件存放于Msg3.0.db。用hex工具打开文件一看,就发现有SQLIte3的头。说明和MacQQ一样,也是SQLite3。加密情况暂时不明,猜想应该是一样的(最终证明的确是一样的。)

既然是sqlite3,那么总体思路不变,找到调用key的函数。首先看的是sqlite.dll,里面有sqlite3_open都没有发现sqlite3_key为名的函数。接下来继续寻找……
发现在KernelUtil.dll里,找到了一些和SQLite3有关的函数,其中的CppSQLite3DB::key似乎就是我们要找的函数。



x32dbg下了一个断点,发现没有命中。于是disassem一下,看看这个函数里面在干嘛。



其中sub_5D2477A0这个函数长得还挺可疑的。其他的函数看起来都人畜无害。跟进去看看:




发现了关键数字“16”,MacQQ上的Msg3.0.db的keysize就是16。所以怀疑这个函数和设置key有关系,暂名为sqlite3_key_。
查看交叉引用,发现了在CppSQLite3DB::open里也被使用了,于是也在这里下个断点。



(顺便还把其他有“key”的地方都打上了断点)




一次性命中,啪得一下,很快啊。x86,参数栈传。可以注意到call这个函数的时候,参数类型sqlite3_key的定义很像。
FYI,定义是 int sqlite3_key(sqlite3 *db, const void *pKey, int nKey);



那么第二个参数就是数据库密码,第三个参数指示长度为16位。key大部分为可见字符。
尝试使用上一篇文章提到的方式,对该数据库进行解密。



发现大成功,说明加密算法和Mac版QQ的加密算法一致。





兴冲冲地用工具打开解密后的db,发现并打不开。
难道解密失败?
继续使用hex工具。可以看到,内容已经全部是明文了。不过前面有400字节的extheader,这就是导致SQLite工具打不开文件的原因。



手动删除400字节的头,Msg3.0.db 打开成功。



数据库可以打开了,但是聊天记录以及聊天记录metadata是编码状态,需要解码后才能使用。

这里简单地讲一下解码方式。相关函数的解码函数在KernelUtil.dll内。

Content字段:前8个字节是头部(MSG),之后分别是4字节的时间戳、4字节的随机数、4字节的颜色码(只有低24位有效)、1字节字号、1字节效果、1字节CharSet、一字节FontFamily。
从第24个字节开始,是字体信息。内部是LV,前两位指示字体名称长度,小端序。之后紧跟着字体名称,大端序。
接下来跳过2个字节。进入多段LV,每一段TLV中,第一字节指示负载类型,0x01是文本消息、0x03是图片消息等等;之后的两个字节指示负载长度,小端序。然后是大端序的负载内容。

Info字段(应该是JCE的Map?):跳过前6位(TD开始)。TLV类型来回摆动,第一次遇到的是0x06开头的LV,后面紧跟着2字节的负载长度,再之后是负载内容。负载内容是key。下面一个TLV以4字节的负载长度开头,之后是负载内容,内容是上面key对应的value。再之后的一个LV又是0x06开头……以此类推

---NNNN--

PS. PC版的QQ是有QQProtect这种流氓功能的,QQProtect以内核态驱动形式载入,还篡改了SSDT。所以直接调试被QQProtect保护的QQ主程序非常困难。这里面有一些小trick,不属于本文讨论的内容。有兴趣的可以自己研究。
PS2. 在打开PC QQ登录的时候,会出现多个进程。大致是启动进程、登录UI进程和服务进程(负责实际工作)。启动进程在唤起UI进程之后会立即被销毁。登录完成后,登录UI进程也会被销毁,断点必须打在服务进程上。

songxp03 发表于 2021-2-14 20:21

厉害了,这么一搞,tx困怕要改加密方式了

tylor1 发表于 2021-3-28 11:14

最后解出数据库中TD头的编码是取反和异或,用的是这个TD字段的长度值。info.db是复合文档,里面是TEA

萌壹 发表于 2021-2-15 09:47

腾讯不追究吗?

maozhenyu 发表于 2021-2-15 04:50

zwtstc 发表于 2021-2-14 21:32
谢谢分享

已更正 感谢。

REK_滑稽 发表于 2021-2-14 20:55

看的一知半解,还是自己太弱了

lowellddh 发表于 2021-2-14 19:28

多谢楼主提供思路~~新春快乐!

callmeo 发表于 2021-2-14 19:46

做好可以出一个软件,以前的聊天记录密码都忘记了打不开了

霸气侧漏m2 发表于 2021-2-14 20:32

{:301_993:}妙啊,有大佬能出个一键工具吗

ahov 发表于 2021-2-14 21:17

ps那个,直接把qq的保护进程用ark工具结束掉不就好了

skl520 发表于 2021-2-14 21:33

网址写 错了吧。。。应该是cn不是com

Mercury233 发表于 2021-2-14 21:42

厉害,学习了,希望不会用得上(

vosdbk 发表于 2021-2-14 22:49

这么看来这个数据库的密码不是每次都变化的咯, 不知道它变化的因素是什么
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 撬开PC QQ的本地SQLite数据库(适用于Msg3.0.db等)