问下有没有用hermes或者openclaw的然后绑定微信的,如果想hermes主动推送内容到微信有什么好办法吗?

Yukimeepo 2026-08-01 22:24 1

微信自己的ilink令牌会失效而且时间很短要定时和hermes对话才行,有没有大佬知道有什么好的方案吗?

最新回复 (14)
  • TAXUEZJU 08-01 22:28
    1

    微信的问题,用别的方法吧

  • taffymeow 08-01 22:28
    2

    期待佬的研发然后开源 ^-^

  • Yukimeepo 楼主 08-01 22:29
    3

    @TAXUEZJU #1 确实是ilink的问题但是别的的话感觉没那么常用的app推送就没意义啊。

  • KEVI 08-01 22:30
    4

    有个 iPad 逆向的协议,有人卖,但应该自己都能逆向。微信 bot 接入的有太多问题了,消息发不稳定

  • Yukimeepo 楼主 08-01 22:30
    5

    @taffymeow #2 这个ilink的刷新只能主动对话,但是主动对话又不敢上脚本。

  • Yukimeepo 楼主 08-01 22:31
    6

    @KEVI #4 主动聊天这种没什么问题,但是推送就经常收不到了。逆向的话不太敢用吧

  • KEVI 08-01 22:42
    7

    @Yukimeepo #6 自用逆向应该还好,不要群发消息应该就好了,找个新的微信号玩。否则就要弄个 GUI 智能体了 ^-^ 可以让 GPT 看看怎么弄

  • Yukimeepo 楼主 08-01 23:02
    8

    @KEVI #7 好的好的

  • 韩天尊 08-01 23:06
    9

    我的 hermes 定时任务每天都能给我推送消息啊

  • Yukimeepo 楼主 08-01 23:08
    10

    @韩天尊 #9 说明你经常和hermes聊天了。所以你的令牌一直刷新。一段时间不聊的话获取不到新令牌就会推送失败了。

  • uixg 08-01 23:09
    11

    逆向微信,拿到密钥,直接读db

  • Yukimeepo 楼主 08-01 23:11
    12

    @uixg #11 ^-^ 有风险吗,感觉会封号封了就炸了

  • uixg 08-01 23:30
    13

    @Yukimeepo #12


    当然有风险,用别怕,怕别用


    找个mac mini之类的长期开机来做,不要用VPS


    我目前的方案:


    不接入微信的网络协议,也不依赖任何官方收发 API。直接读取微信在本地

    SQLCipher 加密消息数据库,再用游标增量轮询把新行交给上层处理。


    所谓"实时",本质是:以固定短间隔对已解密的本地库做基于游标的增量查询

    延迟 ≈ 轮询间隔 + 上层节流,而不是服务器推送。


    三层结构:


    [注入层]   进程内 dylib          —— 抓取 SQLCipher 主密钥(并可关闭防截屏)
    │ 注入进一份固定版本、已重签名的客户端

    [解密读取层] 只读解密器 + 读取脚本 —— 用密钥解密、跑只读 SQL、解码正文、反查发送者

    [桥接轮询层] follow 循环 —— 持游标循环 fetch(since=cursor),逐行吐 NDJSON
    │ 每个会话一个子进程

    [消费层] reader 适配器 + 房间循环 —— 解析 NDJSON、看门狗、持久化游标、退避重启

    事件与游标同事务落库 → 上层观察/直答流水线



    为什么是"读库"而不是"调 API"



    • 现代微信桌面端是 Qt/C++ 架构,消息落在加密的 SQLCipher 库里,

      没有可稳定 hook 的应用内消息层,也没有可用的收发接口。

    • 因此唯一稳的抓取点是:拿到 SQLCipher 主密钥 → 只读解密本地库 → 增量读新行

    • 主密钥由客户端启动时经系统的密钥派生函数(CCKeyDerivationPBKDF,来自

      CommonCrypto)生成;在这个系统符号上做拦截把密钥取出来 —— 相对跨版本稳定。




    逐层详解


    1. 注入层:拿到解密密钥


    在客户端进程内加载一个小 dylib,用 fishhook 重绑定系统的

    CCKeyDerivationPBKDF。这样每次客户端启动、派生 SQLCipher 主密钥时,

    就能在函数返回路径上把那把 32 字节密钥截获并落到一个本地临时位置,供读取层取用。


    注入方式是给客户端可执行文件追加一条 LC_LOAD_DYLIB 加载命令并重签名

    (自签 / Developer-ID),让 dylib 随进程启动自动加载。可选地再注入一个 dylib

    swizzle 掉窗口的防截屏属性,便于可视化/发送路径。


    工程前提:让 bot 运行一份被冻结、已打补丁并重签名的固定版本客户端,

    而不是会自动升级的那份。固定版本 = 抓取契约稳定,这是整套机制稳定性的第一来源。

    挂载、补丁完整性、进程存活、密钥可用性应由一个看门狗持续自检并可自愈。


    2. 解密读取层:只读解密 + 结构化输出


    解密器用捕获到的密钥以口令模式(sqlite3_key(),复刻客户端做法)打开

    SQLCipher 库,只执行单条只读 SQL。加固要点:



    • 三重只读强制:query_only PRAGMA + SQLite authorizer + sqlite3_stmt_readonly(),

      从根上杜绝任何写操作。

    • 数据库路径、密钥、SQL 都经长度前缀的 stdin 私有协议传入,不走命令行参数

      (避免密钥出现在 argv / 进程列表 / 诊断里)。

    • 错误只回固定错误码,不回显路径、密钥或 SQL

    • 客户端运行中可并发只读,无需退出客户端。


    读取脚本在其上做业务解码:定位所有数字消息分片、解码正文(明文或 zstd 压缩)、

    通过 id用户名映射表反查发送者、输出结构化行。常见消息类型:

    1=文本、3=图片、43=视频、47=表情、10000=系统。


    关于密钥派生的通用事实:主密钥 32 字节,PBKDF2-HMAC-SHA512,rounds=256000

    (SQLCipher 4 默认)。这些参数一旦被客户端改动,解密即失效(见末节)。


    3. 桥接轮询层:游标驱动的 follow


    工具自带的"跟随最新"命令每次启动都从最新消息开始,会漏消息。因此桥接层改成

    接受一个显式游标,由消费层持久化、重启后续读:


    loop:
    刷新分片列表(不重启即可拾取新生成的分片)
    fetch(since = cursor, forward_limit = N) # 只取游标之后的新行
    for row in rows:
    清洗/降级(见"健壮性")
    emit(row) # 一行一个 JSON
    cursor = max(cursor, row.local_id)
    emit({control: "poll"}) # 一轮结束的心跳
    sleep(interval) # 固定短间隔

    输入(会话 id / 起始游标 / 间隔 / 初始同步模式)同样走 stdin 私有请求,不落 argv。


    输出协议(每行一个 JSON 对象):























    形态 含义
    数据行 {local_id, type, sender, time, text} 一条消息(已清洗)
    {control: "poll"} 一轮轮询结束的心跳(供健康统计与卡死看门狗喂狗)
    {control: "baseline", local_id: N} 延迟基线已确立(见"初始同步")

    4. 消费层:适配器 + 会话循环



    • reader 适配器:启动 follow 子进程,逐行 readline 解析,校验行大小、JSON 合法性、

      control 类型,把数据行上交业务。内置卡死看门狗:只要 stdout 有数据(包含每轮的

      poll 心跳)就重置计时;超过"命令超时 + 轮询间隔"仍无动静即判定卡死并杀掉子进程。

      因此 poll 心跳不能省 —— 它是"进程还活着"的唯一证据。子进程以独立进程组启动,

      退出时整组回收,避免留下孤儿。

    • 会话循环:每个会话一个循环 / 一个 follow 子进程。取持久化游标 → 收到的每行

      经业务摄取 → 出错则置退避状态并按退避间隔重启。




    游标与初始同步语义


    游标是"已消费到的最大 local_id",单调不减(存储层强制 MAX(...))。

    initial_sync 决定首次基线:



    • 从零开始:游标从 0 起,follow 从头读(会回放历史)。

    • 从最新开始:基线取当前最新 local_id,只读之后的新消息。

      • 若首次游标为 0,follow 进入"等待基线"态:先不吐历史,等库里出现消息后把

        游标钉到当时最新值,再发 baseline 心跳。

      • 意义:防止一份迟到同步的数据库在启动瞬间把历史当"新消息"倒灌进来。




    崩溃边界:一条新消息的事件落库与游标推进必须在同一事务提交 —— 要么都成,

    要么都不成。重复出现的库行凭稳定事件身份幂等,不会被重复处理。




    健壮性设计(改动前务必理解)



    • 毒行绝不能钉死游标:解不出 / 超限 / 含非法字段的行,要降级成"最小可推进游标"

      的 tombstone
      (空 sender/text),而不是抛异常。否则 reader 崩溃重启后游标停在毒行上

      → 死循环。原则是"宁可丢这一行的内容,也要让游标继续前进"。

    • 大小上限:单条正文与单行输出都设硬上限,超限即降级为 tombstone,防止异常大行

      撑爆管道或内存。

    • 内容无关的日志:控制/错误输出只含类型码,不泄露路径、密钥、正文

    • 分片热更新:每轮重新枚举消息分片,新分片无需重启即被拾取。

    • 看门狗分层:进程内卡死看门狗(卡死即杀)+ 会话级退避重启 + 环境级看门狗

      (挂载 / 补丁 / 密钥 / 一次真正的解密探针作为端到端 golden signal,可自动修复)。




    对客户端版本的敏感度(升级即可能失效)


    按脆弱程度排序,便于排障定位:





































    环节 抗更新 说明
    密钥抓取(hook 系统密钥派生函数) hook 的是系统符号,跨版本稳定
    SQLCipher 参数(哈希 / rounds / cipher) 客户端改 KDF 或加密参数则解不开
    数据库 schema(消息表、id用户名映射、媒体索引、联系人库) 表/字段漂移直接让查询失败
    加密媒体容器格式 通常按固定版本适配,格式变了要重做
    注入(加载命令 + 重签名) 客户端改签名/加固方式时,重注入流程可能要改

    核心策略:靠"钉死版本 + 看门狗自愈"回避大多数冲击。 真需要迁到新版本时:



    1. 优先保持不升级那份冻结拷贝(除非旧版无法登录或被服务端淘汰)。

    2. 在新二进制上重建注入链:重新注入 + 重签名,先确认密钥仍能被抓到。

    3. 只读 fixture 离线校验 SQLCipher 参数、消息表/映射表/媒体索引 schema、

      媒体容器格式,全绿再切生产。

    4. 切换采用 drain-first reload(读进程继续、游标保留),避免升级窗口丢消息。




    一句话总结


    抓密钥(hook 系统符号,稳)→ 只读解密本地库(严格只读 + 私有协议)→

    游标增量轮询(单调游标 + 事务落库 + 毒行降级)→ 多层看门狗兜底。

    稳定性来自钉死一个已打补丁的客户端版本;真正需要人工跟进的,只有

    schema 与媒体格式的版本漂移,而这些都能用 fixture 在切生产前先验证。


  • Yukimeepo 楼主 08-01 23:49
    14

    @uixg #13 牛逼,太感谢了。这需要常驻的mac或者windows和一个小号是吧

* 帖子来源NodeSeek
返回