Skip to content

Releases: SymonChu/WeKite

WeKite 3.80:面板收起兜底 v6(@选人不再被误判成点聊天区)

Choose a tag to compare

@SymonChu SymonChu released this 15 Oct 06:03

WeKite 3.80

只改一件事:修「@某个人之后,输入框弹起来又马上收回」 —— 面板收起兜底第 6 版。

3.79 那版为什么会误收

你 10-15 那份日志(8.0.79)把真凶钉死了 —— 真正执行收起的 10 次全部来自同一个钩子:

panel collapse fired: action=0 ty=-1202.0 ime=false src=com.tencent.mm.ui.base.MMPullDownView.dispatchTouchEvent
钩子 执行收起的次数
外层容器 MMPullDownView.dispatchTouchEvent 10 / 10
挂在内层列表上的原生监听器钩(native-listener:w8) 0
内层 ScrollControlRecyclerView.onTouchEvent 0

原因:ViewGroup.dispatchTouchEvent 对落在它范围内的所有触摸都会触发 —— 哪怕这一下随后被后代消费掉。微信自己的收面板监听器挂在内层列表上,所以点 @成员列表 / 点表情面板不会触发它;而 v3.78 为了修 8.0.79 额外挂的外层钩子会。⇒「钩子被叫到」不等于「点在聊天区」。

其中 2 次正好发生在面板展开态(ty=-1202.0 ime=false),就是 @ 那一下。

这次(v6)怎么改

加一条坐标判据:「点聊天区」必须满足 触摸点在 footer 上沿之上。

依据是微信自己的布局:面板被 bottomMargin = -面板高 挤到 footer 底边之外,再用 translationY 整体上移把它露出来 ⇒ 展开时屏幕上从 footer 上沿往下依次是【输入行】【面板(表情面板 / @成员列表 / 「+」面板)】,也就是面板位于 footer 自己的边界下方。所以落在 footer 带内的一律原样交给微信处理(@选人、点表情、点输入框都靠它自己)。

对既有行为的影响:只有真正点在消息区(footer 上沿之上)才会收面板 —— 与「点聊天区收起」的定义一致;8.0.79 / 8.0.77 的收起路径一字未动。

请你这样测

  1. 覆盖安装(versionCode 1180 > 已装版本,直接覆盖)→ 重启微信。
  2. 群聊里 @某个人 → 选人 → 输入框应保持不收回,可以直接接着打字。
  3. 顺带回归:面板/键盘展开时点聊天区(消息之间、列表下方空白)→ 仍应收起。
  4. 日志(这次无论对错都能定案):
    • panel collapse skipped (touch on footer band): action=… rawY=… footerTop=… ⇒ @ 那一下被正确放过;
    • panel collapse touch [源]: … rawY=… footerTop=… ⇒ 记账行现在带坐标,可逐条核对;
    • 若出现 panel collapse fired: … rawY=… footerTop=… 且 rawY < footerTop ⇒ 判据没挡住,我换方向查(不再调阈值)。

装机注意

  • 没动任何 DEX 锚点,不会弹「DEX 缓存更新」。
  • 坐标判据成立的前提是「@成员列表确实落在 footer 那条带里」(按微信的布局推导应当成立),这次日志里的 rawY/footerTop 就是它的真机证据。

构建:run 254(id 38688939843)/ commit 5719d5de / 门禁 v3.80 新增 3 条标记(先在 v3.79 的包上实测全 MISS,反向恰好 3 条 FAIL)。

WeKite 3.79:面板收起兜底 v5(8.0.77 上没有 K0 → 三级探测)

Choose a tag to compare

@SymonChu SymonChu released this 15 Oct 05:12

WeKite 3.79

只改一件事:「点聊天区收起表情面板」的兜底(第 5 版) —— 修 8.0.77 上彻底不生效的问题。

3.78 的问题:写死了 8.0.79 的混淆名

你 10-15 那份日志(同一台机器从 8.0.79 切到 8.0.77)把真因钉死了:

11:18:53  DexCacheManager: host version changed: 8.0.793182 -> 8.0.773141
11:44:32  W FloatingChatFooter: native panel collapse failed:
          No method matching conditions in com.tencent.mm.pluginsdk.ui.chat.ChatFooter
