• - 修复 BOSS直聘登录被安全检测拦:根因是 wechat_plain 的全局设备型号伪装
      脚本连累风控,禁用脚本恢复真实机型后登录正常
    - 本地库明文无加密,Contact/MessageTable 结构与持久化触发时机(反编译确认)
    - parse_resumes.py: 简历(ChatResumeBean)+职位卡片(ChatJobBean)反序列化导出,
      支持招聘模式(myRole=1)/牛人模式(myRole=0)双角色
    - scan_geek_list.py: 纯读屏方案(uiautomator dump + swipe)记录候选人列表,
      不调用私有接口
    - README 第四节写死三条边界:不做自动沟通/自动回复、不做私有接口批量抓取,
      搬到 Hermes 上跑也不改变判断
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »

  • 红点通知需 atuserlist,深逆向未到底,跟原生引用气泡一起后面做。已确认:
    - 纯文字@不触发红点;atuserlist 不在 message 行(convertTo cv 无此列)
    - r0 第5参 obj≠msgSource(当它传会 NPE g9.q5,obj 是"消息key查f9")
    - 微信 UI 发送链路≠我们合成的 r0+z2.b:hook z2 自学习扫 atuserlist 字段零命中
    
    已部署脚手架(WIP,生产不传 at 无影响,自动回复照常):
    - SEND_MSG_INTERNAL 支持 --es at → 构造 msgsource
    - trySendWithRetry/sendViaHighLevel 加 msgSource 参数
    - hookAtDiscovery 自学习 z2 派发点 + sAtFieldPath 持久化(目前学不到)
    
    详见 memory wechat-group-at-atuserlist。⚠️ 重编译 hook 会强退微信=要重登,
    继续挖前一次想全要抓什么。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • - process_event 里确定性拼接 @昵称+U+2005(微信原生分隔符)前缀,仅群消息(isGroup)
    - 确定性代码不靠 LLM/skill(否则会漏会不一致);安全判定仍在原始 draft 上跑
    - 审批页/自动发的文本都带 @;送达校验用带 @ 的文本匹配
    - ⚠️ 仅文字@(可见),不带 atuserlist,未必真 ping 红点;真通知需 hook 加 at 列表(README 待收尾)
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • - 需求文档环节5:补 flush 加固三经验值 + 端到端闭环验证(私聊+群@我送达)
    - README 真机验证:加 2026-07-12 里程碑段(系统正式跑通,~15s 送达)
    - .gitignore 忽略 __pycache__/*.pyc
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • 用户实测发现:触发 NetSceneQueue 派发的是一次真实 app 切换(切走→切回微信),
    且要给足时间。旧版单次切换+被动等 25s 常卡几十秒~分钟。三个经验值:
    - 发送后 sleep(4) 让消息稳稳落库(切太快微信还没登记这条,flush 不到)
    - _onresume_cycle: HOME 背景化 2.5s → am start LauncherUI 切回停 3s(切换给足时间)
    - 切回后停前台连查 DWELL_POLLS 轮,不立刻再切走(否则打断正在进行的网络发送);
      没到 2 再来一轮,总超时 60s
    
    真机实测:屏幕亮/灭(Dozing)都 ~15s flush 到 status=2。memory
    wechat-api-send-onresume-flush 已补加固经验。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • - app.py 加 GET/POST /api/auto_send:读写 policy_config.json 的
      auto_send_enabled(root 属主 644,写经 tmp+su cp,只翻该字段保留 block_keywords)
    - whitelist.html 顶部加开关卡片(开=白名单自动发/敏感词仍拦,关=全审批),开启二次确认
    - orchestrator 每轮 load_config() 即时生效,无需重启
    - 真机验证:读接口 enabled=false、POST true/false 文件正确翻转其余字段完整、/whitelist 200
    - README 待收尾 #4 标完成
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »

  • 复盘 2026-07-11 从"以为一个 hook 就完事"到"挖了四层才根治"的完整过程:
    Java Build.* / native __system_property_get / 系统 settings device_name /
    微信自己首装存下的持久 MMKV 缓存(mmkv.default),缺一漏一处。
    含无效弯路(Settings hook/分区 prop hook 零命中)、正确解(resetprop+
    settings put+清 mmkv 缓存)、按账号不同现象的服务器端记录解释、维护坑。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • 微信在 native __system_property_get 读 ro.product.model,绕过所有 Xposed
    Java hook,登录记录显示真机 "Pixel 10 Pro Fold" 触发预警。
    
    - hookDeviceSpoof: SystemProperties.get 改模式匹配 ro.product.*.model
      + hook Settings.{Global,Secure,System}.getString(device_name/bluetooth_name)
      + hook BluetoothAdapter.getName() + 诊断日志(定位真实读取源用)
      → 真机验证这些 Java hook 全零命中,证实微信走 native 读
    - 真正生效: wechat-model-spoof.sh 用 Magisk resetprop 改系统属性层
      (装到 /data/adb/post-fs-data.d/,开机持久化),native 读也拿伪装值
      → 登录记录变 "samsung SM-X700",Pixel 泄露消失
    - 代价:全机生效(getprop 也变),放弃"仅微信进程内",native 读无法 per-app
    
    详见 memory wechat-pad-login-device-spoof。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • - text_b64 传中文(--es text 被 shell/am 弄乱→卡 status=1)
    - z2.b 只入队,发送后 HOME+LauncherUI 触发 onResume 派发(设备机制非代码 bug)
    - _send_text_verified 轮询 message.status 直到 2,超时仍 1 视为已入队不误报
    - 拆 stage 目录(watcher=_stage / orchestrator=_stage_orch)避开拷库竞态
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »

  • /whitelist 添加改为弹窗:默认列会话过的联系人/群(带昵称),搜索框查全量通讯录,
    复选框多选批量入库。新增 /api/contacts(会话列表) + /api/contacts/search(全量搜),
    /api/whitelist POST 支持批量 items。白名单存储/显示昵称+wxid/群id+类型。真机验证
    33 条默认列表、搜索、批量加(added:2)全通。viewer 改动全文见 wechat-viewer-changes.md。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • wechat_reply_orchestrator.py:消费 watcher incoming.jsonl(cursor增量+单实例锁+
    首跑基线)→ 候选事件(私聊/@我/引用我)→ env2 查上下文(rcontact身份+历史,一次拷库
    全批复用)→ env3 hermes -z 生成 → env4 policy.decide(白名单读 circle.db)→ env5
    落地(auto:send_text_via_hook+auto_sent / review:pending 进 /approvals)。生成失败
    即静默不发,绝不误发。watcher._trigger_orchestrator 读到新消息后 fire-and-forget
    拉起 drain(独立进程不阻塞采集)。真机验证:接线自动触发、真实猎头上下文生成火星人
    口吻草稿并正确进审核队列。auto_send 默认关=全审核(保守起步)。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • wechat_reply_policy.py:确定性安全闸 decide()→skip|auto|review,default-deny
    +敏感词硬override(钱/承诺/约时间白名单也拉回),demo 8/8 过。配置与审批 UI 落在
    手机端 ~/wechat-viewer(Flask):新表 reply_whitelist/reply_queue、/whitelist
    白名单页、/approvals 审批页(可编辑草稿+发送/取消),发送复用 send_text_via_hook。
    真机验证白名单增删查、发送到 filehelper(sent)、取消(cancelled) 全通。viewer 改
    动全文见 wechat-viewer-changes.md + viewer_templates/(不复制用户整个 app)。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »

  • 环节3 不写代码,Hermes 本身生成(deepseek-v4-pro/gateway),走 hermes -z 一次性
    调用(裸端点 8642 需鉴权,401,不用)。SOUL.md 从默认 Hermes 人设改为「火星人的
    手机助手」(替他回微信用其口吻+涉钱/承诺/约时间交本人确认;设备原文已备份)。
    真机验证质量:陌生猎头→「暂不考虑,谢谢」、熟人约饭→「可以啊,几点?在哪吃」,
    均在口吻上。观察:人设的安全约束是软的(约饭仍主动接话),硬门要落到环节4。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • 环节2 无需新代码:Hermes 是有 shell+SQL 的 agent,给 wechat-db-decrypt skill
    补「读会话上下文」一节即可——一次拷库查齐发送者身份(rcontact,显示名优先级
    conRemark>nickname>alias)、最近 N 条历史(剥群 wxid: 前缀/type→占位符/只喂
    文本)、refermsg 引用解析 + 群名,并给出喂环节3 的上下文骨架。真机验证配方
    产出干净上下文。仓库留档 skill/wechat-db-decrypt-SKILL.md。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • wechat_reply_daemon.sh:root 监督器,带 Termux 环境、单实例锁、等微信登录
    就绪(selftest)、看门狗崩溃重启(退避 10s)。
    service.d__wechat-reply-watcher.sh:Magisk service.d 开机钩子(装到
    /data/adb/service.d/wechat-reply-watcher.sh)拉起监督器。
    真机验证:纯 root(boot 上下文)selftest 通过、单实例防重、杀 watcher 自动
    重启、setsid 脱离后挂 init 常驻。已在设备 7×24 运行。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • wechat_reply_watcher.py:纯 ctypes inotify 监听当前账号 EnMicroMsg.db 目录
    (SELinux 放行、零轮询),失败退回 stat mtime;解密增量读 message(isSend=0
    & msgId>last)→ 分类(私聊/群@我/群引用我/群其它)→ 写 incoming.jsonl 队列。
    账号运行时按 MD5("mm"+uin) 自适应,首跑建基线不重放历史。真机验证 inotify
    触发读取、多账号切换自适应、解密/分类均通过。含 --selftest/--once/--tail。
    
    配套需求文档 md/wechat-auto-reply-requirements.md 标注环节1 完成。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »

  • 旧 `ls|head -1` 按字典序选库,多账号设备会选中非登录账号目录,
    却用当前 uin 推的 key 去解 → 解密失败。改为先读 last_login_uin,
    再用 目录名=MD5("mm"+uin) 精确定位登录账号库;定位不到才回退 head -1。
    真机验证 uin=257966415 正确选中主账号 ec4f423b…(旧逻辑误选 653cdc…)。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • 装到设备 ~/.hermes/skills/wechat-spoof-toggle/。对 Hermes 说「开/关平板伪装、
    平板伪装状态」即翻转 flag+提醒手动重启;内置铁律=登录态下绝不替用户重启微信(=踢下线
    +实名验证)。真机验证:Hermes 读 skill 正确报「关(干净 Pixel)」。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • 风控踢下线+实名验证的真正根因 = 登录状态下改设备指纹(不是平板登录本身)。实证:
    火星人在线时,测开关 33 秒内 Pixel→SM-X700→Pixel 翻转两次+重启两次 → 指纹横跳被踢。
    修正之前「平板登录固有高风险别做」的过重判断:登录后设备身份保持稳定即可持续。
    
    - DEVICE_SPOOF 从编译期常量改为运行时 flag 文件 /data/data/com.tencent.mm/files/.wcspoof
      (默认不存在=OFF=干净 Pixel,最低风控风险)。4 个 pad 登录 hook 全由该 flag 门控。
    - wechat_spoof_toggle.sh: 一键翻转 flag,【绝不自动重启微信】(早期自动 force-stop
      重启=登录态下身份突变=踢,已删)。改后由用户在没账号在线时手动重启微信生效,脚本大字警告。
    - 部署到设备 ~/ + ~/.shortcuts/(Termux:Widget 桌面按钮)。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • WeChatHook.java pad-login 注释 + LESSONS.md 加「Hermes 修复交接」段,指向
    wechat-pad-login-repair skill(诊断+no-rebuild 修复+Case B 升级)。memory
    wechat-pad-login-device-spoof / hermes-pixel-mcp-integration 同步。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • 已装到设备 ~/.hermes/skills/wechat-pad-login-repair/。Hermes 能做诊断(logs/dumpsys)+
    no-rebuild 修复(reboot+install-existing/导航到 LoginPasswordUI)+ Case B(需重编译/逆向)
    收集证据升级给人/Claude。Pixel Termux 有 d8/apksigner 但当前模块源码在 Mac,~/WeChatHook
    是旧 stub,故 Hermes 不做重编译。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • 订正旧结论:平板登录被拒根因是 **Pixel 机型不在微信平板白名单**(bk.B/Q 设备型号
    校验 + 服务端副设备机型校验),**与账号「体验资格」无关**——实测同一个小火子老账号
    (当初被归咎为体验资格过期那个)伪装成三星 Galaxy Tab S8(SM-X700) 后平板登录成功。
    
    4 个 hook(缺一不可):
    - hookDeviceSpoof(主进程): setStaticObjectField(android.os.Build,…)=samsung/SM-X700/
      gts8wifi + hook SystemProperties.get 返回 ro.product.*=同款 + ro.build.characteristics
      =tablet。DEVICE_SPOOF 开关。伪装仅微信进程内(getprop 仍显 Pixel)。
    - hookInTabletEnv: bk.A/B→true 兜底。
    - hookLoginHistoryUIInitView/hookLoginUIInitView: LoginPasswordUI/LoginHistoryUI.onCreate
      强制「以平板登录」按钮(字段 N) setVisibility(VISIBLE)+挂 m4 点击。
    
    关键 Tinker CL 坑: 登录 UI 跑在 Tinker CL,登录 hook 必须也注册到 sTinkerCL——否则
    onCreate hook「注册了但 0 次触发」(N VISIBLE 计数 0),退出登录后到 LoginPasswordUI
    (对的页)但没按钮。加 sTinkerCL 注册后日志出 N VISIBLE + m4 attached,按钮即现。
    
    rebuild stub 补 setStaticObjectField/getStaticObjectField。逆向+DEX 分布见
    wechat_pad_login/LESSONS.md。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »

  • Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • 根因: 图片 stage 到 /sdcard 根目录的临时文件(未被 MediaStore 索引)时,微信图片
    CDN 上传管线解析不到该文件 → 上传成破损图(红叹号,接收方收不到)。而已索引的
    /sdcard/Pictures/ 里的图能正常全图上传。之前 Mac 直发用 /sdcard/Pictures/ 现成图
    碰巧成功,掩盖了 staging 的 bug。
    
    修复(send_image_via_hook + wechat_send.sh image):
    - stage 到 /sdcard/Pictures/wx_send_<pid>.<ext>(媒体目录 + 唯一名避免并发覆盖)
    - 广播 MEDIA_SCANNER_SCAN_FILE 触发 MediaStore 索引 + sleep 1 让扫描落地
    - 再发 SEND_IMAGE_INTERNAL
    
    真机验证: 修复前 staged 路径确定性红叹号(Hermes 17:37 + MCP repro 17:43 均失败);
    修复后经 MCP helper(Hermes 同路径)发送全图正常渲染(17:46 AI AGI 日报全分辨率)。
    "CDN submit DONE" 日志只代表提交,不代表上传成功——不能作为送达判据。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • send_voice_tts_via_hook 的最后一步从 send_voice_via_hook(SEND_VOICE_INTERNAL)
    改为 send_voice_cgi_via_hook(SEND_VOICE_CGI)——让 Hermes 的 send_wechat_voice_tts
    MCP 工具(wechat-voice-sender skill 调的)走已验证的 uploadvoice cgi 全合成路:
    音频上传+投递接收方+发送方本地已发送气泡。docstring 同步更新。
    
    已 adb push 同步到设备 ~/.hermes/event_bus/(android_mcp.py + wechat_hook_send.py),
    设备 wechat-image-sender skill 也更新为调 send_wechat_image MCP 工具(弃旧 ACTION_SEND
    UI 模拟)。设备文件权限修为 termux uid 可读(原 root:root 导致 MCP 子进程 import 失败)。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • 新 skill voice-synth-send:一段文本合成为语音,作为微信语音消息发给联系人。
    全程在 Pixel Termux 内跑(Hermes 环境),无需 Mac、无需本地 TTS 模型。
    
    - voice_synth.sh: text → edge-tts(默认,免费云) / 豆包 seed-audio(可选,需额度) → MP3
      → ffmpeg 16k mono PCM → silk-wasm SILK V3 → stage 进微信数据目录 → SEND_VOICE_CGI。
      引擎 edge|doubao;音色可选;豆包 key 走 DOUBAO_KEY 环境变量(不入库)。
    - 澄清 edge-tts 是云 TTS(非本地模型,无需 key/GPU,联网即用);本机 Termux 已具备
      python/edge-tts/node/silk-wasm/ffmpeg。
    - SKILL.md: 用法/引擎对比/真机验证/坑(TMPDIR、SILK 权限、adb-su 无 DNS 是测试
      artifact 非 skill bug)。
    
    真机验证 2026-07-07:edge-tts(6.9s)+豆包 seed-audio(8.2s) 均发火星人成功,多分块上传
    完整可播放,发送方本地已发送气泡。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • 三种消息在使用层齐了(文字/图片/语音全走内部 API 全合成):
    
    - wechat_send.sh voice: 弃用旧 SEND_VOICE_INTERNAL(hot-swap 相关),改走 SEND_VOICE_CGI
      全合成。SILK 须 WeChat 进程可读——动态取 WeChat uid(stat /data/user/0/com.tencent.mm),
      stage 进 /data/data/com.tencent.mm/files/ + chown + restorecon(/sdcard EACCES、
      root cp 进沙盒需正确 owner+ctx)。
    - wechat_hook_send.py: 新增 send_voice_cgi_via_hook(同上 staging + 广播 SEND_VOICE_CGI)。
    - android_mcp.py: send_wechat_voice 改调 send_voice_cgi_via_hook,docstring 更新为全合成。
    - skill_wechat_send/SKILL.md: 语音段改写为 SEND_VOICE_CGI 全合成用法。
    
    真机验证:wechat_send.sh voice + MCP send_voice_cgi_via_hook 均 status=sent +
    hook svrMsgId>0(uploadvoice cgi 服务器接受)。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • sendVoiceViaCgi 之前只上传+投递给接收方,发送方本地无记录。补上:
    - cgi 前把 SILK 写到 voice2/msg_<voiceId>.amr(进程内写,以 WeChat uid,避开
      外部 root cp 被 SELinux categories 挡)供本地回放。
    - w11.r0 Object 构造器插入 f9 语音气泡(voicemsg XML + voiceId 经
      hookF9ImgPathInjector 注入)。
    - convertTo hook 新增 sVoiceCgiInsert 标志:cgi 路已上传+投递,强制 status=4
      (已发送),否则发送方气泡永远转圈「正在发送中」(hot-swap 路仍不强制,靠 H())。
    
    真机 filehelper 对比验证:16:17(修复前)绿气泡转圈无时长 → 16:22(修复后)干净
    「3" 语音条」已发送。接收方(火星人/Mac)收到能播 + 发送方本地正常显示 = 端到端
    双向闭环。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • 真机肉眼确认:SEND_VOICE_CGI 纯合成语音在 filehelper 渲染成绿色语音条(多条
    2"/4"/6"/3" 全无红叹号=投递成功)。文档 §2 改写为全合成实现(分块 cv6 →
    modelbase.o 构造 → i.l()+pq5.g.l() 订阅派发),hot-swap 降级为旧路。TL;DR
    新增 SEND_VOICE_CGI 行。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • 修好派发:裸 z2.b(g) 不 wire 回调 → 场景永不完成、dv6 空。正确派发 =
    modelbase.i.l()(注册响应消费者 d + 返回 pq5.g deferred)+ pq5.g.l(timeoutMs)
    终端订阅触发 cgi。加 sVoiceCgiKeepAlive 强引用防 deferred 弱持有的 i 被 GC。
    
    真机 filehelper 验证(纯合成,无录音/无 hot-swap):
      RESP try=1 svrMsgId(11)=6727180359918674774
      VOICECGI-RESULT errType=0 errCode=0 errMsg=null respClass=r45.dv6
    = 服务器接受请求(errCode=0) + 分配 msgId(>0) = 投递成功。
    
    诊断 hook hookVoiceCgiResult(modelbase.i onSceneEnd 按签名定位) 确认 errCode。
    广播 SEND_VOICE_CGI --es to --es src_path <SILK> --ei duration。SILK 须 WeChat
    进程可读(用其自身 voice2 文件或 chown 到 WeChat uid;/sdcard 会 EACCES)。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • 按捕获的 wire 协议实现全合成语音(无录音、无 hot-swap):
    - 读 SILK → 按 6000 字节分块 → 每块建 r45.cv6 请求 pb([0]self [1]talker
      [2]offset [3]len [4]"newSendVoice_"+voiceId [6]dur [7]cu5(SILK切片) [8]end
      [11]msgsource [12]=4)→ 经 modelbase.o 13参构造器(绕过 modelbase.l 字段名
      base≠tinker 不匹配) → modelbase.i.p(o)(按签名定位) → scene modelbase.g(m1)
      → z2.b(scene) 入队(同文字发送)。
    - 广播 SEND_VOICE_CGI --es to --es src_path <SILK> --ei duration。
    
    真机 filehelper 测试:反射全部解析成功,scene=com.tencent.mm.modelbase.g,
    z2.b 提交 1 块无异常(silk=2593B dur=2000)。投递确认待(设备屏幕 doze +
    需第二账号);已知待补:[15] long 字段省略、本地 f9 气泡未插、cgi 响应
    getLong(11) 未校。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • 真机 hook 追踪确认本机语音走 jg0.x.w 内联 cgi 分支(非 CDN 引擎 addSendTask,
    那是 send_use_cdn_upload=1 的机器才走)。内联路可 z2.b 全合成,复用文字同队列。
    
    新增追踪 hook:
    - hookCdnTrace: h2.d(addSendTask)/l1.keep_onUpload*/jg0.x.u — 证实 CDN 路本机不触发。
    - hookVoiceCgiCapture: hook modelbase.l.a() 过滤 uploadvoice,按类型定位字段(base≠
      tinker 名,NoSuchFieldError 教训),dump 请求 pb r45.cv6 全字段。
    
    捕获的 wire 协议(cgi /cgi-bin/micromsg-bin/uploadvoice, cmdid 127, req cv6/resp dv6):
      [0]self [1]talker [2]netOffset [3]本块SILK长 [4]"newSendVoice_"+voiceId
      [6]时长ms [7]custom cu5(SILK字节) [8]endflag [11]msgsource [12]=4 [15]long
      分块=6000字节/片,末块 end=1 响应 dv6.getLong(11)>0=服务器msgId=投递。
      scene modelbase.g extends m1 → z2.b(scene) 同文字。modelbase.o 有公开构造器可绕
      过 modelbase.l 字段名不匹配。
    
    下一步: sendVoiceViaCgi 实现分块 cgi + z2.b 全合成。详见 memory + WECHAT_SEND_API。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • 图片 CDN 上传打通后,把 MCP 发图工具从旧的 share-intent UI 模拟切到内部 API:
    
    - wechat_hook_send.py: 新增 send_image_via_hook(wxid, image_path) — 先 stage
      到 /sdcard 保证 WeChat 进程可读,再广播 SEND_IMAGE_INTERNAL;hook 内部走
      b80.u.oj(插库+建描述符) + v70.w.oj(提交 CDN 上传),接收方收全分辨率原图。
      新增常量 SEND_IMAGE_ACTION。旧 send_image_via_intent 保留作参考/UI 兜底。
    - android_mcp.py: send_wechat_image 工具改调 send_image_via_hook,更新 docstring
      (无 UI 模拟、无选联系人、无发错人风险;nickname 不解析,须传 wxid)。
    
    真机验证(off-device 走 wechat_hook_send.send_image_via_hook 直调):
    status=sent + hook oj() DONE + CDN submit DONE items=1。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • 图片 CDN 上传打通后,把发图能力接进使用层:
    
    - skill_wechat_send/SKILL.md: 图片段 🟢→✅,给出 SEND_IMAGE_INTERNAL 广播 +
      wechat_send.sh 封装用法,标注真机验证(filehelper + 火星人全图收到)。
    - wechat_send.sh image: 弃用旧的 share intent + 手动选联系人(UI 模拟),
      改走内部 API 广播 SEND_IMAGE_INTERNAL;先 stage 到 /sdcard 保证 WeChat
      进程可读,再 fire-and-forget 到 <wxid>。真机验证 oj()+CDN submit 均 DONE。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • 攻克图片发送最后一公里(LSPosed,微信 8.0.74,真机验证全分辨率送达):
    
    根因: b80.u.oj(o70.k) 只做「插消息 f9 + 插 ImgInfo b0 + 建缩略图」并
    返回 List<o70.l> CDN 上传描述符,自己不提交 CDN。旧代码拿到 res 就丢掉
    list → 上传永不触发(缩略图渲染但全图转圈)。真实编排 pe5.f.a 才循环
    list 逐图提交(b80.s 只是 prebuild service checkPreBuildImg,不含 oj)。
    
    补上第二步(照搬 pe5.f.a): oj() 后对每个 o70.l:
      cdnSvc = n0.c(xs.d1.class)  // v70.w MsgImgFeatureService
      g = new r70.g(l.e, compress, c01.z1.r()/*self wxid*/, talker, k70.i0{a=3})
      cdnSvc.oj(g, l)             // → 启动 CDN 上传协程 e80.c
    
    真机: oj() DONE res=size=1 + CDN submit DONE items=1,无异常;filehelper
    收到消息点开是全分辨率原图(有原图+保存按钮,不再转圈)。
    
    坑: v70.w.oj 内部走 ViewModelProvider.get 须主线程调(广播 receiver 本就在
    主线程);jadx 字段名末位字母=真实 dex 字段;XposedHelpers stub 无
    getLongField 用原生反射。逆向靠拉 Tinker dex + jadx --single-class。
    
    产物: WECHAT_SEND_API.md §3 完整两步实现 + API 表;backups 源码快照。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »

  • 逆向微信 8.0.74 内部发送 API(LSPosed,无 UI 模拟):
    
    - 文字(中英文): w11.r0(type=1) Object-ctor + z2.b NetSceneQueue,真机验证送达。
      中文走 text_b64 base64 通道避免 shell 损坏 UTF-8。避开 dk5.s5.Ni(实为发名片)。
    - 图片: hook 真实发送抓 o70.h/o70.k/o70.i 原样重放,攻克消息构建——
      能建 type=3 图片消息、缩略图渲染、进 pt0.e0 管线;全图 CDN 上传是最后一公里。
    - 语音: jg0.x.w hot-swap(真机验证投递)。
    - wxid 解析: EnMicroMsg.db SQLCipher 解密(key=MD5(imei+uin)[:7])查 rcontact。
    - 坑: 真实代码在 Tinker 补丁 CL(hook 用 sTinkerCL);force-stop 不 flush 加密 WAL。
    
    产物: WECHAT_SEND_API.md(完整逆向文档)+ skill_wechat_send/SKILL.md
         + backups/(WeChatHook.java 快照 + 构建/发送脚本)。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • skills/wechat-voice-sender/SKILL.md:
    - when to use、核心工具调用示例、已知联系人 wxid 表
    - 明确告知 Hermes:不要自己实现 edge-tts/silk-wasm,调工具即可
    - 错误处理表、安全约束
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »