一种基于动态加解密的Android应用加固方法与流程

文档序号:11251242阅读:1303来源:国知局
一种基于动态加解密的Android应用加固方法与流程

本发明涉及一种android应用加固方法,属于信息安全技术领域。



背景技术:

从谷歌2007年推出android系统至今,android市场飞速发展,但android平台编译生成的应用apk极易受到攻击。攻击者通过反编译、逆向工程等技术破解android应用,窃取应用代码和用户数据,给应用使用带来很多不安全因素。因此,针对android系统的防逆向就非常重要。通过对应用的加固,达到保护应用代码、反破解、反逆向、反植入等目的,从而保障android应用的原生性和完整性。

从android2.3开始,代码混淆技术开始使用。通过混淆源java代码或者smali文件等方式。代码混淆在一定程度上减低了代码的可读性,保护了代码,可以抵抗对应用代码的静态分析,但是不能抵抗反编译或调试攻击,实际加固效果较差。

软件加壳技术是android加固技术中重要的一项。软件加壳对源程序进行压缩或者加密。应用程序运行时,首先运行壳程序,对被压缩或加密的源程序进行解压缩或解密,还原出源程序并加载至内存执行。随着对android应用和脱壳技术的研究,简单的压缩或者加密以及很难抵抗外在攻击,加固比较容易被突破。但过于复杂的加密也会减低程序的运行效率。软件加壳隐藏了应用程序源代码,有效地保护了应用程序。但“壳”程序自身也需要保护,防止被攻击者攻击。



技术实现要素:

本发明的目的是为了保护android应用程序,保护应用不被静态和动态分析,克服现有加固方法的不足,提出一种android应用加固方法,对应用程序代码进行加密,对关键部分代码二次加密,实现保护应用代码与运行安全目的。

本发明的设计原理为:本发明涉及一种android应用加固方法,属于信息安全技术领域。本发明包括代码加密、动态防御、完整性校验、动态加载四个模块。加密过程对android应用程序class.dex加密,对核心代码二次加密,并对加密后的签名认证,将加密的结果嵌入资源文件。动态防御过程,检测调试器和模拟器,检测到被调试或运行在模拟器中退出应用程序。开启子进程,子进程和主进程相互ptrace监控,子进程循环检测调试器和模拟器,被调试则结束进程。完整性检测模块,认证签名信息,防止资源和代码被篡改。代码解密模块提取隐藏在图片中的加密信息,解密得到中间数据,对其中的核心代码部分二次解密,将解密后的结果直接加载至内存执行。

本发明的技术方案是通过如下步骤实现的:

步骤1,应用程序加密时,解压需要保护的android应用apk文件,获取代码文件classes.dex,提取classes.dex中核心的方法代码,采用对称加密方法加密核心代码得到加密数据,将加密数据添加特殊起止标志位后,替换class.dex中关键代码,生成新的dex文件。

步骤2,设定另一密钥k2,将步骤1中生成的dex文件加密,将加密后的文件嵌入资源文件。

步骤3,对嵌入后的资源文件做签名,将两次加密密钥k1、k2,签名验证信息和解密程序、文件提取程序存入到so文件中,重新打包应用程序,签名生成新的apk文件。

步骤4,动态防御。应用程序运行时,主进程检测当前系统运行环境是否为模拟器或调试机、当检测到运行在模拟器和调试机、直接退出程序运行;主进程fork出子进程,主进程和子进程相互ptrace监控;子进程定时检测调试机和模拟器,检测到应用正在被调试,子进程退出,主进程监控到子进程已退出时,退出应用程序。

步骤5,完整性检测。提取so文件中的签名信息、验证签名信息是否正确。

步骤6,动态加载。应用程序运行时,提取资源文件中的加密文件和so库中的密钥k1、k2,利用k2对加密文件解密,得到中间代码,定位到关键代码加密位置,提取关键代码的加密数据,利用k1对关键代码解密,获取原始class.dex代码,加载至内存。

有益效果

相比于现有的代码混淆加固方法,代码只是增加了代码看阅读难度,代码保护程度较弱,本发明对代码进行加密,能够更好的保护代码。

相比于软件加壳的加固方法,本发明对普通的代码一次加密,对关键代码二次加密,有效地保护了代码,特别是关键代码的保护。同时将加密的结果和密钥通过水印的方式嵌入图片,保护了加密结果。

