阿里资深工程师分享支付宝热补丁技术—— AndFix原理
本文由嵌入式企鹅圈原创团队成员、阿里资深工程师Hao分享。
上次我们介绍了用dexposed方案实施热补丁的原理,它本质上就是hook要修改的函数,这样一来在正式版本发布时就不能直接拿热补丁的代码集成进去了,因为热补丁是按hook的思路,并且按照实现XC_MethodReplacement类的方式写的,正式的补丁还需要重新包装一边。更重要的是dexposed对art的支持并不好,大大限制了它的使用范围。
今天我们介绍的是AndFix方案:https://github.com/alibaba/AndFix。它按照正常修bug的思路写补丁代码,正式发布时直接集成补丁代码即可,适用范围广,在dalvik和Art上都可以使用。它分为两部分,一是生成补丁的工具,二是客户端加载补丁的SDK。支付宝钱包使用的就是这个方案。
我们基于线上的最新版本修完bug后,会构建出一个apk,用AndFix提供的diff工具,找出已发布的线上的apk和修复后的apk中classes.dex之间的“差异”,也就是修复bug后发生变化的方法,再用工具生成一个apatch文件,跟apk一样,它也是个压缩包,里面包含CERT.RSA、CERT.SF、MANIFEST.MF、diff.dex和PATCH.MF这几个文件。客户端从服务端拉取该apatch文件后,解析diff.dex,找到要加载的类和要替换的方法methodReplaced,最后用hook的方式替换掉,这样就完成了在线修复的工作。本篇我们只介绍客户端加载补丁的SDK的主要原理,不介绍生成补丁的工具,照例还是先不管ART,只介绍dalvik下是怎样运行的。
一、解析补丁的配置文件PATCH.MF
1.首先PatchManager的addPatch方法可以用来添加一个补丁,并执行替换操作。
可见,用生成的补丁文件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文件就已经加载到应用中了。
2. 接下来依次把要修复的类加载进来,并调用fixClass方法开始替换工作。
二、找到要替换的类的方法,并把类成员的属性改为public
这里巧用了java的Annotation原理帮助我们在apk中找到要修复的方法。在apatch中补丁方法写了注释annotation,clazz和method表示要修复的类和方法。在AndFixManager的fixClass中会根据这个Annotation找出要修复的Method对象。遍历类的全部Method,如果发现有MethodReplace的注释就开始准备替换工作。method是原apk(有bug)的方法,meth是新修复的方法,接着调用replaceMethod。
replaceMethod里先后调用了initTargetClass和addReplaceMethod,注意这里的classLoader不是上面提到的pathClassLoader而是原apk中要修复的类的classLoader。这样原来有bug的class和补丁中的class都已经被加载进来了。
initTargetClass中主要调用native的方法setFieldFlag把class中的所有成员都设为public,
addReplaceMethod同样也是调用native的方法replaceMethod。
三、替换原来的Method
替换原来方法的处理方式我们看起来会有点熟悉,一般的java hook差不多都是这样的套路,在jni中找到要替换方法的Method对象,修改它的一些属性,让它指向新方法的Method对象。
这里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、龙芯、炬力、拓尔思等顶级企业资深工程师分享----嵌入式、Linux、物联网、GPU、Android、自动驾驶等技术,欢迎扫码关注微信公众号:嵌入式企鹅圈,实时推送原创文章!
阿里资深工程师分享支付宝热补丁技术—— AndFix原理的更多相关文章
- 支付宝热补丁技术— AndFix原理[阿里Hao]
本文由嵌入式企鹅圈原创团队成员.阿里资深project师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内核热补丁技术揭秘
- 【腾讯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& ...
- 【腾讯Bugly干货分享】QFix探索之路—手Q热补丁轻量级方案
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57ff5832bb8fec206ce2185d 导语 QFix 是手Q团队近期推 ...
- Android热修复技术选型(不在市场发布新版本的情况下,直接更新app)
2015年以来,Android开发领域里对热修复技术的讨论和分享越来越多,同时也出现了一些不同的解决方案,如QQ空间补丁方案.阿里AndFix以及微信Tinker,它们在原理各有不同,适用场景各异,到 ...
随机推荐
- 采用Kettle分页处理大数据量抽取任务
作者:Grey 原文地址: http://greyzeng.com/2016/10/31/big-data-etl/ 需求: 将Oracle数据库中某张表历史数据导入MySQL的一张表里面. 源表(O ...
- 对于 ThreadLocal 的理解和应用
首先,ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的.各 ...
- 实时数据显示--SignalR实例演示
近段时间,有实现一个看板的功能,就是用户更新信息时,即是对数据库的数据进行插入,更新,或是删除时,在墙上的屏幕的数据不需要人为去刷新,用户就能看到更新后的数据. 实现此功能,Insus.NET使用Si ...
- 【吐槽】IM群里几种我认为愚蠢的提问方式
一.“有人吗?” 你能得到一句[在,请说]的答复我就服了你,这样问的结果往往是等半天没一个人鸟你,悲观的你或者就此凄凉的退群了,感概人情冷暖的同时甚至开始怀疑人生:积极的你或者这才意识到~要不干脆说问 ...
- 【SQL】统计所有表的行数
环境:mssql ent 2k8 r2 原理:遍历所有用户表,用sp_spaceused过程分别获取每张表的行数并写入临时表,最后返回临时表 IF OBJECT_ID('tempdb..#TableR ...
- NanUI for Winform 使用示例【第二集】——做一个所见即所得的Markdown编辑器
经过了这一个多星期的调整与修复,NanUI for .NET Winform的稳定版已经发布.应广大群友的要求,现已将NanUI的全部代码开源. GitHub: https://github.com/ ...
- 使用Toast的setText()实现倒计时
点击按钮发送短信以后,倒计时3秒钟后退出Activity.本来想用弹出多个Toast的方法实现,后来发现效果不好,因为Toast.LENGTH_LONG显示3秒钟,Toast.LENGTH_SHORT ...
- 【Java每日一题】20161019
20161018问题解析请点击今日问题下方的"[Java每日一题]20161019"查看 package Oct2016; import java.util.List; publi ...
- PHP的PSR系列规范都有啥内容
PSR 是PHP Standard Recommendation的简写,它其实应该叫PSRs,即系列推荐标准:目前通过的规范有PSR-0(Autoloading Standard).PSR-1(Bas ...
- c++错误代码1
今天敲c++,出现一个错误,这个题目错误代码如下: 并没有提示有错误而终止. 运行结果却错了: 很明显,错误的地方是变量r没有初始化. 这让我知道了,这种情况下的某些变量未经初始化而使用编译器是不会报 ...