QQ数据库解密与SQLCipher密钥提取全平台指南:5步跑通并解密聊天数据库

QQ数据库解密与SQLCipher密钥提取全平台指南:5步跑通并解密聊天数据库

【免费下载链接】qq-win-db-key 全平台 QQ 聊天数据库解密 【免费下载链接】qq-win-db-key 项目地址: https://gitcode.com/gh_mirrors/qq/qq-win-db-key

这个仓库 qq-win-db-key 专门解决QQ数据库解密中最核心的一步——SQLCipher密钥提取:在 Windows(旧版PCQQ、新版NTQQ)、Linux、macOS、iOS、Android 五个平台上,从 QQ 进程内存里直接截获数据库密钥,之后用 SQLCipher 打开聊天数据库。适合想在自己设备上找回、迁移或分析聊天库的开发者。仓库里的脚本都是参考实现,不同 QQ 版本可能跑不通,动手前请通读一遍代码并备份数据。

最快跑通:Windows 上 5 步拿到密钥

主线选旧版 PCQQ + Frida:依赖只有 Python、frida、psutil,不用学调试器,反馈最直接。

第 0 步,拿代码:

git clone https://gitcode.com/gh_mirrors/qq/qq-win-db-key

第 1 步,确认要 hook 的是哪个进程。 任务管理器里可能有多个 QQ.exe,脚本 hook 的是命令行参数带 /hosthwnd= 的那个子进程,用 psutil 这样筛:

for pid in psutil.pids():
    p = psutil.Process(pid)
    if p.name() == "QQ.exe" and len(p.cmdline()) > 1:
        QQ_PID = pid
        break

第 2 步,定位目标函数。 hook 对象是 KernelUtil.dll 里给数据库上锁的 sqlite3_key 类函数。QQ 没把它导出为符号,所以脚本用特征码在内存里扫:

const kernel_util = Module.load('KernelUtil.dll');
const key_function = single_function(
  "55 8b ec 56 6b 75 10 11 83 7d 10 10 74 0d 68 17 02 00 00 e8");

⚠️ 注意:特征码和 QQ 版本强绑定。QQ 升级后这段字节大概率变掉,脚本会直接报 pattern NOT FOUND,需要对新二进制重新提取。

第 3 步,挂 hook 等命中。 函数签名是 sqlite3_key(db, zDbName, pKey, nKey),命中时读出第 3、4 个参数就是密钥:

Interceptor.attach(key_function, {
    onEnter: function (args) {
        var dbName = funcName(args[0], NULL).readUtf8String();
        if (dbName.toLowerCase().endsWith("msg3.0.db")) {
            console.log("nKey: " + args[2].toInt32());
            console.log("*pkey: " + buf2hex(args[1].readByteArray(args[2].toInt32())));
        }
    }
});

一个账号会开一堆 .db,全都走这个函数,所以必须按库名过滤。聊天记录主库是 Msg3.0.db,脚本只放行它。

第 4 步,读结果。 密钥以十六进制字节序列打印,是 16 字节的 ASCII 串,形如 abcd1234.. 加几个特殊符号。

第 5 步,验证。 带着密钥打开数据库能列出表,密钥就是对的(下一节)。

完整脚本在 scripts/windows/pcqq/pcqq_get_key.py,直接 python pcqq_get_key.py 即可,注入成功后保持终端窗口不关,回 QQ 里随便切个会话触发一次数据库读写。

其余平台和主线的差异

五个平台走的是同一条路:找模块 → 静态算出函数偏移 → 下断点或挂 hook → 命中时从参数里读密钥。差别只在工具链和环境门槛:

平台目标模块函数定位方式读密钥方式环境门槛脚本位置
Windows PCQQKernelUtil.dllFrida 特征码扫描Frida hook 读参数Python + fridascripts/windows/pcqq/
Windows NTQQwrapper.node纯 PowerShell 解析 PE:先找 .rdata 里 nt_sqlite3_key_v2: db=%p zDb=%s 字符串,再找引用它的 LEA 指令,经异常目录反推函数入口脚本自带 Debug API 启动 QQ,写 0xCC 软断点,命中后从 R8(x64 第三参数)读 16 字符密钥无额外依赖,PS 5.0+scripts/windows/ntqq/
Linux/opt/QQ/resources/app/wrapper.nodereadelf -lW 算 .rodata 段映射 + strings -t d 找串 + objdump 找引用GDB 脚本内嵌:断 dlopen 等模块加载,命中循环等 nKey==16 再读寄存器root + gdbscripts/linux/
macOS(Apple Silicon)wrapper.node 的 arm64 切片纯 Python 解析 fat binary,靠诊断串定位并回溯函数入口,无需关 SIPlldb 断点回调读 x2/x3(AAPCS64 的第三、四参数)Xcode Command Line Toolsscripts/macos/arm-nosip/
iOSQQ 主二进制硬编码偏移(0xDA1BFB4 对应 v9.0.1.620),另靠 sqlite3 结构体偏移链反查库名frida hook,按数据库文件名过滤越狱或 TrollStore + frida-serverscripts/ios/
Androidlibkernel.soFrida 扫 ARM64 特征码(码里带 ?? 通配字节)frida hook,args[2]/args[3] 即 pKey/nKeyroot、禁 SELinux、关 Magisk Hide/Shamikoscripts/android/

