基于DEX字节码抽离映射混淆的安卓应用加固方法与流程

文档序号:15828745发布日期:2018-11-03 00:12阅读:828来源:国知局

本发明涉及一种安卓应用加固保护方法,具体地涉及一种基于dex字节码抽离映射混淆的安卓应用加固方法。

背景技术

在移动互联网通信中,安卓系统由于其开放和免费特点,得到了大量应用开发人员的支持,各种安卓应用层出不穷,给移动终端用户带来了丰富体验。然而,由于安卓应用主要通过java语言开发,并编译成dex字节码运行在安卓系统的dalvik或art(androidruntime)虚拟机环境中,攻击者通过逆向分析dex实现对安卓应用的破解、篡改、挂钩(hook)和重打包,引起安卓应用的盗版、代码注入和隐私信息泄漏等安全问题。2016年国家互联网应急中(cncert/cc)通过自主捕获和厂商交换,发现移动互联网恶意程序数量近205万个,比2015年增长了39.0%,而且主要针对安卓平台。根据通付盾科技发布的2017年度移动应用安全态势报告,仿冒安卓应用规模2017年从2.3万增长到2.8万,增长21.74%,这些仿冒软件内置恶意代码,并以推送广告、恶意扣费和隐私信息窃取等方式损害用户利益。因此,如何防止安卓应用被非法破解、注入木马、计费、广告等恶意代码,保护隐私信息,维护用户权益,实现安卓应用软件的安全加固保护,成为软件安全研究的热点。

目前,针对安卓应用的安全加固已经取得了一些研究成果,包括反射机制、动态加载、加密、native代码执行、加壳和代码混淆等加固技术和方法,一定程度上消除了逆向分析带来的威胁。但随着内存提取、动态脱壳、污点分析和符号执行等逆向分析技术的出现和快速发展,传统的加固方法已经无法满足需求。



技术实现要素:

为了解决上述技术问题,本发明目的是:提供了一种基于dex字节码抽离映射混淆的安卓应用加固方法,将java层的dex字节码抽离和映射构造混淆dex字节码,并封装到native层中,通过native层的dex映射解释执行环境,对混淆dex字节码进行解释执行,确保混淆后的安卓应用运行逻辑的正确性。本发明方法在不影响运行开销的情况下,不仅大大提高混淆强度,而且能够有效抵御各种逆向分析攻击,具有很强的抗攻击弹性。

本发明的技术方案是:

一种基于dex字节码抽离映射混淆的安卓应用加固方法,包括以下步骤:

s01:将安卓应用apk程序进行解压缩得到原dex文件;

s02:从原dex文件中抽取出待混淆的code_item代码,并根据操作码映射表将code_item进行映射混淆处理;

s03:提取原dex文件中的表信息,与混淆的code_item代码及映射解释器源码一起放在映射解释执行环境的源代码中,将映射解释执行环境的源代码编译得到映射解释执行环境的共享对象库(so)可执行文件;

s04:通过逆向工程将安卓应用中的dex字节码反编译成java源码,并添加映射解释执行环境的java入口方法对原java方法进行替代混淆,编译安卓应用混淆源码成新的混淆dex文件;

s05:把原安卓应用apk中的其他文件、编译新生成的混淆dex文件和映射解释执行环境的so可执行文件一起签名打包成一个新的加固安卓应用apk程序。

优选的技术方案中,所述步骤s02中混淆处理时构造不透明字节码,将映射后的混淆code_item代码和dex表信息分别生成code_item和dex表信息索引后一起封装到native层的so中。

优选的技术方案中,所述步骤s03中,根据操作码映射表及dalvik字节码标准在本地层实现映射解释器,把映射解释器封装到so后和code_item及dex表信息索引一起生成dex映射解释执行环境。

优选的技术方案中,所述步骤s04中结合可变参数传递机制、索引机制和java本地接口(jni)机制在java层的dex中设置映射解释执行环境入口,完成对混淆code_item代码的映射解释执行调用。

优选的技术方案中,所述dex文件中的表信息,包括字符串标识符表、字段标识符表和方法标识符列表。

优选的技术方案中,在封装dex表信息时,保留其原始的索引值,解释code_item的指令操作码时,通过轮询索引链表找到dex表信息的原始索引值,通过该原始索引值获取dex表信息。

与现有技术相比,本发明的优点是:

本发明方法不仅将安卓应用dex字节码进行有效混淆,抵御各种逆向分析与利用,实现安卓应用的安全加固保护。而且混淆后的安卓应用运行逻辑保持正确,运行的安卓系统环境保持不变。

(1)采用抽离映射混淆技术构造不透明dex字节码,并将dex字节码信息从dex文件中抽离至so文件中,使它们能够抵御java层和native层的各种动静态逆向分析攻击,实现dex字节码的有效混淆保护。

