一种Android加固应用程序通用自动化脱壳方法和装置与流程

文档序号:16630182发布日期:2019-01-16 06:29阅读:296来源:国知局
一种Android加固应用程序通用自动化脱壳方法和装置与流程

本发明涉及一种android加固应用程序通用自动化脱壳方法和装置,属于计算机应用安全技术领域。



背景技术:

目前android操作系统已经成为全球市场上所占份额最高的移动终端系统,基于android操作系统的应用程序数量也逐年增多。由于android平台的开放性,应用程序能够较容易的被逆向分析、修改破解、重新打包。针对android应用程序的攻击行为层出不穷,攻击者利用程序中因设计疏忽或逻辑错误产生的漏洞,攻击运行android系统的智能设备,对用户的隐私和安全产生了极大的威胁。为了防止软件被恶意攻击利用,许多开发者采取了应用加固的方式,对程序关键代码进行混淆、加密、隐藏,极大的增加了逆向分析的难度,从而达到对程序进行保护的效果。应用加固逐渐成为增加应用分析破解门槛,保障应用不被恶意篡改的重要手段。

与此同时,以android平台为目标的恶意软件也利用了加固技术的特性,用于躲避杀毒引擎的检测和安全研究人员的分析。从安全研究的角度而言,对加固应用脱壳,还原出程序代码,能够辅助静态分析工具对程序进行更加深入的分析,有利于增强对恶意行为的检测。

在早期的加固方案中,dex文件被整体加密,并存放于android应用程序apk文件之中。在程序运行时,壳代码首先将dex文件进行解密,然后回写至文件系统,并最终利用系统的类加载器classloader进行加载执行。虽然可以在dex文件被加载后,将其从文件系统删除,但仍然不能防止脱壳进程拦截对应函数,并获得完整dex文件。随后的加固技术对dex文件的加载过程进行了改进,将dex文件解密至内存后,直接调用dalvik虚拟机内部接口,完成代码的动态加载。但在这一过程中,内存中将出现完整的原始dex文件,因此可以通过直接搜索内存、hook关键系统函数等方式,对程序进行脱壳。

为了防止解密后的dex文件被整体转储,加固技术进而从两个主要方面对内存中的dex文件进行防护。其一是减少用于定位dex文件位置的内存特征,删除冗余结构信息,破坏原有文件结构;其二是破坏dex文件的内存连续性。经常使用的手段有,清除内存中的dex文件头标志,用于对抗暴力内存搜索;分离映射dex文件,达到内存中的不连续效果;增加了一些错误的数据,提高恢复成本;将java方法native化,并利用jni机制重新还原字节码等等。

综上所述,当前加固技术使得对恶意软件的检测和分析面临诸多困难,其核心问题在于加固技术为隐藏了恶意软件中原有的代码逻辑,极大提高了逆向和分析的门槛。



技术实现要素:

针对现有技术中存在的技术问题,本发明的目的在于提供一种android加固应用程序通用自动化脱壳方法和装置,对于进行加固处理后的android应用程序,可以在不具备专业逆向分析知识的前提下,完成自动化的对加固程序进行脱壳,还原出程序原有逻辑代码。android系统通过为每一个应用程序创建对应的虚拟机来执行应用程序中的代码逻辑,本发明通过对android系统的虚拟机源代码进行修改,具备一定的通用性,可以处理采取不同加固方式的应用,同时也规避了加固应用采取反调试等手段阻止对程序进行脱壳的问题,从而达到通用自动化脱壳的效果。

为了实现上述目的,本发明采用以下技术方案:

一种android加固应用程序通用自动化脱壳方法,包括:

1)dex文件定位单元在加固应用被系统加载至内存且尚未执行任何加固应用所包含代码的时刻完成初始化操作,用于在后续加固应用运行过程中进行持续化监测。当出现新的dex文件加载时(即dex文件定位单元监测到虚拟机加载新的dex文件时),dex文件定位单元将记录虚拟机内部用于表示内存中dex文件信息的dexorjar结构,并发送给类加载器验证单元;其中,dexorjar是虚拟机内部用于表示内存中dex文件信息的一个结构体,每一dexorjar对应一个dex文件信息。

