一种ART下使用自修改技术进行软件保护的方法与流程

文档序号:16882046发布日期:2019-02-15 22:15阅读:333来源:国知局
一种ART下使用自修改技术进行软件保护的方法与流程

本发明属于软件技术领域,具体涉及一种art下使用自修改技术进行软件保护的方法。



背景技术:

随着移动网络以及手机行业的迅速发展,智能手机已经成为人们生活必不可少的部分,而android系统作为移动终端中最为流行的系统,其安全问题也越发的突出。据《阿里聚安全2016年报》显示,2016年度,android平台约10台设备就有一台染毒,设备感染率达10%,89%的热门应用存在仿冒,移动欺诈损失超数亿美金。应用遭到逆向破解,被重新打包,知识产权遭到侵犯的现象屡有发生,严重的损害了开发者以及用户的利益。为了对抗逆向攻击者,保护android软件的安全,国内外学者提出了许多android软件保护技术,例如混淆、加壳、虚拟机保护等。android新版本art虚拟机的诞生,使原本的一些应用保护方法受到了严重的影响而不再适用或受到局限。

android应用程序很容易遭到逆向,由于恶意逆向工程的攻击,许多android应用程序被篡改并重新打包成恶意应用。软件逆向工程是分析程序结构及其行为,来了解程序是如何运作与实现的。逆向工程可以通过了解现有的应用程序的结构与行为,以一个相对较低的代价创造出一个新的有竞争力的应用程序。不仅如此,逆向工程可以用来篡改或破解移动应用程序来获取非法利益,如绕过认证或支付。控制医疗设备的黑客通过篡改移动应用甚至可以威胁到人的生命。攻击者常用的逆向手段大致分为静态分析和动态分析。静态分析,是指在不运行程序的情况下,采用词法分析、语法分析等技术手段对程序分析生成程序的反汇编代码,通过阅读反汇编代码来了解程序功能的一种技术。动态分析,较之静态分析而言,难度要大一些,通过调试程序,了解程序运行时的情况,在关键位置下断点,知晓关键位置的数据,动态的分析程序。一般来说,对抗静态分析,可以采用混淆,加密,加壳等手段。而对抗动态分析,需要反调试技术,以及虚拟机检测技术,防止内存dump的措施等。

代码自修改技术,是指在程序可以在运行期间修改自身的指令,最早由日本研究者于2003年提出。自修改技术在pc端的应用较为普遍,现在已比较成熟。根据《asoftwareprotectionmethodbasedoninstructioncamouflage》所述,自修改代码(self-modifyingcode,smc)技术在软件保护等领域有着广泛应用,防止软件破解等代码分析人员使用逆向工具对程序进行静态分析,增加逆向人员对受保护代码分析的难度。对于android平台下代码自修改的研究,要晚很多,2013年,blueboxsecurity网站的一篇文章为自修改技术在android移动端的应用提供了启示。在文献《基于android平台的软件保护策略的研究与实现》中,张晓证明了在android平台下自修改的可行性,并结合android应用签名验证、完整性验证,提出一种二次smc的软件保护策略。在文献《基于自修改字节码的android软件保护技术研究》中,高琦等人,研究并实现了改变代码执行流程的自修改,为android软件保护提供了新的思路。文献《androidsecurityanalysischallengetamperingdalvikbytecodeduringruntime》提出了一种运用自修改的混淆方法,并对应用的执行效率影响不大。

动态加载技术,在应用保护运用较多的一种形式,是软件加壳。根据文献《软件加壳技术的研究》所述,加壳就是把原始程序嵌套在另一个可执行程序中,而这个可执行程序就是原程序的“壳”,它负责把原始程序从数据段解密出来,并运行。这样的话,原应用是动态加载进来的,可以有效的抵抗静态分析。目前,很多安全公司,例如360,梆梆,爱加密等都有其各自的android加壳方法以及相应产品。而动态加载技术,并不仅仅局限于加壳,也不局限于软件保护,各大热修复方法中也都出现了它的身影,腾讯qzone的热修复框架就是利用了dex的动态加载技术。插件化开发也要使用到动态加载,其实对于动态加载的运用还是可以很灵活的。



技术实现要素:

本发明的目的在于:针对上述android应用程序很容易遭到逆向,由于恶意逆向工程的攻击,许多android应用程序被篡改并重新打包成恶意应用和art模式下软件保护的难度大的问题,提出一种art下使用自修改技术进行软件保护的方法。

本发明采用的技术方法如下:

一种art下使用自修改技术进行软件保护的方法,包括如下步骤:

步骤1:选取被保护应用的待保护关键代码;

步骤2:将步骤1所选关键代码进行抽取;

步骤3:将步骤2抽取出的关键代码进行破坏,并转化为动态加载的dex文件;

步骤4:根据步骤3处理所得的代码和最初的关键代码,生成用于自修改修复的native代码;

