掌桥专利:专业的专利平台
掌桥专利
首页

一种基于混合加固Android系统应用软件安全防护方法

文献发布时间:2023-06-19 10:38:35


一种基于混合加固Android系统应用软件安全防护方法

技术领域

本发明涉及软件安全防护领域,尤其是一种Android应用软件安全防护方法。

背景技术

由于Android系统的高开放性,使得Android平台上的应用程序经常遭到恶意攻击者的攻击。Android应用程序主要由Java语言开发,因此APK中的classes.dex文件很容易被反编译为可读性非常强的Smali文件,通过修改特定逻辑或插入恶意行为代码再进行二次打包,就可以很容易的实现恶意入侵行为。虽然APK中也包含Native层的So文件,它们由C/C++语言实现,相比Dex文件而言具有更高的安全性。但是研究发现,应用级So文件所占APK文件的比例越来越多,且目前很多恶意软件的行为逻辑也转移到了Native层,使得缺少保护的So文件也会成为恶意攻击者的攻击目标。此外,目前的研究既缺少对APK资源文件的安全防护,又没有一套对APK文件的有效防护措施。因此,目前急需一种既能保护APK资源文件,又能又能对Dex文件和So文件进行有效防护的安全防护方法。

发明内容

为了克服现有技术的不足,本发明提供一种基于混合加固Android系统应用软件安全防护方法。针对Android应用软件的安全防护问题,公开了一种混合加固方法。分别包括:资源文件加固、Dex文件加固、So文件加固,以保护应用软件的数据和自身安全。其中,资源文件加固用于防止APK文件数据资源直接被解压分析拿到;Dex文件加固主要用于防止APK文件中实现主要功能的Java层代码被反编译解析出来;So文件加固主要用于防止APK文件中实现核心逻辑的C/C++代码被反编译解析出来。

本发明解决其技术问题所采用的技术方案的步骤如下:

步骤一:对系统资源文件进行混淆、压缩和加密处理

对APK文件中的资源文件进行混淆和压缩处理,混淆和压缩处理步骤包括:

步骤1.1:使用无实际意义的英文字母替换资源文件各层级目录名称和文件名称,如把res/drawable/hello.png替换成r/d/a.png;

步骤1.2:对图片等文件进行压缩处理:由于在APK中几乎所有的png图片都是以STORED的方式存储的,都是未经过压缩处理的。因此,采用7zip对包括png、jpg、JPG、jpeg图片进行压缩;

步骤1.3:解析resources.arsc资源索引文件,并对其中内容进行修改:

步骤1.4:采用HMAC算法对APK文件进行完整性校验,设哈希函数为H,加密密钥为K,待加密文件为F;每种信息摘要函数都对信息进行分组,每个信息块的长度是固定的,记为B;每种信息摘要函数输出一个固定长度的信息摘要,将信息摘要的长度记为L,其中,K不小于L的长度;

使用HMAC算法对文件F进行加密的计算公式如下所示:

其中,ipad为0x36重复B次,opad为0x5c重复B次;

步骤二:对Dex文件抽取关键代码和进行加壳处理

针对Dex文件的加固分为两个部分:

步骤2.1:首先对Dex文件进行关键代码抽取,针对Dex文件抽取的关键代码为非Native函数;

步骤2.2:对Dex文件进行动态加载和关键代码内存映射;

步骤三:对So文件进行加密和压缩处理

对So文件的加固方案为:先按section区块加密So文件,然后整体使用UPX进行压缩处理;

共享目标通过动态结构中的DT_INIT和DT_FINI条目指定初始化/终止函数,初始化/种植函数的代码放在.init和.fini节区中;即:

(1).init:在main函数之前调用,完成进程初始化工作;

(2).fini:在main函数之后调用,完成进程终止操作;

使用_attribute_((section(".mytext")));属性动态给So文件添加一个自定义加密区块.mytext,将核心Native函数定义在其中;

最后,使用UPX对So文件进行压缩和加壳,UPX解压过程完全隐蔽,直接在内存中完成,无需另外的解压缩程序;加壳压缩指令如下所示:

upx.out--android-shlib**.so;

综上,完成对So文件的加固。

所述步骤1.3的具体步骤为:

步骤1.3.1:修改字符串池中的字符串,将资源文件指向路径进行重定向,即参照步骤1.1以无意义字符[a-z0-9]进行替代;

步骤1.3.2:对于specName,只保留启用白名单(whiteList)的部分,将其余部分全部替换为对应资源文件的无意义字符[a-z0-9];

步骤1.3.3:源项entry中引用的资源项字符串池位置进行修正,即重定向entry中指向specName的id值;

