接下来选两个具体的命令,来走读一遍实现功能的流程、使用了哪些功能库。第一个选择解析dex的最后一个功能,打印指定类、方法的反编译代码;第二个选择资源文件解析的最后一个命令,输出指定xml二进制文件对应的可读版本。
1. 打印dex中某个类、方法的smali代码
首先,一定是从cli库中找到对应的命令枚举类型实现。
|
|
在DEX_CODE类型的执行函数部分,可以找到impl类中对应的方法dexCode——ApkAnalyzerImpl类的功能函数代码如下:
|
|
流程比较明确,加了一些简单的注释。
第一步,解压APK
Archives工具类在apkanalyzer.jar中,open这个函数基本上是所有命令的调用必经之路——毕竟解析内容第一步就是解压APK文件。可以看到里面根据zip和其他两种情况,使用了不同的工具类来做解压:
|
|
open函数返回的Archive是个接口,具体如下:
|
|
结合Archives来看,无非是使用java nio的一些文件工具,来实现解压方法。具体到AndroidArtifact上,有一些特殊的分析功能。
第二步,解析dex文件
DexBackedDexFile,该类在dexlib2-2.2.1.jar包中,包名路径是org.jf.dexlib2.dexbacked。这个包在sdk同目录下,也可以在网络上找到它的信息——dexlib2。
dexlib2 is a library for reading/modifying/writing Android dex files
简单讲,这个库可以读、写、改dex文件,很多搞hook、修改dex的工具插件等黑科技都会使用到这个库。可以查询它的javadoc看它具体的功能接口。
呃……不是很友好,没有什么注释的样子。这个类走读的话,看下构造就好了:
|
|
成员属性的初始化,各种数据是如何从dex文件流中解析出来的,找对应的read函数就好了。
DexDisassembler 该类是apkanalyzer.jar里面的类,包名目录是com.android.tools.apk.analyzer.dex。它只有不到70行的长度,构造参数要求传入DexBackedDexFile实体,其中只有两个公用方法:
- public String disassembleMethod(final String fqcn, final String methodDescriptor) throws IOException
- public String disassembleClass(final String fqcn) throws IOException
逻辑也比较简单,通过构造传入的DexBackedDexFile实体,获得dex文件的解析的class信息,然后根据方法需要来输方法或者类的反编译信息。
第三步,根据参数要求输出,并处理异常情况
后面的输出逻辑也是一目了然的。根据是否有method参数,走不通的逻辑。有的话,查找对应的method;没有就输出整个类。如果找不到或者发生其他解析问题,抛出异常。
2. 把二进制XML文件的转换成可读的XML文件打印出来
相比而言,这条命令同样是代码的还原,只不过针对的是资源文件的二进制文件。同样的,找到对应的命令枚举类型的实现定义:
|
|
同样具体功能函数会追溯到impl类中,找到对应的方法:
|
|
同样的open函数,解压好目标APK文件。在校验好文件类型后,调用了BinaryXmlParser的静态方法,该类在apkanalyzer.jar中,具体实现如下:
|
|
文件解析
核心的文件解析部分在binary-resources.jar中,即BinaryResourceFile、Chunk类,包名目录是com.google.devrel.gmscore.tools.apk.arsc。根据BinaryResourceFile的构造可以看出这一点:
|
|
Chunk略上,贴一部分代码基本就可以看出,是个根据资源文件二进制的数据结构特点来处理的具体解析类:
|
|
各种情况处理
解析后有几种情况。具体情况需要分析BinaryResourceFile的具体实现,来看。这里不做深入。最后一种情况则是解析XmlChunk。对应的使用XmlPrinter,该类是BinaryXmlParser中的一个内部工具类。看代码基本可以推断是转化各种Chunk内容的一个内容管理类。通过visitChunks,把XmlChunk的各种属性、元素内容写入XmlPrinter,最终输出可读的xml内容。
这里面除了上面提到的binary-resources相关的工具类和数据Bean之外,还涉及到一个XmlBuilder类,包名目录是com.android.xml,在common-26.0.0-dev.jar中,用于组装xml的各种零部件。
小结
也仅仅是走读代码,读其大略而已。没有深入研究dex、arsc具体的文件格式。
- sdk tools里面有很多工具jar,基本上可以包含所有的apk打包相关的各个环节
- 了解一些反编译的细节之后,多少对打包这件事本身会有更进一步的掌控