阶段 判定成立(fired) 调用失败
8.0.79 段 119 0
8.0.77 段 13 91

钩子本身没问题 —— 8.0.77 上三条钩子都装上了、也都叫到了(panel collapse guard installed on native listener com.tencent.mm.ui.chatting.a9),只有最后那次反射调用找不到方法:

  • 8.0.79:ChatFooter.K0(Z)V 存在,方法体 = Q(0,z,-1);
  • 8.0.77:没有 K0,等价物叫 L0(Z)V,方法体 = N(0,z,-1)(与 79 的 K0 逐指令同构,只差被调方法的混淆名)。

⇒ 兜底在 8.0.77 上必然抛异常、被吞掉,表现就是「表情面板展开后点聊天区不收」。而键盘态看着还能收,是 hideImeFor() 顺手把系统键盘收了救回来的(日志里键盘态其实同样 failed)。

这次(v5)怎么改

三级探测,顺序即优先级,命中即缓存:

顺序 入口 说明
① K0(Z) 8.0.79 的现状路径,先试它 ⇒ 8.0.79 行为一字不变
② setBottomPanelVisibility(GONE) 8.0.77 / 8.0.79 两版同名且未混淆,方法体 39 条指令逐条同构:参数 ≠ 0 时调 K0/L0(true),之后还会通知面板可见性监听者 ⇒ 比直接调 L0 更完整,也是抗混淆的长期入口
③ L0(Z) 8.0.77 的等价物,②将来也被改名时的保底

顺带两处:命中结果缓存(不再每次触摸做反射查找);「三级全无」的失败日志从 91 行收敛成 1 行。

请你这样测

  1. 覆盖安装(versionCode 1178 > 已装版本,直接覆盖,不用卸载)→ 重启微信。
  2. 8.0.77 那台:进聊天 → 点表情按钮展开面板 → 点聊天区 → 应收起。
  3. 8.0.79 那台:同样操作 → 应和以前完全一样(回归检查)。
  4. 日志里各出现一行即可定案:
    • panel collapse entry resolved: setBottomPanelVisibility(GONE) ⇒ 8.0.77 走对了新入口;
    • panel collapse entry resolved: K0(Z) ⇒ 8.0.79 仍是老路径;
    • native panel collapse unavailable on 8.0.77… ⇒ 三级全没命中(说明还有别的差别,我再换方向)。

装机注意

  • 没动任何 DEX 锚点(本文件唯一锚点 methodRefreshBottomHeight 未碰),预期不会弹「DEX 缓存更新」。
  • ② 那条入口是离线取证(两版同名 + 方法体逐指令同构),这次装机就是它的真机验证 —— 万一 8.0.77 仍不收,日志会直接指出下一步方向。

构建:run 253(id 38681367817)/ commit ba6b3657 / 门禁正向 3 + 负向 1 条新标记,反向对 v3.78 的包恰好 4 条 FAIL、零无关 FAIL。

WeKite 3.78:面板收起兜底 v4(跟着宿主监听器走 + 全量记账)

Choose a tag to compare

@SymonChu SymonChu released this 14 Oct 22:55

WeKite 3.78

只改一件事:「点聊天区收起面板/键盘」的兜底重做(第 4 版),并且把「为什么没收」做成日志。

3.77 那次我判断错在哪

读了你的 3.77 日志(01:45:00–01:47:20,507 行):

  • 三条钩子都装上了(外层 MMChattingListView -> MMPullDownView.onTouchEvent、内层 ScrollControlRecyclerView -> ScrollControlRecyclerView.onTouchEvent),
  • 但整段窗口一次 panel collapse fired 都没有 —— 也就是说钩子要么没被叫到、要么状态判断全不成立,而上一版那条「原生监听器收到触摸」的日志被我删掉了,导致这份日志没法自证「到底有没有点到」。
  • 另外那句 innerInOuterTree=true 说明我上一版「点消息不经过外层」的解释不成立(内层列表确实在外层子树里),所以真因还没找到 —— 这也是它比 3.76 更差的原因:3.76 至少偶尔还能收。