步骤1.3.4:根据修改的内容重新计算每一个chunk的大小,并修改整个资源索引文件的chunk大小;

步骤1.3.5:重新打包生成resources.arsc和R.java。

所述需要进行加密和完整性校验的文件有:assets目录下所有文件、res目录下所有文件、配置文件AndroidManifest.xml和resources.arsc资源配置文件。

所述步骤2.1中Dex文件关键代码抽取过程如下:

步骤2.1.1:解析Dex文件,获取并保存所有函数的代码结构体信息;对于每一个函数,获取其在Dex文件中的codeOff偏移,即找到该函数在DexMethod结构体中的codeOff变量信息;其中,获取codeOff偏移的函数是一个Native函数;

步骤2.1.2:检查所有方法的DexCode结构体中insns[insnsSize]信息,找出所有非Native函数,即insns[insnsSize]中保存是指令信息的函数;

步骤2.1.3:在lib库下面新建关键函数文件,对于每一个非Native函数,获取其指令个数和指令偏移地址,找到指令集并统一拷贝到关键函数文件中;

步骤2.1.4:通过将原有指令全部乘0的方式构造出相同数量的空指令集,覆盖掉原始指令,实现指令置空;

步骤2.1.5:更新Dex文件头信息,包括:校验和checksum、签名signature和文件大小file_size;

步骤2.1.6:使用AES128对于写入到关键函数文件中的信息进行统一加密。

所述Dex文件动态加载和关键代码内存映射步骤如下:

步骤2.2.1:基于反射机制调用DexFile类的openDexFile方法,加载字节码得到Dex文件对应的cookie值并保存;其中,获得cookie值的方法是先通过自定义类加载器DynamicDexClassLoader,再调用loadDex方法加载指定Dex文件;cookie是一个4字节的int型指针,指向了内存中的DexOrJar结构体,pDexMemory指向Dex文件加载到内存中的地址;

步骤2.2.2:重写findClass方法,反射调用DexFile类的getClassNameList方法以获取Dex文件中所有的类和反射调用DexFile类的defineClass方法以传递cookie值;

步骤2.2.3:重写loadClass方法,加载指定的类;

步骤2.2.4:在指定类的DexClassData结构体中获取该类所有函数,根据所有函数的DexMethod结构体信息,找到每一个函数的codeOff偏移,通过该偏移量找到该函数的DexCode结构体信息;

步骤2.2.5:通过DexCode结构体中的insns[insnsSize]判断是否为Native函数:

若该方法是Native的,则直接加载对应的Native指令集;

若该方法非Native,则解密关键函数文件并根据codeOff偏移和指令集长度获取该方法被抽取的指令集。修改当前内存属性为可读写,并将原始指令集映射到内存中,先保存当前方法的空指令集指针,再重定向关键函数指令集指针为映射到内存中的原始指令集地址;

步骤2.2.6:关键函数运行结束后,再次重定向关键函数指令集指针为先前保存的空指令集指针,并将内存属性恢复。

所述针对section的加密流程如下:

(1)解析So文件,从文件头读取section偏移shoff、shnum和shstrtab;

(2)读取shstrtab中字符串,存在str中;

(3)从shoff位置读取section header,存放在shdr中;

(4)通过shdr→sh_name在str字符串中索引,匹配.mytext字符串;

(5)通过字段shdr→sh_offset和字段shdr→sh_size,将.mytext内容读取并保存在content中;

(6)使用AES128算法对content内容加密;

(7)将content内容写回So文件中;

步骤三中,使用_attribute_((constructor));属性声明解密函数,解密流程如下:

(1)解析So文件,得到So文件在内存中的起始地址;

(2)读取ELF头,通过e_shoff获得加密区块的内存加载地址,ehdr.e_entry获取加密区块的大小和所在内存块;

(3)修改加密区块所在内存块的读写权限为读写;

(4)将[e_shoff,e_shoff+size]内存区域数据解密;

(5)修改内存区域的读写权限为原始权限。

本发明的有益效果在于由于针对Android应用软件加固的关键在于对于资源文件、关键数据和关键代码进行隐藏和加密,同时在不消耗大量内存和运行速度的前提下保护加密密钥。现有技术针对Dex文件和So文件的加固方案进行了很多研究,同时也有提出利用时间换空间的白盒加密算法,但对于Android应用软件的体积和运行速度的造成了很大影响。本发明通过对APK资源文件进行加密、压缩处理,对Dex文件关键代码进行抽取和加密、加壳处理,对So文件进行加密、压缩和加壳处理,同时利用Android自带的AndroidKeyStore实现对加密密钥的安全管理。整体加固前后,APK文件大小和运行速度的损失变化不大,在实现全面加固的前提下,也能保障应用软件的无损运行。

