首页
社区
课程
招聘
[旧帖] [原创]对QQ Registry.db的再次分析 0.00雪花
发表于: 2012-9-16 22:33 8392

[旧帖] [原创]对QQ Registry.db的再次分析 0.00雪花

2012-9-16 22:33
8392

我还是要改一下的我的分析,我的分析连QQ版本都没有说,因此这次完善下
首先说下我原先的的目的,我的目的很简单,就是想编程实现取消QQ记住密码选项
原先我认为QQ记住密码选项肯定是某一样设置,经过网上搜索 得知All Users\QQ下
Registry.db里面包含QQ用户列表,将它删掉,QQ列表就全空了,看来设置就在这个文件
里面,但是删除不是我的目的,我的目的是取消记住密码选项
没办法,随手把QQ拖到OD里,谁让它不加壳,不反调试,我的QQ是QQ2012beta3,估计QQ2011也差不多
先说一下Registry.db文件,它是复合文档,里面有很多流和存储,用DBViewer打开该文件

明眼人一下子就看到了Main_LoginAccountList流,QQ用户列表信息百分之百放在这里面
刚才不是说把QQ拖到OD里吗,先运行QQ,QQ肯定要打开Registry.db的,大家都知道下什么断点了吧,
我下的是ZwCreateFile,原因是所有文件打开操作都要经过它,下好断点后登陆QQ,或者点一下QQ用户
列表,QQ自动断下来了,如果你电脑正常的话,第一个就是打开All Users\QQ目录下的Registry.db
查看堆栈信息,继续往下翻,能看到C:\Program Files\Tencent\QQ\Users\All Users\QQ\Registry.db,
Main_LoginAccountList,GlobalDataRegistry:等字符串,还能看到

学过C++的都知道,TXOpenStorage@@YAJPB_WHAAV?$scoped_refptr@VCStorage@@@@AAV?$scoped_refptr@VCCompoundDocument@@@@@Z
它类似如C++里面的StgOpenStorage函数,可见这里是打开复合文档Registry.db的,
通过IDA我们知道,它的原型是
int __cdecl TXOpenStorage(void *lpFileName, int, int, int);
但我们接下来要怎么做,当然是看它是怎样解析Main_LoginAccountList流的
既然这样,它肯定会读取流吧,通过IDA我们看到,有一个符合我们要求的函数,或者说是
类成员,这个就是符号?Read@CStream@@QAEJPAXKPAK@Z,原型是
long __thiscall CStream::Read(void *, unsigned long, unsigned long *);
另外还可以看到它的地址是300520A8,取消上面的断点,下300520A8,也就是 CStream::Read(void *, unsigned long, unsigned long *)方法,继续运行,程序
如期的停在了300520A8,返回该函数后,到达下面的代码

查看堆栈

可见,CStream::Read第一个参数是缓存区,第二个是读取的大小,第三个未知,这时
016100B8就是读取到的流的数据,也就是那堆TD,TA,
熟悉OD的人肯定知道下硬件访问断点到016100B8到它的首字节,看下它是怎么解密这一大串
数据的,如果不出错的话,程序停在了这里,这是在用memcpy复制缓存区,

它将016100B8的数据复制到01610D20,不用我说了大家也知道再次下硬件断点01610D20吧,
取消原先的016100B8断点,下01610D20的首字节,运行程序,停在了这里

解密的海洋已经达到,其中ESI就01610D20,因为它会对Main_LoginAccountList流进行加密
如果该函数返回后01610D20,应该就是这样的

我这里的堆栈地址是0x01607AA8,原先应该是0x01610D20,因为我重新弄了一遍
至于解密方法,我分析不出来,技术有限,但是通过跟进它的解密函数,还是能得出一些信息

上一部分是介绍了逆向的过程,这部分主要介绍腾讯DB的格式,我只能说以下全是我推测出来,正确性未知
用DBViewer打开Main_LoginAccountList的流,DBViewer你们一定在网上找不到吧,稍后我会发出来的


大概每个人的这个流前两个字节都TD,还依稀的看TA,TD等
我只能先说腾讯的数据类型,这样好理解一些
0x01 相等于C++里面的BOOL(4个字节)
0x02 相等于C++里面的char(1个字节)
0x04 相等于C++里面的short(2个字节)
0x06 相等于C++里面的unsigned int(4个字节)
0x07 相等于C++里面的int(4个字节)
0x08 Uncode字符串
0x09 缓存区,char数组
0x0b 不知道名字,只知道是以Td开头
0x0c 不知道名字,只知道是以Ta开头