这次(v4)怎么改

  1. 不再猜哪个视图:直接从宿主自己的 View.mListenerInfo.mOnTouchListener 取出微信那个收面板监听器实例,钩它自己的 onTouch —— 触发点和微信原生收起完全同点。3.77 里这个入口在「监听器还没装上」时被我静默跳过了,现在改成「下一帧重试 + 失败写日志」,没有静默分支。
  2. onTouchEvent 与 dispatchTouchEvent 都挂(3.76 那版靠 dispatchTouchEvent 收到过 20 次触摸,3.77 只挂 onTouchEvent 是倒退)。
  3. 每条钩子前 8 次调用都记账:panel collapse touch [源]: action=… view=… ty=… ime=… kbFrame=… ⇒ 下一次的日志无论「钩子没被叫到」还是「判据不成立」都能直接看出来。
  4. 键盘判据两条并用(insets + 可见帧差),避免单一信号失灵就把整个判定静默跳过。
  5. 结构取证:列出本页所有自带 OnTouchListener 的视图(类名 + 身份哈希 + 监听器类名 + 是否已注册),用来判「微信的收面板监听器到底挂在哪个对象上」。
  6. 动作仍是微信自己的收起入口 + 键盘可见时补一手系统 IME 收起。

请你这样测(这次日志一定能定位)

  1. 覆盖安装后重启微信。
  2. 进聊天页 → 点输入框让键盘弹出 → 点聊天区(消息之间、列表下方空白都算)。
  3. 不管收没收,都导出日志给我。日志里会出现下面几类行,判读方式:
    • panel collapse guard installed on native listener … —— 最关键的那条钩子装上了;
    • touch-listener hosts (…) —— 本页带触摸监听器的视图清单(能看出原生监听器挂在谁身上);
    • panel collapse touch [源]: action=… ty=… ime=… kbFrame=… —— 我们的钩子确实被叫到了,并给出当时的展开态;
    • panel collapse fired: … —— 判定成立、已经执行了收起动作。
  4. 如果这三类一行都没有,说明那一下的触摸根本没走这些路径 —— 那我会改用「拿你的日志直接比对微信原生监听器流」的方式定位。

装机注意

  • 没动任何 DEX 锚点,不会弹「DEX 缓存更新」,直接覆盖安装。
  • 设置里「恢复底栏模糊」已在 3.77 删除(属预期)。

WeKite 3.77:面板收起兜底重做 + 删除「恢复底栏模糊」

Choose a tag to compare

@SymonChu SymonChu released this 14 Oct 16:59

WeKite 3.77

一个修复 + 一处删除 + 一处顺带改动。

1. 修复:点聊天区收不起面板/键盘(兜底重做)

3.76 猜错了两处,这次对着你手机上那份 8.0.79 的反汇编逐指令核对后重做:

  • 微信自己的「收面板监听器」挂在消息列表内部那一层,不是外层容器 —— 3.70~3.76 的兜底钩的是外层,点消息的触摸根本碰不到它。你那两份日志里这条就是铁证:原生监听器 442 次、旧兜底 30 次,一次都没有时间重合(最近的一对也差 2 秒以上)。
  • 微信自己的收起时机是手指按下(DOWN),不是抬起(UP)—— 旧兜底盯的是 UP,盯错了事件。

现在:内外两层列表都注册,并直接挂到微信那个监听器实例上(触发点和微信自己完全同点,原生被它的内部判据挡住时由模块替它收);按下与抬起都判;键盘态再额外用系统接口收键盘 —— 微信那个收起动作只管表情/工具面板,键盘本来不归它管,这就是「面板能收、键盘不收」的原因。

验证:键盘弹出后点聊天区(消息之间、列表下方空白都算),键盘应落下、悬浮卡回到原位;表情面板同理。若还有不收的情况,导出日志,先看有没有 panel collapse fired: action=... —— 有它说明兜底确实触发了(那行还带 ty= 与 ime=,能直接看出当时的展开态),没有它说明点的那一下没走这条路径,把日志发我。

2. 删除:「恢复底栏模糊」开关