步骤5:使用自修改状态机算法对步骤4中的native代码进行保护;

步骤6:对步骤5生成的代码集成编译并打包,生成最终被保护的apk。

首先将选取的关键代码进行抽离,再将关键代码构造出被保护的dex,并根据构造时所进行的破坏信息生成相应的自修改修复的native代码;然后,对此部分native代码运用自修改状态机算法对其进行保护,生成最终的so库;最后,进行集成,编译,打包生成最终被保护的apk。

优选地,所述步骤2对关键代码的抽取通过关键代码抽取模块完成,抽取后将相应的调用更改为动态加载与自修改保护后的调用方式,所述关键代码抽取模块的步骤为:

步骤2.1:将被保护的关键代码从其实现的类中剥离出来,新建一个被保护的类,将关键代码放在此被保护的类中;

步骤2.2:而此被保护的类打成jar,使用dx工具转化为dex格式,作为动态加载的目标,抽取模块只是将关键代码提取出来;

步骤2.3:将原先调用关键方法的位置,更改为动态加载此dex,并调用dex中的关键方法,而此种调用的同时,将自修改回填正确代码的native实现,放在动态加载dex之后,调用关键方法之前。

优选地,所述步骤3通过构造被保护的dex模块对被抽离出的关键代码进行处理,破坏其中逻辑并记录破坏信息,并通过dx转化,生成相应待加载的dex文件。

优选地,所述步骤4中的native通过自修改代码生成模块生成,该模块根据步骤3的破坏修改信息生成相应的自修改修复代码,具体工作步骤为:

步骤4.1:查看应用内存信息并找到加载的dex的起始与结束位置;

步骤4.2:获得类的stringid,获得方法的stringid,获得类的typeid,获得方法的typeid,获得classdefitem的地址,获得classdataoff代码地址;

步骤4.3:计算要替换的指令地址,使此部分内存可读写并替换内存数据。

优选地,所述步骤5中对native代码的保护通过自修改保护模块完成,该模块运用自修改自动机算法native代码分割为4块,并加入2段无关代码,运用算法对该native代码进行保护,具体工作步骤是:

步骤5.1:定义构造的两段无关代码块分别为useless_1(),useless_2();

步骤5.2:将构造的无关代码与自修改的native代码相结合,并拆分为六个片段,各片段如下:

a:查看应用内存信息并找到加载的dex的起始与结束位置部分代码,findaddress();

b:获得类的stringid,获得方法的stringid,获得类的typeid部分代码,findid();

c:获得方法的typeid,获得classdefitem的地址,获得classdataoff代码地址部分代码,findcode();

d:无关代码块1,useless_1();

e:计算要替换的指令地址并替换内存数据,modify();

f:无关代码块2,useless_2()。

综上所述,由于采用了上述技术方法,本发明的有益效果是:

1、本发明中,代码自修改在art下使用的研究很少,而原本dalvik的自修改方法,由于art所带来的一系列改变,在art下不再适用。本发明提供的方法使用hook的方式更改应用加载dex的流程,在动态加载时规避了格式的转换,在恰当的时机实现自修改修复,解决了art下由新的文件结构带来的原本方法不适用的问题。

2、本发明中,该方法结合动态加载与自修改技术,能够对应用的关键代码进行有效保护,通过方法抽离与自修改修复隐藏了关键代码,防止了逆向攻击者的静态分析,极大的增加了逆向攻击者动态分析的难度。在研究art下自修改方法的基础上,将其运用在软件保护之中,设计了art下的自修改保护方法。

3、本发明中,根据art下的自修改保护方法设计并实现了一套应用保护系统,该系统能够对android应用进行保护,并对其中的关键代码进行自修改保护。

4、本发明中,运行时自修改代码,以及使用自修改状态及算法,使得代码的执行是动态的,关键代码只有在真正运行时出现,使得所有静态分析都无法奏效,是一种动态的保护关键代码的方法。

附图说明

图1为本发明的总体流程架构示意框图;

图2为本发明的保护处理流程示意框图;

图3为本发明的运行时处理流程示意框图;

图4为本发明的hook方案示意框图;

图5为本发明的自修改状态机算法示意框图。

具体实施方式

为了使本发明的目的、技术方法及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅用以解释本发明,并不用于限定本发明。

实施例1

表1测试环境

pc端用于处理待保护应用,经过应用保护系统最终生成已保护的apk,以及查看日志信息分析。而手机端用于测试已保护应用的运行状况。