关于TD的格式
0~2 两个字节,总是TD,也就是54 44
2~4 两个字节,保留,总是01 01
4~6 两个字节,条目数量
到了这里,就要看,条目数量了,如果条目数量为0的话,下面的就没了,如果为2的话就说明有两条数据,这里假如为2
第一条数据
6~7 一个字节,数据类型,就是上面说的腾讯数据类型的哪些值
7~9 两个字节,数据的名字长度,这里叫nameLen1,简称L1,解密字符串的关键
9~9+L1 L1个字节,数据的名字,加密的Unicode字符串
9+L1~9+L1+4 4个字节,数据的长度,这里叫DataLen1,简称N1
9+L1+4~9+L1+4+N1 N1个字节,看6~7的数据类型,如果是是Uncode字符串的话,还要进行解密,如果是数字等的话,就不用了
第二条数据,够长了
9+L1+4+N1~9+L1+4+N1+1 一个字节,数据类型,就是上面说的腾讯数据类型的哪些值
9+L1+4+N1+1~9+L1+4+N1+1+2 两个字节,数据的名字长度,这里叫nameLen2,简称L2,解密字符串的关键
9+L1+4+N1+1+2~9+L1+4+N1+1+2+L2 L2个字节,数据的名字,加密的Unicode字符串
9+L1+4+N1+1+2+L2~9+L1+4+N1+1+2+L2+4 4个字节,数据的长度,这里叫DataLen2,简称N2
9+L1+4+N1+1+2+L2+4~9+L1+4+N1+1+2+L2+4+N2 N2个字节,如果是是Uncode字符串的话,还要进行解密,如果是数字等的话,就不用了
终于说完了

关于TA的格式,和TD差不多
0~2 两个字节,总是TA,也就是54 41
2~4 两个字节,保留,总是01 01
4~8 四个字节,条目数量,TD的是两个字节
到了这里,就要看,条目数量了,如果条目数量为0的话,下面的就没了,如果为1的话就说明有一条数据,这里假如为1
第一条数据
8~9 一个字节,数据类型,注意,没有数据名字了,光数据了
9~13 四个字节,数据长度,叫DataLen1,简称N1
13~13+N1 数据,看8~9的数据类型,以确定数据

可以看到腾讯的数据类型里面包含TD,和TA,这说明一个TD或者TA的数据还可能是一个TD或者TA的数据,就这样嵌套
首先说下解密字符串的方法,用C++表示就是这样

/*
szSrcBuf 要解密的缓冲区
szDestBuf 解密之后的缓冲区
nLen 要解密的缓冲区长度
*/
void Decrypt(unsigned char *szSrcBuf, unsigned char *szDestBuf, unsigned int nLen)
{
	unsigned int			key;
	unsigned int			i;

	if(!szSrcBuf || !szDestBuf || !nLen)
		return;

	key = (nLen >> 8) | (nLen & 0xff);
	for(i = 0; i < nLen; i++)
	{
		szDestBuf[i] = ~szSrcBuf[i];
		szDestBuf[i] ^= key;
	}

	szDestBuf[i] = '\0';
	szDestBuf[i + 1] = '\0';
}

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 6
支持
分享
最新回复 (13)
雪    币: 47147
活跃值: (20485)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
感谢你与大家分享,现在你己是正式会员。
2012-9-17 10:06
0
雪    币: 2015
活跃值: (902)
能力值: ( LV12,RANK:1000 )
在线值:
发帖
回帖
粉丝
3
key就一个字节,取长度的低16bit,高8位和低8位异或一下。
key = ((nLen >> 8) ^ nLen) & 0xff ;
2012-9-17 12:34
0
雪    币: 446
活跃值: (186)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
4
坛主,我又改了一下,能加精吗
2012-9-18 09:39
0
雪    币: 446
活跃值: (186)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
5
你也逆向过?
2012-9-18 15:10
0
雪    币: 15
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
1E 00 数据的名字长度,key=0x1e
数据:B2 E1 94 E1 83 E1 BE E1 A0 E1 8D E1 8D E1 B4 E1 92 E1 84 E1 93 E1 AD E1 88 E1 92 E1 95 E1
我的解密方法:
比如第一个数据B2,B2先自身求反得到4D,4D再与key异或得到53。
这些数据解密出来后都是unicode编码。

网上百度有人说info.db是好友文件。
我跟踪其解析Info.db文件时,发现有16字节的数据Key参与解密,EDI=E8EA4386,2EDD4C28,EE8215A4,596F4F13这4组数据,不知道怎么计算出来的。是不是和楼主所说的“这个Key好像跟平台有关”,就不得而知了。
2012-9-19 14:12
0
雪    币: 363
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
虽然说不记住密码不是很实用,但是楼主这个探索的精神值得学习
2012-9-19 14:35
0
雪    币: 120
活跃值: (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
哇,学习了,很厉害哦,强悍
2012-9-19 18:15
0
雪    币: 73
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
最近大家貌似对qq都比较有兴趣啊
2012-11-27 14:11
0
雪    币: 3373
活跃值: (1368)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
11
曾经对QQ下过手,但是因为技术不够,放弃了。看楼主文章 豁然开朗。
2012-11-27 16:40
0
雪    币: 20
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
楼主很强大,学习了!
2012-12-22 10:47
0
雪    币: 36
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
学习了 很强呀!!

楼主知道这么多
2012-12-22 12:07
0
雪    币: 36
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
那个key是服务器返回的
2014-5-29 15:40
0
雪    币: 35
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
大神啊,膜拜啊!我什么都没学过!~~~~(>_<)~~~~
2014-5-29 16:10
0
游客
登录 | 注册 方可回帖
返回
//