Files
wx-win-agent/README.md
T
rogee 13c31fc902
Build web service image / build (push) Successful in 1m53s
feat: add remote control plane and whitelist reads
2026-09-12 09:46:05 +08:00

102 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# WxAgent
WxAgent 使用 C#/.NET 8 独立实现微信 Windows 桌面端自动化能力。当前已完成 **M1 技术验证**、M2 会话/消息扩展切片、M3 监听和完整消息模型,并包含只读数据库 MVP。
## 项目结构
- `node-agent/`Windows 节点端,C#/.NET 8;包含 UIA、Win32、Desktop Agent、CLI、托盘和节点本地服务兼容层。
- `control-plane/`:远程中心控制面,Go;Go 测试与实现代码同目录。
- `tests/node-agent/`:节点端 .NET 测试及只读 SQL 离线检查。
- 远程控制面架构、部署、验证与限制见 [`docs/WxAgent-远程控制面架构与部署说明-v1.0.md`](docs/WxAgent-远程控制面架构与部署说明-v1.0.md)。
## 当前能力
- `doctor`:检测 Windows 会话、`Weixin.exe` 进程/版本/只读访问权限、微信窗口、关键 UIA 控件和数据库根目录。
- `inspect-ui`:通过 FlaUI.UIA3 导出脱敏 UI 树;名称和动态 AutomationId 只保留长度和短哈希。
- `session list/search/current/open`:列出可见会话、输出分类搜索结果和精确匹配、读取及切换当前会话。
- `chat send/read/history/listen/monitor`:仅以文件传输助手做默认验证,支持文本发送、可见及历史消息读取,并以 UIA 结构事件结合两秒低频轮询实时发现消息。
- `chat monitor`:逐行输出 `MessageEvent` JSON,使用有界语义指纹去重和受当前用户 ACL 保护的 checkpoint,支持 Host 重启后的短期续接;默认隐藏正文和引用内容。
- 消息模型覆盖文本、图片、文件、视频、语音、链接、引用和系统消息;公开监听 API 为 `IAsyncEnumerable<MessageEvent>`,可选回调逐个隔离异常。
- `chat reply-latest`:通过消息行实时边界右侧气泡定位执行引用回复;解析微信 `回复文本\n引用 <发送者> 的消息 : <原文>` 格式。
- `chat send-file/send-image`:使用剪贴板粘贴发送文件或真实图片数据,不打开文件选择框,并恢复常见文本、图片或文件剪贴板内容。
- `smoke`:执行 `doctor`、脱敏 UI 树导出,并向文件传输助手发送唯一 ASCII 标记后读回确认。
- 远程控制面支持节点注册、心跳、任务队列、`send-text` 以及受本地白名单保护的会话/联系人/消息只读任务;当前实现与部署方式见架构说明文档。
- 文本输入使用 UIA ValuePattern 直接设置并在发送前逐字校验,避免中文输入法组合态改变消息内容。
- `db scan`:以 `PROCESS_QUERY_INFORMATION | PROCESS_VM_READ` 扫描 WCDB 十六进制候选,只保存通过具体数据库 page 1 HMAC-SHA512 验证的密钥。
- `db query`:通过 SQLCipher 4 以文件系统 ReadOnly、私有缓存、无连接池和 `query_only` 读取 `sqlite_master` 元数据,并确认写操作被拒绝。
## 安全边界
允许读取本机 `Weixin.exe` 的已提交可读内存和本机加密数据库。禁止 DLL 注入、内存修改、数据库写入、协议破解、登录/验证码/风控绕过。候选密钥不会被输出;只有带 `--save` 的显式命令才会将已验证密钥原子保存到当前用户 LocalAppData,并应用当前用户 ACL。当前受控环境使用明文 hex key 存储,尚未引入 DPAPI。
没有进程句柄到数据库文件路径关联时,`PageHmacVerified` 仅证明密钥属于具体数据库,不表示账号当前活跃。
## 构建
```bash
export PATH="$HOME/.dotnet:$PATH"
dotnet restore WxAgent.sln -p:EnableWindowsTargeting=true
dotnet test tests/node-agent/WxAgent.Core.Tests -c Release
dotnet build WxAgent.sln -c Release -p:EnableWindowsTargeting=true
dotnet publish node-agent/WxAgent.Host -c Release -r win-x64 --self-contained true \
-p:EnableWindowsTargeting=true -p:PublishSingleFile=true \
-p:IncludeNativeLibrariesForSelfExtract=true -p:PublishTrimmed=false
```
## CLI
```powershell
WxAgent.Host doctor
WxAgent.Host inspect-ui --output artifacts/ui-tree.json
WxAgent.Host smoke --timeout 45
WxAgent.Host chat send --text "hello"
WxAgent.Host session list
WxAgent.Host session search --query "文件传输助手" --exact
WxAgent.Host session current
WxAgent.Host session open --name "文件传输助手"
WxAgent.Host chat read --limit 20
WxAgent.Host chat read --limit 20 --include-content
WxAgent.Host chat history --limit 100 --scrolls 10
WxAgent.Host chat reply-latest --text "quoted reply"
WxAgent.Host chat send-file --path C:\path\file.txt
WxAgent.Host chat send-image --path C:\path\image.png
WxAgent.Host chat listen --seconds 30
WxAgent.Host chat monitor --seconds 60 --state-file artifacts\listener-state.json
WxAgent.Host db scan --timeout 120
WxAgent.Host db scan --save --timeout 120
WxAgent.Host db status
WxAgent.Host db query --account <account-root-fingerprint> --database contact/contact.db
WxAgent.Host db contacts --account <account-root-fingerprint> --limit 200 --offset 0
WxAgent.Host db contacts --account <account-root-fingerprint> --contains "搜索文本" --limit 200 --offset 200
```
默认密钥文件:`%LOCALAPPDATA%\WxAgent\database-keys.json`。CLI 和日志不会打印完整密钥。
`db contacts` 按 username 排序,`--contains` 为区分大小写的字面量子串,不把 `%``_` 当通配符。根据 `hasMore/nextOffset` 继续读取,下一页须保持相同账号和筛选条件;默认隐藏昵称、备注及头像地址,标识符脱敏。跨页不是事务快照,读取期间发生联系人增删时可能重复或遗漏。
公共 C# 分页入口为 `WechatChatClient.GetContactsPageAsync(limit, offset, contains, groupsOnly, accountId, keyFile, cancellationToken)``groupsOnly: true` 读取数据库已知群,`false` 读取非群联系人,`null` 读取全部。多账号必须明确选择,不推断哪个账号当前已登录。`GetFriendsAsync` 是有数量上限的兼容接口;完整读取使用分页入口。群成员通过 `chat_room``chatroom_member``contact` 的只读 join 读取,不回退 UI 枚举;原生 URL 卡片通过微信内置浏览器的“更多 → 转发…”发送,`chat send-url-card` 不需要 `--confirm`。其余管理操作必须检查 `Success/Code`;只有明确返回 `ResultUnconfirmed` 时才表示未完成确认、禁止自动重试。剩余限制见 [PENDING](docs/PENDING.md)。
## Windows 真机验证
目标主机:`10.1.1.101`,用户 `rogee`,微信 `C:\Program Files\Tencent\Weixin\Weixin.exe`。UIA 命令必须在微信所在的已登录、未锁定交互会话中运行;SSH Session 0 只能用于部署和非 UI 数据库命令。
```bash
scp -r node-agent/WxAgent.Host/bin/Release/net8.0-windows10.0.19041.0/win-x64/publish/* \
rogee@10.1.1.101:'C:/Users/Rogee/wx-agent/'
```
发布后至少运行:
```powershell
WxAgent.Host doctor
WxAgent.Host inspect-ui --output artifacts/ui-tree.json
WxAgent.Host smoke
WxAgent.Host db scan --save --timeout 180
WxAgent.Host db status
WxAgent.Host db query --account <fingerprint> --database <relative-db-path>
```
M1 已完成文件传输助手激活、文本发送/读回、新消息发现和微信重启后的重新连接验证。M2 扩展切片已完成会话搜索精确匹配、引用回复解析、历史滚动读取及去重;验收见 `docs/validation/M2-Search-Quote-History-2026-09-04.md`。M3 已完成实时监听、轮询兜底、完整消息类型、有界去重、回调隔离和 checkpoint 重启续接;验收见 `docs/validation/M3-Listening-2026-09-04.md`。重启后若微信要求手机确认登录,必须由用户正常确认;WxAgent 不绕过登录流程。
`SQLitePCLRaw.bundle_e_sqlcipher` 2.1.11 仅用于当前开发与真机验证。正式商业发布前必须完成许可与安全基线评审;若不能接受其已弃用状态、SQLCipher 4.5.2 community 和 SQLite 3.39.2,则切换 Zetetic 官方 SQLCipher for .NET 后重新执行全部数据库验收。