Android应用加固的那点事

移动开发
从开发的角度来讲则是App源代码安全问题,基于代码审计层次的;从软件保护角度来讲app安全则是对源代码的代码混淆,资源加密,逻辑加固;从用户的角度来讲就是App本身的安全性,是否会对个人隐私财产造成损失。

Labs 导读

随着人们对智能手机依赖的程度越来越高,因智能手机软件安全导致用户信息泄露、财产损失事件频发,人们开始越来越关注App安全这个领域。从开发的角度来讲则是App源代码安全问题,基于代码审计层次的;从软件保护角度来讲app安全则是对源代码的代码混淆,资源加密,逻辑加固;从用户的角度来讲就是App本身的安全性,是否会对个人隐私财产造成损失。

Part 01、 为什么要进行加固? 

Android操作系统全部开源,可以对Android应用程序Apk进行解包,对DEX文件进行逆向工程,就可以获取到原始的源代码和应用程序逻辑。通过逆向工程可以窃取应用程序的核心代码、攻破程序逻辑限制、篡改应用程序或注入恶意代码、嗅探应用服务器API接口。

通过应用加固可以增加软件的逆向成本,保护软件的利益不受损坏,保护软件版权,防止应用被破解,保护应用程序的关键信息不被窃取。

Part 02、  Apk加固的原理 

应用程序Apk的关键信息都保存在DEX文件中,加固重点是保护DEX文件不被逆向。常用思路就是打包时使用私有算法改变DEX文件结构,无法使用常规手段读取DEX文件内容;由于DEX文件结构发生了变化,宿主机也无法读取识别DEX文件,就需要应用程序提供自定义的加载程序,完成DEX文件的解密与加载。

图片

Apk加固后主DEX文件已经是看不到原码,这样就达到了加固的效果,但是这样做会导致主App的Application已经是没有效了,可以通过自定义Application生命周期里的创建函数attachBaseContext和onCreate函数,在attachBaseContext中将解密出来的DEX交给系统处理,onCreate的时候要将主App的Application创建出来,并替换系统中的Application引用,这样就可以保证Activity顺利加载执行。

Part 03、 加固发展过程 

Apk加固技术,前后经历了四代技术变更,保护级别在每一代都有所提升。

图片

3.1 第一代加固:动态加载

原理➪ 第一代加固技术用于保护应用的逻辑不被逆向与分析,主要基于Java虚拟机提供的动态加载技术。开发阶段中将程序切分成加载(Loader)与关键逻辑(Payload)两部分,并分别打包;运行时加载部分(Loader)会先运行,释放出关键逻辑(Payload),然后使用Java的动态加载技术进行加载,并转交控制权。

图片

缺陷:第一代加固技术的缺陷是动态加载机制要求其关键逻辑(Payload)部分必须解压,并且释放到文件系统,这就给了攻击者机会去获取对应的文件。攻击者可以通过自定义虚拟机,拦截动态加载机制所使用的关键函数,在这个函数内部,复制文件系统中的关键逻辑(Payload)文件。

3.2 第二代加固:不落地加载

原理➪ 第二代加固技术主要为了解决解密后的Payload需要写入文件系统被窃取的问题,由代码接管Application对象的创建,主要流程:

1)Loader被系统加载。

2)系统初始化Loader内的StubApplication。

3)StubApplication解密并且加载原始的DEX文件(Payload)。

4)StubApplication从原始的DEX文件(Payload)中找到原始的Application对象,创建并初始化。

5)借助Java反射机制,将系统内所有对StubApplication对象的引用使用替换成原始Application。

6)由Android系统进行其他组件的正常生命周期管理。

图片

缺陷:第二代加固技术不会将解密后的DEX存储到文件系统,但是在应用启动时要处理大量的加解密加载操作,会造成应用长时间假死(黑屏),用户体验差。相对于第一代技术没有本质区别,虽然能防止第一代加固技术文件必须落地被复制的缺陷,但是逆向工作者也可以从内存中找到DEX文件,通过GDB等调试工具,相对于第一代加固提高了DEX获取的成本。

3.3 第三代加固:指令抽离

