清理安卓NTQQ中指定群聊的图片

上一篇文章中,我成功解密了NTQQ的聊天记录数据库(nt_msg.db)。接下来,我会读取数据库中指定群聊的聊天记录信息,从中获取消息中的图片路径,并进行删除。

整体上,主要分为两步:第一步是读取数据库,解析其中的图片路径,这一步是在电脑(windows)下进行;第一步会生成一个json文件,里面包含解析出来的图片路径,而第二步则是将这个json放入手机中,在手机里进行删除。

数据库解码

在上一篇文章中,我已经解密了nt_msg.db并保存为了一个新的数据库文件,这个新文件可以直接读取,不需要解密。
由于我的目标是群聊的聊天记录,所以需要读取其中的group_msg_table这个表。主要关注两个字段:40030表示群号,40800表示聊天记录内容。

我的聊天记录比较多,所以读取所有的群的聊天记录太耗时间了,我只需要删除其中某几个群的聊天记录图片。
SQL语句如下,其中的12345和23456表示我需要读取的群聊:

SELECT `40800`, `40030` FROM group_msg_table WHERE `40030` IN ('12345', '23456');

40800这个字段存储的并不是明文的聊天记录,而是一串protobuf字节,需要使用blackboxprotobuf这个包来进行解码,解码的结果是一个dict,而这里面可能存在层层嵌套的关系,例如dict里面包含list,list里面包含dict,或者包含另一串protobuf字节,因此可能需要以递归的形式进行解码。解码过程、各种字段的含义、以及遍历方式主要参考了qq-dumpQQNT_Export

在解码的过程中,如果遇到“Exceeds the limit (4300 digits) for integer string conversion”这样的报错,可以在代码顶部加上:

import sys
sys.set_int_max_str_digits(0)

这里只需要关注图片相关的内容,根据消息导出计划proto_maps.py,我需要找到解码结果中的45406或45424字段。按理说,45406字段应该是bytes类型,而45424字段则是str类型,且两者的长度都应该是32,但不知为何偶尔可能会遇到别的情况,例如类型不同或长度不符的情况,目前还不知道原因,只能暂且忽略这些。

对于45406字段的bytes,对其进行.hex().upper()操作,转换为长度32的全大写字符串,而对于45424的字符串,不需要做处理,通常它本身就是一个长度32的全大写字符串。它们的本质其实是md5十六进制字符串。

一般来说,图片可能存在于以下3个目录:chatthumb、chatimg、chatraw,分别对应缩略图、压缩后的图片、原图。要得到图片路径,需要进行以下操作:
1. 将45424或经过处理后的45406字符串和目录名拼接到一起,例如“chatimg:{md5}”这样的格式;
2. 对这个拼接后的字符串进行crc64运算,得到一个十六进制字符串,并去除开头的“0x”,然后前面加上“Cache_”,这就是文件名;
3. 取2的结果的后3个字符,得到子目录的名称,前面再加上上述说的3个目录,即可得到图片的路径。
代码如下:

def crc64(s):
    _crc64_table = [0] * 256
    for i in range(256):
        bf = i
        for _ in range(8):
            bf = bf >> 1 ^ -7661587058870466123 if bf & 1 else bf >> 1
        _crc64_table[i] = bf
    v = -1
    for c in s:
        v = _crc64_table[(ord(c) ^ v) & 255] ^ v >> 8
    return v

def get_img_path(folder, md5):
    url = f"{folder}:{md5}"
    filename = 'Cache_' + hex(crc64(url)).replace('0x', '')
    return os.path.join(f"./{folder}/", filename[-3:], filename).replace("\\", "/")

将得到的所有图片路径,按照群号分组,写入json,格式如下:

{"group_number", ["img_path_1", "img_path_2"......]}

删除

我已经解析好了图片路径,并生成了一个json。下面就该把目标转移回手机上了。
编写一个新的脚本,在手机上运行,用于读取这个json文件,得到里面的图片路径,并执行删除,这一步很简单,就不多解释了。
需要注意的是,上面生成的图片路径并不是一个绝对路径,它的开头是chatthumb或chatimg或chatraw,这3个目录实际上都在“/storage/emulated/0/Android/data/com.tencent.mobileqq/Tencent/MobileQQ/chatpic/”里面,需要先执行os.chdir()来进入chatpic目录下,再执行删除。

至此,所有的步骤都完成了。这个过程中可能会有错误,例如误删或漏删的情况,但由于数据量太大了,即使有问题也难以发现,没办法。

参考

1. https://github.com/Tealina28/QQNT_Export
2. https://github.com/miniyu157/qq-dump

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注