出于腾讯将所有的QQ架构统一为QQNT(嗯,喷香的Electron跨平台演绎——当然电能与性能消耗就轮不到他们论证了)
导致现在每个平台的解密方法都差不多。
0. 解密前准备
一个root过的手机(anything you like)
Termux与MT管理器
1. 获取密钥
打开termux终端 安装tsu(pkg install tsu)
然后
sudo cat /data/user/0/com.tencent.mobileqq/databases/beacon_db_com.tencent.mobileqq |grep "home_uin"
请注意 如果是同框架的TIM应该为com.tencent.tim; 工作空间/分身空间的UID不为0(Owner/机主)
得到以下输出类似物:
"home_uin": "390251789","uid":"u_mIicAReWrdCB-kST6TXH7A"
在/data/user/0/com.tencent.mobileqq/files/uid/目录下,可见到文件名形如390251789###u_mIicAReWrdCB-kST6TXH7A的若干个文件,其中u_mIicAReWrdCB-kST6TXH7A即为nt_uid。
保存好uid。
然后使用mt管理器,打开/data/user/0/com.tencent.mobileqq/databases/nt_db/nt_qq_{QQ_path_hash}目录 复制出nt_msg.db文件。
用任何可靠的方式复制粘贴到电脑上(Localsend/数据线)
然后 xxd nt_msg.db
将文件头部跟随在QQ_NT DB后的可读字符串复制,形如6tPaJ9GP,记为rand
然后使用以下脚本计算
#!/usr/bin/env python3
import argparse
import hashlib
def md5_hex(text: str) -> str:
return hashlib.md5(text.encode("utf-8")).hexdigest()
def calc_hashes(nt_uid: str, rand: str) -> tuple[str, str]:
qq_uid_hash = md5_hex(nt_uid)
qq_path_hash = md5_hex(qq_uid_hash + "nt_kernel")
db_key = md5_hex(qq_uid_hash + rand)
return qq_path_hash, db_key
def main() -> None:
parser = argparse.ArgumentParser(
description="根据 nt_uid 和 rand 计算 QQ_path_hash 与数据库密钥"
)
parser.add_argument("nt_uid", help="例如: u_mIicAReWrdCB-kST6TXH7A")
parser.add_argument("rand", help="例如: 6tPaJ9GP")
args = parser.parse_args()
qq_path_hash, db_key = calc_hashes(args.nt_uid, args.rand)
print(f"QQ_path_hash: {qq_path_hash}")
print(f"DB key: {db_key}")
if __name__ == "__main__":
main()
然后清理无关文件头:
使用tail命令(仅 Linux):tail -c +1025 nt_msg.db > nt_msg.clean.db
使用 Python:python -c "open('nt_msg.clean.db','wb').write(open('nt_msg.db','rb').read()[1024:])"
就已获得一个可以打开(但不一定干净,而且QQ偶尔会炸表导致数据库发生问题)
2. 打开数据库
选用SQLiteStudio,使用sqlcipher模式打开数据库,密码空,加密方式填入:
PRAGMA key = 'pass'; -- pass 替换为之前得到的密码(32字节字符串)
PRAGMA cipher_page_size = 4096;
PRAGMA kdf_iter = 4000; -- 非默认值 256000
PRAGMA cipher_hmac_algorithm = HMAC_SHA1; -- 非默认值(见上文)
PRAGMA cipher_default_kdf_algorithm = PBKDF2_HMAC_SHA512;
PRAGMA cipher = 'aes-256-cbc';
当然直接解密也是可以的
sqlcipher nt_msg.clean.db "pragma key = 'pass'; pragma kdf_iter = 4000; pragma cipher_hmac_algorithm = HMAC_SHA1;" .d | tail +2 | sqlite3 nt_msg.decrypt.db
坏表会导致回滚事务,因此为了救表可以用
sqlcipher nt_msg.clean.db "PRAGMA key = 'pass'; PRAGMA kdf_iter = 4000; PRAGMA cipher_hmac_algorithm = HMAC_SHA1; .dump" | grep -iv "ROLLBACK;" | sqlite3 nt_msg.decrypt.db
3. 自动工具
https://github.com/kingsznhone/ntqq_msg_db_util
可以拿来自动化清洗记录并且炼丹了()