热修复 DexPosed AOP Xposed MD
| Markdown版本笔记 | 我的GitHub首页 | 我的博客 | 我的微信 | 我的邮箱 |
|---|---|---|---|---|
| MyAndroidBlogs | baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com |
目录
dexposed
基本实现原理简介
Dalvik 和 ART 虚拟机
加载 so 库的逻辑
findAndHookMethod 的执行过程
支持的版本
官方文档
集成
基本使用
在指定方法前后注入逻辑
完全替换某一指定方法
用于热修复
dexposed
重要提醒:
- 1、此方案不支持ART(Android 5.0 及之后的Android版本),这一点是致命的!
- 2、此方案不支持Dalvik 3.0(专为平板设计的Android版本)
- 3、只支持 ARM 架构
基于此,注定它会逐步失声,再多的优点也是徒劳。
dexposed enable 'god' mode上帝视角 for single android application.

基本实现原理简介
Dexposed中的AOP原理来自于Xposed。
在Dalvik虚拟机下,主要是通过改变一个方法对象方法在Dalvik虚拟机中的定义来实现,具体做法就是将该方法的类型改变为native并且将这个方法的实现链接到一个通用的 Native Dispatch 方法上。
这个 Dispatch 方法通过JNI回调到Java端的一个统一处理方法,最后在统一处理方法中调用 before、after 函数来实现AOP。
在Art虚拟机上目前也是是通过改变一个 ArtMethod 的入口函数来实现。
Dalvik 和 ART 虚拟机
什么是Dalvik:
Dalvik是Google公司自己设计用于Android平台的Java虚拟机。Dalvik虚拟机是Google等厂商合作开发的Android移动设备平台的核心组成部分之一。它可以支持已转换为
.dex(即Dalvik Executable)格式的Java应用程序的运行,.dex格式是专为Dalvik设计的一种压缩格式,适合内存和处理器速度有限的系统。Dalvik 经过优化,允许在有限的内存中同时运行多个虚拟机的实例,并且每一个Dalvik应用作为一个独立的 Linux 进程执行。独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。
什么是ART:
Android操作系统已经成熟,Google的Android团队开始将注意力转向一些底层组件,其中之一是负责应用程序运行的Dalvik运行时。因此Google开发了更快执行效率更高更省电的替代ART运行时,ART代表 Android Runtime,其处理应用程序执行的方式完全不同于Dalvik。
Dalvik是依靠一个
Just-In-Time (JIT)编译器去解释字节码。开发者编译后的应用代码需要通过一个解释器在用户的设备上运行,这一机制并不高效,但让应用能更容易在不同硬件和架构上运行。ART则完全改变了这套做法,在应用安装时就
预编译字节码到机器语言,这一机制叫Ahead-Of-Time (AOT)编译。在移除解释代码这一过程后,应用程序执行将更有效率,启动更快。
ART优点:
- 系统性能的显著提升。
- 应用启动更快、运行更快、体验更流畅、触感反馈更及时。
- 更长的电池续航能力。
- 支持更低的硬件。
ART缺点:
更大的存储空间占用,可能会增加10%-20%。更长的应用安装时间。
总的来说ART的功效就是“空间换时间”。
加载 so 库的逻辑
google在android4.4之后的版本都用art取代了dalvik,所以要 hook android4.4以后的版本就必须去适配art虚拟机的机制。这也解释了为什么会有dexposed和dexposed_l两个so。
目前官方表示,为了适配art的dexposed_l只是beta版,所以最好不要在正式的线上产品中使用它。
public synchronized static boolean canDexposed(Context context) {
if (!DeviceCheck.isDeviceSupport(context)) {
return false;
}
return loadDexposedLib(context); //load xposed lib for hook.
}
private static boolean loadDexposedLib(Context context) {
try {
if (android.os.Build.VERSION.SDK_INT > 19){
System.loadLibrary("dexposed_l");
} else if (android.os.Build.VERSION.SDK_INT == 10
|| android.os.Build.VERSION.SDK_INT == 9 || android.os.Build.VERSION.SDK_INT > 14){
System.loadLibrary("dexposed");
}
return true;
} catch (Throwable e) {
return false;
}
}
可以看到,在sdk版本大于19时,会去调用dexposed_l,否则会调用dexposed。
findAndHookMethod 的执行过程
jar包的java部分代码结构很简洁,DexposedBrigde是主要的功能调用类,XposedHelpers则是一个反射功能类,其他则为一些辅助类。
DexposedBrigde中用来hook的方法findAndHookMethod的执行过程大致为:
- 首先会通过
XposedHelpers这个反射工具类的findMethodExact方法来找到对应的Method。 - 然后会执行
hookMethod方法。 - 然后里面会调用
hookMethodNative方法,我们需要给hookMethodNative传递的参数分别是:根据反射定位到得要hook的Method、声明定义Method的class、slot标记runtime的标记符、包含函数入参,返回值类型以及对应回调的自定义类。 - 这样就完成了对应的hook。
支持的版本
Dexposed 支持从 Android 2.3 到 4.4(不包括3.0)的所有 dalvik 运行时 arm 架构设备。稳定性已在我们的长期产品实践中得到证实。
| Runtime | Android Version | Support |
|---|---|---|
| Dalvik | 2.2 | Not Test |
| Dalvik | 2.3 | Yes |
| Dalvik | 3 | No |
| Dalvik | 4.0-4.4 | Yes |
| ART | 5 | Testing |
| ART | 5.1 | No |
| ART | M | No |
官方文档
What is it?
Dexposed is a powerful yet并且 non-invasive非侵入性的 runtime AOP (Aspect-oriented Programming) framework for Android app development, based on the work of open-source Xposed framework project.
Dexposed是一个功能强大但非侵入性的运行时AOP框架,适用于Android应用程序开发,基于开源Xposed框架项目。
The AOP of Dexposed is implemented purely纯粹的 non-invasive, without any annotation processor, weaver or bytecode rewriter. The integration is as simple as loading a small JNI library in just one line of code at the initialization phase初始化阶段 of your app.
Dexposed的AOP是纯粹非侵入性的,没有任何注释处理器,编织器或字节码重写器。 集成就像在应用程序初始化阶段只在一行代码中加载一个小JNI库一样简单。
Not only the code of your app, but also the code of Android framework that running in your app process can be hooked. This feature is extremely useful in Android development as we developers heavily rely on严重依赖 the fragmented old versions of Android platform (SDK).
不仅应用程序的代码,而且还可以hooked在您的应用程序进程中运行的Android框架的代码。 此功能在Android开发中非常有用,因为我们开发人员严重依赖分散的旧版Android平台(SDK)。
Together with dynamic class loading, a small piece of compiled Java AOP code can be loaded into the running app, effectively altering the behavior of the target app without restart.
结合动态类加载,可以将一小段编译好的Java AOP代码加载到正在运行的应用程序中,从而有效地改变目标应用程序的行为而无需重新启动。
Typical use-cases
典型使用场景
- Classic AOP programming,典型的 AOP 编程
- Instrumentation (for testing, performance monitoring and etc.),仪表化 (测试,性能监控等等)
- Online hot patch to fix critical, emergent or security bugs,在线热补丁修复关键,紧急或安全漏洞
- SDK hooking for a better development experience,可以 hooking SDK 以便能有更好的开发体验
集成
将 patchloader.jar 导入工程
Directly add dexposed aar to your project as compile libraries, it contains a jar file "dexposedbridge.jar" two so files "libdexposed.so libdexposed_l.so" from 'dexposed' directory.
直接将 dexposed aar 添加到您的项目作为编译库,它包含一个jar文件 “dexposedbridge.jar” 两个来自'dexposed'目录的 .so 文件 “libdexposed.so 和 libdexposed_l.so”。
注意:这里aar文件只包含了armeabi架构的so文件,所以不支持 x86 架构。
compile 'com.taobao.android:dexposed:0.1.1@aar'
初始化:
// Check whether current device is supported (also initialize Dexposed framework if not yet)
if (DexposedBridge.canDexposed(this)) {
Log.i("bqt", "Use Dexposed to kick off AOP stuffs.");
} else {
Log.i("bqt", "Not Supported");
}
基本使用
There are three injection注入 points for a given method: before, after, replace.
在指定方法前后注入逻辑
可以不改变原函数的执行,但是在原函数执行前后去做一些其他的额外处理,例如改变入参和返回值等等的一些事情。
// Target class, method with parameter types, followed by the hook callback (XC_MethodHook).
DexposedBridge.findAndHookMethod(Activity.class, "onCreate", Bundle.class, new XC_MethodHook() {
// To be invoked before Activity.onCreate().
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
Activity instance = (Activity) param.thisObject; //thisObject保持对目标类实例的引用
Bundle bundle = (Bundle) param.args[0]; //数组args包含所有参数
Intent intent = new Intent();
XposedHelpers.setObjectField(param.thisObject, "mIntent", intent); //XposedHelpers提供了很多实用的方法
if (bundle.containsKey("return"))
param.setResult(null); //调用setResult将绕过原始方法体,直接使用指定的参数作为方法返回值。
}
// To be invoked after Activity.onCreate()
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
XposedHelpers.callMethod(param.thisObject, "sampleMethod", 2);
}
});
DexposedBridge.findAndHookMethod(Log.class, "d", String.class, String.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam arg0) throws Throwable {
String tag = (String) arg0.args[0];
String msg = (String) arg0.args[1];
System.out.println(tag + "," + msg);
}
});
完全替换某一指定方法
可以将原有要执行的函数替换成一个我们需要的新的执行函数
DexposedBridge.findAndHookMethod(Activity.class, "onCreate", Bundle.class, new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
Log.i("bqt", "在原始方法上下文之外重写方法逻辑有点棘手,但仍然可行");
return new Object();
}
});
用于热修复
使用的前提是,我们需先创建一个热修复工程,打包后在我们项目中动态下载下来。
因为里面基本没什么逻辑,所以包很小,不用担心网络和下载时间的影响
补丁项目参考:dexposed/sample/patchsample
该项目可以生成一个将由
dexposedexamples运行的apk,patchloader.jar是从dexposedexamples的“com.taobao.patch”包中导出的。
原始项目参考:dexposed/sample/dexposedexamples
原始项目修复bug的核心逻辑:
File cacheDir = getExternalCacheDir();
if (cacheDir != null) {
String fullpath = cacheDir.getAbsolutePath() + File.separator + "patch.apk";//这个是我们下载到本地的热修复包
PatchResult result = PatchMain.load(this, fullpath, null);
if (result.isSuccess()) {
Log.i("bqt", "hotPath load apk success.");
} else {
Log.i("bqt", "hotPath load apk error. " + result.getErrorInfo());
}
}
最核心的逻辑其实就是这一行代码:
PatchResult result = PatchMain.load(this, fullpath, null);
2018-6-9
热修复 DexPosed AOP Xposed MD的更多相关文章
- 热修复 AndFix 阿里 apkpatch MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Android 热补丁和热修复
参考: 各大热补丁方案分析和比较 Android App 线上热修复方案 1. Xposed Github地址:https://github.com/rovo89/Xposed 项目描述:Xposed ...
- 热修复 RocooFix篇(一)
吐槽之前先放一张大帅图. (md 这张图貌似有点小 不纠结这个了==) 有时候项目刚刚上线或者迭代 测试或者在线上使用测出一个bug来 真让人蛋疼 不得不重新改bug测试 打包混淆上线感觉就向find ...
- Android热修复框架汇总整理(Hotfix)
Android平台出现了一些优秀的热更新方案,主要可以分为两类:一类是基于multidex的热更新框架,包括Nuwa.Tinker等:另一类就是native hook方案,如阿里开源的Andfix ...
- Android热修复技术原理详解(最新最全版本)
本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结 通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简单 ...
- 阿里Sophix热修复
阿里巴巴对Android热修复技术已经进行了长达多年的探索. 最开始,是手淘基于Xposed进行了改进,产生了针对Android Dalvik虚拟机运行时的Java Method Hook技术,Dex ...
- Andfix热修复原理
一.前言 最近腾讯弄出一个Tinker热修复框架,那么本文先不介绍这个框架,先来介绍一下阿里的一个热修复框架AndFix,这个框架出来已经很长时间了,但是看网上没有太多非常详细的讲解,这里就来做一次分 ...
- Android热修复技术原理详解
阿里Dexposed -- native解决方案 原理: 直接在native层进行方法的结构体信息对换,从而实现完美的方法新旧替换,从而实现热修复功能 他的思想完全来源于Xposed框架,完美诠释 ...
- 深入探索Android热修复技术原理读书笔记 —— 热修复技术介绍
1.1 什么是热修复 对于广大的移动开发者而言,发版更新是最为寻常不过的事了.然而,如果你 发现刚发出去的包有紧急的BUG需要修复,那你就必须需要经过下面这样的流程: 这就是传统的更新流程,步骤十分繁 ...
随机推荐
- 深刻领悟javascript中的exec与match方法之异同
阅读本文之前,请先看下面一道题: 题目17:Read the following javascript code: var someText="web2.0 .net2.0"; ...
- Asyncio中Lock部分的翻译
Asyncio中Lock部分的翻译 Locks class asyncio.Lock(*, loop=None) 原始锁的对象. 这个基础的锁是一个同步化的组件,当它上锁的时候就不属于典型的协程了(译 ...
- Win10 下 VMware 的安装,以及 VMware 里安装 Ubuntu 18
- Windows系列之(一):Windows10 上运行Ubuntu Bash
1. 前言 2016年4月6日,Windows 10 Insider Preview 发布的版本 14316,添加了Ubuntu Bash,在Windows上提供一个Linux环境,可以直接执行Lin ...
- Slickflow.NET 开源工作流引擎高级开发(一) -- 流程外部事件的调用和变量存储实现
前言:流程实现基本流转功能外,通常也需要调用外部事件,用于和业务系统的交互,同时存储一些流程变量,用于追踪和记录业务数据变化对流程流转的影响. 1. 流程事件 流程执行过程中,伴随各种事件的发生,而且 ...
- 浅尝一致性Hash原理
写在前面 在解决分布式系统中负载均衡的问题时候可以使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡的作用.但是普通的余数ha ...
- MikroTik RouterOS网址资源收集
routeros|mikrotik|ros|软路由论坛|中国路由网|软件路由|软件路由器|routeros技术论坛|路由论坛 - Powered by Discuz! Mikrotik RB450 ...
- LINUX下动态链接库的使用-dlopen dlsym dlclose dlerror(转)
dlopen 基本定义 功能:打开一个动态链接库 包含头文件: #include <dlfcn.h> 函数定义: void * dlopen( const char * pathn ...
- echarts 怎样去掉白色边框线 和怎样去除背景中的网格
echarts怎样去掉白色边框线: echarts怎样去除背景中的网格线
- Html学习笔记3
1表格的标题和表头: <table> <caption>成绩单</caption> <tr> <th>姓名</th> <t ...