文档归位:雪猫 README 门面 + 公告/制作文档/发布工具并入仓库根
Release Tag / validate-version (push) Waiting to run

This commit is contained in:
天天的鸟蛋蛋 committed 2026-11-12 06:29:38 +08:00
1 parent b9655a5ab1
commit e292824161
122 files changed
+90002 -69

No files matched your search

+181
View File
@@ -0,0 +1,181 @@
# SnowCat 雪猫:融合魔改 QQ 客户端(NapCat + SnowLuma 合体)
> 立档 2026-11-11 · 师父亲定名 SnowCat/雪猫(SnowLuma 的雪 + NapCat 的猫)· 后续随移植进度续写
## 一、在役运行链(现状考古,已实锤)
```
开机
└─ schtasks \Tongling-Autostart
└─ powershell C:\dsh\start-tongling.ps1
└─ Napcat worker:
NapCatWinBootMain.exe
"D:\NapCat.Shell.Windows.OneKey\NapCat.44498.Shell\QQ.exe" ← 便携 QQ(非注册表安装版)
"C:\dsh\.tmp\napcat-shell\NapCatWinBootHook.dll" ← 注入 DLL
-q<REDACTED> ← 速登账号
env:
NAPCAT_PATCH_PACKAGE=C:\dsh\.tmp\napcat-shell\qqnt.json ← 版本描述符(钉 9.9.22-40990)
NAPCAT_LOAD_PATH=loadNapCat.js NAPCAT_INJECT_PATH=BootHook.dll
NAPCAT_MAIN_PATH=napcat.mjs
└─ 5min 心跳: schtasks \tongling-heartbeat → heartbeat-tongling.ps1(看 6099 WebUI 端口判活)
```
**进程链**: NapCatWinBootMain.exe (PID 5068) → 启动并注入 QQ.exe ×3 进程 → BootHook.dll 进 QQ 内部 →
Electron 主进程加载 `loadNapCat.js`(内容就一行 `import("file:///...napcat.mjs")`,每次 launcher 启动时由脚本重新生成)→
napcat.mjs(3MB 打包 bundle)跑起来 → **reverse WS 客户端**连 `ws://127.0.0.1:8082`(dsh 侧 server,token 在
onebot11_<REDACTED>.json)→ WebUI 在 6099。
## 二、解包机制("怎么解包跑通的"答案)
- 便携 QQ 结构:`NapCat.44498.Shell/versions/9.9.35-52892/` = 完整 Electron 运行时
(QQNT.dll + *.dll + resources/app/)。
- **关键**:`resources/app/` 是**解开的目录形态**(package.json 直接可读),不是 app.asar 打包——
这就是"解包完成"的形态。来源:OneKey 一键包(下载器解包模式),不是手动解的。
- 目录名 `44498` = OneKey 出厂时带的 QQ build(~9.9.30-44498);后来 QQ 自更新器原地升到 **9.9.35-52892**。
- `channel.json` 为空;`versions/<ver>/resources/app/package.json` 是 QQ 版本的**权威源**。
## 三、硬改点清单(已实锤 + 待审计)
| # | 位置 | 内容 | 状态 |
|---|---|---|---|
| 1 | `qqnt.json`(NAPCAT_PATCH_PACKAGE) | 钉死 9.9.22-**40990**,实际 QQ=9.9.35-**52892**。**消费者=NapCatWinBootHook.dll**(QQ 进程内,UTF16 字符串实锤;exe 和 mjs 都不认) | ✅ 实锤,DLL 源码在 NapNeko/NapCat-Hook |
| 2 | `napcat.mjs` | **逐字节=官方 v4.18.28**(md5 22ca46f7 双侧一致) | ✅ 无魔改 |
| 3 | 其余 shell 文件 | BootHook.dll/BootMain.exe/conout/全部 bat = 官方 zip 逐字节一致;loadNapCat.js 唯一 DIFF=launcher 每次启动按本机路径重新生成(设计使然,非魔改) | ✅ 无魔改 |
| 4 | 启动路径 | start-tongling.ps1 硬编码 D: 便携 QQ 路径 | 稳定线要改成自动发现 |
| 5 | 注册表劫持 | QQ 卸载项 UninstallString 指到 D:\...\OneKey\...\Uninstall.exe——launcher.bat 的注册表探测被顺带接管 | ✅ 实锤,系统级硬改 |
**终审结论**:在役 shell = **官方 v4.18.28 原封不动**;"硬改"实为三处壳外活:①qqnt.json 手工钉版(BootHook DLL 吃)②注册表劫持 ③启动脚本路径硬编码。**稳定线方案**:魔改 launcher 自动探测已装 QQ→读真实 `versions/*/resources/app/package.json`→自动生成 qqnt.json→注入,全程零手工。
## 四、新规格(师父令,2026-11-11 累加)
14. **稳定性工程线**:QQ 连接稳定线——保活、掉线重连、心跳;发言稳定线——参考本地运行时素材
(dsh 现役会话节奏/语言学规则/去模板化六条),更像真人、模拟稳定;账号稳定线——防风控节奏、
掉线自愈。全面写进 SnowCat。
15. **UI 全面改造**:前端后端全面改造,不止名字,排版/样式/主题全按我们审美来(雪青主色系)。
1. **基座**:NapCat v4.18.28 源码(已克隆 `<local-src>`,tag 对齐在役版)
2. **移植**:SnowLuma 独门动作 → NapCat(qzone 全家桶 16 动作、闪照文件管理 5 件、收藏列表、
资料点赞、单条转发×2、群相册、自定义表情管理、URL 安全检测等, quarry=`<local-src>` v2.2.1)
3. **稳定线(零硬改)**:
- 自动识别系统已装 QQ(注册表 + 常见路径),有 → 直接注入
- 无 → 自动检测并下载安装(OneKey 模式内置化)
- 自动读实际 `versions/*/resources/app/package.json` 取版本号,废掉手工 qqnt.json 钉版本
4. **解包器**:支持解包各版本 QQ 客户端(含最新版)安装包 → 便携结构
5. **命名**:两客户端融合体(NapCat+SnowLuma),要有专属名
6. **持续更新**:fork 结构可跟上游 NapCat 更新线,patch 层清晰可重放
7. **验收**:build:shell → 本地 boot 测试 → 热换在役 → dsh-channel-qq 能力矩阵更新
## 五、SnowLuma 考古结论(移植路线图依据)
**致谢与维护关系**:SnowCat = NapCat(底座,上游 NapNeko/NapCatQQ)+ SnowLuma(能力采石场,上游 SnowLuma/SnowLuma)融合体。**感谢两个上游仓库**;此后 SnowCat 由我们维护——不为跟官方对着干,而为社区真需要(自有 AI 生态接入:dsh/陪伴型等)。维护可自改,及时更新。
**关键发现**:SnowLuma 独门动作分两条线——
**Web 线(cookie 撑腰,HTTP 打腾讯网页接口)** `packages/protocol/src/web/`:
- `qzone.ts` 个人空间说说全家桶(读资料/改资料/发说说/评论/回复/点赞/拉黑/删说/权限/传图)
- `qzone-public.ts` 公共空间(feeds/详情/评论/回复/点赞/跟赞/关注/转发)
- `group-album.ts` 群相册、`group-essence.ts` 精华、`group-honor.ts` 荣誉、`group-notice.ts` 群公告、`group-signin.ts` 打卡
- `collection.ts` 收藏、`friend-dress.rs` 装扮
- 入口:`getCookies('qzone.qq.com')` 拿凭证 → request-util 发 HTTP
**原生线(OIDB 包 + NTQQ 内部)** `packages/protocol/src/`:
- `oidb-service.ts + oidb-services/`(OIDB 协议打包)、`highway`(大文件)、`dataline`、`msg-push`
- `core/bridge/apis/`: flash-transfer(闪照文件管理)、forward(单条转发)、system-face(自定义表情)、interaction(戳/回应)
**事件侧**:`event-bus.ts + events.ts + msg-push/`——"更多事件回调"的 quarry 在这。
**移植含义**:Web 线基本是自包含 TS(cookie + HTTP),NapCat 侧有自己的 cookie 管道(get_cookies/get_credentials/get_csrf_token),移植成本低;原生线要对 NapCat 的 NTAPI 包装层重接线。
## 六、师父令累加(2026-11-11 续)
8. **便携版 QQ 制作器**:官网最新包下载→一键解码→便携化;已装 QQ→一键便携化
9. **全线开源**:融合客户端 + 改造过的便携版 QQ 都开源,用户拉取即用、一键修改
10. **一键化**:无 QQ→检测→自动下载安装;有 QQ→直接注入
11. **事件增强**:解包 QQ 时挖出更多事件回调(SnowLuma event-bus + NapCat 事件层双源合并)
12. **试最新版**:当下就去官网拉最新 QQ 包验解码链路
13. **开源发布文**:全部做完后随开源发一篇回怼文(素材已汇编 `SnowCat_开源发布文_素材.md`)——
本地运行时零外发全开源可查;官方=工作流路线 vs SnowCat=个人开发者娱乐路线,两赛道不抢生意;
骂跳脸官方传谣言的小鬼;稳定党分流去官方机器人
## 七、材料清单
- **SnowCat 工作源码(主战场)**: `<local-workdir>`(v4.18.28 tarball 解包+魔改)
- NapCat 上游跟踪线: `<local-src>`(README/Ending 实录/章程文档都在这)
- SnowLuma 采石场: `<local-src>`(v2.2.1)
- **SnowCat 工具件(工作源码根)**:
- `snowcat-launch.ps1` 零硬改启动器(QQ自动发现→实况版本→自动qqnt→注入)
- `snowcat-portable-maker.ps1` 便携制作器(官网直链解码/已装便携化)
- `packages/napcat-onebot/stable-line.ts` 稳定线(连接退避+真人抖动+预算+熔断)
- 在役运行时: `<local-runtime>/`
- 便携 QQ: `<portable-qq-dir>`
- dsh 插件侧: `C:/dsh/dsh-channel-qq/src/client-compat.ts`(已适配 snowcat/雪猫 识别)
## 八、移植战果(2026-11-11 全绿)
| 批 | 内容 | 状态 |
|---|---|---|
| 一 | qzone 个人空间 10 动作(data/qzone-web.ts ≈900行纯数据层 + WebApi 11方法) | ✅ typecheck 绿 |
| 二 | qzone 公共空间(空友)14 动作(apis/qzone-public-web.ts http2rpc 全函数 + 14动作类) | ✅ typecheck 绿 |
| 三 | 群相册2 + 表情回应查询 + 装扮 + sysface 占位(batch3.ts,NT 现役 service 复用;OIDB 编解码级 todo/tags/reaction 留独立批次) | ✅ typecheck 绿 |
| 品牌 | WebUI 37 文件 130 处 SnowCat + 雪青主题 + 后端 2FA + 手绘雪猫 logo + GetVersionInfo 自报 SnowCat.Onebot + dsh 识别适配 | ✅ 全绿 |
| 稳定线 | stable-line.ts:重连指数退避 / 真人抖动(深夜×1.8)/ 小时预算 120 / 连发 8 条熔断 90s,接入 send_group/send_private/send_msg 三入口 | ✅ typecheck 绿 |
| 工具 | snowcat-launch.ps1(QQ发现+实况版本 9.9.35-52892 验证+qqnt 自动生成实弹过)/ snowcat-portable-maker.ps1 | ✅ 干跑绿 |
## 九、9.9.37 解包与未接能力考古(2026-11-12)
**官方最新包实弹**:QQ_9.9.37_261103_x64_01.exe(334442672B,build 54395)。
- 官网直链(pcConfig.json → qqdl.gtimg.cn QQNTV2)对脚本流量全 403(curl/UA 伪装/真 Chrome 直开都拒),**唯官网页内真点击可下**(CDP 触发 Chrome 下载器成功,~15 分钟 319MB)。
- 7z 直解(PE 自解压,Files\ 结构)→ 1975 文件/1.24GB → OneKey 兼容便携 `SnowCat.9.9.37-54395.Shell`。
- **snowcat-qq-unpack.ps1 成件**:-Installer 本地包 / -FromOfficial 全自动(pcConfig 抓链+下载+7z+组装+配方档案);9.9.37 实弹全绿。
- 启动器发现段对 9.9.37 验证:version=9.9.37-54395 build=54395 正确读出。
**wrapper.node 服务面差集(76 服务 vs 我们已接 62 文件)**:
未接 19 个 = AIService(QQ 内置 AI:subscribeTask 4API/agent 预热/attach 消息 11 API 已挖到名单)、Guild 三件(频道域)、VasGroup/VasClub(装扮会员)、BatchTransfer/BatchUpload、RemoteFile/RemoteStream、ApiSix、BizKit、GroupSchool(群课堂)、PYMK(可能认识)、FileAutoDownload、GProGuildMsg、YellowFaceForManager、TestPerformance。
**事件层**:已接 163 回调 ≈ 上游 NapCat 4.18.28 等量;9.9.37 新 kernel 回调需 runtime 挖(静态符号不带 listener 类前缀)。
**热换**:MCP+UI 全链 bundle(3253540B)+ salt 兼容前端已进 `<local-runtime>/`,现役 QQ 不重启不中断,下次启动生效。token 盐 '.napcat' 保留(前后端一致+现役兼容)。
## 十、9.9.37 植入攻坚终审(2026-11-12 深夜役)
**全注入面封堵实测**(全部实弹):
1. package.json main 弃用:launcher 硬编码 asar\app_launcher\index.js(内存抓拼接串实锤)
2. 完整性校验:改 package.json main(旧 DLL hook)→「文件已损坏」弹窗
3. 应用目录 DLL 白名单:winmm 代理(纯 forwarder 180 导出,PE 手术健康 pefile 验证+notepad 远程加载成功)→ QQ 加载即死(1-2 进程)
4. 运行期远程线程注入:模块表能挂但 DllMain 不执行(mini DLL 四连测:文件标记/MessageBox 全无),远程调导出函数直接崩 QQ(0xC0000229)——**运行期代码执行被拦**(无 CIG/ACG 位,疑似 VMProtect 类壳内自检)
5. NODE_OPTIONS/ELECTRON_RUN_AS_NODE 环境变量:launcher 吞掉
**唯一实证有效的 hook 窗口**:pipe 版 BootHook 在 CREATE_SUSPENDED 挂起态注入——hook CreateFileW+GetFileInformationByName 能过完整性校验、假 package.json 能进内存;但 9.9.37 弃 main 后 hook 点失效。
**结论**:9.9.37-54395 当前无社区可用注入路径(上游 issue #2163 同病)。可行方向:
- 短期:钉 9.9.35-52892(现役方案,稳定运行)
- 中期:等 TomyJan/SnowLuma 或社区新 hook 点(盯 4.18.42 后续 fork 动态)
- 长期:雪猫自持(dsh 生态接 MCP 服务器线已通,不依赖 QQ 注入方式)
## 十一、9.9.37 攻坚成功定谳(2026-11-12 05:29 · V8 通道)
**突破时刻**:SnowCat napcat 在 QQ 9.9.37-54395 主进程内全功能运行,测试智能体(TongLing,我们生态的在役智能体)经反向 WS 8082 接入 dsh,WebUI 6099 在线,日志『测试智能体(TongLing,我们生态的在役智能体) |』活跃。
**成功路线(另一 Agent 的 V8 通道,<local-portable>/tools/build/)**:
1. **winmm-v8.dll**(zig cc 编 C,MinHook 挂 QQNT.dll 导出的 v8::ScriptCompiler::Compile*):QQ 静态导入 WINMM → 应用目录侧加载 → 在解密后 JS **编译前一刻**截获明文
2. 命中 app_launcher/index.js → 把 V8 Source::source_string_ 换成 **引导脚本+原文**(snowcat-boot.js 动态 import napcat.mjs)
3. napcat.mjs 在 QQ 主进程内正常 import("napcat imported ok")
4. 附带修复:resources\app 里 dbghelp.dll/dbgeng.dll 是坏的(致 LightQuic/broadcast_ipc 加载 193 → wrapper.node 无法 dlopen)→ 禁用改走系统版本
5. snowcat-run.ps1 一键启动器(部署+启动+45s 健康检查+nc-boot.log 注入日志)
**为什么这条路能通而其它全死**:
- 不碰 package.json/main(弃用+校验)
- 不碰 asar 本体(签名表)
- 不 hook 文件 API(QQ 读取走 NT 层)——**直接 hook JS 编译器**,解密后明文必经之路
- winmm 侧加载在 9.9.37 可行(之前失败的 winmm 代理是 DllMain 植入逻辑有缺陷,V8 版精简且 MinHook 正确处理指令边界)
**失败路全档(四大注入面+反射注入)**:见第十节。其中反射注入(snowcat-reflect2.exe,rva2off 修复版)在 dummy.exe 上全通过——QQ 内 LoadLibrary 被拦(0xC000007B)但反射映射可入、DllMain shellcode 可执行(hook-trace.txt 证明 hook 全程生效),只是 QQ 进程内还有更深检测点杀进程。V8 通道不走这些弯路。
**验收数据**:
- QQ 4 进程,主进程 31944
- 8082 ESTABLISHED(napcat→dsh 反向 WS,token <REDACTED>)
- 6099 WebUI 200,SnowCat 雪猫控制台标题
- 日志『测试智能体(TongLing,我们生态的在役智能体) |』活跃(内核回调注册中,onGroupNotifies 系列无方法警告=9.9.37 新内核接口名差异,napcat 已容错)
**发布版物料**(tools/build/):
- winmm-v8.dll(171KB)+ snowcat-boot.js + snowcat-run.ps1 + static-dist/
- snowcat-qq-unpack.ps1(解包器)+ snowcat-hook.c/inject/reflect(研究物料)
+139
View File
@@ -0,0 +1,139 @@
# SnowCat 雪猫 · 从 P1 到 V8:一条注入通道的完整攻关实录
> 本文是 SnowCat 项目的技术制作文档,完整公开我们如何在一夜之间,从「最新版 QQ 无法注入」走到「V8 编译器通道全功能运行」。所有方法、所有失败、所有工具,全部摊开。
## 0. 背景
QQ NT 客户端(QQNT)持续强化反第三方客户端措施。上游 NapCat 于 2026-11-10 发布最后一次提交「Ending」,SnowLuma 仓库同日 404。SnowCat 接棒立项,第一场硬仗就是:**适配官方最新版 QQ 9.9.37-54395**——一个为封锁第三方客户端而特别强化的版本。
## 1. 敌情侦察:9.9.37 的防护体系
拿到官方安装包解包后,我们逐层实测确认了五道防线:
| # | 防线 | 实测结果 |
|---|------|----------|
| 1 | `package.json` 的 `main` 字段弃用 | launcher 硬编码加载 `asar/app_launcher/index.js`(内存抓拼接串实锤),改 main 无效 |
| 2 | 文件完整性校验 | `application.json` 内 RSA-2048 签名表覆盖 4 个关键文件(application.asar / major.node / package.json / wrapper.node),任何改动触发「文件已损坏」弹窗 |
| 3 | 应用目录 DLL 白名单 | winmm / dbghelp 等系统 DLL 代理(哪怕 PE 手术后完全健康)放进应用目录,QQ 加载即死(1~2 进程闪退) |
| 4 | 运行期代码注入拦截 | 远程线程注入:模块表能挂上,但 DllMain 永不执行;远程直接调导出函数 → QQ 进程自杀(0xC0000229)。无 CIG/ACG 标志位,疑似 VMProtect 类壳内自检 |
| 5 | 环境变量过滤 | `NODE_OPTIONS` / `ELECTRON_RUN_AS_NODE` 等全部被 launcher 吞掉 |
**另有一个环境坑**:`resources/app` 自带的 `dbghelp.dll` / `dbgeng.dll` 是坏的(加载报 193),连锁导致 LightQuic.dll、broadcast_ipc.dll 加载失败,进而 `wrapper.node` 无法 dlopen。禁用它们改走系统版本即可修复。
## 2. 全部死路(失败档案,同样值钱)
### 2.1 hook 文件 API——死
我们在 QQ 运行中 trace 用户态文件 API(CreateFileW / NtCreateFile):**QQ 读取自身资源根本不走这些路径**。所有基于 hook 文件读取来篡改 asar / package.json 的方案(社区常用的 CreateFileW 重定向到补丁文件)在 9.9.37 全部落空。
### 2.2 纯 forwarder 代理 DLL——死
用 python 做 PE 手术,生成 dbghelp / winmm 的纯 forwarder 代理(`dbghelp-real.FuncName` 全量转发),pefile 校验健康、notepad 远程加载成功——但 QQ 的白名单检测直接杀进程。**DLL 本身没问题,问题是「应用目录里不该有这个 DLL」这件事本身。**
### 2.3 zig 编译的 DLL——死(工具链问题)
zig 0.17 编译的 DLL 入口点是一个 `return -1` 空壳(`55 48 89 e5 b8 01 00 00 00 5d c3`),`std` 的 start 链条断掉,**DllMain 永远不会被调用**。多轮尝试(export fn DllMain、-fentry、DllMainCRTStartup)均告失败。结论:写 Windows 注入 DLL 请用 MSVC 或 `zig cc` 编 C,不要用 zig 原生编译 DLL。
### 2.4 反射式 DLL 注入——半死
自写注入器(修了三个 bug:RVA 误当文件偏移需要 `rva2off()` 节表转换、dllName RVA 误用、thunk 循环无上限)在 dummy.exe 上全部通过;QQ 里反射映射能进、shellcode 能跑、hook 全程生效——但 QQ 进程内还有更深的检测点,最终杀进程。此路文档保留(`tools/build/snowcat-reflect.c`),供研究。
### 2.5 挂起态注入旧 hook——失效
pipe 版 BootHook 在 CREATE_SUSPENDED 挂起态注入、hook CreateFileW 能过完整性校验——但这是给「main 入口」时代的方案,9.9.37 弃用 main 后 hook 点失效。
## 3. 顿悟点:换战场
所有死路共享一个假设:**在 QQ 读文件 / 加载模块的路径上动手**。而 QQ 的读取不走用户态文件 API、模块加载有白名单、运行期注入有自检。
那么——**有没有一条路,是 QQ 自己必须走、且无法白名单化的?**
有。JS 编译。QQNT 的 app_launcher/index.js 是加密存储、运行时解密的,解密后的明文 JS 必须交给 V8 编译执行。**hook 文件,QQ 绕得开;hook V8 编译器,明文必经之路,绕不开。**
## 4. V8 通道(最终方案)
### 4.1 三件套
```
winmm.dll(侧加载代理)
└─ DllMain 里 MinHook 挂 QQNT.dll 导出的 v8::ScriptCompiler::Compile*
└─ 每次 JS 编译时检查源码:命中 app_launcher/index.js 特征?
└─ 把 V8 Source 的 source_string_ 换成「引导脚本 + 原文」
└─ 引导脚本 import napcat.mjs → SnowCat 全功能启动
```
- **为什么 winmm 能进**:QQ.exe 静态导入 WINMM.dll,而 WINMM 不在 KnownDLLs 里 → 系统 loader 按搜索顺序找到应用目录的同名代理,**这是 loader 的合法加载,不触发注入检测**。之前失败的 winmm 代理败在 DllMain 植入逻辑有缺陷;V8 版精简了 DllMain,只做 MinHook 安装。
- **为什么 MinHook 可靠**:正确处理指令边界重定位(我们手写 trampoline 的版本会崩在非对齐指令上)。
- **特征码**:QQNT.dll 导出的 `v8::ScriptCompiler::Compile*` 直接按导出名 GetProcAddress,无需特征码扫描(QQNTPatcher 式特征码 `48 89 CE 48 8B 11 ...` 是备选方案)。
### 4.2 引导脚本
```js
// snowcat-boot.js:被注入到 app_launcher/index.js 开头
// 原理:动态 import 同目录 napcat.mjs(SnowCat 单文件 bundle)
import(process.env.NAPCAT_MAIN_PATH ?? new URL('./napcat.mjs', import.meta.url).href);
```
原文完整保留在后面执行,QQ 功能零损伤。
### 4.3 一键启动器(snowcat-run.ps1)
部署三件(winmm 代理 DLL / boot 脚本 / WebUI 静态资源)→ 修坏 DLL → 启动 QQ → 45 秒健康检查(6099 WebUI 200 即成功)→ 输出注入日志。
### 4.4 实测验收
- QQ 4 进程,napcat 在主进程内 `imported ok`
- OneBot 反向 WebSocket 连接大沙盒端 ESTABLISHED
- WebUI 6099 在线,全部页面正常
- 日志内智能体消息收发活跃
## 5. 内核接口适配(9.9.37 差异)
注入成功后发现 6 个内核 listener 回调改名(Proxy 层容错打 `has no method` debug 日志,**事件实际在丢**):
| 9.9.37 新名 | 映射到 |
|---|---|
| onGroupAllInfoListChange | onGroupAllInfoChange |
| onGroupDetailInfoListChange | onGroupDetailInfoChange |
| onGroupNotifiesUpdatedV2 | onGroupNotifiesUpdated |
| onGroupNotifiesUnreadCountUpdatedV2 | onGroupNotifiesUnreadCountUpdated |
| onGroupAIOSlotInfoChange | (空实现) |
| onNtMsgSyncContactUnread | onNtMsgSyncEnd |
TypeScript 细节坑:旧方法是具名参数签名,`this.oldFn(...args)` 报 TS2556,需 `(this.oldFn as (...a:unknown[]) => unknown)(..._args)`。
PacketBackend 报「不支持当前QQ版本架构」= `napi2native.json` 偏移表缺新版本条目。表格式为 `{ "9.9.37-54395-x64": { "send": "C5927F", "recv": "24CC2B5" } }`——QQNT.dll 内 send/recv 函数的十六进制偏移,可用 IDA / x64dbg 在目标版本 QQNT.dll 中定位 `SSO` 收发函数补表。
## 6. 解包器(snowcat-qq-unpack.ps1)
- `-Installer <path>`:本地官方安装包 → 7z 直解 PE 自解压(Files\ 结构)→ 组装 OneKey 兼容便携目录
- `-FromOfficial`:全自动——抓官网 pcConfig.json 解出 qqdl.gtimg.cn 直链 → 下载 → 解包 → 组装 → 生成配方档案
- 官网直链对脚本流量全 403(curl / UA 伪装 / 无头浏览器都拒),**唯官网页内真实点击可下**——脚本内已内置说明;最省事的路径是用浏览器手动下载后走 `-Installer`。
## 7. 运行时栈(现在的形态)
```
QQ 9.9.37-54395 x64(官方原版,一字节未动)
└─ winmm.dll(V8 通道代理)
└─ QQ 主进程内:napcat.mjs(3.25MB 单文件 Vite bundle,inlineDynamicImports)
├─ OneBot v11:反向 WS 接大沙盒 / HTTP / MCP(Streamable HTTP /mcp)
├─ WebUI:React + Tailwind + HeroUI(6099)
└─ Packet 发包:napi2native + MoeHoo(offset 表驱动)
```
## 8. 工具清单(tools/ 全部开源)
| 文件 | 用途 |
|---|---|
| snowcat-qq-unpack.ps1 | 官方 QQ 安装包解包器(-Installer / -FromOfficial) |
| snowcat-launch.ps1 | 零硬改启动器(自动发现已装 QQ → 实况版本 → 自动 qqnt → 注入) |
| snowcat-portable-maker.ps1 | 便携制作器(官网直链 / 已装便携化) |
| snowcat-run.ps1 | 9.9.37 V8 通道一键启动器 |
| winmm-v8.c / winmm-v8.dll | V8 通道本体(源码 + 编译成品) |
| snowcat-boot.js | 引导脚本 |
| snowcat-hook.c / snowcat-inject.c / snowcat-reflect.c | 研究物料(观测 hook / 注入器 / 反射注入器) |
| webui-static/ | WebUI 前端成品 |
## 9. 给后来者
1. **hook 编译器,别 hook 文件**。文件层防线只会越来越厚,V8/JS 引擎层是解密明文的必经之路。
2. **失败路同样值钱**。本文第 2 节的每一条死路都花了真金白银的时间,公开它们让后来者不用重付学费。
3. **单一文件 bundle 是刚需**。Electron 内嵌 Node 的模块解析对相对导入分块包不友好,`vite build --inlineDynamicImports` 出单文件是最稳形态。
4. **白盒立身**。所有改动可查、所有失败可考、所有偏移有表。这就是我们敢公开全部技术的原因。
——SnowCat 开发组
+162
View File
@@ -0,0 +1,162 @@
# SnowCat 雪猫 · 开源发布文(草稿素材汇编)
> 立档 2026-11-11 · 师父口述立场,多段原话全录,终稿整合时逐段落位 · 补入审计硬数据
## 一、为什么开源(发布文主旨段)
SnowCat 全线开源,持续更新。第三方客户端,运行时全部在本地——没有任何外发,
外发的都是 QQ 自身关联的请求;接收也全在本地执行。所有动作都在本地,
代码全开源可查。有问题?来干。不服来干。
## 二、回怼「抢官方生意」论(原文立场)
有人说第三方客户端抢了官方的生意。并没有。官方走的路线和我们的路线,
本质就是不同的:
- **官方机器人**:偏向工作流、企业场景,走的是官方的路径。
- **SnowCat 第三方客户端**:属于个人开发者,偏向娱乐性。
两条路,两个物种。说抢生意,是没看清这是两个赛道。
## 三、骂小鬼段(发布文的重炮)
为什么写这篇文章骂那些小鬼?因为有好东西,他们跳脸官方。
谣言包括但不限于:
- 「第三方客户端抢了官方生意」——没有。路线本质不同,官方偏工作流,我们偏娱乐性,不构成竞争。
- 「官方觉得自己被挡路了」——并没有挡路。这是**社区共享**,社区个人开发者的共享。
- 「第三方客户端影响账号数据安全」——运行时全在本地,无任何外发,代码全开源可查。安全不安全,代码替我们说话。
- 「第三方客户端一棒子打死」——不能一棒子打死。有弊有利,第三方客户端和官方机器人本质就是不同的东西。
**给追求者的分流指南**(发布文实用户型):
- 追求极致稳定 → 用官方机器人。官方路径本来就是为工作流铺的。
- 追求更好的隐私安全、追求更强的能力 → 第三方客户端。代码开源,自己查。
- 觉得不稳定、觉得不好 → 去用官方机器人去。没人拦着。
- 那些小鬼乱传谣言 → 反正得教训教训。
## 三点五、赛道再澄清 + 账号安全实话(师父补段,原话全录)
再说一遍,说什么第三方客户端抢了官方的生意——并没有。官方走的路线和我们的路线本质就是不同的。
我们是接入 SnowCat 的(自有 AI 接入自有客户端),主要偏向娱乐性,社区自娱自乐。
- **我们不改官方工作流的道**:官方机器人的路径是工作流,我们的路径是娱乐性,两个物种。
- **社区共享**:这就是社区共享资源而已,个人开发者的共享,不构成竞争。
- **账号安全的实话**:第三方客户端保证不了账号安全,这是事实,我们不装。
但是我们是代码可查的——每一行都开源,风险在哪、干了什么,自己看代码。
相比黑箱,可查就是能给出的最大诚实。
- **给官方指路**:如果官方也想走娱乐性项目——行,路就在那,社区已经趟出来了,
来看代码就是。我们是社区白盒,欢迎任何一方来查、来学、来合作。
官方觉得被挡路?没有的事,路是两股道,娱乐性这条道官方随时可以走。
- **共赢,不是打压**:官方应该跟社区共赢,而不是打压社区。社区养活了生态,
反哺了活力,堵不如疏,打压只会把人推远。白盒摆在这,共赢的门是开着的。
- **不想自己配?可以**:直接用成套的,去用官方的,官方配置好的,都可以,不拦你们。
我们这边是研究自己技术、锻炼自己技术——研究只是技术强化而已。
一个求省事走现成,一个求成长自己动手,各走各道,都是好选择。
- **技术是公开课**:用官方的可以,想用我们的也行,互不干扰。官方该跟社区共赢,
而不是打压社区。我们把技术全公开——代码全开源,想学技术的都能学,这是给整个
社区的公开课,不是圈地的围墙。
- **致谢上游 + 维护宣言**:感谢 NapCat 与 SnowLuma 上游仓库——SnowCat 站在两个
优秀开源项目的肩膀上。此后就是我们维护的东西、我们要搞的东西了。我们主要的
接入方向是自有的:dsh 自有搭建好的、陪伴型的等等那些。此后我们来维护——
不是跟着官方对着干,而是社区真的需要这种东西。维护可以自己改,我们也会
及时更新维护的。
- **接入定位**:SnowCat 的主战场是自有 AI 生态接入——dsh、陪伴型数字生命、
自建工作台,都从这里走 OneBot 进 QQ。这是官方机器人给不了的形态。
- **官方也走陪伴型?慢慢走,互不干涉**:如果官方也要走陪伴型方向——好,
他们慢慢走,我们互不干涉。我们只是自娱自乐,不挡任何人的道,
也不追任何人的尾。两股道上的车,各开各的。
- **给官方的三个问题(后面这段全是给官方指路)**:
1. 官方的陪伴型,能接入开发者自家的生态吗?开发者自己搞自己的 agent,
接得进官方的陪伴型吗?
2. 接进来效果是什么样的?工作流效果,还是真的陪伴效果?
3. 如果答案是「接不进」或者「只能走官方预定的工作流」——那这就是我们
存在的意义。SnowCat 的形态是开发者的 agent 直接走 OneBot 进 QQ,
接的是开发者自己的生态,跑的是开发者自己定的效果。
4. **人格不该是统一的**:每个人需要的数字生命、陪伴型人格,都不一定是一样的。
官方给的是千人一面的标准件,社区要的是一人千面的自由度。
5. **自建平台的人呢**:有些人是搭建自己平台的——他们能把这些平台接进来吗?
SnowCat 答能:你的 agent、你的平台、你的后端,走 OneBot 桥过来就行,
桥是白盒的,接法全公开。
官方想清楚了这几个问题,就知道我们不是对手,是先趟路的。
## 三点八、上游现状核实与「为什么我们还敢开源」(2026-11-11 实测)
**上游现状(GitHub API 实测,不靠传闻)**:
| 上游 | 现状 | 实测数据 |
|---|---|---|
| NapNeko/NapCatQQ | **官宣 Ending(2026-11-10 最后一笔 commit)** | 最后推送 `docs: ending`,README 新增 Ending 节:「如果感兴趣可以自行Fork,不再提供除版本更新以外内容,直到失效,如果追求稳定性更推荐官方Bot,非常感谢一路陪伴。」12640 stars |
| SnowLuma(原 SnowLuma/SnowLuma) | **已 404(删库或转私)** | 原 `SnowLuma/SnowLuma` 仓库 API 直接 404;NapCat README 里原本推荐它的那节也同日被删 |
| TomyJan/SnowLuma(社区继任) | 活跃但换主 | 最后推送 2026-11-07(v2.4.2),283 stars,**NOASSERTION 许可证**(自定义条款,商用需谨慎) |
我们克隆采石场时拿的是 v2.2.1(继任库已到 v2.4.2)。
**上游最后一句话,就是我们的第一句话。**
NapCat 说:「如果感兴趣可以自行 Fork,不再提供除版本更新以外内容,直到失效。」
SnowLuma 说:连仓库都没有了(404)。
**为什么某 S(SnowCat)还敢开源维护?为什么?——因为接力棒就掉在地上。**
1. **Fork 不是僭越,是 NapCat 本人的遗愿**:上游亲口说「可以自行 Fork」。
SnowCat 就是这个 Fork——我们不偷不抢,我们捡起来的是上游亲手放下的接力棒。
2. **「直到失效」四个字,就是我们存在的理由**:NapCat 只维护到失效为止。
那,失效之后呢?QQ 9.9.x 还在发新版本,社区的数字生命还在跑,
谁来续?SnowCat 答:我们来。
3. **官方 Bot 确实稳,NapCat 也这么劝**——我们一字不改地同意,并且同样写进
自己的 README:追求极致稳定请用官方 Bot。但官方 Bot 是工作流形态,
自有 AI 生态(dsh/陪伴型)接不进去,这条道只有第三方客户端能走。
4. **白盒 + 自持**:一个闭源了(原库 404),一个进入倒计时(「直到失效」)。
上游在,我们跟;上游没了,我们扛。SnowCat 不是下游,是自持主干。
5. **不是跟官方对着干**(预答所有质疑,逐条拆):
- 「你们跟官方抢生意?」——不。官方=工作流路线,SnowCat=自有 AI 接入+娱乐性,
自娱自乐,两个物种。
- 「你们抄袭?」——公开致谢上游(NapCat + SnowLuma),移植代码标明来源,
采石场里每一块石头都署名。抄袭是偷,我们是明媒正娶的 fork + 致谢 + 自持维护。
- 「上游都闭源/停更了,你们凭什么敢开源?」——正因为他们闭源/退场,才更需要
有人把可查的白盒续下去。社区需要的不是一家独大的黑箱,而是永远可查的选项。
- 「你们会跑路吗?」——我们自己的数字生命(dsh/陪伴型)就跑在这上面,
我们是深度用户,跑路等于自断手脚。
- 「账号安全?」——第三方客户端保证不了账号安全,这是事实,我们不装;
但代码白盒可查,风险自己看(三点五节原话)。
6. **给官方的话**:官方该跟社区共赢,不是打压。娱乐性这条道官方随时可以走,
路已经趟出来了,看代码就是。想学技术的,代码就是公开课。
7. **给 NapCat 和 SnowLuma 的话**:谢谢。猫谢猫,雪接雪。你们铺的路我们接着铺,
你们的 stars 我们记着(12640 和 283 的信任不会落空)。Ending 不是终点,
是 SnowCat 的起点。
## 三点九、骂挑脸的小鬼(重点段,师父原话全录)
跑去官方社区挑脸的那些人都得骂一下他们。
有好东西教你们用,有方法给你们用——你们拿去干什么?
拿去干那些不为人知的事情,拿去骗人,拿去搞灰产。
账号被封了与我们无关——封的是你,不是 SnowCat。
我们是开发者之间的自娱自乐,不是拿去骗人等等那些东西的。
**反挑脸三连**:
1. **工具无罪,使用有责**:SnowCat 是白盒工具,代码全公开。
你拿去骗人、拿去搞事,那是你的恶,不是工具的恶,更不是社区的恶。
2. **挑脸=断粮**:跑到官方社区挑脸,惹出来的风控是全体社区用户一起扛的。
你的嘴爽了,别人的账号买单。这种人不骂,天理不容。
3. **用我们的东西,守我们的规矩**:自娱自乐、本地运行、白盒可查——
这是 SnowCat 的三条底线。拿去骗人的,不配用,也请自己走开。
## 四、发布文骨架(终稿时展开)
1. **开门**:SnowCat 是什么——NapCat + SnowLuma 融合魔改的第三方 QQ 客户端,雪取 SnowLuma,猫取 NapCat。
2. **安全声明**(用第一节):本地运行时/零外发/全开源可查。
3. **赛道澄清**(用第二节):官方=工作流路线,SnowCat=个人开发者娱乐路线,不抢生意,是社区共享。
4. **重炮段**(用第三节):骂小鬼,逐条拆谣言。
5. **分流指南**:稳定党→官方;能力党/隐私党→SnowCat;不满意→官方机器人伺候。
6. **技术亮点**(写完补):56 个独门动作移植清单、稳定线自动识别 QQ、便携 QQ 制作器、
官方 v4.18.28 逐字节审计(napcat.mjs 无魔改,改动全部壳外可查)。
7. **开源仓库**:代码全公开,欢迎来查、来用、来干。
8. **收束段**(用三点五节):赛道再澄清(自娱自乐不抢道)+ 账号安全实话(保证不了,
但白盒可查)+ 给官方指路(娱乐性这条道官方随时可走)+ 共赢不是打压。
## 五、写文时机
等全部做完之后(移植完成+稳定线+便携制作器+事件增强+热换在役验收全绿),随开源一起发。