美文网首页
JNI——热修复(阿里AndFix)

JNI——热修复(阿里AndFix)

作者: 追寻米K | 来源:发表于2018-10-10 23:10 被阅读0次

android 的虚拟机是加载dex,并不是像java虚拟机那样加载class。

简单说一下原理:

public class Test{

            public static void main(String[] args){

                        Mik mik = new Mik();

                        mik.doIt(); 

        }

}

当一个应用启动,首先开辟一个方法区,然后加载Test.class类的字节码,这些字节码当然包括main方法的字节码,当走到main时,会把main方法做压栈操作,得到main栈帧,再去加载Mik.class的字节码,Mik mik = new Mik();分为三步,第一步:在方法区申明一个 Mik的mik符号变量,第二步再去开辟堆内存,第三步,给mik这个变量赋值。调用的时候在方法表查询对应的方法索引,然后根据索引找到方法的结构体指针,所以只要替换掉这个结构体指针,就把方法切换了。

Dalvik虚拟机:

1、Dalvik虚拟机采用JIT技术,字节码都需要通过即时编译器(just in time JIT)转换为机器码,发生在运行时。

2、把dex文件转换为odex来运行

ART虚拟机:

1、把字节码转换成机器码的过程放在了安装时

2、安装时把dex使用系统的dex2oat工具把dex转化为OAT文件,OAT是一种android私有的ELF文件格式,它不仅包含从dex翻译过来的本地机器指令,还办含有原来的DEX文件的内容。

所以在后面修复的时候改成class的加载状态ART就不需要了。

只是简单的 说一下区别而已

流程:(模仿AndFix)

1 发现bug 并修改bug,将修复的java文件 编译成class 然后打包成dex 放到服务器 供客户端下载

2    将修复的方法体 Method 从dex 文件取出,将会出现bug的方法 Method 也取出来

3    将取出的正确的  和 错误的method 一并传到底层做替换操作

4    底层替换 (指针替换)

先在客户端写一个有bug的方法。

1、再模仿写一个修改好的方法

2、把修复好的java编译成class,因为包名要跟错误的class文件一致,所以错误的class有多少文件夹层级,正确的class也要有多少层。

至于生成class文件可以javac,也可以把修复好的项目运行一下把class拷贝出来像这样:

3、生成dex,androidSdk/build-tools/27.0.3/dx.bat(27.0.3随便一个版本号)当然要配置环境变量啦。

路径1是输出dex的目录,路径2是java文件所在的文件夹(因为文件夹层级跟项目对应),得到out.dex复制到SD卡中(假装是下载的),接下来就解析这个dex得到class最后得到具体的方法。

加载dex并得到class

通过class得到正确的方法和错误的方法,最后调用native方法替换

底层替换涉及到虚拟机,所以就有dalvik和art的区别,先说dalvik:

因为要修改指针的指向,所以得用到虚拟机中的部分功能啦,主要从这两个头文件中拷贝代码,组成自己的头文件(怎么知道拷贝这些的,我也不知道。。。大神研究之后的结果,从android 源码里面拷贝的)

android4.4/dalvik/libdex/DexFile.h

android4.4/dalvik/vm/Object.h

ART虚拟机:

7.0的兼容:

混淆问题:

混淆时候类名,方法名改变了,所以做不到修复的,上面是通过系统的dx.bat生成dex现在使用阿里的工具生成dex。

下载andfix 里面有工具ApkPath,使用这个工具生成两个包的差分。

apkpatch.bat -f new.apk -t old.apk -o output -k 签名.jks -p 123456 -a mik -e 123456 (MAC 和 Linux 是apkpatch,sh)

-f 修复好的apk  -t 出现bug的apk   -o输出的文件 -k签名  -p签名密码  -a别名

-e 别名密码

源码

相关文章

网友评论

      本文标题:JNI——热修复(阿里AndFix)

      本文链接:https://www.haomeiwen.com/subject/mkwksftx.html