2024年1月7日发(作者:)
QQ聊天记录解析
一、 问题概述
需要确定QQ安装文件路径,确定后根据分析的QQ号,获得QQ聊天记录文件。通过解析和解密该文件,得到QQ聊天记录的全部内容。
二、 文件存放路径
以路径:C:Program 为例:
路径层次
1
路径名称
QQ安装目录
详细说明
C:Program FilesTencentQQ
为安装QQ时的默认路径,如果QQ程序装在别的目录,也可以进行注册表搜索,得到安装目录。(代码1)
2 QQ号码目录 593389426
表示需要解析QQ聊天记录的QQ号码。
3
表示聊天记录消息信息存储文件。
using (ryKey reg =
bKey
(@"SoftwareTencentQQ"))
{ QQPath = ue("Install") as string; }
代码1:(得到的QQPath为QQ安装目录)
三、 问题解决方案
步骤名称
1:定义六种QQ
消息基础类型
详细说明
六种消息类型分别为:
1:BIMMsg:广播信息
2:C2CMsg:客户对客户信息
3:GroupMsg:QQ群信息
4:MobileMsg:移动QQ用户信息
5:SysMsg:系统信息
6:TempSessionMsg:临时信息
这六种类型是根据解析文件所可能获得的结构类型建立的基础常量。
2:解析首先用分析文件
文件,可以得到以下的结构化形式:
可以看出,解析出的结构,如果类型中存在聊天记录的,会显示,不存在聊天记录的类型,不会被提取出来。
在结构化图中,还有一种比较特殊的类型Matrix,他是保存加密密钥相关的信息。
下面再按照上图的结构化层次,一行一行进行解析。
就拿C2CMsg为例:
首先解析到行C2CMsg,发现他是文件夹行(类型FileType=1)并且路径FilePath(表示父文件夹)不是六种类型之一,则不处理。
再解析到行593389426,发现是文件夹行,路径FilePath
=“C2CMsg” ,为六种类型之一,则记录该行,准备分析。
再解析到行,是文件行(类型FileType=2),也不处理。
在第一次遍历的时候,只考虑文件夹的情况。通过第一次遍历解析,就可以将全部的父文件为六种类型的文件
夹提取出来,(可以发现这些文件夹为QQ号,群号,系统号10000)。
其他的几种类型文件夹解析方式同上。
得到全部相关文件夹后,遍历文件夹,解析其中的文件。从结构化层次中可以看到每个文件夹都有两个数据文件,分别是:
1: (聊天记录信息密文存储文件)
通过解析此文件,得到需要的聊天记录信息。但得到的信息为加密信息,还需要通过TEA算法,结合3中的公共密钥,对信息进行解密,得到最终的聊天记录信息。
2: (聊天记录索引文件)
通过解析此索引,得到每种类型文件夹内,一共存在的聊天记录数,方便对文件处理。
还有一个我们需要的特殊文件,是存放在特殊文件夹Matrix中的,这个文件是解密密钥的相关文件。通过QQ号和此文件信息,结合MD5算法和TEA算法,可以解析处聊天记录的公共密钥。为后面解密文件提取信息做准备。
3:获得TEA算法 1:取得QQ号的MD5散列值。
解密密钥
2:用二进制流提取出的文件信息,和1中的散列值进行MD5算法解密,得到一个解密字串。
3:将2中的解密字串作为输入值,1中的MD5散列作为解密密钥,调用TEA算法,获得的解密结果就为聊天记录信息的公共密钥。
4:根据1中的六种建立的文件夹作为解析的聊天记录的存储路径。
类型,分别在算法程序所在文件夹内建立六个子文件夹
5:在4中文件夹内遍历2中提取出的QQId文件夹,根据其父路径根据需要,建立(FilePath),在建立六种类型文件夹下,再建立以QQID命QQID子文件夹
名的文件夹,这些文件夹就是最后解析出的聊天记录文件存储地。
6:解析数据文件 遍历2中提取出的QQId文件夹,开始解析数据文件。
1:以二进制流读取文件进行解析,此文件是
文件的索引文件。即记录文件的记录数和记录长度。文件是以每4个字节为单位记录文件的长度数。
例如:读取文件,得到的byte数组为
0 0 0 0 96 0 0 0 216 0 0 0 96 1 0 0
则表示文件记录数为4。
第一个记录段长度为96-0=96;
第二个记录段长度为216-96=120;
第三个记录段长度为256+96-216=136;
第四个记录段长度为文件总长度-(256+96);
将这些信息全部记录下来,为下面解析提供数据。
2:以二进制流读取文件进行解析,此文件为记录信息。通过上面得到的每个记录段的长度,分别对文件二进制流读取相应的长度,就可以得到记录段的密文信息。通过TEA算法解密,得到记录段的真实二进制流信息。
3:分析得到的二进制流信息。
⑴读取前四个字节,表示消息的时间,这里的时间是以据“1970年1月1日8点”的偏移量(ticks)表示。
这里的时间是格林威治标准时间(1970-1-1)+中国时区(偏差8小时)。
通过方法
DateTime time =
new DateTime(1970, 1, 1,8,0,0) +
new TimeSpan(0, 0, ticks);
得到准确的消息时间。
⑵过滤内部偏移量:根据消息所属的类型,确定偏移量。其中
BIMMsg,C2CMsg,MobileMsg偏移量为1;
GroupMsg偏移量为8;
SysMsg偏移量为4;
TempSessionMsg偏移量为9;
如果消息所属类型为TempSessionMsg,执行第三步,否则跳过,直接执行第四步
⑶先用ReadInt32读取二进制流的4个字节,读取内容为一个长度值,通过该长度值,再读取相应长度的字节数ReadBytes(长度)。读出的信息表示临时信息所属的组信息。
⑷用ReadInt32读取二进制流的4个字节,读取内容为一个长度值,通过该长度值,再读取相应长度的字节数ReadBytes(长度)。读出的信息表示该条消息的发送人的信息。
⑸用ReadInt32读取二进制流的4个字节,读取内容为一个长度值,通过该长度值,再读取相应长度的字节数ReadBytes(长度)。读出的信息表示该条消息的具体内容。
还存在问题:
1:如图有的QQ的文件,会出现IMInfo文件夹和文件,用途未知。
2:解析文件时,按步骤读取了二进制流的字节数后,还会有剩余的字节,而且剩余的字节数不一致,不知道用途是什么。


发布评论