2)由类加载器验证单元对监测到的每一项dex文件匹配相应的类加载器classloader,并形成关联记录。即对于每一dex文件a,如果能够匹配查询到dex文件a的类加载器classloader,则形成dex文件a与匹配类加载器classloader的关联记录,如果未找到匹配的类加载器classloader,则不形成关联记录。

3)根据上述关联记录,模拟系统类加载和数据解析过程,遍历并获取dex文件不同组成部分所在内存中的内容,此时获取到的内容为dex文件的解密后数据内容。

4)根据dex文件标准规范,创建脱壳后dex文件模板,完全重构dex文件,将对应解密部分填充至dex文件模板中,即得到脱壳后包含完整解密数据的dex文件。

进一步,步骤1)具体包括:

1-1)在虚拟机中创建一个新的线程,该线程的作用为周期性地主动轮询dex文件加载信息。通过虚拟机运行过程中的全局变量gdvm,可以访问dvmglobals结构,并从中获取到有关dex文件加载的相关信息。gdvm.userdexfiles保存了由自定义类加载器加载的dex文件集合,通过主动遍历这个集合,可以得到虚拟机内部用于表示内存中dex文件信息的dexorjar结构,用这种方法得到的集合记为pm。由于每一个dexorjar对应了一个dex文件,所以此时,获得dexorjar的集合pm,即等价于获得了已加载dex文件集合。

1-2)被动监测dex文件加载事件。在执行dex文件中的代码前,系统需要完成dex文件加载、类加载以及类初始化等操作。动态钩取在这个过程中的关键系统函数,即可获得dex文件的加载信息。具体而言,将选取dvmrawdexfileopen和defineclassnative函数,记录函数被调用时的参数信息。以defineclassnative为例,该函数一共接收4个参数,name:待加载类的名称;loader:加载该类使用的classloader;cookie:待加载类所在的dex文件;suppressed:处理加载过程中产生的异常。此时,cookie参数的值恰为指向dexorjar结构的指针。用这种方法得到的集合记为pn。

1-3)在加固程序启动至当前时刻,由加固程序本身已加载至内存中dex文件的总集合pa=pm∪pn,将被发送至类加载器验证单元。

进一步,步骤2)具体包括:

2-1)从gdvm.loadedclasses获取虚拟机中所有已经加载类的信息,每一个类都对应一个classobject结构,而classobject中的pdvmdex成员,表明了当前类所对应的dex文件,classloader成员保存了加载此类的类加载器的值。故pdvmdex与classloader形成对应关系。

2-2)对于pa中的每一项dexorjar,先取得其成员dvmdex的值,若所有classobject的pdvmdex成员均没有指向上述dvmdex,则说明当前dex文件中并没有任何类被加载;反之,则获取正确的classloader值。

进一步,步骤3)具体包括:

3-1)根据dex文件与classloader的关联记录,使用classloader加载对应dex文件中所有的类,使得该dex文件中的类被加载至内容中;

3-2)根据关联记录中,代表了dex文件在内存中表达的dexorjar结构,解析dex文件不同组成部分中的内容,整个过程以dexorjar结构为起点,遍历其指向的dex文件所有成员内容,若获取到的内容是指向其它内存区域的指针,则进行递归获取,若获取到的内容是数据,则将其复制保存至临时的内存空间中。整个过程遵守dex文件本身的规范格式;

进一步,步骤4)具体包括:

4-1)根据dex文件标准规范,在内存中生成脱壳dex文件模板,dex文件模板包含的结构有dex文件头、数据索引结构区、数据区和静态链接数据区,此时脱壳dex文件模板对应各项数据结构内部实际内容均为空;

