{"id":21344328,"url":"https://github.com/mythologyli/qq-nt-db","last_synced_at":"2025-10-07T11:32:26.739Z","repository":{"id":204432963,"uuid":"704943166","full_name":"Mythologyli/qq-nt-db","owner":"Mythologyli","description":"QQ NT Windows 数据库解密+图片/文件清理","archived":false,"fork":false,"pushed_at":"2024-07-27T06:52:29.000Z","size":2263,"stargazers_count":93,"open_issues_count":4,"forks_count":6,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-22T07:06:16.761Z","etag":null,"topics":["qq","qq-nt","sqlcipher","sqlite"],"latest_commit_sha":null,"homepage":"https://myth.cx/p/qq-nt-db/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Mythologyli.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-14T15:22:27.000Z","updated_at":"2025-01-21T17:09:08.000Z","dependencies_parsed_at":null,"dependency_job_id":"3fa72c3f-1ed8-45eb-9346-e6e229ffae35","html_url":"https://github.com/Mythologyli/qq-nt-db","commit_stats":null,"previous_names":["mythologyli/qq-nt-db"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mythologyli%2Fqq-nt-db","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mythologyli%2Fqq-nt-db/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mythologyli%2Fqq-nt-db/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mythologyli%2Fqq-nt-db/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Mythologyli","download_url":"https://codeload.github.com/Mythologyli/qq-nt-db/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236293645,"owners_count":19125694,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["qq","qq-nt","sqlcipher","sqlite"],"created_at":"2024-11-22T01:18:20.609Z","updated_at":"2025-10-07T11:32:21.695Z","avatar_url":"https://github.com/Mythologyli.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# QQ NT Windows 数据库解密+图片/文件清理\n\n笔者测试时使用的 QQ 版本：9.9.3-17412\n\n经验证的 QQ 版本：9.9.3-17749 9.9.12-26339\n\n## 找到数据库 `passphrase`\n\n1. 使用 IDA Pro 打开 `C:\\Program Files\\Tencent\\QQNT\\resources\\app\\versions\\9.9.3-17412\\wrapper.node`。打开 Strings 视图，搜索 `sqlite3_key_v2`\n\n    ![](docs/1.png)\n\n2. 跳转到主视图，再跳转到引用该字符串的位置\n\n    ![](docs/2.png)\n\n    ![](docs/3.png)\n\n3. 按下 F5 反编译此函数\n\n    ![](docs/4.png)\n\n    参考[文档](https://www.zetetic.net/sqlcipher/sqlcipher-api/#sqlite3_key)可知 `sqlite3_key_v2` 的参数为：\n\n    ```c\n    int sqlite3_key_v2(\n        sqlite3 *db,                   /* Database to be keyed */\n        const char *zDbName,           /* Name of the database */\n        const void *pKey, int nKey     /* The key */\n    );\n    ```\n   \n    可以猜测 a3 为我们所需的 `passphrase`。打上断点\n\n4. 退出 QQ 并重新打开，但不要登录。使用 IDA Debug 的 Attach to Process 功能，附加到 QQ 进程。之后登录，可以看到断点被命中\n\n    ![](docs/5.png)\n\n    打开一个 Locals 视图(调试器视图-\u003e本地变量)查看参数的值\n\n5. 命中后，跳转到 a3 对应的位置，直到看到如下图所示的 16 位字符串。`#8xxxxxxxxxxx@uJ` 即为我们需要的 `passphrase` (不一定是这个格式，但总字符数是一样的)\n\n    ![](docs/6.png)\n\n## 导出/修复数据库\n\n数据库位置：`C:\\Users\\\u003cUSERNAME\u003e\\Documents\\Tencent Files\\\u003cQQ\u003e\\nt_qq\\nt_db`\n\n你需要的是 .db 格式的文件。\n\n首先，每个数据库文件头部有 1024 个字符的无用内容，去除这部分内容：\n\n+ Windows\n    ```bash\n    type nt_msg.db | more +1025 \u003e nt_msg.clean.db\n    ```\n\n+ UNIX\n    ```bash\n    cat nt_msg.db | tail -c +1025 \u003e nt_msg.clean.db\n    ```\n\n此时文件已经可以通过 DB Browser for SQLCipher 直接查看，注意迭代次数填写 4000。\n\n下面解释直接解密数据库的方法。\n\n考虑到在 Windows 上编译 sqlcipher 较为困难，笔者使用了 MSYS2 环境并直接安装了`mingw-w64-x86_64-sqlcipher`\n\n笔者处理了 `nt_msg.db`、`files_in_chat.db` 两个文件，并将处理后的文件移动到 `data/clean_db`\n\n根据 sqlcipher 的文档，解密数据的流程为：\n\n1. 打开数据库\n\n    ```bash\n    $ sqlcipher\n    sqlite\u003e .open nt_msg.clean.db\n    ```\n   \n2. 输入 `passphrase`\n\n    ```bash\n    sqlite\u003e PRAGMA key = '#8xxxxxxxxxxx@uJ'; PRAGMA kdf_iter = '4000';\n    ```\n\n3. 导出无加密的数据库\n\n    ```bash\n    sqlite\u003e ATTACH DATABASE 'nt_msg.db' AS plaintext KEY ''; SELECT sqlcipher_export('plaintext'); DETACH DATABASE plaintext;\n    sqlite\u003e .exit \n    ```\n\n不过，很有可能在导出时提示数据库损坏 `Runtime error: database disk image is malformed`。此时需要对数据库进行修复：\n\n```bash\nsqlite\u003e .output nt_msg.sql\nsqlite\u003e .dump\nsqlite\u003e .exit\n```\n\n之后对得到的 `nt_msg.sql` 进行处理，并使用 `sqlite3` 生成无加密的数据库\n\n```bash\n$ cat nt_msg.sql | sed -e 's|^ROLLBACK;\\( -- due to errors\\)*$|COMMIT;|g' | sqlite3 nt_msg.db\n```\n将解密后的数据库移动到 `data/decrypted_db`\n\n## 图片/文件清理\n\n下图是 `nt_msg.db` 中的表：\n\n![](docs/7.png)\n\n注意 `c2c/group_msg_table` 中的 `40800`（消息内容）是 Protobuf 二进制。笔者暂时没有弄明白每个字段的意义\n\n图片/文件清理可以参考仓库中的两个 Python 脚本\n\n## 致谢\n\n[QQBackup/qq-win-db-key](https://github.com/QQBackup/qq-win-db-key)\n\n[https://lengyue.me/2023/09/19/ntqq-db/](https://lengyue.me/2023/09/19/ntqq-db/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmythologyli%2Fqq-nt-db","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmythologyli%2Fqq-nt-db","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmythologyli%2Fqq-nt-db/lists"}