说明

原文首发于WeChat8Xposed通用hook框架适配新版微信-单元测试适配新微信

如有访问异常或者问题讨论请前往原文浏览

前言

最近在研究个人的微信bot,也就是想做一个微信聊天的机器人。搜索之下发现了一个有意思的库WechatSpellbook。

Wechat Spellbook 是一个使用Kotlin编写的开源微信插件框架,底层需要 Xposed 或 VirtualXposed 等Hooking框架的支持,而顶层可以轻松对接Java、Kotlin、Scala等JVM系语言。让程序员能够在几分钟内编写出简单的微信插件,随意揉捏微信的内部逻辑。

正好做下研究,利用这个框架配合xposed做 微信数据抓取 微信公众号阅读量的采集分析 还有微信机器人的制作

问题出现

在使用中发现该库已经无法正常满足最版本的微信hook
需要重新对其做适配工作

于是我新建了一个项目 WeChat8Xposed

地址在 https://github.com/HuRuWo/WeChat8Xposed

fork了原库的代码作为组件 导入之后开始做适配工作。

MirrorUnitTest 测试版本适配

我们知道的。xposed要生效hook到指定的位置的类和方法

最重要的就是类名和方法名

而由于大多数软件开启了混淆模式,有时候神奇的路径就会变化。即使是非常微小的版本差异也会导致路径大相径庭。

WechatSpellbook 原作者非常贴心的准备了一个MirrorUnitTest 测试文件来解析文件路径。

MirrorUnitTest原理分析

通过阅读MirrorUnitTest的源码,我大致了解就是通过apk的文件dex分析,来寻找指定的目标类。

几个核心的测试类方法:

apkFile.exists()

检查安装包文件 也就是你要hook的版本的微信安装包 记得放在指定目录下面

MirrorClasses + MirrorMethods + MirrorFields

映射类 映射方法 映射变量 也即是我们讲的特征值

变成一个Objects 传入MirrorUtil 作为查找目标类的特征值

val objects = MirrorClasses + MirrorMethods + MirrorFields

MirrorUtil

核心的适配 自动适配表达式 的工具类

通过传入特征值来寻找和记录类路径

  1. MirrorUtil.clearUnitTestLazyFields(instance)

清除上次的缓存

2.MirrorUtil.generateReportWithForceEval(objects)

测试是否能找到目标类

apkFile.delete()

删掉因为解析产生出来的垃圾文件 大概有几百M 测试完成通过将全部自动删除

下载目标版本的apk文件

值得注意的是 原作者的库里留下了测试文件 MirrorUnitTest

针对一些目标版本做了测试从6.60版本一直到6.73版本的适配测试

如何做一个新版的适配测试呢

这就要拉下来我们要适配的版本apk

今天是2021-6-21日,官网最新的版本是 v806版本 下载链接 https://dldir1.qq.com/weixin/android/weixin806android1900_arm64.apk我们把

它拉下来放到文件下apks/domestic目录下面

编写测试可用性脚本

测试脚本新增一行

@Test fun verifyPlayStorePackage8_0_6() {
verifyPackage("$DOMESTIC_DIR/wechat-v8.0.6.apk")
}

然后点击运行测试 查看输出日志 分析通过特征值是否找到了指定的目标类一测就出问题了

没有找到 NotificationManagerCompat

scriptjava.lang.Error: Failed to evaluate NotificationManagerCompat       at
com.gh0u1l5.wechatmagician.spellbook.mirror.android.support.v4.app.Classes$$special$$inlined$wxLazy$1.invoke(WechatGlobal.kt:112)       at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)       at
com.gh0u1l5.wechatmagician.spellbook.WechatGlobal$UnitTestLazyImpl.getValue(WechatGlobal.kt:138)       at
com.gh0u1l5.wechatmagician.spellbook.util.MirrorUtil.generateReportWithForceEval(MirrorUtil.kt:64)       at
com.gh0u1l5.wechatmagician.spellbook.MirrorUnitTest.verifyPackage(MirrorUnitTest.kt:84)       at
com.gh0u1l5.wechatmagician.spellbook.MirrorUnitTest.verifyPlayStorePackage8_0_6(MirrorUnitTest.kt:152)       at java.lang.reflect.Method.invoke(Native Method)       at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)       at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)       at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)       at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)       at
androidx.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:80)       at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)       at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)       at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)       at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)       at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)       at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)       at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)       at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)       at org.junit.runners.ParentRunner.run(ParentRunner.java:363)       at
androidx.test.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:104)       at org.junit.runners.Suite.runChild(Suite.java:128)       at org.junit.runners.Suite.runChild(Suite.java:27)       at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)       at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)       at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)       at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)       at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)       at org.junit.runners.ParentRunner.run(ParentRunner.java:363)       at org.junit.runner.JUnitCore.run(JUnitCore.java:137)       at org.junit.runner.JUnitCore.run(JUnitCore.java:115)       at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)       at
androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:388)       at
android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2091)

如何修复这个异常

这个异常意味着特征类没有找到 需要重新制作特征类
也就是要重新适配路径核心就在mirror文件夹下面
有所有通用映射规则的 也就是wechat应用程序包的类结构映射。
哪个类出现异常就要修复哪个类的问题

