首页
社区
课程
招聘
[原创]Xposed高级用法 实现Tinker热修复
发表于: 2019-11-18 16:36 9193

[原创]Xposed高级用法 实现Tinker热修复

2019-11-18 16:36
9193
Hi ,大家好 我是珍惜 
给大家简单 介绍一下 如何用Xposed 实现 对某个类的 替换 覆盖 
在不编译源码的情况 直接修改 原Class 内容 

(之前的这篇帖子 也不错 xposed实现 Native层 Hook


当我们 在 findClas的时候 其实 我们最终都会去 dexElements数组里面 去寻找 我们需要的类 


路径 为 :
ClassLoder.java->
BaseDexClassLoader.java->
DexPathList.java-> dexElements

这个寻找其实是 遍历 如下图 

也就是说  我们只需要 我们想加载的 类 放在前面  在通过 反射 set   即可 做到 热修复 

腾讯的 Tinker其实大概原理也是这样 阿里的是 动态修改 了 insns数组 直接修改 某个方法的字节码 
这也是 热修复 分为冷插拔  和热插拔的 区分 (是否需要 二次启动 ) 
后面会详细 跟大家说 具体 原因 

下面给大家 简单复现一下流程 











很简单 当我点按钮的时候 会进行Testclass的  获取 会进行遍历 elements数组  生成这个类 

调用方法 以后  肯定会崩掉 这种情况 xposed无论如何Hook都 很无力 (可以Try)


我们先首先生成一份正确的 dex 如下图 









可以看到 在 Test函数 里面 我已经将 原来的异常 换成  Log  打印 



xposed模块里面 写 先Hook attach拿到 对方进程的 classloader

在 attach 执行完毕  里面 进行 修复 因为这个时候 dex已经 加载完毕了 直接进行修复即可 



(需要提前开启 被修复 app的 sd卡读写权限 因为 我是用对方的进程去读写 sd卡 内容的 )
在HookMain里面 进行 class的 初始化 拿到 每个 classloader里面的 element数组 
然后进行合并  详细 功能 可以看一下 注释 



将生成的dex放到 sd/dex/目录下面 


先拿到 加载正确类的 classloader自己手动创建 



然后 开始拿到 正确的 classloader  
传入 对应的 classloader   通过反射的方式 拿到 element数组 


拿到 两个 classloader里面的 elements数组   然后进行合并 



当我们 把合并以后的 classloader 里面的 element数组 在 set原来的 回去  


参数1 是 合并以后的 element数组
 参数2 是 合并之前两个数组的大小 (用于判断是否合并成功 )





激活xposed模块 并运行   

可以 看到  替换是成功的    壳子的不落地加载也是这个原理 



如果 xposed取消 钩子 可以看得到 程序还是老样子进行崩溃 了 






这块  有几个坑 跟大家说一下 
问题1; 为什么 我不用 一个静态方法 作为 Test 如下图 

 




如果 这个 这个方法是静态的  在MianActivity的时候 就会进行初始化 这个时候 这个类已经被初始化了
 在此调用的时候他就不会 去findclass也就不会遍历  element 数组  所以会修复无效 因为 我现在 
每一次 都是 new一个 新的对象 这个 对象 是未经过 初始化的 所以 需要 需要遍历 element数组 拿到 class 这个时候 可以完成热修复 

问题2;热修复的 方式 为什么 分为冷插拔 和 热插拔 

Tinker就属于 冷插拔 就是 在 错误 的类  element数组   前面 加入 我们自己需要的 正确的类 这种方式需要 App重启 才可以 

阿里的 就属于热插拔 他是直接修改 错误方法的字节码 Insns数组 可以直接 修改 对应的 Bug 这种不需要重启 

问题3 ; 这个xposed修复   的作用是什么 ?他有什么价值 ?

我可以在不编译   源码的情况 直接 修改源码里面的内容    随时可关,随时可开  

只需要拿到 系统的 classloader 在加载自己修改 过以后的 内容 如上述操作 即可 

具体项目 如下 






[课程]Android-CTF解题方法汇总!

收藏
免费 10
支持
分享
最新回复 (12)
雪    币: 574
活跃值: (364)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
666
2019-11-18 16:38
0
雪    币: 1366
活跃值: (5584)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
3
先占楼。
2019-11-18 16:41
0
雪    币: 38
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
大佬。。。
2019-11-18 17:12
0
雪    币: 386
活跃值: (1120)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
值得参考
2019-11-18 17:20
0
雪    币: 32
活跃值: (1020)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
Xposed在这里只是给你提供了一个注入的时机,貌似并没有什么“高级”的用途。
2019-11-18 17:50
1
雪    币: 263
活跃值: (399)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
7
2019-11-18 20:56
0
雪    币: 21449
活跃值: (62288)
能力值: (RANK:125 )
在线值:
发帖
回帖
粉丝
8
感谢分享~
2019-11-22 17:02
0
雪    币: 122
活跃值: (536)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
不编译源码的情况下,怎么知道你要修改什么方法?系统函数的话就算了,replacement就能改了
2019-11-25 10:57
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
牛 批牛 批可 是楼 主你 的标 题符 号是 被 吃了吗很简 单当 我点按 钮的时 候 会进 行Testclass的获 取会进 行遍 历elements数 组  生 成这 个类
2019-11-25 20:45
0
雪    币: 3261
活跃值: (13749)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
11
北冥鱼丶 不编译源码的情况下,怎么知道你要修改什么方法?系统函数的话就算了,replacement就能改了
如果我要替换大量的类,大量的方法的时候这种效率是最高的... 
2019-11-25 23:04
0
雪    币: 122
活跃值: (536)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
珍惜Any 如果我要替换大量的类,大量的方法的时候这种效率是最高的...
好的吧……这种需求我是没见过
2019-11-26 11:09
0
雪    币: 3261
活跃值: (13749)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
13
北冥鱼丶 好的吧……这种需求我是没见过
比如 修改源码  ,没办法竟然 改 rom 这样方便点啦
2019-11-26 14:33
0
游客
登录 | 注册 方可回帖
返回
//