(2)通过dex映射解释执行环境提供一种基于native层映射解释执行的dex字节码间接执行方法,并利用可变参数传递机制、索引机制和jni机制实现dex字节码混淆后的正确运行,使得安卓应用加固后无需改变安卓系统的运行环境,从而保证了安卓应用的独立性和通用性。

(3)混淆dex字节码直接通过映射解释器解释执行,无需通过字节码映射表将混淆dex字节码还原成原始dex字节码,避免因保护字节码映射表所引起的新的安全问题。

附图说明

下面结合附图及实施例对本发明作进一步描述:

图1为本发明基于dex字节码抽离映射混淆的安卓应用加固方法的流程图;

图2为操作码映射混淆过程示意图;

图3为code_item链表索引示意图;

图4为字符串标识符表信息索引;

图5为映射解释执行环境入口示意图;

图6为映射解释执行环境示意图。

具体实施方式

为使本发明的目的、技术方案和优点更加清楚明了,下面结合具体实施方式并参照附图,对本发明进一步详细说明。应该理解,这些描述只是示例性的,而并非要限制本发明的范围。此外,在以下说明中,省略了对公知结构和技术的描述,以避免不必要地混淆本发明的概念。

实施例:

如图1所示,一种基于dex字节码抽离映射混淆的安卓应用加固方法,该方法包含dex抽离映射混淆和映射解释执行,具体包括以下步骤:

s01:将安卓应用apk程序进行解压缩得到原dex文件;

s02:从原dex文件中抽取出待混淆的code_item代码,并根据操作码映射表将code_item进行映射混淆处理;code_item是安卓dex文件格式中的内容。

s03:提取原dex文件中的表信息,与混淆的code_item代码及映射解释器源码一起放在映射解释执行环境的源代码中,将映射解释执行环境的源代码编译得到映射解释执行环境的共享对象库(sharedobject,so)可执行文件;

s04:通过逆向工程将安卓应用中的dex字节码反编译成java源码,并添加映射解释执行环境的java入口方法对原java方法进行替代混淆,编译安卓应用混淆源码成新的混淆dex文件;

s05:把原安卓应用apk中的其他文件、编译新生成的混淆dex文件和映射解释执行环境的so可执行文件一起签名打包成一个新的加固安卓应用apk程序。

在dex抽离映射混淆中,首先对安卓应用中dex的code_item代码和dex表信息进行抽离处理,其次根据操作码映射表对抽离出来的code_item代码进行映射混淆构造不透明字节码,并利用安卓native化特性将映射后的混淆code_item代码和dex表信息分别生成code_item和dex表信息索引后一起封装到本地层(native层)的so(sharedobject)中。

在安卓应用中,安卓java方法编译在dex文件的code_item中。因此,首先在dex中找到code_item代码,并将它从dex中抽离出来。例如,一个算术运算安卓java方法,其源代码如下所示。

以上安卓java方法编译后在dex中的code_item代码如下所示。

其中,0x04000200000000000b9529000500000092000202900103000f01为安卓java方法test1对应的code_item代码。其中,0x92000202900103000f01为code_item的insns字节码(框内数据),它对应test1方法的c=a*a,b+c运算指令和return返回指令。

然后,根据dalvik字节码语法在code_item中确定其指令流中的操作码信息,并依次把每个操作码根据操作码映射表替换成新的操作码。以test1方法的字节码为例,其操作码映射混淆过程如图2所示。

在图2中,首先分析该字节码包含3条指令,其操作码分别为0x92、0x90和0x0f。根据图2的操作码映射表,操作码映射后分别变为0x17、0x2c和0x76。映射混淆后,code_item的insns字节码为0x170002022c0103007601,如下所示。

可以看出,code_item的操作码映射保证了即使安卓应用的code_item被分析出来时,也难以逆向出其原始code_item代码。将抽离并进行操作码映射混淆后的code_item代码组成一个code_item链表索引,其格式如图3所示。

在图3中,每个code_item对应一个链表索引值(index)。然后通过c/c++程序编译将code_item索引封装到so中。混淆后的code_item代码执行由native层的映射解释执行环境完成。为提高混淆后的code_item代码在native层的解释执行效率,将code_item代码用到的dex表信息,包括字符串标识符表(string_ids_item)、字段标识符表(field_ids_item)和方法标识符列表(method_ids_item)等组成对应的dex表信息索引,然后和混淆code_item代码一样封装到so中。例如,字符串标识符表信息索引格式如图4所示。

从图4可以看出,字符串标识符表信息封装到so文件后,其在原字符串标识符表信息的索引值(string_id)对应到so文件中的链表索引值(index)会发生变化。因此,在封装dex表信息(如string_ids_item)时,同时会保留其原始的索引值(如string_ids)。这样,当解释code_item的指令操作码时,会通过轮询索引链表找到dex表信息的原始索引值。然后,通过该原始索引值获取dex表信息。例如,当执行code_item的const-string指令操作码时,它将字符串标识符表中指定的引用放入指定的寄存器中,这时根据const-string指令操作码的string_id值找到图4索引链表中相同string_id值的string_id_item项,然后返回该项的string值。这样就保证了dex字节码的解释环境变化后,其依旧能够正确高效地执行。