具体的修复下篇分析。

WeChat8Xposed通用hook框架适配新版微信-单元测试适配新微信相关推荐

  1. android hook 第三方app_基于 VirtualApp 结合 whale hook框架实现hook第三方应用

    要点 1. whale hook framework 使用示例: 2. 参考项目:VirtualHook: 3. 按照 VirtualHook 修改 VirtualApp: 4. 编写 hook pl ...

  2. 狼厂项目实践:通用检索框架准实时流的设计与实现

    背景 检索对实时性的要求很高,不仅是对索引建立.结果召回.策略干扰等核心部分,也包括数据录入的部分.检索的数据流主要包括全量数据与增量数据,其中全量数据是在运行前就已经生成好的,在检索进程运行开始时就 ...

  3. 15类Android通用流行框架

    15类Android通用流行框架 Android流行框架 缓存 DiskLruCache Java实现基于LRU的磁盘缓存 图片加载 Android Universal Image Loader 一个 ...

  4. Android通用流行框架大全

    Android通用流行框架大全 1. 缓存 名称 描述 DiskLruCache Java实现基于LRU的磁盘缓存 2.图片加载 名称 描述 Android Universal Image Loade ...

  5. 如何写一个Android inline hook框架

    Android_Inline_Hook https://github.com/GToad/Android_Inline_Hook_ARM64 有32和64的实现,但是是分离的,要用的话还要自己把两份代 ...

  6. iOS逆向之hook框架frida的安装和使用

    一.Frida 利用 Hopper.class-dump.ios-ssl-kill-switch.Keychain-Dumper.MachOParser 可以进行静态分析. 使用 CycriptTri ...

  7. 安卓逆向_24( 一 ) --- Hook 框架 frida( Hook Java层 和 so层) )

    From:Hook 神器家族的 Frida 工具使用详解:https://blog.csdn.net/FlyPigYe/article/details/90258758 详解 Hook 框架 frid ...

  8. android多个微信支付,想用快速开关一键收付款?Android 版微信没适配但你可以自己做...

    作为一个原生 Android 铁粉,我得承认国内定制 ROM 在很多细节都有可圈可点之处,比如移动支付:这段时间一直在体验的 ColorOS,快速设置面板中默认就有支付宝和微信的收付款快捷方式:在 M ...

  9. Android 关于模拟点击和Hook框架的杂谈

    1. 背景 就跟我们以前玩页游挂机一样,Android端也有游戏,而且样式繁多,如果重复的操作每次都要自己重复一遍操作,那不得烦死,所以就有了这篇文章,本文仅探讨方案,大家可以尝试.而且现在的模拟器( ...

  10. 新年签通用php,C#开发微信门户及应用微信现金红包的封装及使用

    在上篇随笔后,经过对整个微信框架的完善和重构,已经完成了对微信支付.企业付款.现金红包.代金券及各种卡劵进行了封装完成,并把其中微信支付及摇一摇红包部分等内容作为公众号和企业号通用的部分,这些支付相关 ...

最新文章

  1. 使用Auto TensorCore CodeGen优化Matmul
  2. 云信小课堂|5分钟快速实现iOS端PK连麦场景
  3. CentOS 初体验十:文件权限查看和修改
  4. Java ObjectStreamField getName()方法与示例
  5. 断言assert使用方法
  6. 图的表示方法和C++实现
  7. 7-110 吃火锅 (15 分)
  8. java 抽象 属性_在java中如何定义一个抽象属性示例详解
  9. axios 请求拦截封装使用
  10. 学php什么自考专业,什么自考专业容易过自学考试哪些专业好考(已帮助356690人)...
  11. Clipboard.js – 现代方式实现复制文本到剪贴板
  12. 兴业银行研发中心笔试题_2021国考笔试成绩即将发布,面试重点考什么?
  13. GMT时间转换为当地时间的方法
  14. OpenWrt固件编译、软件包Ipk的编译详解
  15. php实现室内地图导航,叠加室内地图-室内地图-示例中心-JS API 示例 | 高德地图API...
  16. java五子棋音乐_五子棋加背景音乐
  17. 怎样把游戏从计算机卸载了,电脑桌面上的游戏怎么卸载,电脑桌面上的游戏怎么卸载?...
  18. 使用HTML5+调用手机摄像头和相册
  19. R语言之-caret包应用
  20. Linux上怎样安装gcc

热门文章

  1. html页面到服务器上乱码,网页乱码问题
  2. 基于arduino ws2812b简单的渐变代码
  3. 华为的薪酬体系整体框架,值得收藏
  4. 365锦鲤助手修改版,砍价小程序
  5. select模型+epoll模型+reactor模型
  6. java基本语法实验体会_实验一 Java 开发环境及基本语法
  7. 面试题:数据库的优化
  8. 读《超级整理术》--对整理的思路
  9. C语言经典面试题100道(附完整答案)
  10. 华为手机怎样关闭鸿蒙系统,华为手机怎么升级鸿蒙系统-华为手机升级成鸿蒙系统教程汇总...