这个开关从加上那天起从未生效过 —— 代码里取 Activity 的方式对那个宿主类是空值(字节级已核),首页实例名单一直是空的,开关等于空转。它和「美化首页底部导航栏」都在 hook 同一个母类,留着是隐患,按你的选择整体删掉:功能、设置项、日志都不再在包里。首页底栏保持微信原样。

3. 顺带:导出群成员汇总行移到文件末尾

表头下面直接是成员数据,末尾空一行再写「成员数 / 导出时间 / 群ID」,粘进 Excel/WPS 就是纯表。

装机注意

  • 没动任何 DEX 锚点,不会弹「DEX 缓存更新」,直接覆盖安装。
  • 设置里少了「恢复底栏模糊」这一项(属预期)。

WeKite 3.76:键盘态收起兜底 + 导出汇总行移末尾

Choose a tag to compare

@SymonChu SymonChu released this 14 Oct 13:56

WeKite 3.76

两个修复:键盘弹出后点聊天区不收起、导出群成员的汇总行移到文件末尾。

1. 修复:键盘弹出后点聊天区不收起

3.75 日志实锤:表情面板态的兜底正常工作(点聊天区即收),键盘态却一次都没触发——根因是 3.72 兜底条件里写了「键盘可见时不抢」,这个假设错了。

原生行为本来就是「列表收到抬起即收起」,键盘和表情面板一视同仁。现在键盘态也走同一条收起路径(微信自己的收起动作,会先收键盘再落卡片)。

验证:键盘弹出后点聊天区任意位置,键盘与悬浮卡应一起落下。若依旧不收,导出日志给我,看 panel collapse fallback fired 是否出现。

2. 导出群成员:汇总行移到末尾

之前「成员数 / 导出时间 / 群ID」这行在表头下方第二行,粘进 Excel 会占一格正文。现在移到文件最末,表头下面直接是成员数据,粘贴即纯表。

装机注意

没动 DEX 锚点,不弹「DEX 缓存更新」。3.75 直接覆盖安装即可。

WeKite 3.75

Choose a tag to compare

@SymonChu SymonChu released this 14 Oct 12:58

WeKite 3.75

三个修复/改动打包:面板收起兜底装上(3.73)、导出群成员入口不在群成员个人页显示(3.74)、导出可另存为 CSV,Excel 双击即开(3.75)。

1. 修复:表情面板/键盘展开后点聊天区不自动收起

3.72 的兜底钩从来没装上——日志实锤 hook failed: No method matching conditions:8.0.79 的消息列表类自己没重写触摸分发方法(从安卓父类继承),而查找只翻类自己声明的方法。3.73 起查找范围扩到继承链,一行修好。

验证:装上后日志出现 panel collapse guard installed on MMChattingListView.dispatchTouchEvent,点聊天区面板即收起。若钩装上了但面板仍不收,那是收起入口不够,把日志发我。

2. 修复:导出群成员入口在群成员个人页也显示

从群成员列表点进某个人的资料页时,「当前会话」还停留在这个群,旧判据误命中。现在改成看页面自身的 wxId(群资料页=群 id,个人页=成员 wxId),不是群 id 就不显示。

3. 导出群成员:可另存为 CSV

点入口仍照旧复制到剪贴板,随后弹出系统保存对话框,默认文件名 群成员-<群名>.csv。文件为 UTF-8 带 BOM——Excel/WPS 双击即开,中文不乱码、自动分列。

装机注意

没动 DEX 锚点,不弹「DEX 缓存更新」。3.72 或更早版本直接覆盖安装即可。

WeKite 3.74

Choose a tag to compare

@SymonChu SymonChu released this 14 Oct 13:03

修复:导出群成员入口在群成员个人页也显示;文案去掉(TSV)。

根因

从群成员列表点进某个人的资料页时,「当前会话」还停留在这个群上,旧判据 WeCurrentConversationApi.value 命中群 id,就把入口挂到了成员的个人资料页。

修法

改成看页面自身带的 wxId(群资料页=群 id,个人页=成员 wxId),不是群 id 就不显示——与「查看群成员消息」功能的既有处理一致。

没动 DEX 锚点,不弹「DEX 缓存更新」。

WeKite 3.73