如图1-5所示,对待保护应用的保护处理流程中,第一步是构造快速安全的动态加载的方案。应用保护中使用动态加载需要保证快速且安全,快速要保证用户没有明显的滞顿感,安全要保证直接从内存中加载dex。dalvik下的快速安全动态加载方案为,构造自己的类加载器,且要调用libdvm.so中dalvik_dalvik_system_dexfile_opendexfile_bytearray函数,将字节码以一个byte数组的形式传入就可以利用其加载内存中的dex文件。根据加载dex的流程,还需要在自定义的类加载器的构造函数中,反射调用opendexfile方法得到dex的cookie值,然后重写其findclass函数,反射调用getclassnamelist方法,传递cookie值得到dex中所有类,然后进行类路径转化,再反射调用defineclass方法,传递cookie值返回一个class对象。至此实现了dalvik下的安全加载。art下要实现快速安全的动态加载且同时使得自修改方案能够在动态加载的基础上实施,本文的方案是采用hook方式更改加载流程,使动态加载过程中省去dex2oat的转化。具体实施为,hookexecv函数,让负责把dex文件转化为oat文件的dex2oat进程退出,hook方案的示意图如图4所示。这样就避免了转换oat的过程且直接加载到内存,不必释放oat文件到外部存储,且省去了转化的时间加快了第一次加载的速度。

第二步,关键代码抽离,构造被保护的dex。即将应用的关键代码从主程序剥离出来,将其形成一个插件类的形式,打成jar包,并通过dx转化为dex,用于之后的动态加载调用。且此dex要经过破坏操作,将正确的关键逻辑破坏掉。同时,主程序中调用关键代码的部分,都修改为动态加载调用。

第三步,生成自修改修复代码,根据上一步的破坏,已经正确的关键逻辑,生成相应的自修改修复的native代码用于运行时,将被破坏的逻辑修复为正确的逻辑。而自修改的步骤为首先要解析出dex文件的内存地址。dex文件被加载进内存之后,可以通过查看该应用进程的内存数据找到dex文件对应的起始与结束地址。而在dalvik下,内存中的其实是odex文件,并不是直接的dex文件,那么需要在odex文件中获取到dex文件的偏移地址,可以依靠校验dex文件的魔数“dex\n”来定位其偏移地址。定位到内存中dex之后,就需要根据其格式一步步找到我们需要修改的修改点。获取方法和类的stringid索引值,再根据这个索引值获取方法和类的typeid索引值。然后定位到classdefitem的地址,进一步获取到方法的指令。这时候就可以修改内存为可读写模式,使用memcpy进行内存数据的覆盖,将相应内存数据覆盖为修改后的指令,至此完成修改。

第四步,自修改状态机保护,自修改状态机算法是davidaucsmith提出的一种已经被证实十分有效的软件保护技术。该算法使得,程序不会在同一时间点呈现出全部的明文,程序永远处于不断变化之中。图5为自修改状态机算法示意图,首先将被保护函数func()划分为大小相同或不一的六个片段,并把这六个片段存放于六块大小相等的内存区域之中。然后六块内存再分为上下两部分,并构造出初始状态m0,之后每轮进行变换,使得程序在不断的变换之中得到运行。

首先,根据自修改的流程,可知应用要进行一次自修改,需要如下几步:

(1)查看应用内存信息并找到加载的dex的起始与结束位置;

(2)获得类的stringid,获得方法的stringid,获得类的typeid,获得方法的typeid,获得classdefitem的地址,获得classdataoff代码地址;

(3)计算要替换的指令地址,使此部分内存可读写并替换内存数据。

其次,为了保护自修改部分的代码,还需要构造出两段无关的代码,用于扰乱攻击者,且相应无关代码不会对程序结果产生任何影响,也不产生极大的性能开销。定义构造的两段无关代码块分别为useless_1(),useless_2()。然后将上一步构造的无关代码与自修改的native代码相结合,并拆分为六个片段,各片段如下:

a:查看应用内存信息并找到加载的dex的起始与结束位置部分代码,findaddress();

b:获得类的stringid,获得方法的stringid,获得类的typeid部分代码,findid();

c:获得方法的typeid,获得classdefitem的地址,获得classdataoff代码地址部分代码,findcode();

d:无关代码块1,useless_1();

e:计算要替换的指令地址并替换内存数据,modify();

f:无关代码块2,useless_2()。

关键代码如下:

构造出初始状态后,依据图5的变换,实现自修改状态机算法对此部分native代码进行保护。

总体框架中的混淆保护,即对整体待保护应用进行简单混淆,也是最基础的保护。反调试保护,即在应用中插入反调试代码,以更改的对抗动态分析。完整性校验保护,即在应用中插入对应用的哈希值校验,和签名校验,以便判别应用是否经过篡改。

运行时处理流程如图3所示,关键部分在于,运行到关键逻辑之前,首先要将其动态加载进内存,再通过自修改修复其中已经被破坏的逻辑。之后才能正常运行关键代码,且运行关键代码结束后,又恢复为修复前的指令集,使得关键代码只有在真正运行时才出现在内存中。

以上所述仅为本发明的较佳实施例而已,并不用以限制本发明,凡在本发明的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明的保护范围之内。

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