From ead036cf9219137f736727f511c75e9cfb180f44 Mon Sep 17 00:00:00 2001 From: yibo Date: Wed, 29 Jul 2026 00:14:48 +0800 Subject: [PATCH] research(wechat): 验证 Tinker 补丁 dex 与 base.apk 一致,Flutter 线索大概率跟单图发布无关 --- wechat_send_internal/BRANDSERVICE_PUBLISH_RESEARCH.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+), 0 deletions(-) diff --git a/wechat_send_internal/BRANDSERVICE_PUBLISH_RESEARCH.md b/wechat_send_internal/BRANDSERVICE_PUBLISH_RESEARCH.md index 3269b69..13ca09a 100644 --- a/wechat_send_internal/BRANDSERVICE_PUBLISH_RESEARCH.md +++ b/wechat_send_internal/BRANDSERVICE_PUBLISH_RESEARCH.md @@ -408,6 +408,28 @@ setNativeEditorDebugMode(mode) 鉴于今天已经连续两天、多轮真机验证 + 两次反编译资产过期的教训,这是一个自然的收尾点。 +### 6.5 验证结果:不是反编译资产过期,是 Flutter/Pigeon 这条线本身大概率跟这次的发布流程无关 + +用户要求直接验证"当前真机在跑的 APK,类名是否变了"——按此做了严格验证: + +1. 查当前安装信息:`versionName=8.0.74 versionCode=3120 lastUpdateTime=2026-07-06`;`~/wechat_apk/base.apk`(旧反编译资产的来源)是 2026-07-27 从设备拉的,版本吻合,**base.apk 本身没有过期**。 +2. 但真正在跑的代码还叠了一层 **Tinker 热更新补丁**(`/data/data/com.tencent.mm/tinker/patch-83069b25/`,2026-07-12 生成)——补丁目录里翻到 **`lib/arm64-v8a/libapp.so`**(Flutter Dart AOT 编译产物的标准文件名),实锤"我的作品"这个 Flutter 功能是**靠 Tinker 热更新下发的**,不在原始安装包里。这印证了本文档最早(§一)就记录过的教训:"base.apk ≠ 正在跑的码",但这次要验证的类恰好两边都有。 +3. 拉了 Tinker 补丁的 `dex/tinker_classN.apk`(174MB,17 个 dex),用 `strings` 扫每个 dex 确认 `BizPublishApi`/`lx.m5` 具体在哪个 dex(`classes11.dex`,跟 base.apk 反编译时的 `smali_classes11` 目录编号一致),用 jadx 直接反编译这个 dex 里的 `BizPublishApi.java` 全文对比。 + +**结论:两份反编译(base.apk vs Tinker 补丁)内容完全一致**,不是类名/代码变了导致 hook 落空。真正读懂的是 `BizPublishApi$Companion.setUp()` 的完整分发逻辑:11 个方法各自对应一个具名的 Flutter `BasicMessageChannel`(channel 名形如 `"dev.flutter.pigeon.mm_auto_gen.BizPublishApi.notifyBizPublishResult"`),**onMessage 收到 Dart 端发来的消息后直接 `bizPublishApi.notifyBizPublishResult(...)` 调用**,中间没有任何反射/代理/多态转发会让 Xposed 的方法级 hook 失效。也就是说:**hook 挂的位置技术上完全正确**(后来证实两份 dex 里代码一字不差),**两轮真机验证零触发的唯一合理解释是:Dart/Flutter 那一侧压根没有为这次测的"贴图号发单图"这个简单流程发送这条 Pigeon 消息**。 + +结合已经稳定复现的事实——`js1.m.c()`/`bizh5webtransfer` 每轮都稳定触发 60-280 次,且每轮发布都真实成功(`chksm` 持续变化)——比较合理的推断是:**`BizPublishApi` 这套 Pigeon 桥接大概率服务于另一个更复杂的发布场景(比如完整的公众号图文创作/`appmsg_editor` 富文本文章),不是"贴图号 + 单图 + 短文字"这个我们一直在测的简化路径**。这条 Flutter 线索本身是真实存在的架构,但对当前要抓的这个具体流程,很可能是一条死胡同。 + +### 6.6 下一步方向(记录以便随时接续,未执行) + +真正的提交调用大概率仍然落在已经反复确认触发、但从未逐条精确解码时间线的 `js1.m.c()`/`bizh5webtransfer` 洪流里(每轮 60-280 次调用,此前只做了整体分类统计,没有按"点击发表那一刻精确到毫秒级"做过 reqUrl 逐条比对)。下次可以: + +1. 精确记录"点击发表"那一次 `input tap` 的系统时间戳(已经在脚本里做了,`date +%s.%N`),再把 `js1.m.c()` 洪流按时间排序,重点看 tap 后最先触发的几条、以及包含 `action=` 参数值明显不是 `get_*`/只读语义的那几条(此前扫描全部都是 get/batch_report 语义,但没有严格逐条过一遍,可能漏看)。 +2. 或者干脆放弃继续猜测哪个原生/Flutter 类是入口,转向"发布结果一定会写库"这个更确定的信号——去 hook WCDB(`hookWCDB` 已有,之前用于消息表)看贴图号发布成功后有没有对应的本地 DB INSERT,反过来从写库那一刻回溯调用栈,比继续挨个猜 jsapi 类更有把握。 +3. 或接受目前的进展,转向"半自动"方案(人工点发布,工具只管生成图片+文案)——今天两天的调查已经把所有直觉候选都验证过一遍,继续投入的边际收益在下降。 + +三个方向都还没做,留给下次接手时决定。 + --- ## 四、现场状态(写这份记录时) -- libgit2 0.21.4