4-2)根据步骤3)中获取的解密数据信息,按照dex文件标准规范依次填充脱壳dex文件模板,具体包含字符串信息、类型信息、原型信息、字段信息、方法信息、类信息以及依赖信息等等。在填充过程中,需要正确计算实际数据在文件中的偏移,并将该偏移写至dex文件的数据索引结构区。例如,对于某字符串数据a,其相对dex文件头部的偏移量为x,其位于数据索引结构区的结构为string_id_item,则该偏移量x需写入string_id_item中,对于其他类型的数据也需做类似操作。在计算和写入偏移时,会存在多级索引的情况,即初级索引结构将指向次级索引结构,此时需依照dex文件规范正确计算偏移,并填充至dex文件模板中的正确位置。

4-3)判断填充数据的有效性,若填充数据无效,则执行步骤4-4),否则执行步骤4-5)。具体而言,数据的有效性指的是该数据对应的内存区域是可达的,其数据格式符合当前数据类型的编码要求。例如,字符串数据应该符合mutf-8编码方式;

4-4)判断填充数据的冗余性,若填充数据是冗余的,则自动计算该填充数据的内容,否则清空dex模板中填充数据对应的结构以免对dex文件的还原造成不必要的影响(比如填充数据i是冗余的,该填充数据i在dex模板的填充位置是结构b,那么清空该结构b)。数据的冗余性指的是该数据为dex文件规范中硬编码部分,或者可以由其它信息计算而来。可判断为冗余数据,并能被自动计算的内容如下。dex_file_magic:存在于dex文件头部的常量字节列表,以便系统对文件进行识别和检测某些形式的损坏,该值包含"dex\n"和代表版本编号的3个十进制数字,并以"\x00"字节结尾;checksum:存在于dex文件头部,标示文件的校验和,用于检测文件损坏情况;signature:存在于dex文件头部,代表文件剩余内容的sha-1哈希签名;map_list:存在于数据结构索引区,代表文件全部内容列表,用于提供一种遍历整个dex文件的简单方式,属于冗余信息,直接清除将不影响dex文件正常解析。

4-5)将内存中的脱壳dex文件写入外部存储介质中,完成自动化脱壳流程。

本发明还提供一种实现上面所述方法的android加固应用程序通用自动化脱壳装置,包括全局控制单元,dex文件定位单元,类加载器验证单元,dex文件重构单元。

dex文件定位单元包括:dex内存数据结构解析单元,将虚拟机中保存的dex文件全局信息解析为脱壳需要的dex文件内存结构信息;函数动态钩取单元,能够在虚拟机动态运行过程中,按照需求钩取函数,获得在所钩取函数被调用时或者运行时的具体上下文信息,包括参数传递信息、函数返回信息。

类加载器验证单元包括:类内存数据结构解析单元,能够通过虚拟机中classobject结构解析出对应dex文件信息;类与dex文件关联单元,将确定类所对应的dex文件。

dex文件重构单元包括:内存定位单元,将模拟系统解析dex文件的方式,根据dex文件内存结构信息定位到各个数据区域解密后的内存地址;数据有效性验证单元,能够根据文件编码和校验方式判断当前获取内存数据的有效性;数据填充单元,将根据dex文件标准规范来计算各项数据偏移和长度,并完成填充工作。

与现有技术相比,本发明的积极效果为:

本发明通过修改android系统代码,实现了对加固程序的通用自动化脱壳,由于脱壳操作发生在系统代码层面,无需外部引入调试接口,避免了加固程序反调试技术带来的技术阻力。本发明采用的完全重构dex文件方法,解决了以往脱壳方案中出现的数据转储内存不连续或内存不完整的情况。同时,在获取内存数据时,将完全模拟操作系统解析的方式,保证了解密数据的正确性和有效性。

附图说明

图1本发明的整体系统结构图。

图2本发明的dex文件定位单元结构图。

具体实施方式

下面结合实施例和附图进一步阐述本发明所述的技术方案。

如图1所示为本系统的整体架构。本系统由四部分构成,包含全局控制单元,dex文件定位单元,类加载器验证单元,dex文件重构单元。该系统及其包含的单元以独立模块的方式在android系统中运行,并不影响android系统的正常功能。因此,本系统可以直接安装在以android为主操作系统的智能设备,或带有android系统模拟器的计算机设备之中。

