• 博马23466.com_博马23466.com【微信快捷支付】

  • 发布时间:2016-01-13 05:20 | 作者:yc | 来源:互联网 | 浏览:1200 次
  • 博马23466.com_博马23466.com【微信快捷支付】

    虚拟机在发动的时分,会有许多的发动参数,其间一项等于verify选项,当verify选项被翻开的时分,上面doVerify变量为true,那么就会实行dvmVerifyClass进行类的校验,要是dvmVerifyClass校验类成功,那么这个类会被打上CLASS_ISPREVERIFIED的象征,那么详细的校验进程是什么姿态的呢?

    此代码在DexVerify.cpp中,如下:

    650) this.width=650;" width="600" title="安卓App热补丁动态修正技能:让App像Web相同宣布新版别 ..." class="zoom" id="aimg_" alt="安卓App热补丁动态修正技能:让App像Web相同宣布新版别 ..." src="http://www.gameres.com/data/attachment/forum//30/fmcmlw36vlz6mlfv.png" />

    5 小时前 上载

    下载附件 (85.93 KB)

    1. 验证clazz->directMethods法子,directMethods包括了以下法子:

    1. static法子

    ?2. private法子

    ?3. 布局函数

    2.?clazz->virtualMethods

    1. 虚函数=override法子?

    归纳一下等于要因此上法子中直接引证到的类(榜首层级联系,不会进行递归查找)和clazz都在同一个dex中的话,那么这个类就会被打上CLASS_ISPREVERIFIED象征

    650) this.width=650;" width="549" title="安卓App热补丁动态修正技能:让App像Web相同宣布新版别 ..." class="zoom" id="aimg_" alt="安卓App热补丁动态修正技能:让App像Web相同宣布新版别 ..." src="http://www.gameres.com/data/attachment/forum//30/zhraxa85aau8kxhq.png" />

    5 小时前 上载

    下载附件 (481.88 KB)

    所以为了完成补丁计划,以是有需要从这些法子中下手,避免类被打上CLASS_ISPREVERIFIED象征

    当一个App宣布今后,俄然发清楚明了一个严酷bug需求进行紧迫修正,这时分公司各方就会忙得焦头烂额:从头打包App、测验、向各个运用墟市和道路换包、提示用户晋级、用户下载、掩饰笼罩装配无意偶尔分只是是为了修正了一行代码,也要支付无穷的成本进行换包和从头宣布

    这时分就提出一个疑问:有没有法子以补丁的法子动态修正紧迫Bug,不再需求从头宣布App,不再需求用户从头下载,掩饰笼罩装配?

    办理计划

    该计划根据的是android dex分包计划的,对付dex分包计划,网上有几篇讲解了,以是这儿就不再赘述,详细能够看这儿https://m.oschina.net/blog/

    大略的归纳一下,等于把多个dex文件塞入到app的classloader当中,可是android dex拆包计划中的类是没有重复的,要是classes.dex和classes1.dex中有重复的类,当用到这个重复的类的时分,体系会遴选哪个类进行加载呢?

    让咱们来看看类加载的代码:

    public Class findClass(String name, List suppressed) {

    for (Element element : dexElements) {//每个Element等于一个dex文件

    DexFile dex = element.dexFile;

    if (dex != null) {

    Class clazz = dex.loadClassBinaryName(name, definingContext, suppressed);

    博马23466.com_博马23466.com【微信快捷支付】

    if (clazz != null) {

    return clazz;

    }

    }

    }

    if (dexElementsSuppressedExceptions != null) {

    suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));

    }

    return null;

    }

    仿制代码

    一个ClassLoader能够包括多个dex文件,每个dex文件是一个Element,多个dex文件排列成一个有序的数组dexElements,当找类的时分,会按序次遍历dex文件,然后从当前遍历的dex文件中找类,要是找类则回来,要是找不到从下一个dex文件持续查找

    理论上,要是在不相同的dex中www.ye321,com有相同的类存在,那么会优先遴选排在前面的dex文件的类,如下图:

    650) this.width=650;" width="600" title="安卓App热补丁动态修正技能:让App像Web相同宣布新版别 ..." class="zoom" id="aimg_" alt="安卓App热补丁动态修正技能:让App像Web相同宣布新版别 ..." src="http://www.gameres.com/data/attachment/forum//30/ndmn71pz17iba.jpg" />

    5 小时前 上载

    下载附件 (101.4 KB)

    在此根基上,咱们构想了热补丁的计划,把有疑问的类打包到一个dex(patch.dex)中去,然后把这个dex刺进到Elements的最前面,如下图

    650) this.width=650;" width="600" title="安卓App热补丁动态修正技能:让App像Web相同宣布新版别 ..." class="zoom" id="aimg_" alt="安卓App热补丁动态修正技能:让App像Web相同宣布新版别 ..." src="http://www.gameres.com/data/attachment/forum//30/q3powk43gl7zaopx.jpg" />

    5 小时前 上载

    下载附件 (81.61 KB)

    好,该计划根据第二个拆分dex的计划,计划完成要是懂拆分dex的道理的话,咱们该当很快就会完成该计划,要是没有拆分dex的项目的话,能够参阅一下google的multidex计划完成然后在刺进数组的时分,把补丁包刺进到最前面去

    好,看似疑问很大略,轻松的搞定了,让咱们来实验一下,修正某个类,然后打包成dex,刺进到classloader,当加载类的时分出现了(本例中是ActivityManager要被替换):

    650) this.width=650;" width="600" title="安卓App热补丁动态修正技能:让App像Web相同宣布新版别 ..." class="zoom" id="aimg_" alt="安卓App热补丁动态修正技能:让App像Web相同宣布新版别 ..." src="http://www.gameres.com/data/attachment/forum//30/sfd0wcmbfj8jccfc.jpg" />

    5 小时前 上载

    下载附件 (112.24 KB)

    为何会出现以上疑问呢?

    从log的意思上来讲,ModuleManager引证了ActivityManager,可是发明这这两个类地点的dex不在一同,其间:

    1. ModuleManager在classes.dex中

    2. ActivityManager在patch.dex中

    成果发生了同伴

    这儿有个疑问,拆分dex的许多类都不是在同一个dex内的,如何没有疑问?

    让咱们查找一下抛出同伴的代码地点,嘿咻嘿咻,找到了一下代码:

    650) this.width=650;" width="568" title="安卓App热补丁动态修正技能:让App像Web相同宣布新版别 ..." class="zoom" id="aimg_" alt="安卓App热补丁动态修正技能:让App像Web相同宣布新版别 ..." src="http://www.gameres.com/data/attachment/forum//30/jahlftqffal6l9.png" />

    5 小时前 上载

    下载附件 (233.24 KB)

    从代码上来看,要是两个相关联的类在不相同的dex中就会报错,可是拆分dex没有报错这是为何,原先这个校验的前提是:

    650) this.width=650;" width="540" title="安卓App热补丁动态修正技能:让App像Web相同宣布新版别 ..." class="zoom" id="aimg_" alt="安卓App热补丁动态修正技能:让App像Web相同宣布新版别 ..." src="http://www.gameres.com/data/attachment/forum//30/ll4kpjcq4zc6wwjw.jpg" />

    博马23466.com_博马23466.com【微信快捷支付】

    5 小时前 上载

    下载附件 (22.26 KB)

    要是引证者(也等于ModuleManager)这个类被打上了CLASS_ISPREVERIFIED象征,那么就会进行dex的校验那么这个象征是什么时分被打上去的?

    让咱们在持续查找一下代码,嘿咻嘿咻~~,在DexPrepare.cpp找到了一下代码:

    650) this.width=650;" width="571" title="安卓App热补丁动态澳门皇家赌场怎么用支付宝支付修正技能:让App像Web相同宣布新版别 ..." class="zoom" id="aimg_" alt="安卓App热补丁动态修正技能:让App像Web相同宣布新版别 ..." src="http://www.gameres.com/data/attachment/forum//30/sx7boubujdduddm2.png" />

    5 小时前 上载

    下载附件 (82.2 KB)

    这段代码是dex转化成odex(dexopt)的代码中的一段,咱们知道当一个apk在装配的时分,apk中的classes.dex会被虚拟机(dexopt)优化成odex文件,然后才会拿去实行

    毕竟空间的计划是往统统类的布局函数里边刺进了一段代码,代码如下:

    if (ClassVerifier.PREVENT_VERIFY) {

    System.out.println(AntilazyLoad.class);

    }

    仿制代码

    650) this.width=650;" width="600" title="安卓App热补丁动态修正技能:让App像Web相同宣布新版别 ..." class="zoom" id="aimg_" alt="安卓App热补丁动态修正技能:让App像Web相同宣布新版别 ..." src="http://www.gameres.com/data/attachment/forum//30/g5zdvuuhl1i7l7vh.png" />

    5 小时前 上载

    下载附件 (268.25 KB)

    其间AntilazyLoad类会被打包成独自的hack.dex,这么当装配apk的时分,classes.dex内的类都邑引证一个在不相同dex中的AntilazyLoad类,这么就避免了类被打上CLASS_ISPREVERIFIED的象征了只需没被打上这个象征的类都能够进行打补丁操作

    然后在运用发动的时分加载进来.AntilazyLoad类地点的dex包有需要被先加载进来,否则AntilazyLoad类会被标记为不存在,即便后续加载了hack.dex包,那么他也是不存在的,这么屏幕就会出现苍茫多的类AntilazyLoad找不到的log

    以是Application作为运用的入口不能刺进这段代码(因为载入hack.dex的代码是在Application中onCreate中实行的,要是在Application的布局函数里边刺进了这段代码,那么等于在hack.dex加载之前就运用该类,该类一次找不到,会被永远的打上找不到的象征)

    其间:

    class ClassVerifier {

    public static boolean PREVENT_VERIFY = false;//false避免代码被实行,进步功能

    }

    仿制代码

    之以是遴选布局函数是因为他不添加法子数,一个类即便没有显式的布局函数,也会有一个隐式的默许布局函数

    空间运用的是在字节码刺进代码,而不是源代码刺进,运用的是javaassist库来进行字节码刺进的

    危险:

    虚拟机在装配时期为类打上CLASS_ISPREVERIFIED象征是为了进步功能的,咱们强行避免类被打上象征是不是会影响功能?这儿咱们会做一下愈加详细的功能测验

    可是在大年夜项目中拆分dex的疑问现已比较严酷,许多类都没有被打上这个象征

    怎么打包补丁包:

    1.空间在正式版别宣布的时分,会天生一份缓存文件,里边记录了统统class文件的md5.还有一份mapping稠浊文件

    2.在后续的版别中运用-applymapping选项,运用正式版其余mapping文件,然后核算编译完成后的class文件的md5和正式版别进行比较,把不相同的class文件打包成补丁包

    补白:该计划如今也运用到咱们的编译进程当中,编译不需求从头打包dex,只需求把修正过的类的class文件打包成patch dex,然后放到sdcard下,那么就会让篡改的代码见效

  • 相关内容

友情链接: