apk文件的加密在我们的应用上架之前必不可少。通常我们是使用第三方加固软件,比如乐固,360加固宝类似的程序替我们完成。但是了解其原理对我们来说还是非常有用处的。
这篇来介绍通过dex 文件加密实现apk 加密的方式。
1 总体思路
2 对核心代码工程进行加密
核心工程中androidManifest 添加的application 是引用壳工程中的application.
(1) 在打包过程中,对打包好的apk进行解压到指定路径。
(2)对解压包中的dex文件进行加密,这里具体的加密算法自行选择。
3 对壳工程的处理
(1)壳工程生成aar包,将aar进行解压缩
(2) 解压后的classes.jar通过dx文件进行dex处理生成dex文件
利用dx --dex --output=命令
(3)将生成的dex文件复制到核心工程的解压包中。
4 对处理后的解压包进行压缩生成apk文件
(1)字节对齐
利用Android SDK中zipalign工具进行对齐
(2)给新的apk添加签名,生成签名apk
利用Android SDK中jarsigner进行签名
5 运行阶段
(1) 由于manifest中指定的application 是未加密的壳工程中的,所以可以直接加载到内存进行运行。
(2)除了application以为的其他核心代码由于都加密了,所以无法通过验证进行加载,那么就需要进行dex的解密,这个解密过程就放在application进行处理。
如何解密:
1 获取到私有目录下apk文件,输出到指定目录
2 解压apk并解密被加密了的dex文件(解压包中包含多个dex文件所以需要去遍历处理,但是注意壳文件中的dex包不要进行解密)
3 加载加密后dex文件
这里需要用到类加载器的知识进行技术支持。
(1)通过反射找到BaseDexClassLoader中的pathList属性,pathList是DexPathList类型的对象。
DexPathList中维护了一个dex文件数组(dexElementss数组),classLoader加载类的时候会从这dex数组中查找
(2 )创建我们自己的dex文件数组,这里不同api版本实现不一,需要进行版本适配
(3)将解密后的dex文件插入到DexPathList的dexElements
6 加密解密后的思考!
Q 这种dex加壳脱壳的方式有什么弊端?
A: 由于整个application没有进行加密,同时整个加密过程有全部在该文件中,稍微懂脱壳的开发者能够根据解密过程,对apk进行破解,安全性不佳。
Q 有什么方法可以完善
A:思路不变,将application中的解密过程抽出来,比如放到so库中,然后so库再进行混淆。这样一操作,有很让很多不懂C的破解者无从下手。反正就是对加密过程再进行一道道的处理。