Android Xposed热修复原理简析
简单介绍下热修复,基于Xposed中的思想,通过修改c层的Method实例描述,来实现更改与之对应的java方法的行为,从而达到修复的目的。
Xposed:
诞生于XDA论坛,类似一个应用平台,不同的是其提供诸多系统级的应用。可实现许多神奇的功能。Xposed需要以越狱为前提,像是iOS中的cydia。Xposed可以修改任何程序的任何java方法(需root),github上提供了XposedInstaller,是一个android app。提供很多framework层,应用层级的程序。开发者可以为其开发一些系统或应用方面的插件,自定义android系统,它甚至可以做动态权限管理(XposedMods)。
Android系统启动与应用启动
Zygote进程是Android手机系统启动后,常驻的一个名为‘受精卵’的进程。
- zygote的启动实现脚本在/init.rc文件中
- 启动过程中执行的二进制文件在/system/bin/app_process
任何应用程序启动时,会从zygote进程fork出一个新的进程。并装载一些必要的class,invoke一些初始化方法。这其中包括像:
- ActivityThread
- ServiceThread
- ApplicationPackageManager
应用启动中必要的类,触发必要的方法,比如:handleBindApplication,将此进程与对应的应用绑定的初始化方法;同时,会将zygote进程中的dalvik虚拟机实例复制一份,因此每个应用程序进程都有自己的dalvik虚拟机实例;会将已有Java运行时加载到进程中;会注册一些android核心类的jni方法到虚拟机中,支撑从c到java的启动过程。
Xposed做了手脚
Xposed在这个过程改写了app_process(源码在Xposed : a modified app_process binary),替换/system/bin/app_process这个二进制文件。然后做了两个事:
- 通过Xposed的hook技术,在上述过程中,对上面提到的那些加载的类的方法hook。
- 加载XposedBridge.jar
这时hook必要的方法是为了方便开发者为它开发插件,加载XposedBridge.jar是为动态hook提供了基础。在这个时候加载它意味着,所有的程序在启动时,都可以加载这个jar(因为上面提到的fork过程)。结合hook技术,从而达到了控制所有程序的所有方法。为获得/system/bin/目录的读写权限,因而需要以root为前提。
Xposed的hook思想
那么Xposed是怎么hook java方法的呢?要从XposedBridge看起,重点在XposedBridge.hookmethod(原方法的Member对象,含有新方法的XC_MethodHook对象);,这里会调到
private native synchronized static void hookMethodNative(Member method, Class<?> declaringClass, int slot, Object additionalInfo);
这个native的方法,通过这个方法,可以让所hook的方法,转向native层的一个c方法。如何做到?
When a transmit from java to native occurs, dvm sets up a native stack.
In dvmCallJNIMethod(), dvmPlatformInvoke is used to call the native method(signature in Method.insns).
在jni这个中间世界里,类型数据由jni表来沟通java和c的世界;方法由c++指针结合DVM*系(如dvmSlotToMethod,dvmDecodeIndirectRef等方法)的api方法,操作虚拟机,从而实现java方法与c方法的世界。那么hook的过程是这样:首先通过dexclassload来load所要hook的方法,分析类后,进c层,见代码XposedBridge_hookMethodNative方法,拿到要hook的Method类,然后通过dvmslotTomethod方法获取Method*指针,
Method* method = dvmSlotToMethod(declaredClass, slot);
declaredClass就是所hook方法所在的类,对应的jobject。slot是Method类中,描述此java对象在vm中的索引;那么通过这个方法,我们就获取了c层的Method指针,通过
SET_METHOD_FLAG(method, ACC_NATIVE);
将该方法标记为一个native方法,然后通过
method->nativeFunc = &hookedMethodCallback;
定向c层方法到hookedMethodCallback,这样当被hook的java方法执行时,就会调到c层的hookedMethodCallback方法。
通过meth->nativeFunc重定向MethodCallBridge到hookedMethodCallback这个方法上,控制这个c++指针是无视java的private的。另外,在method结构体中有
method->insns = (const u2*) hookInfo;
用insns指向替换成为的方法,以便hookedMethodCallback可以获取真正期望执行的java方法。现在所有被hook的方法,都指向了hookedMethodCallbackc方法中,然后在此方法中实现调用替换成为的java方法。
总结
回顾Xposed,以root为必要条件,在app_process加载XposedBidge.jar,从而实现有hook所有应用的所有方法的能力;而后续动态hook应用内的方法,其实只是load了从zypote进程复制出来的运行时的这个XposedBidge.jar,然后hook而已。因此,若在一个应用范围内的hook,root不是必须的,只是单纯的加载hook的实现方法,即可修改本应用的方法。
业界内也不乏通过「修改BaseDexClassLoader中的pathList,来动态加载dex」方式实现热修复。后者纯java实现,但需要hack类的优化流程,将打CLASS_ISPREVERIFIED标签的类,去除此标签,以解决类与类引用不在一个dex中的异常问题。这会放弃dex optimize对启动运行速度的优化。原则上,这对于方法数没有大到需要multidex的应用,损失更明显。而前者不触犯原有的优化流程,只检查需要hook的方法,更为纯粹、有效。
Android Xposed热修复原理简析相关推荐
- Android Handler与Looper原理简析
一直感觉自己简直就是一个弱智,最近越来越感觉是这样了,真的希望自己有一天能够认同自己,认同自己. 本文转载于:https://juejin.im/post/59083d7fda2f60005d14ef ...
- Android热修复-Tinker简析
一.简介 日常工作工作中难免会遇到项目上线后出现bug问题,如果紧急发版往往由于渠道审核时间问题,导致bug修复不及时,影响用户体验.这时我们需要引入热修复,免去发版审核烦恼. 热更新优势: 让应用能 ...
- Android Andfix热修复原理
正常开发流程 热修复开发流程 当线上的项目出现问题了,需要重新发布版本解决bug,重新发新版本apk; 但是随着技术不断的更新,线上项目出现bug,可以通过热修复,在不需要发布新版本的情况下进行bug ...
- android中so文件格式详解,[原创]一 Android ELF系列:ELF文件格式简析到linker的链接so文件原理分析...
Android ELF系列:ELF文件格式简析和linker的链接so文件原理分析 Android ELF系列:实现一个so文件加载器 Android ELF系列:手写一个so文件(包含两个导出函数) ...
- 【Android 热修复】热修复原理 ( 多 Dex 打包机制 | 多 Dex 支持 | Dex 分包设置 | 开发和产品风格设置 | 源码资源 )
文章目录 一.Dex 打包设置 1.多 Dex 支持 2.Dex 分包设置 3.开发和产品风格设置 ( 非必须 ) 二.完整 build.gradle 配置 1.build.gradle 配置 2.d ...
- 【Android 热修复】热修复原理 ( 合并两个 Element[] dexElements | 自定义 Application 加载 Dex 设置 | 源码资源 )
文章目录 一.合并两个 Element[] dexElements 二. 完整修复包加载工具类 三. 源码资源 一.合并两个 Element[] dexElements 在 [Android 热修复] ...
- 【Android 热修复】热修复原理 ( Dex 文件拷贝后续操作 | 外部存储空间权限申请 | 执行效果验证 | 源码资源 )
文章目录 一.Dex 文件准备 二.外部存储空间权限申请 1.清单文件申请权限 2.动态申请权限 三.文件拷贝 1.文件拷贝 2.执行效果 四. 源码资源 一.Dex 文件准备 在 [Android ...
- 【Android 热修复】热修复原理 ( 修复包 Dex 文件准备 | Dex 优化为 Odex | Dex 文件拷贝 | 源码资源 )
文章目录 一.修复包 Dex 文件准备 二.Odex 优化 三.Dex 文件拷贝 四. 源码资源 一.修复包 Dex 文件准备 异常代码 : 故意写一个异常代码 , 并执行该代码 , 肯定会崩溃 ; ...
- Android 热修复原理篇及几大方案比较
热修复说白了就是"即时无感打补丁",比如你们公司上线一个app,用户反应有重大bug,需要紧急修复.2015年以来,Android开发领域里对热修复技术的讨论和分享越来越多,同时也 ...
最新文章
- php数据库字段类型,mysql 字段类型说明
- python 基础 7.6 sys 模块
- android高仿微信UI点击头像显示大图片效果
- python安装第三方包总是超时_(python pip安装第三方库超时问题(raise ReadTimeoutErrorself._pool, None, 'Read timed out.')...
- 困了。还得背课文。变词型
- grafana授权公司内部邮箱登录 ldap配置
- 32位linux系统支持多大内存吗,linux32位操作系统支持大内存
- JavaScript高级程序设计学习(二)之基本概念
- requestmapping配置页面后_第004课:Spring Boot 项目属性配置
- spring接收ajax参数的几种方式
- 【割点】【割边】tarjan
- linux fdisk指定ext4,如何在Linux中创建新的Ext4文件系统(分区)
- 英语口语8级是这么炼成的!
- TFP-161/100/6MM/6MM/MPU在红尘里,靠近菩提
- 【BZOJ4484】【JSOI2015】最小表示(拓扑排序,bitset)
- C语言中将字符数字转换为数值的小技巧和方法
- 针对车载系统相关的功能分析(车载OS、芯片、导航、DC、总线系统等)
- 公众号文章阅读量数据导出
- isset与empty的区别
- 一池江水半江灯。繁星点点落江城,严霜寒雪封不住,若明若暗水火情
热门文章
- 用css做透明效果,CSS实现毛玻璃透明效果
- Blizzard(暴雪)公司的发迹史
- redis惰性删除 lazy free 源码剖析,干货满满
- T-SQL语言中局部变量(@)和全局变量(@@)
- 5g基站服务器需要芯片吗,5G基站为什么需要使用不一样的电源模块
- 误删除的图片怎么恢复?
- liquibase mysql_Liquibase的简单使用
- Saiku更改導出文件的文件名(十九)
- linux负载监控工具,理解 Linux 的平均负载和性能监控
- 2022年12月25日(星期天):骑行沙堤村