由于笔者是一个活在过去的人, 近日在使用发布于 2025 年的 QQ 9.9.21-38711 安装 LiteLoaderQQNT 1.4.1 时出现了登录后约 0.08 分钟后自动退出登录并跳回登录页面的问题。在进行一些分析和 logging 并与 Claude Opus 5.5 xhigh (Max Plan) 进行简单交流后花费高达少于 8 分钟的时间修复了此问题, 且为了记录将解决方案分享到此文章。
简要分析
app.quit 的调用 stack trace
1 | 2026-11-01T18:47:12.902Z [pid 27124 +8819ms] !!! app.quit [] |
通过日志记录调用栈不难发现,17.background.js 多次调用了 app.quit app.relaunch 等方法,基本确定是这个 JS 手动触发退出而非 LiteLoader 本体报错崩溃。
进一步对其进行插入脚本分析:
1 | 2026-11-01T19:36:38.480Z [pid 23024 +6761ms] [region 1367811] hash.update(["QQ:unsafe check"]) -> [Hash] {} |
可见 QQ:unsafe check 字样,且对 QQ 进程进行快照里也包含此字样,确定为此版本 QQ 的防篡改,且 LiteLoader 群内的替换 dbghelp.dll 与 QQ.exe 均没有解决此版本 QQ 上的此问题(有可能是不进行向下兼容故没有处理)。
读取 globalThis.LiteLoader
同样方式查出疑似 QQ 对 LiteLoader 的读取:
1 | 2026-11-01T19:11:16.209Z [pid 18368 +39750ms] LiteLoader getter denied Error |
对比 1.3.1 和 1.4.1 的代码后发现,globalThis.LiteLoader 在1.4.0+ 是一个 getter:
1 | Object.defineProperty(globalThis, "LiteLoader", { |
如果调用者不在白名单内,1.4.x 会返回 null,而 1.3.1 调用返回的为 undefined 。
读取 _getPreloadPaths[0]
对 1.3.x 和 1.4.x 的代码 diff 后发现另一处差异:
1 | # 1.4.1 |
1 | # 1.3.0 |
1.4.1 的 preload path 里,LiteLoader 的 preload 在 QQ 前面,而 1.3.0 的则在 QQ 后面。
胁迫 Claude 对此进行分析后得出:
1 | D.bindWinEvents 17.background.js:1:1372175 |
QQ 会判断 _getPreloadPaths()[0] 是否位于其本体的 application.asar 下,如果不是依旧会触发风控。
解决方案
修改 src/main/api.js
45 行附近:
1 | Object.defineProperty(globalThis, "LiteLoader", { |
修改 src/main/hook.js
20 行附近 :
1 | function proxyPreload(func) { |
修改后进行测试,再无重启现象。插件加载正常。
说些什么吧!