layout: layout
title: 各大热补丁方案分析和比较
date: 2015-11-20 11:46:13
categories:
- android
tags:
- android
- hotpatch
最近开源界涌现了很多热补丁项目,但从方案上来说,主要包括Dexposed、AndFix、ClassLoader(来源是原QZone,现淘宝的工程师陈钟,在15年年初就已经开始实现)三种。前两个都是阿里巴巴内部的不同团队做的(淘宝和支付宝),后者则来自腾讯的QQ空间团队。
开源界往往一个方案会有好几种实现(比如ClassLoader方案已经有不下三种实现了),但这三种方案的原理却徊然不同,那么让我们来看看它们三者的原理和各自的优缺点吧。
Dexposed
基于Xposed的AOP框架,方法级粒度,可以进行AOP编程、插桩、热补丁、SDK hook等功能。
Xposed需要Root权限,是因为它要修改其他应用、系统的行为,而对单个应用来说,其实不需要root。 Xposed通过修改Android Dalvik运行时的Zygote进程,并使用Xposed Bridge来hook方法并注入自己的代码,实现非侵入式的runtime修改。比如蜻蜓fm和喜马拉雅做的事情,其实就很适合这种场景,别人反编译市场下载的代码是看不到patch的行为的。小米(onVmCreated里面还未小米做了资源的处理)也重用了dexposed,去做了很多自定义主题的功能,还有沉浸式状态栏等。
我们知道,应用启动的时候,都会fork zygote进程,装载class和invoke各种初始化方法,Xposed就是在这个过程中,替换了app_process,hook了各种入口级方法(比如handleBindApplication、ServerThread、ActivityThread、ApplicationPackageManager的getResourcesForApplication等),加载XposedBridge.jar提供动态hook基础。
具体到方法,可参见XposedBridge:
/**
* Intercept every call to the specified method and call a handler function instead.
* @param method The method to intercept
*/
private native synchronized static void hookMethodNative(Member method, Class<?> declaringClass, int slot, Object additionalInfo);
其具体native实现则在Xposed的libxposed_common.cpp里面有注册,根据系统版本分发到libxposed_dalvik和libxposed_art里面,以dalvik为例大致来说就是记录下原来的方法信息,并把方法指针指向我们的hookedMethodCallback,从而实现拦截的目的。
方法级的替换是指,可以在方法前、方法后插入代码,或者直接替换方法。只能针对java方法做拦截,不支持C的方法。
来说说硬伤吧,不支持art,不支持art,不支持art。
重要的事情要说三遍。尽管在6月,项目网站的roadmap就写了7、8月会支持art,但事实是现在还无法解决art的兼容。
另外,如果线上release版本进行了混淆,那写patch也是一件很痛苦的事情,反射+内部类,可能还有包名和内部类