了解APK构建打包流程
构建构成中用到的工具
aapt/aapt2 android资源打包工具
aidl android接口描述语言转化为跨进程通信.java文件的工具
javac java编译器
proguard 代码混淆工具
dx/d8 转化.class文件为Davik VM能识别的.dex文件
apkbuilder 打包生成.apk文件
jarsigner 签名工具
zipalign 字节码对齐优化工具
AAPT : Android Asset Packaging Tool
第一步:资源合并(本地资源,第三方arr库)
第二部: 资源文件编译assets,AndroidManiFest.xml,res.生成R.java文件,赋予每一个非assets文件一个id,以常量的形式定义于R.java文件,生成resources.arsc文件,用来描述那些具有ID值的资源配置文件信息,他的内容就相当于是一个资源索引表,包含了所有的id值的数据集合,在该文件中,如果某个id对应的是string,那么该文件会直接包含该值,如果id对应资源是某个layout或者drawable资源,那么该文件会存入对应资源的路径。
resources.arsc文件可以通过Android studio中的Analyze apk功能查看文件结构
aidl文件编译
aidl:android interface Definition Language
aidl工具解析接口定义文件,然后生成相应的Java代码接口供程序调用,如果在项目中没有用到aidl,则不会走到这一步
输入:aidl后缀的文件,位于工程src/main/aidl目录。
输出:可用于进程通信的C/S端java代码,位于build/generated/source/aidl.
java源码编译
R.java和aidl生成的Java文件,再加上工程的源代码,使用javac编译生成的class文件
输入 java源码文件夹(另外还包括了aapt生成的R.java,aidl生成的文件,以及BuildConfig.java)。
输出 对于gradle编译,生成的class文件保存在build/intermediates/classes.
proguard 代码混淆
javac完成代码编译后,一般还会对源码进行混淆,类似于加密。目的是为了增加反编译的难度,同时也将代码名称进行缩短,减少代码占用体积
输入:编译后的.class文件,混淆规则配置文件proguard-rules.pro
输出:被混淆后的.class文件,混淆前后的映射文件
转化为DEX文件
dx工具生成可供系统虚拟机可以执行的classes.dex文件,dx会将class转化为Dalvik字节码,生成常量池,消除冗余数据
输入:所有的.class文件
输出:classes.dex文件
打包apk文件
打包生成APK文件,旧的apkbuilder脚本已经废弃,现在通过sdklib,jar的ApkBuilder类进行打包。
输入:ap_资源包文件,classes.dex文件,未编译的资源文件(assets资源等),libs等文件
输出:apk文件
签名apk文件
队apk文件进行签名,文件签名后设备才会允许安装
输入 上一步骤的apk文件、签名文件(Debug Release KeyStore)
输出 签名后apk文件
zipalign优化
zipalign对签名后的apk文件进行对齐处理,使APK中所有资源文件距离文件起始偏移为4字节倍数,从而在通过内存映射访问apk时会更快,同时也减少了设备在运行时内存的耗损
输入:签名后的apk文件
输出:对齐优化后的apk文件
APK典型文件
AndroidManiFest.xml 程序全局配置文件表
classes.dex Davilk字节码
resources.arsc 资源索引表
META-INF 该目录下存放的是签名信息
res 该目录存放的是资源文件
assets 该目录下存放的是一些配置或资源文件
关联技术
APK加固
资源混淆
热修复
插件化
快速多渠道打包
Dex文件编译流程
java文件源码编译 通过javac将源码编译为class文件
多DEX分包 脚本将类根据一些规则划分到主dex和从dex中,生成配置文件
proguard优化混淆 对.class文件进行压缩、优化、混淆处理
转化为为dex文件 dx/d8将.class文件转化为dex文件
了解DEX编译过程与MultiDex方案原理
MultiDex方案背景
64K引用限制
原因:DexOpt优化的限制 早期的Android系统中的DexOpt会把每一个类的方法id检索起来,存在一个链表结构里面,链表的长度是由short类型来保存的,导致了方法id的数目不能超过65536个。
dalvik bytecode的限制
dalvik的invoke-kind指令集,设置16bit表示方法的引用数,最大值为65536,invoke-kind
Android 5.0以前 使用dalvik可执行 文件分包支持库
Android 5.0以后默认支持从apk文件加载多个DEX文件
了解proguard混淆与防反编译
混淆的目的 加大反编译的难度
配置 在build.gradle中配置
常见的混淆配置
keep 用来保留Java的元素不进行混淆
-keep 保留类和类中的成员,防止他们被混淆或移除
-keepClassmembers 只保留类中的成员,防止他们被混淆和移除
-keepClasseswithmembers 保留类和类中的成员,防止他们被混淆或移除,前提是指名的类中的成员必须存在,若不存在还是会混淆
dontwarn
引入的library可能存在一些无法找到的引用和其他问题,在build中可能会发出警告会导致build终止,因此为了build继续进行,需要dontwarn处理这些无法解决的library的警告。
需要keep的情况
enum枚举
Android 四大组件
自定义控件,集成view的类
实现了Parcelable接口
序列化和反序列化的类
反射的成员变量或者方法(包括jni,js中的反射)
注解
Native方法
第三方sdk
反编译工具对抗
花指令 在原始程序中插入一组无用的字节,但又不会改变程序的原始逻辑,程序仍然可以继续运行,然而反编译工具在反编译的时候这些字节会出错,造成反汇编工具失效,提高破解难度,
资源混淆
修改aapt
修改aapt处理资源文件相关的源码,参考proguard方式对APK中资源文件名使用简短无意义名称进行替换,给破解者造成困难,从而做到资源的相对安全
修改resources.arsc
根据resources.arsc文件格式,修改资源名与路径的映射关系。
网友评论