Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱
MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

目录

dexposed

GitHub

重要提醒:

  • 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虚拟机的机制。这也解释了为什么会有dexposeddexposed_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的更多相关文章

  1. 热修复 AndFix 阿里 apkpatch MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  2. Android 热补丁和热修复

    参考: 各大热补丁方案分析和比较 Android App 线上热修复方案 1. Xposed Github地址:https://github.com/rovo89/Xposed 项目描述:Xposed ...

  3. 热修复 RocooFix篇(一)

    吐槽之前先放一张大帅图. (md 这张图貌似有点小 不纠结这个了==) 有时候项目刚刚上线或者迭代 测试或者在线上使用测出一个bug来 真让人蛋疼 不得不重新改bug测试 打包混淆上线感觉就向find ...

  4. Android热修复框架汇总整理(Hotfix)

      Android平台出现了一些优秀的热更新方案,主要可以分为两类:一类是基于multidex的热更新框架,包括Nuwa.Tinker等:另一类就是native hook方案,如阿里开源的Andfix ...

  5. Android热修复技术原理详解(最新最全版本)

    本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结   通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简单 ...

  6. 阿里Sophix热修复

    阿里巴巴对Android热修复技术已经进行了长达多年的探索. 最开始,是手淘基于Xposed进行了改进,产生了针对Android Dalvik虚拟机运行时的Java Method Hook技术,Dex ...

  7. Andfix热修复原理

    一.前言 最近腾讯弄出一个Tinker热修复框架,那么本文先不介绍这个框架,先来介绍一下阿里的一个热修复框架AndFix,这个框架出来已经很长时间了,但是看网上没有太多非常详细的讲解,这里就来做一次分 ...

  8. Android热修复技术原理详解

    阿里Dexposed -- native解决方案 原理: 直接在native层进行方法的结构体信息对换,从而实现完美的方法新旧替换,从而实现热修复功能   他的思想完全来源于Xposed框架,完美诠释 ...

  9. 深入探索Android热修复技术原理读书笔记 —— 热修复技术介绍

    1.1 什么是热修复 对于广大的移动开发者而言,发版更新是最为寻常不过的事了.然而,如果你 发现刚发出去的包有紧急的BUG需要修复,那你就必须需要经过下面这样的流程: 这就是传统的更新流程,步骤十分繁 ...

随机推荐

  1. MEF框架简介

    下面主要介绍一下MEF的架构,希望从总体上有所了解,更改OpenExpressApp后我会再写篇文章介绍一下如何在OpenExpressApp中使用MEF的. 主要示意图 各种Export提供者从目录 ...

  2. General PE format layout

  3. java之jvm学习笔记十三(jvm基本结构) 通俗易懂的JVM 文件,没有之一

    http://blog.csdn.net/yfqnihao/article/details/8289363

  4. Win32动态链接库和MFC 动态链接库

      通过使用 DLL,程序可以实现模块化,由相对独立的组件组成.例如,一个计帐程序可以按模块来销售.可以在运行时将各个模块加载到主程序中(如果安装了相应模块).因为模块是彼此独立的,所以程序的加载速度 ...

  5. .Net Discovery 系列之二--string从入门到精通(下)

    前两节我们介绍了string的两个基本特性,如果你觉得你已经比较全面的了解了string,那么就来看看这第3.4两节吧. 三.有趣的比较操作  在第一节与第二节中,我们分别介绍了字符串的恒定性与与驻留 ...

  6. mycat应用场景

    mycat应用场景 以下是几个典型的应用场景:单纯的读写分离,此时配置最为简单,支持读写分离,主从切换分表分库,对于超过1000万的表进行分片,最大支持1000亿的单表分片多租户应用,每个应用一个库, ...

  7. 使用集成SOA网关的PL / SQL中的REST

    使用集成SOA网关的PL / SQL中的REST Oracle电子商务套件集成SOA网关(ISG)是一款开箱即用的模块,支持在Oracle Integration Repository中发布支持的接口 ...

  8. Java Jackson - Json Polymorphism

    from://http://www.studytrails.com/java/json/java-jackson-Serialization-polymorphism.jsp Jackson prov ...

  9. 转换java keytools的keystore证书到OPENSSL的PEM格式文件

    背景:原先业务使用的前端为haproxy,直接端口转发至tomcat,后端进行ssl连接,所以当时生成的步骤如下 ? 1 2 •生成密钥对:keytool -genkey -alias tomcat- ...

  10. Swift - 通过叠加UILabel来实现混合的进度条

    Swift - 通过叠加UILabel来实现混合的进度条 效果 源码 https://github.com/YouXianMing/Swift-Animations // // MixedColorP ...