支付宝热补丁技术— AndFix原理[阿里Hao]
本文由嵌入式企鹅圈原创团队成员、阿里资深project师Hao分享。
上次我们介绍了用dexposed方案实施热补丁的原理。它本质上就是hook要改动的函数。这样一来在正式版本号公布时就不能直接拿热补丁的代码集成进去了,由于热补丁是按hook的思路,而且依照实现XC_MethodReplacement类的方式写的。正式的补丁还须要又一次包装一边。
更重要的是dexposed对art的支持并不好,大大限制了它的使用范围。
今天我们介绍的是AndFix方案:https://github.com/alibaba/AndFix。
它依照正常修bug的思路写补丁代码。正式公布时直接集成补丁代码就可以。适用范围广。在dalvik和Art上都能够使用。
它分为两部分,一是生成补丁的工具,二是client载入补丁的SDK。
支付宝钱包使用的就是这个方法。
我们基于线上的最新版本号修完bug后。会构建出一个apk,用AndFix提供的diff工具,找出已公布的线上的apk和修复后的apk中classes.dex之间的“差异”。也就是修复bug后发生变化的方法。再用工具生成一个apatch文件,跟apk一样,它也是个压缩包。里面包括CERT.RSA、CERT.SF、MANIFEST.MF、diff.dex和PATCH.MF这几个文件。client从服务端拉取该apatch文件后。解析diff.dex,找到要载入的类和要替换的方法methodReplaced,最后用hook的方式替换掉,这样就完毕了在线修复的工作。本篇我们仅仅介绍client载入补丁的SDK的主要原理。不介绍生成补丁的工具,照例还是先不管ART。仅仅介绍dalvik下是如何执行的。
一、解析补丁的配置文件PATCH.MF
1.首先PatchManager的addPatch方法能够用来加入一个补丁,并执行替换操作。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
可见。用生成的补丁文件File来构造一个Patch类,然后再执行loadPatch来载入补丁。
由于补丁文件apatch是一个jar包。所以用JarFile、Manifest等类来解析META-INF/PATCH.MF配置文件。找到要替换的类名,接下来loadPatch调用AndFixManager的fix方法,传入补丁的File对象、当前Context的classLoader和从PATCH.MF解析出的要替换的补丁类名。
fix方法中用传入的classLoader构造一个自己定义的pathClassLoader。它的findClass方法用来找到要替换的类的Class对象。
这里的dexFile直接由loadDex得到,这样补丁文件里的dex文件就已经载入到应用中了。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
2. 接下来依次把要修复的类载入进来,并调用fixClass方法開始替换工作。
二、找到要替换的类的方法。并把类成员的属性改为public
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" style="line-height: 25px; white-space: pre-wrap; color: rgb(62, 62, 62); font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;font-size:14px;" alt="" />
这里巧用了java的Annotation原理帮助我们在apk中找到要修复的方法。在apatch中补丁方法写了凝视annotation,clazz和method表示要修复的类和方法。在AndFixManager的fixClass中会依据这个Annotation找出要修复的Method对象。遍历类的全部Method,假设发现有MethodReplace的凝视就開始准备替换工作。method是原apk(有bug)的方法,meth是新修复的方法,接着调用replaceMethod。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
replaceMethod里先后调用了initTargetClass和addReplaceMethod,注意这里的classLoader不是上面提到的pathClassLoader而是原apk中要修复的类的classLoader。这样原来有bug的class和补丁中的class都已经被载入进来了。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
initTargetClass中主要调用native的方法setFieldFlag把class中的全部成员都设为public,
addReplaceMethod相同也是调用native的方法replaceMethod。
三、替换原来的Method
替换原来方法的处理方式我们看起来会有点熟悉,一般的java hook几乎相同都是这种套路,在jni中找到要替换方法的Method对象。改动它的一些属性。让它指向新方法的Method对象。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
这里dvmDecodeIndirectRef_fnPtr和dvmThreadSelf_fnPtr都是在AndFix初始化时赋好值的函数指针。用来调dvm的dvmDecodeIndirectRef和dvmThreadSelf函数。
这里apilevel > 10的意思是,在apilevel 10曾经dvm是用c语言实现的,以后是用C++实现的。
以上全部的过程是在应用MainApplication的onCreate中被调用。所以当应用重新启动后。原方法和补丁方法都被载入到内存中,并完毕了替换,在后面的执行中就会执行补丁中的方法了。
AndFix的长处是像正常修复bug那样来生成补丁包,但能够看出不管是dexposed还是AndFix,都利用了java hook的技术来替换要修复的方法,这就须要我们理解dalvik虚拟机载入、执行java方法的机制,并要掌握libdvm中一些重要的作用结构和函数的使用。
- 百分百原创,每周两篇,阿里、魅族、nvidia、龙芯、炬力、拓尔思等顶级企业资深project师分享----嵌入式、Linux、物联网、GPU、Android、自己主动驾驶等技术,欢迎扫码关注微信公众号:嵌入式企鹅圈,实时推送原创文章!
支付宝热补丁技术— AndFix原理[阿里Hao]的更多相关文章
- 阿里资深工程师分享支付宝热补丁技术—— AndFix原理
本文由嵌入式企鹅圈原创团队成员.阿里资深工程师Hao分享. 上次我们介绍了用dexposed方案实施热补丁的原理,它本质上就是hook要修改的函数,这样一来在正式版本发布时就不能直接拿热补丁的代码集成 ...
- Android热补丁技术—dexposed原理简析(阿里Hao)
本文由嵌入式企鹅圈原创团队成员.阿里资深工程师Hao分享. 上篇文章<Android无线开发的几种常用技术>我们介绍了几种android移动应用开发中的常用技术,其中的热补丁正在被越来越多 ...
- Android热补丁技术—dexposed原理简析(手机淘宝采用方案)
上篇文章<Android无线开发的几种常用技术>我们介绍了几种android移动应用开发中的常用技术,其中的热补丁正在被越来越多的开发团队所使用,它涉及到dalvik虚拟机和android ...
- 阿里开源的热补丁框架AndFix使用教程
阿里巴巴推出的AndFix框架 首次给出大家这个框架的地址:https://github.com/alibaba/AndFix 对源码比较感兴趣的同学们可以自行研究代码 AndFix原理介绍 AndF ...
- UCloud内核热补丁技术揭秘
- Android热更新技术——Tinker、nuwa、AndFix、Dexposed
一.热修复技术作用 线上app BUG紧急修复,不重新发版,不重新安装,在线远程修复问题 二.局限性与适用场景 补丁只能针对单一客户端版本,随着版本差异变大补丁体积也会增大: 补丁不能支持所有的修改, ...
- Android dex分包方案和热补丁原理
一.分包的原因: 当一个app的功能越来越复杂,代码量越来越多,也许有一天便会突然遇到下列现象: 1. 生成的apk在2.3以前的机器无法安装,提示INSTALL_FAILED_DEXOPT 2. 方 ...
- 【腾讯Bugly干货分享】微信热补丁Tinker的实践演进之路
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57ad7a70eaed47bb2699e68e Dev Club 是一个交流移动 ...
- 【腾讯bugly干货分享】微信Android热补丁实践演进之路
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=1264& ...
随机推荐
- web UIproject师必读的一篇文档,写的很好
今天在花瓣网上看到的一片文章.写的是web UIproject师的工作应该是如何的,内容非常精彩,分享给小伙伴.希望web UIproject师看了之后有所启示. 我不是一个简单的web UI htt ...
- 安装Scala 找不到或无法加载主类 scala.tools.nsc.MainGenericRunner 错误
对于安装Scala时 找不到或无法加载主类 scala.tools.nsc.MainGenericRunner 错误,不管是linux还是window系统,原因很大可能是scala的安装路径中出现空格 ...
- Scala快学笔记(一)
一,基本概念: 1,Scala是一种基于JVM的面向对象和函数式编程语言 2,基本类型:数值类型 ->:Byte,Short,Int,Long,Float,Double和布尔类型:Boolean ...
- gensim加载word2vec训练结果(bin文件)并进行相似度实验
# -*- coding: utf-8 -*- import gensim # 导入模型 model = gensim.models.KeyedVectors.load_word2vec_format ...
- Java中的值传递与“引用传递”
首先,Java没有 引用传递 这么一说. Java仅仅有值传递.传递的都是值,基本数据类型传递的是值.引用类型传递的是地址值. 我来理一下这当中宛如米线跟米面绞在一起了,再跟粉丝混在一起的关系. 好的 ...
- 菜鸟调错(五)——jetty执行时无法保存文件
背景交代: 上一篇博客写的是用jetty和Maven做开发.測试.在使用的过程中遇到一个小问题.就是在jetty启动以后,改动了jsp.xml等文件无法保存. 错误信息: 解决方式: 到Maven库( ...
- hibernate学习系列-----(9)hibernate对集合属性的操作之Map集合篇
照旧,先新建一个StudentMap.java实体类,将hobby属性使用map集合接口来存放: package com.joe.entity; import java.util.Map; publi ...
- .net错误处理机制
原地址:http://blog.csdn.net/lxbg90058/article/details/5651767 没有不出错的软件 从不出错的软件从某种程度上讲是不可能的! 和普通人的观念相反,创 ...
- 【BIEE】17_仪表盘提示中值按顺序显示
我们在使用仪表盘提示的时候,常常会遇到这种问题,客户需要将一些常见的放在最上边,这样方便显示 例如:现在有数据库表如下 我们需要在提示中展示机构名称,我们如下新建提示 展示效果如下: 我们从上图可以看 ...
- lucene 转义含有查询关键词的字符的
http://www.oschina.net/question/1092_560 Escaping Special Characters Lucene支持转义查询中的特殊字符,以下是Lucene的特殊 ...