附图说明

图1为本发明APK加固前文件大小。

图2为本发明APK加固后文件大小。

图3为本发明加固前dex文件解析效果。

图4为本发明加固后dex文件解析效果。

图5为本发明加固前后应用启动时间对比图。

具体实施方式

下面结合附图和实施例对本发明进一步说明。

本发明针对Android应用软件的安全防护问题,公开了一种混合加固方法。分别包括:资源文件加固、Dex文件加固、So文件加固,以保护应用软件的数据和自身安全。其中,资源文件加固用于防止APK文件数据资源直接被解压分析拿到;Dex文件加固主要用于防止APK文件中实现主要功能的Java层代码被反编译解析出来;So文件加固主要用于防止APK文件中实现核心逻辑的C/C++代码被反编译解析出来。

步骤一:对系统资源文件进行混淆、压缩和加密处理

对APK文件中的资源文件进行混淆和压缩处理,混淆和压缩处理步骤包括:

步骤1.1:使用无实际意义的英文字母替换资源文件各层级目录名称和文件名称,如把res/drawable/hello.png替换成r/d/a.png;

步骤1.2:对图片等文件进行压缩处理:由于在APK中几乎所有的png图片都是以STORED的方式存储的,都是未经过压缩处理的。因此,采用7zip对包括png、jpg、JPG、jpeg图片进行压缩;

步骤1.3:解析resources.arsc资源索引文件,并对其中内容进行修改:

1)修改字符串池中的字符串,将资源文件指向路径进行重定向,即参照步骤(1)以无意义字符[a-z0-9]进行替代;

2)对于specName,只保留启用白名单(whiteList)的部分,将其余部分全部替换为对应资源文件的无意义字符[a-z0-9];

3)源项entry中引用的资源项字符串池位置进行修正,即重定向entry中指向specName的id值;

4)根据修改的内容重新计算每一个chunk的大小,并修改整个资源索引文件的chunk大小;

5)重新打包生成resources.arsc和R.java;

步骤1.4:采用HMAC算法对APK文件进行完整性校验,设哈希函数为H,加密密钥为K,待加密文件为F;每种信息摘要函数都对信息进行分组,每个信息块的长度是固定的,记为B(如:SHA1为512位,即64字节);每种信息摘要函数输出一个固定长度的信息摘要,将信息摘要的长度记为L(如:MD5为16字节,SHA-1为20个字节)。其中,K的长度理论上是任意的,但一般为了安全强度考虑,选取不小于L的长度。

使用HMAC算法对文件F进行加密的计算公式如下所示:

其中,ipad为0x36重复B次,opad为0x5c重复B次;

进行加密和完整性校验的文件有:assets目录下所有文件、res目录下所有文件、配置文件AndroidManifest.xml和resources.arsc资源配置文件;

步骤二:对Dex文件抽取关键代码和进行加壳处理

针对Dex文件的加固分为两个部分:

步骤2.1:首先对Dex文件进行关键代码抽取,因为在Dex文件中,若一个函数为Native函数,则其结构体中的insns[insnsSize]存放的是指向Native函数的指针;否则insns[insnsSize]中存放的是该函数的指令信息,且Native函数的具体实现内容保存在So文件,So文件的反编译难度大,无法通过反编译方式得到可阅读的源码。因此,针对Dex文件抽取的关键代码为非Native函数;则Dex文件关键代码抽取过程如下:

步骤2.1.1:解析Dex文件,获取并保存所有函数的代码结构体信息;对于每一个函数,获取其在Dex文件中的codeOff偏移,即找到该函数在DexMethod结构体中的codeOff变量信息;其中,获取codeOff偏移的函数是一个Native函数;

步骤2.1.2:检查所有方法的DexCode结构体中insns[insnsSize]信息,找出所有非Native函数,即insns[insnsSize]中保存是指令信息的函数;

步骤2.1.3:在lib库下面新建关键函数文件,对于每一个非Native函数,获取其指令个数和指令偏移地址,找到指令集并统一拷贝到关键函数文件中;

步骤2.1.4:通过将原有指令全部乘0的方式构造出相同数量的空指令集,覆盖掉原始指令,实现指令置空;

步骤2.1.5:更新Dex文件头信息,包括:校验和checksum、签名signature和文件大小file_size;

步骤2.1.6:使用AES128对于写入到关键函数文件中的信息进行统一加密。

步骤2.2:其次,由于被提取过关键函数后的Dex文件是不完整的,若直接加载到虚拟机中直接运行,则对应的关键函数无法被执行。因此,需要对Dex文件进行动态加载和关键代码内存映射;则Dex文件动态加载和关键代码内存映射步骤如下:

