吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3844|回复: 3
收起左侧

[Android 原创] [玩转WX之二]如何让插件稳定运行?一步一步分析Tinker热加载关键流程

  [复制链接]
陈司机 发表于 2021-2-2 21:13
本帖最后由 陈司机 于 2021-2-2 21:23 编辑

系列文章:
上篇 [玩转WX之一]一行命令打印安卓WX数据库密码并取出数据库文件到电脑查看

有兴趣的请关注,系列文章保持高实用性,不说废话,点明过程中的重点,最后直接给出结果。

基础须知:
1.热加载是可以让安卓App不重新安装但是又能改机运行逻辑的技术,腾讯系软件使用自家的热加载系统Tinker。
2.应用程序会从清单的appliction name开始进行运行, 一把程序加壳,多dex,热加载,都在这里做工作,这是应用程序自己的代码能被最早执行的地方。
3.热加载分成总体分资源,so, dex热加载,业务逻辑代码绝大部分在dex, 所以一般关注dex热加载比较多。
4.系统会先执行Application里面的生命周期函数attachBaseContext,比我们熟悉的onCreate更早。


如果代码是热加载的,很有可能会导致插件运行出错。如下所示:

wx热加载前的classloader
dalvik.system.PathClassLoader[DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/system/framework/com.google.android.maps.jar", zip file "/data/app/com.tencent.mm-cm3A_pxRWC2RjCfVnM6X4A==/base.apk"],nativeLibraryDirectories=[/data/app/com.tencent.mm-cm3A_pxRWC2RjCfVnM6X4A==/lib/arm64, /data/app/com.tencent.mm-cm3A_pxRWC2RjCfVnM6X4A==/base.apk!/lib/arm64-v8a, /system/lib64]]]

wx热加载后classloader
dalvik.system.DelegateLastClassLoader[DexPathList[[zip file "/data/user/0/com.tencent.mm/tinker/patch-d93c1e4d/dex/tinker_classN.apk"],nativeLibraryDirectories=[/data/user/0/com.tencent.mm/tinker/patch-d93c1e4d/lib/lib/arm64-v8a, /data/app/com.tencent.mm-cm3A_pxRWC2RjCfVnM6X4A==/lib/arm64, /data/app/com.tencent.mm-cm3A_pxRWC2RjCfVnM6X4A==/base.apk!/lib/arm64-v8a, /system/lib64]]]


为了兼容热加载,我们也要对类加载器进行修正。如何修正热加载器,我们要先对热加载流程做个分析,做到心中有数。



以下代码基于WX7.0.19

我们开始从0开始跟进分析,先查看应用程序入口

1

1


来看类  com.tencent.mm.app.Application

2

2


来看 com.tencent.mm.app.Application 父类 TinkerApplication

3

3



类初始化之后,就会由系统调用生命周期函数 attachBaseContext

4

4


loadTinker

5

5


反射调用真正的tryLoad

6

6


使用 tryLoadPatchFilesInternal 进行热加载

7

7

快速看下这个函数,发现比较重要的是loadTinkerJars
这个函数也对dex热加载文件进行验证以及读入

8

8



由loadTinkerJars进入installDexes

9

9


进入installDexes,根据不同的系统环境, 安装热更新

10

10


安卓热更新的关键是创建新的TinkerClassLoader,合并原有的classLoader

11

11


完成新的类加载器创建,并替换Application的类加载器

12

12



替换线程上下文和LoadedApk的classloader

13

13

替换classloader完毕,校验是否加载成功,如果成功了,就用tinker_xxx.dex等的类

14

14


经过上面分析,我们这样玩:
wx没替换classloader,我们就不替换xp的classloader;
wx替换了classloader,我们跟着替换xp的classloader。

class Hook : IXposedHookLoadPackage {
    override fun handleLoadPackage(LoadPackageParam: XC_LoadPackage.LoadPackageParam) {
        if (LoadPackageParam.packageName == "com.tencent.mm") {
            Log.i("ACCESS", "%%% app_cl 1: ${AndroidAppHelper.currentApplication()?.classLoader}")
            // 这个时候,wx未修改classloader,保持xp的不变,
            XposedBridge.hookAllMethods("com.tencent.tinker.loader.app.TinkerApplication".getClass(LoadPackageParam.classLoader), "onBaseContextAttached", object :XC_MethodHook() {
                override fun afterHookedMethod(param: MethodHookParam) {
                    LoadPackageParam.classLoader = XposedHelpers.callMethod(param.thisObject, "getClassLoader") as ClassLoader
                    LoggerUtil.i("ACCESS", "%%% app_cl 2: ${LoadPackageParam.classLoader}")
                    XposedBridge.hookAllMethods("com.tencent.mm.app.MMApplicationWrapper".getClass(LoadPackageParam.classLoader), "onCreate", object :XC_MethodHook() {
                        override fun afterHookedMethod(param: MethodHookParam) {
                            // 这个时候tinker有可能已经发生热加载了
                            val app = XposedHelpers.getObjectField(param.thisObject, "app")
                            val context = XposedHelpers.callMethod(app, "getApplicationContext") as Context
                            Log.i("ACCESS", "%% context:${context} cl:${context.classLoader}")
                            // 使用全局static对这两个关键变量进行保存。
                            Global.context = context
                            Global.classLoader = context.classLoader // 后面所有查找类加载类使用这个类加载器。不要再使用xp回调传过来的。或者使用TinkerClassLoader.findClass。
                            // 下面开始调用注入逻辑
                        }
                    })
                }
            })
        }
    }
}

免费评分

参与人数 3吾爱币 +3 热心值 +2 收起 理由
杨辣子 + 1 + 1 虽然不会安卓, 但是看教程感觉很n13!
shiina0831 + 1 + 1 谢谢@Thanks!
Jack2002 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

silianwuyi 发表于 2021-2-2 22:03
学习学习
lijs168 发表于 2021-2-2 22:44
shiina0831 发表于 2021-2-3 09:37
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-28 11:34

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表