Choose a tag to compare

@SymonChu SymonChu released this 14 Oct 13:03

修复:表情面板/键盘展开后点聊天区不自动收起(3.72 兜底钩没装上的补刀)。

3.72 为什么没生效

日志实锤:兜底钩查找消息列表类的触摸分发方法时报「No method matching conditions」——8.0.79 的消息列表类自己没重写这个方法,是从安卓父类继承的,而查找逻辑只翻类自己声明的方法,翻不到就放弃,兜底从来没装上。

3.73 修法

查找范围扩大到继承链(一行改动)。装上后日志应出现「panel collapse guard installed on MMChattingListView.dispatchTouchEvent」,点聊天区收面板应恢复。

没动 DEX 锚点,不会弹「DEX 缓存更新」,3.72 直接覆盖安装即可。

WeKite 3.72

Choose a tag to compare

@SymonChu SymonChu released this 14 Oct 12:12

WeKite 3.72

修复:表情面板/键盘展开后点聊天区不自动收起(3.71 兜底在 8.0.79 上未生效的补刀)。

3.71 的兜底为什么没生效

真机日志实证:原生的收起监听收到了 38 次"抬起"事件,但 8.0.79 的收起判定里多了两个内部检查,把收起动作拦在了半路。同时 3.71 装的兜底监听器一条日志都没有——它用的监听器接口和微信进程里的不是同一个类(跨类加载器),装上即静默失效,等于完全没装。

3.72 的修法

不再给列表"装监听器",改成直接钩微信自己的消息列表类(MMChattingListView)的触摸分发——这类钩子穿透类加载器,3.71 的诊断钩已实证可用。抬起时若面板展开,替微信触发一次它自己的收起动作(走原生路径)。面板没展开时什么都不做。

装机注意

没动 DEX 锚点,不会弹「DEX 缓存更新」。从 3.71 直接覆盖安装即可。

WeKite 3.68:修文件预览状态栏带透出壁纸

Choose a tag to compare

@SymonChu SymonChu released this 14 Oct 08:18

WeKite 3.71

新功能:导出群成员 + 修复:表情面板/键盘展开后点聊天区不自动收起(8.0.79 + 悬浮输入框)。

新功能:导出群成员

群资料页多一行「导出群成员」,点击即复制全部成员到剪贴板。

  • 七列 TSV 格式(制表符分隔),粘贴进 Excel / WPS 自动分列:
    群昵称 | 昵称 | 备注 | 微信号 | wxId | 邀请人
  • 首行表头,第二行汇总(成员数 / 导出时间 / 群 ID)
  • 排序:设了群昵称的在前(一般是群主/管理),其余按昵称
  • 「邀请人」列:微信只给部分群记邀请关系,缺失的显示 —,这是数据本身的限制
  • 非好友成员查不到昵称时以 wxId 兜底,不丢人
  • 数据全部来自微信本机数据库(聊天与联系人接口),不上传任何内容

修复:面板不自动收起

现象:表情面板或键盘展开后,点聊天区其它位置不收起。只在「微信 8.0.79 + 悬浮输入框开启」的组合出现(8.0.77 同配置正常)。

取证:字节级对比两个版本的微信,原生收面板链路完全相同且健在——问题出在 8.0.79 给聊天窗口包了一层新容器(边到边布局),叠加悬浮卡几何后,点在卡片区域的"抬起"落不到消息列表上,原生的收起监听收不到。

修法:模块给消息列表装一个只观察的触摸监听——抬起时若面板处于展开状态,就替微信触发一次它自己的收起动作(走原生路径,不自绘、不改状态机)。面板没展开时什么都不做。

自带诊断:同时钩了原生监听,日志会打一行「原生链是否收到抬起」。如果你装上后问题依旧,导出日志给我,那一行能直接判明剩下的原因。

装机注意

  1. 先清 DEX 缓存再重启微信(模块设置里):之前连装几版时缓存卡在中间态,左滑引用、强制平板模式等 5 个功能被跳过没加载——清一次全回来;
  2. 覆盖安装即可(versionCode 1163 > 上一版);
  3. 本次不改 DEX 锚点,不会弹「DEX 缓存更新」。