附图说明

图1为本发明一种android应用加固方法原理图;

图2为应用加密模块流程图;

图3为动态防御模块主进程检测流程图;

图4为动态防御模块子进程检测流程图;

图5为应用解密模块流程图。

具体实施方式

为了更好的说明本发明的目的和优点,下面结合实施例对本发明方法的实施方式做进一步详细说明。

具体流程为:

步骤1,关键代码加密。

步骤1.1,提取android应用apk压缩文件中的classes.dex文件。

步骤1.2,定位核心代码,核心代码部分包括:程序activity、service生命周期代码,程序登录等涉及密钥与验证的代码、程序核心算法代码。分别提取各段核心代码。

步骤1.3,采用密钥k1,对每块关键代码进行aes加密。

步骤1.4,将各段加密后的代码加上起止标识位,替换原代码,重新计算dex文件长度和校验值。

步骤2,dex文件加密。

步骤2.1,对步骤1生成的dex,使用密钥k2加密,将加密结果嵌入资源文件。

步骤2.2,将嵌入加密结果的资源文件利用hmac-md5签名校验,签名密钥使用k1+k2(字符串拼接),hash校验值、两次加密密钥k1、k2和用于提取资源文件中的代码、解密代码存储到so文件中。

步骤3修改androidmanifest.xml中application,将apk资源文件和自定义的壳dex文件和so文件重新打包和签名、生成新的apk文件。

步骤4动态防御。

步骤4.1,通过proc文件系统读取/proc/pid/status文件就存储了进程号为pid的进程状态,定时检测/proc/pid/status中的tracerpid,若该字段不为0时表示调试进程的pid,若检测到tracerpid不为0,则应用正在被调试。调试应用时,应用程序运行在虚拟中。相比于真实设备,虚拟机存在一些特殊的文件,/system/bin/qemu-props,/system/lib/libc_malloc_debug_qemu.so文件和目录/sys/qemu_trace,分别检测这三个文件或目录是否存在,若存在,则认为运行在模拟器中。当检测到被调试或运行在模拟器中,则直接杀死主进程,退出应用程序。

步骤4.2,使用fork函数fork出子进程,主进程和子进程分别调用ptrace,相互监控。子进程利用pipe管道通信向主进程注入一段字符串,主进程读取子进程注入消息,当一定时间内没有读取到字符串,则子进程启动异常,直接退出应用程序

步骤4.3子进程循环检测调试机和模拟器。利用步骤4.1方法检测是否被调试。另外,当使用ida调试应用时,android_server监听23946端口。检测/proc/net/tcp文件,当23946端口正在被android_server占用时,检测到应用正在被ida调试。当利用ida调试器来过反调试时,采取的方式是单步调试。相比于正常运行,单步调试的运行速度要慢的多,正常代码指令的速度一般在1000ms,检测代码执行的时间,设定经验阈值2000ms,当时间间隔超过阈值,则认为正在被反调试。通过以上流程,当检测到被反调试时,子进程退出,主进程在监控到子进程已经退出时,直接退出应用程序。

步骤5,完整性检测。使用jni(javanativeinterface)调用机制访问so库文件,提取so文件中的k1和k2以及签名校验值,利用k1+k2计算包含加密结果的资源文件的hmac-md5值,比较so文件中的签名校验值,如果两个值不同,则应用代码遭到篡改,退出应用程序。

步骤6,动态加载。

步骤6.1,从资源文件中提取被加密的原始dex文件

步骤6.2,提取密钥k2,对步骤5.1提取加密,得到中间结果。

步骤6.3,提取密钥k1,扫描中间结果,发现标识字符串0x6d61696e0x76312e30,读取接下来的8位字符长度以及长度对于的二进制流,利用k1对提取出的二进制流解密,将解密结果替换中间结果中的包括标识字符串、长度和二进制流部分。扫描整个中间结果,使用dexclassloader类加载器将解密出的二进制代码直接加载到内存,不生成中间文件,完成解密工作。

以上所述的具体描述,对发明的目的、技术方案和有益效果进行了进一步详细说明,所应理解的是,以上所述仅为本发明的具体实施例而已,并不用于限定本发明的保护范围,凡在本发明的精神和原则之内,所做的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1