全局控制单元可以是运行在android系统上的应用程序,或者运行在计算机设备的应用软件,其目的在于为系统的使用提供可视化的操作流程以及直接的信息反馈。通过全局控制单元,将包含指定需要进行脱壳处理的目标应用程序,获取脱壳时产生的调试信息,转储脱壳后的文件至指定存储设备中等等全局设定功能。当指定目标应用程序后,系统则进入脱壳流程。

如图2所示,dex文件定位单元工作流程主要分为两个阶段,分别为完成动态函数钩取工作和记录dex文件加载行为。动态函数钩取操作将在应用加载的最初时机完成,具体而言,将在android系统框架调用zygoteinit.main函数之前,完成对系统关键函数的钩取,具体而言,将选取dvmrawdexfileopen和defineclassnative函数。由于zygoteinit.main函数是android系统建立虚拟机环境的函数,在这个函数调用前,加固程序的代码均没有被执行,因此在此时建立监控能完全获取后期dex文件的加载情况。当建立监控后,android系统将完成剩下的初始化操作,并执行目标程序代码。同时,该单元还将使用主动轮询的方式进行内存查找,通过虚拟机运行过程中的全局变量gdvm,可以访问dvmglobals结构,并从中获取到有关dex文件加载的相关信息。此时,dex文件定位单元将获取已加载dex在内存中的具体表达,并将其记录下来,具体而言,将记录其dexorjar结构。

类加载器验证单元的工作流程为,从gdvm.loadedclasses获取dalvik虚拟机中所有已经加载类的信息,每一个类都对应一个classobject结构,而classobject中的pdvmdex成员,表明了当前类所对应的dex文件,classloader成员保存了加载此类的类加载器的值。故pdvmdex与classloader形成对应关系。对于dex定位单元中记录的每一项dexorjar,先取得其成员dvmdex的值,若所有classobject的pdvmdex成员均没有指向上述dvmdex,则说明当前dex文件中并没有任何类被加载;反之,则获取正确的classloader值。获取该值的意义在于,壳代码可以通过重写loadclass方法,避开双亲委派的框架,这样就可以实现重新加载已经加载过的类,也能够在加载类的时候注入额外代码。当前大部分加固技术并不会一次性完成dex文件中所有类的解密,而是在目标类被加载时,通过自定义的类加载操作,或者利用相关类加载函数,完成对目标类的解密。因此,通过获取壳函数使用的类加载器,并模拟系统解析类的方式去主动加载dex文件中的所有类,即可达到dex文件内存中解密的目的。

为了完整的获取dex文件内容,dex重构单元将依据此内存结构和dex文件标准规范,在内存中重构脱壳后的dex文件,并按照前文全局控制单元的设定,将脱壳后dex文件转储至指定存储设备中。具体包含了以下步骤:

1)依据加壳dex文件,生成对应的脱壳dex文件模板,此时脱壳dex文件对应各项数据结构均为空;

2)依次构建脱壳dex文件数据索引区域以及其对应的数据保存区域,例如针对pstringids索引,其对应数据保存区域保存有dex文件中的字符串数据。除字符串信息之外,还将依次获取类型信息、原型信息、字段信息、方法信息、类信息以及依赖信息等等;

3)判断填充数据的有效性和冗余性。具体而言,数据的有效性指的是该数据对应的内存区域是可达的,其数据格式符合当前数据类型的编码要求。例如,字符串数据应该符合mutf-8编码方式。数据的冗余性指的是该数据为dex文件规范中硬编码部分,或者可以由其它信息计算而来。例如,dex文件头部应以"dex\n"作为起始部分。

4)将填充后的dex文件写入指定存储设备中,完成脱壳。

经过以上流程,则完成了对加固应用程序的自动化脱壳,在系统使用过程中,仅需指定需要处理的目标应用程序。

尽管为说明目的公开了本发明的具体实施例和附图,其目的在于帮助理解本发明的内容并据以实施,但是本领域的技术人员可以理解:在不脱离本发明及所附的权利要求的精神和范围内,各种替换、变化和修改都是可能的。本发明不应局限于本说明书最佳实施例和附图所公开的内容,本发明要求保护的范围以权利要求书界定的范围为准。

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