中文站

插件 APK 保护方案介绍,化解 Android 生态中的安全漏洞风险

导读:插件化是 Android 技术领域里关注度较高的技术框架,插件化框架给 Android 开发者带来了很多便利,但是针对插件 APK 的保护也需要开发者重点关注。本文通过对插件化框架的背景以及原理的介绍,分享了易盾目前对插件 APK 的保护方案。(文 | 网易易盾-尹彬彬)

1.前言

插件化是 Android 技术领域里关注度较高的技术框架,自从 2012 年插件化概念被首次提出,到现在各种插件化方案百花争艳,插件化的热度一直居高不下。

在插件化框架中,插件依赖于宿主应用,宿主应用通过动态加载、反射等方式将插件包加载使用。作为一种特殊的应用场景,对插件的保护自然不同于一般的加固保护场景。目前市面上大多是针对非插件 APK 的加固保护方案,针对插件 APK 的保护方案目前还比较欠缺,因此亟需一种针对插件 APK 的加固保护方案。

本文将简要阐述插件化技术的背景、原理和应用场景,同时会介绍如何对插件包这种场景做加固保护。

2.插件化技术背景

何为「插件化」,顾名思义,就是把一些核心复杂依赖度高的业务模块封装成独立的插件,然后根据不同业务需求进行组合,动态替换,可对插件进行管理、更新等操作。

在插件化中有两个基础概念:

宿主:所谓宿主,就是需要能提供运行环境,给资源调用提供上下文环境,一般也就是我们主 APK ,要运行的应用,它作为应用的主工程,实现了一套插件的加载和管理的框架,插件都是依托于宿主的 APK 而存在的。

插件:插件可以想象成每个独立的功能模块封装为一个小的APK ,可以通过在线配置和更新实现插件APK在宿主APK中的上线和下线,以及动态更新等功能。

那么为何要使用插件化技术?简单来说有以下这几点好处:

插件动态更新,用户无需重新安装宿主 APK 就能升级应用功能;

按需加载不同的插件,实现灵活的功能配置;

宿主与插件分开编译,无需频繁更新,减少版本上线成本开销。

下面是比较出名的几个开源的插件化框架,按照出现的时间排序。大致可以看出插件化技术的发展脉络,根据实现原理可以将这几个框架划分成了三代。


第一代:dynamic-load-APK 最早使用 ProxyActivity 这种静态代理技术,由 ProxyActivity 去控制插件中 PluginActivity 的生命周期。该种方式缺点明显,插件中的 activity 必须继承 PluginActivity,开发时要小心处理 context。而 DroidPlugin 通过 Hook 系统服务的方式启动插件中的 Activity,使得开发插件的过程和开发普通的 APP 没有什么区别,但是由于 Hook 过多系统服务,异常复杂且不够稳定。

第二代:为了同时达到插件开发的低侵入性和框架的稳定性,在实现原理上都是趋近于选择尽量少的 Hook,并通过在 manifest 中预埋一些组件实现对四大组件的插件化。另外各个框架根据其设计思想都做了不同程度的扩展,其中 Small 更是做成了一个跨平台,组件化的开发框架。

第三代:VirtualApp 比较厉害,能够完全模拟 APP 的运行环境,能够实现 APP 的免安装运行和双开技术。Atlas 是阿里开源出来的一个结合组件化和热修复技术的 APP 基础框架,其广泛的应用与阿里系的各个 APP,号称是一个容器化框架。

3.插件化核心原理

插件化方案主要是解决下面三个问题:

插件中代码的加载和与宿主的互相调用。

插件中资源的加载和与宿主的互相访问。

插件中四大组件的调用与生命周期的管理。

针对插件四大组件的处理上,插件化主要存在两大流派:插桩代理方案,Hook 方案。

插桩代理方案

简要概括下,就是在宿主的包中通过定义代理组件来对插件中的组件进行代理,由宿主的组件类同步插件中组件的生命周期,相当于对插件中组件功能进行转发。


Hook 方案

通过 Hook 系统 Framework 层与组件启动相关的接口,并在 Manifest 文件中注册预先占位组件,达到欺上瞒下的效果,启动的是宿主中占位的组件,实际执行的代码逻辑是插件中相应组件的逻辑,由于宿主中占位的组件被注册过,被 Hook 代理的插件组件生命周期和原生组件基本上是一致的。不过 Hook 方案因为要兼容不同的 Android 系统版本,需要做各个版本的适配,兼容性存在一定的风险。


4.插件化应用场景

APP 插件

随着项目的不断前进,当 APP 规模发展到一定阶段后,业务逻辑日趋复杂,实现模块化的开发成为一种刚需。插件化方案提供了一种解决的思路。将 APP 中部分独立的功能封装成模块,作为插件 APK 进行加载。一方面可以使业务模块化,不同模块互不干扰,另外,模块在不同的 APP 中可以进行复用,减少代码重复建设。

游戏插件

游戏作为娱乐 APP,其中的功能模块同样有着降低耦合、减少复杂度的需求。比如登录、支付、人脸识别等功能模块,这些模块作为通用功能也可以插件化,使得游戏开发者可以专心于游戏业务逻辑的实现。另外像目前云游戏概念也比较火,开发者通过在项目中嵌入云游戏模块,可以快速上线不同的云游戏插件,无需频繁发版就可以让玩家有更丰富的游戏体验。

双开应用

双开应用可以算是插件化技术的延伸场景,作为插件的 APK 可以实现在双开应用里多开运行。这时的宿主 APP 即双开 APP 替代系统对插件 APK 实现免安装运行,以及与原系统应用的数据隔离(双开)。

5.插件 APK 保护方案

插件包由于是被宿主动态加载启动的,其启动时机是由宿主是否调用加载插件相应逻辑进行触发的,与正常 APP 有完整的系统启动流程不同。传统的整体加固方案是通过代理 Application 获得执行入口,然后通过内存加载原始 Dex 对 APK 进行保护,这种方案显然无法应用在插件包 APK 的保护中。

目前易盾在插件化场景下,采用自研 VMP 方案来对保护插件 APK 中的代码。VMP 方案是把待保护的插件核心代码进行 Naitve 化,使之转换到易盾自定义的虚拟机中去执行,保护粒度到方法级,这样不受插件 APP 启动时机的影响。

例如在某游戏合作过程中,他们除了对宿主做加固外,还希望对支付插件等核心模块进行高强度的保护,避免关键的支付逻辑被黑灰产破解利用,最终使用了易盾插件化保护方案,下图是 VMP 方案的保护效果(非实际代码,仅作演示):

保护前:


保护后:


经过保护后可以看到针对这个类的代码已经完全被 Native 化保护了,避免被反编译及逆向分析。易盾自研 VMP 方案具有安全强度高、兼容性较好的特点,加固后的插件使用方式与未加固的插件包基本一致,不会增加开发者额外的接入成本。

6.结语

插件化框架给 Android 开发者带来了很多便利,但是针对插件 APK 的保护也需要开发者重点关注。本文通过对插件化框架的背景以及原理的介绍,并给出了易盾目前对插件 APK 的保护方案。有兴趣的开发者可以联系试用。