几点实操判断:

  • Windows NTQQ 是最省事的路,不装 Frida 也能跑:powershell -ExecutionPolicy Bypass -File scripts/windows/ntqq/windows_ntqq_get_key.ps1,脚本自己从注册表找 QQ 安装目录、以调试器方式拉起 QQ,你只管正常登录。拿到密钥后脚本会直接结束 QQ 进程,属正常行为;加 -NoDebugForKey 则只做静态分析不下断点。
  • macOS 数据库~/Library/Application Support/QQ/nt_qq_<hash>/nt_db/nt_msg.dbLinux~/.config/QQ 下,脚本输出里会直接给路径。
  • Android 有第二条路:不注入,改用系统备份功能备份 com.tencent.mobileqq,再用 scripts/android/android_get_backup_key.py 从备份里提密钥,风险更低。更保险的是 PCQQ 自带的"导出消息记录(mht)",能用官方导出就别上注入。

密钥到手之后

1024 字节文件头怎么去掉

NTQQ 的 nt_msg.db 头部多了一段 1024 字节的自定义头,SQLCipher 认不出,直接开会报错,先切掉:

tail -c +1025 nt_msg.db > nt_msg.clean.db

旧版 PCQQ 的 Msg3.0.db 没有这段头,不用切。拿不准就查前 1024 字节是否为合法 SQLCipher 页面,或两种都试一遍。

SQLCipher PRAGMA 参数怎么配

QQ 用的参数全是非默认值,按 SQLCipher 默认值解密必挂。逐项对照:

参数说明
cipher_page_size4096页大小
kdf_iter4000远低于默认 256000,写错直接解不开
cipher_hmac_algorithmHMAC_SHA1部分版本见过 SHA512,先按 SHA1
cipher_default_kdf_algorithmPBKDF2_HMAC_SHA512KDF 算法
sqlcipher nt_msg.clean.db << 'EOF'
PRAGMA key = '你的密钥';
PRAGMA cipher_page_size = 4096;
PRAGMA kdf_iter = 4000;
PRAGMA cipher_hmac_algorithm = HMAC_SHA1;
PRAGMA cipher_default_kdf_algorithm = PBKDF2_HMAC_SHA512;
.tables
EOF

能列出表即密钥正确。报 file is not a database 时,按顺序查:key 是否写在所有 PRAGMA 之前、文件头切没切、kdf_iter 是不是 4000。

单库与批量解密

单个库要留一份明文副本,做法是打开加密库后 ATTACH 一个空 key 的新库,逐表拷贝:

ATTACH DATABASE 'nt_msg_plain.db' AS plain;
CREATE TABLE plain.msg AS SELECT * FROM main.msg;  -- 每张表一行

批量处理就套一层循环,对目录下每个 .db 重复上面动作即可;更省事的是直接用仓库里的现成脚本:scripts/windows/pcqq/pcqq_dump.py 在注入进程内调用 QQ 自己的 sqlite3 接口,新开一个明文库、设 PRAGMA synchronous=ON 后逐表落盘,避免把大文件拖进内存。

校验结果别只信 .tables:对主消息表 SELECT COUNT(*) 看行数是否合理,再抽查几条消息内容。行数正常但内容乱码,说明 KDF 参数还是不对;能读但表缺失,多半是只解了部分库。

常见坑:现象、原因与处理

现象原因处理
pattern NOT FOUNDQQ 版本更新,特征码/偏移已变对新二进制重新提取特征码或偏移
pattern FOUND MULTI特征码太短,命中多处加长特征码,或结合上下文约束
脚本报 QQ not launched. exit.没找到 cmdline 带参数的 QQ.exe 子进程先登录 QQ 再跑,用任务管理器确认进程
hook 有输出但拿不到想要的密钥同会话开了多个库,命中了别的库核对 dbName 输出,调整库名过滤条件
file is not a databaseNTQQ 的 1024 字节头没切tail -c +1025 处理后重试
解开了但数据损坏KDF/HMAC 参数不匹配逐项核对 4000 / HMAC_SHA1 组合
Android 注入失败SELinux 或 Magisk Hide、Shamiko 拦截先禁 SELinux、关隐藏规则再注入
iOS 断点打偏偏移 0xDA1BFB4 只对应 v9.0.1.620反汇编自己的版本重新取偏移

合规提醒与延伸学习

以上技术仅限恢复、迁移自己设备、自己账号上的聊天数据等合法场景,不得用于获取他人数据。⚠️ 仓库明确警告:注入类脚本可能破坏数据库或触发风控,优先用官方导出功能,在虚拟机或备用账号上实验。想深入的话,从 SQLCipher 官方文档理解 KDF 与 HMAC 参数,从 Frida 文档吃透 Interceptor 和模式扫描,再对照本仓库各平台脚本的源码和实际调试输出读一遍,比任何教程都直接。

【免费下载链接】qq-win-db-key 全平台 QQ 聊天数据库解密 【免费下载链接】qq-win-db-key 项目地址: https://gitcode.com/gh_mirrors/qq/qq-win-db-key

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值