文章目录
  1. 1. apkpatch工具实现分析
    1. 1.1. 一、工具入口
  2. 2. 二、补丁包合并
  3. 3. 三、生成补丁包
    1. 3.1. 3.1、对比两个APK的类和方法
    2. 3.2. 3.2、写入PACTH.MF文件

apkpatch工具实现分析

apkpatch工具是配套阿里AndFix框架的一个生成aptach补丁包的工具,链接地址是:https://github.com/alibaba/AndFix/tree/master/tools 。主要包含反编译对比两个APK的类和方法、修改类名写入PACTH.MF文件、生成补丁apatch包。

由于没有从网上找到对应的源码,以下分析过程均通过jd-gui工具反编译jar包阅读反编译代码完成。

一、工具入口

从命令行执行apkpatch命令时,调用的是com.euler.patch.Main类中的静态main()方法。通过对参数的解析,解析出两个APK的路径及签名文件相关信息。根据命令参数的不同,主要分为两个过程,第一个过程是如果参数中有-m参数,那么会执行补丁包的合并过程,即将-m参数指定的文件合并到一个merge.aptach文件中;另外一个过程是通过构造com.euler.patch.ApkPatch类对象,调用其doPatch()方法,启动生成补丁包。

解析-m参数为合并代码逻辑反编译代码如下图所示:

解析参数为合并

生成补丁包的逻辑反编译代码如下图所示:

生成补丁包

二、补丁包合并

合并操作是调用com.euler.patch.MergePatch类中的doMerge()方法,其中会调用mergeCode(File)方法,将需要的合并的patch包中的classes.dex合并到一个dex文件中。合并过程是通过调用调用com.android.dx.merge.DexMerger类merge()方法完成。

三、生成补丁包

生成补丁包

3.1、对比两个APK的类和方法

在执行apkpatch工具时,命令参数-f表示的是新生成的APK,-t参数表示的是原APK包,两个APK不同的信息保存在com.euler.patch.diff.DiffInfo类实例中,其中包括,不同的类信息、方法信息以及属性信息。这些不同的信息是通过调用com.euler.patch.diff.DexDiffer类的diff()方法获取。

这里有个关键的地方是将修改的方法,也可以说是出现bug的方法会增加一个Lcom/alipay/euler/andfix/annotation/MethodReplace;注解,在android加载补丁包的环境中,方法替换是根据方法是否有@MethodReplace注解而进行替换的。

通过调用ApkPatch类的buildCode(File, File, DiffInfo)方法,将所有新增的类或发生修改的类根据类名将类的信息转换成smali格式的文件,修改类名信息后,即加上_CF后缀,重新生成新的新的dex文件。

3.2、写入PACTH.MF文件

紧接着调用ApkPatch的父类,即Build类的build(File, File)方法打成APK包,同时调用getMeta()方法写入PATCH.MF文件补丁包信息。getMeta()方法具体实现是在ApkPatch类中,注意PATCH.MF文件中的Patch-Classes字段对应的内容是带_CF后缀的类名。这个在android运行环境中解析的时候会用到这个字段。

getMeta()方法反编译代码如下所示:

写入MF信息

最后是调用Build类中的release()方法对打包的APK文件进行签名,生成包含签名信息的patch包。

– EOF –

文章目录
  1. 1. apkpatch工具实现分析
    1. 1.1. 一、工具入口
  2. 2. 二、补丁包合并
  3. 3. 三、生成补丁包
    1. 3.1. 3.1、对比两个APK的类和方法
    2. 3.2. 3.2、写入PACTH.MF文件