一个APK文件通常包含以下文件:
- class.dex: Dalvik字节码,可被Dalvik虚拟机执行。
- AndroidManifest.xml: 一个Android清单文件,用户描述该应用程序的名称、版本号、所需权限、注册服务、链接到的其它应用程序。该文件使用XML文件格式。
- META-INF文件夹:下面有3个文件
- MANIFEST.MF:清单信息
- CERT.RSA:保存应用程序的证书和授权信息
- CERT.SF:保存SHA-1信息资源列表
- res:APK所需要的资源文件夹
- assets:不需编译的原始资源文件目录
- resources.arsc:编译后的二进制资源文件
- lib:库文件目录
Dalvik虚拟机与反编译:
区别于JAVA虚拟机(JVM),安卓虚拟机称为Dalvik虚拟机(DVM)。Java虚拟机运行的是Java字节码,Dalvik虚拟机运行的是Dalvik字节码。Java虚拟机基于栈架构,Dalvik虚拟机基于寄存器架构。
DVM拥有专属的DEX可执行文件格式和指令集代码。smali和baksmali则是针对DEX执行文件格式的汇编器和反汇编器,反汇编后DEX文件会产生.smali后缀的代码文件,smali代码拥有特定的格式与语法,smali语言是对Dalvik虚拟机字节码的一种解释。
apktool工具是在smali工具的基础上进行封装和改进的,除了对DEX文件的汇编与反汇编功能外,还可以对APK中已编译成二进制的资源文件进行反编译和重新编译。如下是使用apktool工具来反汇编APK文件得到其对应文件信息(默认是输出到同名当前目录,可以使用-o参数输出到执行目录):
apktool d /Users/johnnie/Downloads/xxx.apk
- AndroidManifest.xml 配置文件
- apktool.yml 反编译生成的文件,供apktool使用
- assets/ 不需反编译的资源文件目录
- lib/ 不需反编译的库文件目录
- res/ 反编译后的资源文件目录
- smali/ 反编译生成的smali 源码文件目录
其中,smali目录结构对应着原始的java源码src目录。(也是Dalvik字节码提取的关键位置,类似于Windows的EXE的opcode,可见都有其共通性!)
Dalvik指令的分类与描述
smali是对DVM字节码的一种解释,虽然不是官方标准语言,但所有语句都遵循一套语法规范。Dalvik opcodes的详细说明可以参考这篇文章,里面详细列举了Dalvik Opcode的含义及用法、例子。
由于Dalvik指令有两百多条,对需要的进行了分类和精简,去掉了无关的指令,只留下了M、R、G、I、T、P、V七大类核心的指令集合,并且只保留操作码字段,去掉了参数。M、R、G、I、T、P、V七大类指令集合分别代表了移动、返回、跳转、判断、取数据、存数据、调用方法七种类型的指令。如下分类与描述: