参考文档:https://developer.android.google.cn/studio/build/multidex.html#keep

1、由文档中可以知道 了解到 在Android5.0之前我们使用的是Dalvik虚拟机,默认情况下,Dalvik 限制应用的每个 APK 只能使用单个 classes.dex 字节码文件。要想绕过这一限制,您可以使用 Dalvik 可执行文件分包支持库,它会成为您的应用主要 DEX 文件的一部分,然后管理对其他 DEX 文件及其所包含代码的访问。

当然,当5.0以后,Android 5.0(API 级别 21)及更高版本使用名为 ART 虚拟机的运行时,后者原生支持从 APK 文件加载多个 DEX 文件。ART 在应用安装时执行预编译,扫描 classesN.dex 文件,并将它们编译成单个 .oat 文件,供 Android 设备执行。因此,如果您的 minSdkVersion 为 21 或更高值,则不需要 Dalvik 可执行文件分包支持库。

由于我们现在应用基本都在5.0以后的版本,所以大都支持多dex分包支持了,但是也会有一些其它的设备,比如智能家居等有使用低版本的时候,可能会遇到64K的问题,为了正常使用多分包功能,可以参考上面的文档中介绍的如下方式:

修改模块级 build.gradle 文件以启用 Dalvik 可执行文件分包,并将 Dalvik 可执行文件分包库添加为依赖项,如此处所示:

android {defaultConfig {...minSdkVersion 15 targetSdkVersion 28multiDexEnabled true}...
}dependencies {compile 'com.android.support:multidex:1.0.3'
}

2、我们一般的apk是这样的,直接打开apk是可以看到里面的源码的,如下图所示

这样对大家来说就不安全,我们所要做的就是把我们的apk中的dex文件加密,让别人就算拿到我们的apk里面啥也看不到。如下图所示,点击加密之后的apk,里面啥也没有,一个代码都看不到,这就是我们要做的:

2、具体怎么做呢?请看下图介绍

上图中左边是我们未加密的apk打开之后显示的文件结构,我们需要一个proxy代理application  以及一个 加密所用的Tools ,用tools来给左边的两个dex进行加密,然后在把加密之后的文件和左边其它的文件一起打包成apk 这样别人就看不到我们的源码了,但是新的文件的dex文件用户是无法运行的,这个时候,我们就需要一个proxy 的application,把我们新打包的apk所有内容交给代理application,然后让代理application去和Android系统对接,因为系统可以加载dex文件的,所以这个时候,我们的代理application要做的就是把拿到的加密的apk中的dex文件进行解密,然后在交给系统处理。

3、我们要先了解自己写的代码是如何被加载到内存的,可以在MainActivity中用以下代码查看:

Log.d("wwy",getClassLoader().toString());    经过运行发现打印信息为:dalvik.system.PathClassLoader  

我们在系统源码中查找这个PathClassLoader ,查看父类 BaseDexClassLoader

我们通过Android系统源码找到  PathClassLoader------>  BaseDexClassLoader  ----->  findClass()方法  -----> pathList.findClass() 方法    ,接着查看 pathList 类中都是什么,发现这个类中的方法 就是 findClass(String name,List<Throwable> suppressed) ;它通过循环遍历DexFile ,其实这就是获取dex文件,其实系统所有的dex文件都是要经过这里处理的

所以关键来了,既然所有的dex文件都是通过这里处理,也就是 dexElements  , 它本身就是一个数组,我们只需要通过反射拿到这个数组,接着我们通过代码把我们自己的解密之后的dex文件放到我们定义的一个数组中,然后把我们的数组和系统的dex文件数组合并在一起,交给系统去处理。

这里我们在看系统的dex文件数组 dexElements 是怎么初始化的呢?通过查看系统源码,发现如下,

那么我们通过反射拿到这个方法,就可以拿到系统的dex文件数组了,然后再把我们的数据和系统合并后在赋给系统里面的dexElements 这样就把dexElements更新后,这样我们的dex文件就加载到android里面运行了。

好了具体的思路上面就介绍到这里,下面开始实现这个功能。

4、我们新建一个android project ,然后,在项目里面Create New Module 选择 Android Library   ,这就是给我们代理的application ,命名为:proxy_core ;然后还需要一个加密工具,在项目中 Create New Module 选择 Java Library  这个java library不需要我们运行时处理,它直接在我们编译的时候就进行加密,这就是为什么创建的是java library ,这命名为:proxy_tools  建好之后,记得把这个proxy_tools 添加到项目中,如下:

添加编译完之后,在app的build.gradle中会自动如下所示:

好了,下面就开始写代码了!

具体的在下个博客中详细介绍。先下班了!哈哈。。。  代码用到的三个工具类请在移步:https://download.csdn.net/download/i123456789t/11239056

具体代码实现请看下一篇:https://blog.csdn.net/I123456789T/article/details/91819275

Android中Apk加固之Dex文件的加密与解密相关推荐

  1. Android中apk加固完善篇之内存加载dex方案实现原理(不落地方式加载)

    一.前言 时隔半年,困扰的问题始终是需要解决的,之前也算是没时间弄,今天因为有人在此提起这个问题,那么就不能不解决了,这里写一篇文章记录一下吧.那么是什么问题呢? 就是关于之前的一个话题:Androi ...

  2. Android中的ClassLoader与dex文件加密实现分析

    Android中的ClassLoader BaseDexClassLoader Dex类加载器的基类,包含Dex类加载器之间通用功能的实现. DexClassLoader A class loader ...

  3. Android中常用的编码和解码(加密和解密)的问题

    1. URL Encoding     编码目的是为了在⺴址上可以包含中文等特殊字符 解码是为了把编码后的内容还原成原始的内容 格式如下%9C%3C%F3%98 规则: %hex_byte 就是将实际 ...

  4. Android打包出多个dex文件,一个APK中包含多个dex方法

    原因 每个单独的dex(Dalvik Executable)文件中的方法id范围为[0, 0xffff]:65536,包括安卓系统框架,三方库和自己写得代码中的方法.所以如果你的工程很大,包含了超过6 ...

  5. android dex文件过多,Android Studio中的多个Dex文件异常

    突然间,我在Android Studio中的项目中收到以下错误.Android Studio中的多个Dex文件异常 Execution failed for task ':app:dexDebug'. ...

  6. 【Android 安全】Android 应用 APK 加固总结 ( 加固原理 | 应用加固完整的实现方案 | 源码资源 )

    文章目录 一. APK 加固原理 1. Android 应用反编译 2. ProGuard 混淆 3. 多 dex 加载原理 4. 代理 Application 开发 5.Java 工具开发 6.Ap ...

  7. 从源码角度解析Android中APK安装过程

    从源码角度解析Android中APK的安装过程 1. Android中APK简介 Android应用Apk的安装有如下四种方式: 1.1 系统应用安装 没有安装界面,在开机时自动完成 1.2 网络下载 ...

  8. 【Android 安装包优化】Android 中使用 7zr 可执行程序 解压缩文件

    文章目录 一.Android 中使用 7zr 可执行程序 解压缩文件 二.完整代码示例 三.参考资料 一.Android 中使用 7zr 可执行程序 解压缩文件 在上一篇博客 [Android 安装包 ...

  9. 【Android 安装包优化】Android 中使用 7zr 可执行程序 压缩文件

    文章目录 一.Android 中使用 7zr 可执行程序压缩文件 二.完整代码示例 三.参考资料 一.Android 中使用 7zr 可执行程序压缩文件 在上一篇博客 [Android 安装包优化]A ...

最新文章

  1. 从方法论到零售客户实践 解码阿里巴巴数据中台——2018上海云栖大会
  2. python可以自学吗-python自学行吗 新手可以自学python吗
  3. RHEL在VM虚拟机下仅主机模式不能联网的解决方法
  4. [导入]ASP.NET断点续传和多线程下载
  5. Spring容器中Bean的作用域
  6. Mac配置Java环境变量等
  7. openwrt mt7620 内存大小检测
  8. 国产自主可控的MBSE建模与仿真平台SkyEye
  9. Linux之cut命令
  10. zeppelin 配置 spark
  11. Android基础控件EditText
  12. 网规:第2章 计算机网络规划与设计-2.8网络故障分析与处理
  13. Python 用下划线作为变量前缀和后缀指定特殊变量
  14. 【图论】用链式前向星(邻接表)存有向图(图文代码逐句分析)
  15. Termux安装Python
  16. 冠捷云计算机功能,USB3.0显示器亮相!AOC多款LCD新品赏
  17. 如何创建一个进度条控件
  18. 支付宝APP支付扫码支付
  19. Python 爬虫之 Beautifulsoup4,爬网站图片
  20. 小红书投放怎么变现?品牌做小红书的变现效果好吗

热门文章

  1. Box2d 物体互相碰撞的条件
  2. 去除影像黑边的N种方法
  3. 对话西乔霍炬,什么塑造了今天的编程世界?
  4. npm的命令参数 --save-dev和 --save两者有什么区别
  5. python 做山水画_python -- yield keyword
  6. 屏幕适配之带虚拟按键手机屏幕适配
  7. php 获取首字母,PHP_php 获得汉字拼音首字母的函数,php获取汉字拼音的第一个字母 - phpStudy...
  8. 一些比较值得思考和了解的.NET相关的面试题
  9. Docker RabbitMQ日志映射
  10. 关于python卸载遇到 No python 版本号 installation was detected的问题