原理➪ 由于前两代加固技术均是对文件级别进行加密,DEX文件在内存中的Payload是连续的,可以被攻击者轻易获取。第三代加固技术保护级别深入到了函数级别。发布阶段将原始DEX内的函数内容(Code Item)清除,单独写入到一个文件中,App启动后,在运行阶段将函数内容重新恢复到对应的函数体。

图片

缺陷:指令抽离技术使用了大量的虚拟内部结构与未被文档公开的特性,再加上Android复杂的厂商定制,给DEX文件窃取带来了很大的难度。但是指令抽离技术的某些方案与虚拟机的JIT性能优化冲突,无法达到最佳的运行性能。攻击者可以通过自定义Android虚拟机,在解释器的代码上记录每一个函数的内容(CodeItem),通过遍历触发所有函数,从而获取到全部的函数内容,最终重新组装成一个完整的DEX文件。目前已经有自动化工具可以指令抽离技术中脱壳。

3.4 第四代加固:指令转换

原理➪ 第四代加固技术提供了函数级别的级别的保护,但是攻击者借助Android虚拟机内的解释器执行代码,依然可以获取到DEX文件,第四代加固技术使用自定义的的解释器来替代标准解释器,由于自定义的解释器无法对Android系统内的其他函数进行直接调用,必须使用JAVA的JNI接口进行调用。

图片

缺陷:指令转换技术必须通过虚拟机提供的JNI接口与虚拟机进行交互,攻击者可以直接将指令转换/VMP加固方案当作黑盒,通过自定义的JNI接口对象,对黑盒内部进行探测、记录和分析,进而得到完整DEX程序。

3.5 下一代加固:虚拟机源码保护

原理➪ 虚机源码保护加固是用虚机技术保护所有的代码,包括Java,Kotlin,C/C++,Objective-C,Swift等多种代码,具备极高的兼容性;使App得到更高安全级别的保护,运行更加稳定。虚机源码保护在App内部隔离出独立的执行环境,该核心代码的运行程序在此独立的执行环境里运行。即便App本身被破解,这部分核心代码仍然不可见。

图片

虚机源码保护拥有独特的可变指令集,极大的提高了指令跟踪、逆向分析的难度。同时,虚机源码保护还提供了反调试能力和监控能力。虚机源码保护可以通过自身的探针感知到环境的变化,实时探测到外界对本环境的调试、注入等非正常执行流程变化,将调试动作引入程序陷阱,并发出警报,进而进行实时更新,提高安全强度。虚机源码保护加固作为当前领先的加固技术,在未来很长一段时间,能够为App提供足够强度的保护。

Part 04、 结束语 

Apk加固是一把双刃剑,一方面可以保护App的核心代码算法,提高破解/盗版/二次打包的难度,缓解通过代码注入/动态调试/内存注入等形式攻击;另一方面加固是改变标准执行流程,增加了许多防护机制,会影响兼容性,影响程序运行效率,增加App维护难度,部分应用市场会拒绝加壳后的应用上架。因此我们需要选择一个平衡点,不要追求一味的安全,也不要过于开放,要保护好自身的数据与知识产权。

责任编辑:庞桂玉 来源: 移动Labs
相关推荐

2019-07-01 14:55:44

应用安全web安全渗透测试

2018-03-15 15:12:00

润乾报表集成

2011-04-14 14:23:06

软件测试测试

2013-10-12 13:26:08

设计加载

2012-02-22 09:32:58

云计算微软Azure

2018-04-02 15:10:17

ToastSnackbarAndroid

2015-09-01 15:12:45

JavaHashMap那点事

2011-05-25 19:37:47

2021-07-30 07:28:15

Kafka消息引擎

2011-08-31 10:15:48

桌面管理软件

2010-08-10 15:08:17

UPS电源评测

2009-07-03 14:16:30

JSP Servlet

2013-04-09 10:03:29

iOS6.0旋转兼容

2013-04-28 09:50:02

PHPMySQL

2012-06-11 15:02:53

ASP.NET

2011-02-22 09:47:58

WatchStor 征

2018-10-22 13:34:24

SD-WAN运维网络

2010-07-22 10:07:01

SharePoint

2015-11-05 18:03:15

虚拟化云计算资源池

2011-08-30 14:59:34

Qt数据库
点赞
收藏

51CTO技术栈公众号