在dex映射解释执行中,首先根据操作码映射表及dalvik字节码标准在native层实现映射解释器。然后,把映射解释器封装到so后和code_item及dex表信息索引一起生成dex映射解释执行环境。最后,结合可变参数传递机制、索引机制和jni(javanativeinterface,java本地接口)机制在java层的dex中设置映射解释执行环境入口,完成对混淆code_item代码的映射解释执行调用。

为确保dex字节码被抽离映射后其混淆code_item代码能够被正确地在native层中执行,需要在java层中设置抽离映射的混淆code_item代码执行入口,称为映射解释执行环境入口。它包括java方法参数、code_item索引值和映射解释执行环境入口方法,如图5所示。

从图5可以看出,安卓应用dex字节码混淆后,dex的code_item代码被修改成用原始java方法参数和一个code_item索引值调用的映射解释执行环境入口方法,该入口方法内部结合可变参数传递机制、索引机制和jni机制调用native层的映射解释执行环境。在设置入口方法时,首先定义一个obfcodeitementry类,它是映射解释执行环境的java层入口类。obfcodeitementry根据java方法的不同返回类型,定义不同的入口方法,如obfcodeitementry.cint和obfcodeitementry.cfloat等。这些入口方法的参数为可变参数,且都是native属性,说明其通过jni调用native层实现的映射解释执行环境。在test1方法中,其参数为两个int型变量a和b,返回类型为int。因此,在设置入口方法时,根据返回int型定义其入口方法定为cint方法,即obfcodeitementry.cint,其入口方法代码如下所示。

以上代码中,调用obfcodeitementry.cint方法时,使用对象数组object[]作为可变参数,其值分别为newinteger(a),newinteger(b),integer.valueof(0)。其中,前两个参数a和b是test1方法的参数,第3个参数0是code_item的索引值。为了便于参数的传递,这些参数被统一封装成java类类型。

经映射解释执行环境入口设置后,安卓应用中dex的code_item代码变为入口方法所对应的code_item代码,如下所示。

从中可以看出,当对该安卓应用进行逆向分析时,原始的code_item代码被抽离映射混淆,且原始code_item代码在执行时不会被动态加载到安卓系统的art运行环境中。此外,安卓应用中dex的code_item代码不再包含原java方法的任何执行逻辑,所以很难对其进行有效的逆向分析。

当上述的code_item代码被调用时,会由obfcodeitementry.cint通过jni从java层调入native层的映射解释执行环境,它包含映射解释器、混淆code_item代码和dex信息表,如图6所示。其中,映射解释器是一个根据操作码映射表和dalvik操作码标准实现的混淆code_item代码解释器。

从图6可以看出,安卓应用中没有被混淆的dex字节码,其解释执行通过安卓art虚拟机完成。安卓应用混淆code_item代码的解释执行将通过映射解释执行环境完成,这时映射解释执行环境根据java层传入的索引值获取native层中code_item和dex表信息索引中对应的混淆code_item代码和dex表信息,然后进一步调用映射解释器对其进行解释执行。如果混淆code_item代码中存在调用安卓系统方法等执行逻辑,将通过jnienv接口与art进行交互。

在以上代码中,mapinterprexeenvirint()函数是obfcodeitementry.cint入口方法对应native层的映射解释执行环境实现,其object_array参数接收obfcodeitementry.cint方法的参数值{a,b,0}。根据object_array接收的code_item索引值0,mapinterprexeenvirint()通过调用getcodetitem()函数在code_item索引中找到java方法对应的混淆code_item代码。接着,以object_array接收的java方法参数值{a,b}和混淆code_item代码作为参数调用映射解释器函数mappinginterpreter()。根据art的解释执行原理,art解释器提供goto和switch两种实现方式。本文的映射解释器采用switch方式解释执行映射操作码,即根据操作码映射表设置case值及其对应的解释执行过程。

根据操作码的映射关系,case值0x2c对应的处理过程是dalvik字节码中0x90指令类型为add_int的处理过程。根据操作码映射关系实现的映射解释执行环境保证了在java方法的code_item代码被抽离映射混淆后,该方法仍然能够被正确解释执行。

应当理解的是,本发明的上述具体实施方式仅仅用于示例性说明或解释本发明的原理,而不构成对本发明的限制。因此,在不偏离本发明的精神和范围的情况下所做的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。此外,本发明所附权利要求旨在涵盖落入所附权利要求范围和边界、或者这种范围和边界的等同形式内的全部变化和修改例。

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