步骤2.2.1:基于反射机制调用DexFile类的openDexFile方法,加载字节码得到Dex文件对应的cookie值并保存;其中,获得cookie值的方法是先通过自定义类加载器DynamicDexClassLoader,再调用loadDex方法加载指定Dex文件;cookie是一个4字节的int型指针,指向了内存中的DexOrJar结构体,pDexMemory指向Dex文件加载到内存中的地址;

步骤2.2.2:重写findClass方法,反射调用DexFile类的getClassNameList方法以获取Dex文件中所有的类和反射调用DexFile类的defineClass方法以传递cookie值;

步骤2.2.3:重写loadClass方法,加载指定的类;

步骤2.2.4:在指定类的DexClassData结构体中获取该类所有函数,根据所有函数的DexMethod结构体信息,找到每一个函数的codeOff偏移,通过该偏移量找到该函数的DexCode结构体信息;

步骤2.2.5:通过DexCode结构体中的insns[insnsSize]判断是否为Native函数:

1)若该方法是Native的,则直接加载对应的Native指令集;

2)若该方法非Native,则解密关键函数文件并根据codeOff偏移和指令集长度获取该方法被抽取的指令集。修改当前内存属性为可读写,并将原始指令集映射到内存中,先保存当前方法的空指令集指针,再重定向关键函数指令集指针为映射到内存中的原始指令集地址;

步骤2.2.6:关键函数运行结束后,再次重定向关键函数指令集指针为先前保存的空指令集指针,并将内存属性恢复。

综上,实现针对Dex文件的关键函数抽取和动态加载;

步骤三:对So文件进行加密和压缩处理

对So文件的加固方案为:先按section区块加密So文件,然后整体使用UPX进行压缩处理;

共享目标通过动态结构中的DT_INIT和DT_FINI条目指定初始化/终止函数,初始化/种植函数的代码放在.init和.fini节区中;即:

(1).init:在main函数之前调用,完成进程初始化工作;

(2).fini:在main函数之后调用,完成进程终止操作;

使用_attribute_((section(".mytext")));属性动态给So文件添加一个自定义加密区块.mytext,将核心Native函数定义在其中;

针对section的加密流程如下:

(1)解析So文件,从文件头读取section偏移shoff、shnum和shstrtab;

(2)读取shstrtab中字符串,存在str中;

(3)从shoff位置读取section header,存放在shdr中;

(4)通过shdr→sh_name在str字符串中索引,匹配.mytext字符串;

(5)通过字段shdr→sh_offset和字段shdr→sh_size,将.mytext内容读取并保存在content中;

(6)使用AES128算法对content内容加密;

(7)将content内容写回So文件中;

使用_attribute_((constructor));属性声明解密函数,解密流程如下:

(1)解析So文件,得到So文件在内存中的起始地址;

(2)读取ELF头,通过e_shoff获得加密区块的内存加载地址,ehdr.e_entry获取加密区块的大小和所在内存块;

(3)修改加密区块所在内存块的读写权限为读写;

(4)将[e_shoff,e_shoff+size]内存区域数据解密;

(5)修改内存区域的读写权限为原始权限;

最后,使用UPX对So文件进行压缩和加壳,UPX解压过程完全隐蔽,直接在内存中完成,无需另外的解压缩程序;加壳压缩指令如下所示:

upx.out--android-shlib**.so;

综上,完成对So文件的加固。

本发明分别通过步骤一至步骤三对APK文件中资源文件、Dex文件和So文件的加固防护进行了说明。下面通过对比实验,来验证本发明所提方法的有效性。

对比实验

本发明实验所用数据来自国内外Android应用市场上的热门应用,包括视频、音乐、办公、运动、社交、金融等常见类型,共计下载APK文件300个,实验硬件环境如表1所示。

表1实验环境

首先,本发明针对所提方法进行安全加固效果测试。分别对加固前后的APK文件进行反编译解析,效果如下:

对APK加固前后文件内容及大小的变化对比,如图1、图2所示。

可以看出,本发明所提方法在对APK加固前后的文件大小变化不大,在可控范围之内。

(2)对另一个APK加固前后的Dex文件解析对比,如图3和图4所示。

其次,本专利选取包括视频、音乐、办公、运动、社交、金融等常见类型APK文件各50个,对它们分别进行加固措施,计算每一类APK加固前后的应用平均启动时间,如表2所示:

表2加固前后应用启动时间对比

可以看出,本发明所提方法对应用程序启动的平均影响效率仅为21.5%,完全在可接受范围内。折线对比如图5所示。

相关技术
  • 一种基于混合加固Android系统应用软件安全防护方法
  • 一种基于Android系统的安全防护方法
技术分类

06120112623624