基于Android平台的软件加固方案的设计与实现*
2016-01-04
基于Android平台的软件加固方案的设计与实现*
巫志文1,2,李炜1,2
(1 北京邮电大学网络与交换技术国家重点实验室,北京 100876,2 东信北邮信息技术有限公司,北京 100191)
摘 要本文在深入分析Android的系统架构、软件结构及其执行机制的基础上,提出和实现了一种基于classes.dex文件动态加载的Android软件加固方案,实现软件关键代码的隐藏,可以有效地对抗各种针对Android软件的逆向工程攻击。
关键词软件加固;系统架构;Android
Android是google公司于2007年推出的开源手机操作系统,由于其强大的功能和灵活的定制能力,使其在短短几年内便跃居智能手机操作系统市场份额的首位,据著名市场研究机构IDC的最新数据表明,2014年第二季度,Android系统智能手机的市场份额高达84.7%,远超其他系统[1]。
虽然Android系统在设计之初便充分考虑到了安全问题,但随着其广泛应用,诸多潜在的安全问题还是逐渐地暴露出来,对其安全性的研究开始受到人们的广泛关注。由于Android平台软件使用的编程语言是Java,而Java源代码编译后的二进制代码极易被反编译,导致其破解难度远小于其他使用编译性语言编写的程序。虽然Android 2.3以后加入了代码混淆机制,但通过逆向工程,其API级别上的代码仍是难以隐藏,对攻击者来说,破解的可能性仍是很大。
本文详细分析了Android的系统架构、程序结构、程序执行机制以及Android平台软件面临的逆向威胁,提出和实现了一种基于classes.dex文件动态加载的Android软件加固方案。
1 Android系统架构
Android是基于Linux内核的开放式操作系统,采用层次化系统架构。如图1所示,Android 自底向上分为4个主要功能层[2],分别是: Linux内核层、系统运行库层、应用程序框架层和应用程序层。
Android 4.0版本以前,其内核为Linux 2.6内核,4.0及之后的版本使用Linux 3.X内核。Linux内核服务实现诸如内存管理、进程管理、网络协议栈和驱动模型等核心系统功能[3]。系统运行库层位于Linux内核层之上,由系统类库和Android运行时构成,是应用程序框架的支撑,为Android系统中的各个组件提供服务。应用程序框架层提供开发Android应用程序所需的一系列类库,包含4种基本组件,丰富的控件、资源管理器、内容提供器、活动管理器等,使开发人员可以快速地进行应用程序的开发,方便地重用组件,也可以通过继承实现个性化的扩展。
图1 Android系统架构图
2 Android软件结构及其执行机制
本软件加固方案是在对Android软件结构及其执行机制进行深入研究和分析的基础上提出的,下面对相关知识进行介绍。
每个要被安装到Android系统中的应用都要被编译打包成为一个后缀名为.apk的单独的文件,其中包含了应用程序的二进制代码、资源及配置文件等。apk文件实际上是一个zip格式的压缩文件,解压后,可以看到其文件结构及功能描述如表1所示。
表1 Android应用程序文件结构
其中,classes.dex是java源码编译后生成的Dalvik二进制字节码文件,可以直接在Dalvik虚拟机中运行。classes.dex文件由文件头、索引区和数据区三大部分组成[4],表2给出了各部分包涵的内容及相关说明。
表2 classes.dex文件结构
其中,文件头部分主要包括校验和以及其他结构的偏移地址和长度信息。其部分结构定义如表3所示。
表3 classes.dex文件头部分结构定义
Dalvik虚拟机在执行应用的时候,首先要解压apk文件并校验完整性,然后执行classes.dex文件中的字节码[5]。在执行classes.dex文件时,Dalvik虚拟机首先会检查其文件头部分的checksum字段和siganature字段,确保classes.dex文件没有被损坏或篡改,然后才根据文件头里定义的其他结构的偏移地址和长度信息进行寻址解析与执行。这也是本软件加固方案的理论基础所在。
3 基于classes.dex文件动态加载的Android软件加固方案
虽然Android平台采用了多层次的安全保护机制,但由于Android平台自身的缺陷,使用易于反编译的Java语言,其软件仍然受到来自各方面的威胁,其中最重要的威胁便是逆向攻击。即通过逆向工程,破解软件的关键部位,从而获取软件信息或实施一系列恶意攻击。逆向Android软件的一般步骤是:首先是对其进行反编译,然后阅读反汇编代码,如果有必要还会对其进行动态调试,找到突破口后注入或直接修改反汇编代码,最后重新编译软件进行测试。整个过程可分为反编译、静态分析、动态调试、重编译等4个环节。逆向防护技术也是从这四个方面进行的,包括对抗反编译工具、对抗静态分析、对抗动态调试和防止重编译等[6]。
为了对抗来自逆向工程的攻击,结合前文分析的Android软件结构与执行机制,本文提出了一种基于classes.dex文件动态加载的Android软件加固方案。本方案首先将Android软件分为两部分:软件主体部分与核心功能部分。软件主体部分是实际安装在Android系统中的部分,核心功能部分是软件主体部分调用的需要重点保护的功能代码。本方案将核心功能部分编译成一个独立的apk文件,加密后将其隐藏于软件主体部分的classes.dex文件体内,需要使用时再进行实时的代码分离与动态加载,从而达到隐藏软件关键代码,软件加固的效果。
3.1 方案实现
本软件加固方案由两大部分组成,分别是软件加固模块和动态加载模块。下面对两个模块的具体实现进行介绍。
3.1.1 软件加固模块
根据前文对classes.dex文件的文件结构和执行机制的研究,我们知道,Android系统在解析执行classes.dex文件的时候,如果发现其文件头的校验码字段与SHA-1签名字段无误,则认为此文件未损坏或未被篡改,是可以执行的。因此,可以猜想,如果在classes.dex文件后面增加一些内容,同时在增加这些内容后,修改classes.dex文件的校验码、SHA-1签名及文件大小(修改文件后,该字段也会相应发生变化)字段,classes.dex仍然能够正确执行。经试验,该方法是可行的。基于这个原理,本方案把部分软件的关键代码编译成一个独立的文件,添加到classes.dex文件后面,然后在程序运行时动态地分离出这些代码,再通过反射机制对这部分关键代码进行动态加载。同时,可以对这些关键代码进行加密处理,需要执行时再进行解密。经过这样处理后,逆向工程逆向出来的代码便只有软件的主体部分,而核心部分被隐藏。而且,即使核心部分被发现了,也会由于代码被人为加密而无法得到解密后的源码,从而很好地保护了核心代码。整个加固的实现流程如下:
(1)解压软件主体部分apk文件,提取其classes. dex文件。
(2)将核心功能部分代码编译成独立的apk文件,并对其进行加密。
图2 APK加固流程图
(3)把加密后的apk文件写入到软件主体部分的classes.dex文件的末尾,并在文件尾部添加加密数据的大小,用以解密时找到核心功能部分代码的起始位置。
(4)重新计算classes.dex文件的checksum、signature 和file_size字段的值。分别计算这几个字段变化之后的值,替换原位置的内容即可。
(5)将修改后的classes.dex文件放回软件主体部分apk包中,使用Android SDK中提供的签名工具对程序进行签名。
整个加固流程如图2所示,加固后的classes.dex文件结构如图3所示。
3.1.2 动态加载模块
经过加固的软件安装到Android系统中后,需要调用被隐藏的核心功能部分的时候,需要对其进行动态分离、解密和加载,这个过程是与软件加固过程一一对应的。整个动态加载的实现流程如下:
(1)软件主体部分从自身的apk文件中读取classes.dex文件,在classes.dex文件尾部得到加密数据的长度,根据加密数据长度计算出加密数据的起始位置,从而读取得到加密数据。
(2)运行解密方法。解密得到核心功能部分apk。
(3)通过Android API提供的DexClassLoader类,对核心功能部分代码进行反射调用,从而实现核心功能部分代码的动态加载。
(4)调用完成后,删除核心功能部分apk文件,从而避免核心功能部分代码暴露在系统内部存储之中,被攻击者得到。
整个动态加载的流程如图4所示。
3.2 方案效果
为了验证效果,本方案建立了两个Android工程,分别是软件主体部分工程与核心功能部分工程。包名分别是com.willen.apkshellandroid与com.willen. apkLoad。对软件主体部分apk文件使用本方案的加固方式进行加固后,分别使用目前最流行的Android逆向工具dex2jar与apktool进行逆向分析。
dex2jar实现将classes.dex文件反编译成一个jar包,图5是使用dex2jar逆向之后形成的jar包在jar包查看工具jd-gui下显示的效果。从图中可以看出,逆向出来的代码只有软件主体部分(com.willen. apkshellandroid包的代码),核心功能部分的代码(com. willen. apkLoad包的代码)被隐藏了,无法查看。
apktool实现将classes.dex文件反编译成smali汇编代码,图6是通过apktool反编译后的代码结构。从图中可以看出,逆向出来的代码中仍然是只有软件主体部分代码,核心功能部分的代码被隐藏。
图3 加固后的classes.dex文件结构
图4 APK动态加载流程图
图5 通过dex2jar逆向后的代码
经过上述验证可以看出,本软件加固方案可以有效对抗各种针对Android软件的逆向工程攻击,提高Android软件的安全性。
4 结论
作为目前智能手机市场占有率最高的操作系统,Android系统的安全性备受瞩目。采用此方案,可以极大程度地提高Android软件的安全性。
参考文献
[1]IDC:Android 手机市场份额高达 84.7%,中低端手机成主力军[OL]. [2014-8-15]. http://bbs.dgtle.com/thread-204503-1-1. html
[2]乜聚虎, 周学海, 余艳玮, 等. Android安全加固技术[J]. 计算机系统应用,2011,20(10):74-77.
[3]吴倩,赵晨啸,郭莹. Android安全机制解析与应用实践[M].北京:机械工业出版社,2013.
[4]Dalvik Executable Format[OL]. [2014-10-21]. http://source. android.com/devices/tech/dalvik/dex-format.html.
[5]陈昱,江兰帆. 基于Google Android平台的移动开发研究[J]. 福建电脑,2008(11):156-157.
图6 通过apktool逆向后的代码
[6]丰生强. Android软件安全与逆向分析[M]. 北京:人民邮电出版社,2013.WU Zhi-wen1,2, LI Wei1,2
Design and implementation of software reinforcement scheme based on Android platform
(1 Beijing University of Posts and Telecommunications, Beijing 100876, China; 2 EBupt Information Technology Co., Ltd. Beijing 100191, China)
AbstractThis paper deeply analyzed Android's system architecture, software structure and it's execute mechanism, proposed and implemented an Android software reinforcement scheme base on classes.dex fi le's dynamic loading. This scheme can hide software's key code and can effectively resist reverse attack against Android software.
Keywordssoftware reinforcement; system architecture; software structure; Android
* 基金项目:国家973计划项目(编号:2013CB329102);国家自然科学基金资助项目(No. 61471064,61372120, 61271019, 61101119, 61121001);长江学者和创新团队发展计划资助(编号:IRT1049);教育部科学技术研究重点(重大)项目资助(编号:MCM20130310);北京高等学校青年英才计划项目(编号:YETP0473)。
收稿日期:2014-02-20
文章编号1008-5599(2015)01-0033-05
文献标识码A
中图分类号TN929.5