软件水印的嵌入和提取方法
【专利摘要】本申请公开了一种软件水印的嵌入和提取方法,在嵌入水印时,根据用户触发的事件流和待嵌入的水印信息,生成相应的水印代码,并嵌入到各事件对应的汇编代码段中。本发明,通过在水印和程序本身之间建立一种逻辑依赖关系,可以提高水印信息的隐藏性。采用本发明可以对Android平台应用软件进行有效保护。
【专利说明】软件水印的嵌入和提取方法
【技术领域】
[0001]本发明涉及计算机软件安全技术,特别是涉及一种软件水印的嵌入和提取方法。
【背景技术】
[0002]目前,随着安卓移动智能终端的飞速发展,近年来围绕移动应用程序出现了一种新兴经济模型。然而,应用程序重打包给应用程序开发人员、应用商店及用户带来了巨大的风险。恶意用户通过应用程序重打包能够破坏开发者的收入来源,侵犯其知识产权。最近的研究表明,应用程序重打包是Android恶意软件在外进行传播最常见的机制之一。调查还表明,应用程序重打包成为手机银行应用的严重漏洞。面对这些安全威胁,需要对应用软件进行保护。
[0003]目前国内外在软件保护领域做了大量的研究,提出了一些软件保护方法,并且构造了相应的软件保护工具。目前主要的软件保护方法可分为:代码混淆,软件水印,内容数字版权加密保护技术,应用加壳,代码克隆检测等。
[0004]代码混淆(Obfuscated code)亦称花指令,是将计算机程序的代码,转换成一种功能上等价,但是难于阅读和理解的形式的行为。代码混淆可以用于程序源代码,也可以用于程序编译而成的中间代码。执行代码混淆的程序被称作代码混淆器。目前已经存在许多种功能各异的代码混淆器。
[0005]代码混淆方法包括以下几种方式:
[0006](I)将代码中的各种元素,如变量,函数,类的名字改写成无意义的名字。比如改写成单个字母,或是简短的无意义字母组合,甚至改写成“―”这样的符号,使得阅读的人无法根据名字猜测其用途。
[0007](2)重写代码中的部分逻辑,将其变成功能上等价,但是更难理解的形式。比如将for循环改写成while循环,将循环改写成递归,精简中间变量,等等。
[0008](3)打乱代码的格式。比如删除空格,将多行代码挤到一行中,或者将一行代码断成多行等等。
[0009]混淆器的作用不仅仅是保护代码,它也有精简编译后程序大小的作用。由于以上介绍的缩短变量和函数名以及丢失部分信息的原因,编译后jar文件体积大约能减少25%,这对当前费用较贵的无线网络传输是有一定意义的。
[0010]软件水印(software watermark)技术是所有软件保护的研究中较新的一个领域,是数字水印技术的分支,软件所有者通过在软件中嵌入特有信息,来标识作者、发行商、所有者、使用者等信息,部分嵌入信息携带着版权保护信息和身份认证信息,可以鉴别出非法复制和盗用的软件产品。
[0011]软件加壳是利用特殊的算法对EXE、DLL文件(Android中为dex文件)里的资源进行压缩,改变其原来的特征码,隐藏一些字符串等等,使一些资源编辑软件不能正常打开或者修改。在对Android dex文件加壳过程中,涉及到以下3种角色:
[0012]加壳程序:加密源程序为解壳数据、组装解壳程序和解壳数据;
[0013]解壳程序:解密解壳数据,并运行时通过DexClassLoader动态加载;
[0014]源程序:需要加壳处理的被保护代码。
[0015]内容数字版权加密保护技术(Digital Rights Management,DRM)指的是出版者用来控制被保护对象使用权的一些技术,这些技术保护的有数字化内容(例如:软件、音乐、电影)以及硬件,处理数字化产品的某个实例的使用限制。DRM首先建立应用授权中心,编码压缩后的应用内容,可以利用密钥(Key)进行加密保护(lock),加密的应用头部存放着KeyID和应用授权中心的URL。用户在使用时,根据应用头部的KeyID和URL信息,就可以通过应用授权中心的验证授权后送出相关的密钥解密(unlock),应用方可使用。
[0016]上述传统的软件保护工具虽然仍被大多数开发者使用,某些算法强度也比较高,但是,各方法所实现的功能还是存在一定的局限性。
[0017]具体而言,代码混淆、静态软件水印、应用加壳等应用保护方法,只能增加攻击者破解应用的难度,并不能阻止有经验的攻击者利用IDA等逆向工具手动分析破解Android应用。目前部分主流的软件保护工具,如Proguard、ApkProtect等都出现了相应的反混淆、脱壳工具,这些工具也侧面说明了上述这些方法的部分缺陷,破解难度较小。
[0018]目前主流的应用商店如GooglePlay、亚马逊中国等,提供了自己的内容数字版权加密保护技术,开发者调用相应的工具库即可防止应用被破解和重新打包。但是这些保护机制存在部署难度较大、消耗大量开发成本等问题。例如,对于Google Play的内容数字版权加密保护技术,应用软件每次启动的时候都会验证证书,这一过程需要数据连接。而,很多应用软件都是离线工作,因此会导致应用软件无法启动。
[0019]Android应用软件水印技术的主要需求在第三方商店以及手机厂商,开发者并不希望提供源码以供嵌入水印,使得基于Java源码的水印方法并不适用于Android应用保护。由于Android平台是使用dalvik虚拟机运行Android程序的,而dalvik虚拟机运行的是dalvik字节码,dalvik字节码有不同于汇编指令的指令特点,因此目前已有的基于x86等汇编指令的软件水印技术,也无法直接应用到Android基于Dalvik字节码指令中。
[0020]由此可见,目前的软件保护方法不适用于对Android平台应用软件的保护。
【发明内容】
[0021]有鉴于此,本发明的主要目的在于提供一种软件水印的嵌入和提取方法,可以对Android平台应用软件进行有效保护。
[0022]为了达到上述目的,本发明提出的技术方案为:
[0023]一种软件水印的嵌入方法,包括:
[0024]a、对待嵌入的水印进行拆分,得到一组水印值;
[0025]b、启动待嵌入水印的软件,捕获用户触发的事件,并根据所捕获到的每个事件的原始信息,按照事件触发的时间顺序,生成事件密钥脚本文件;
[0026]C、判断所述水印值的数量是否小于等于所述捕获的事件数量;如果是,则将每个所述水印值分别与所述事件密钥脚本文件中的事件建立--对应关系,其中,不同水印值对应不同事件;否则,执行步骤b ;
[0027]d、将每个所述水印值转化为水印代码,并嵌入到该水印值所对应事件的汇编代码段中。
[0028]一种软件水印的提取方法,用于对利用上述方法嵌入的水印进行提取,包括:
[0029]根据所述事件密钥脚本文件,生成按照事件触发的时间顺序排列的事件流;
[0030]按照所述事件触发的时间顺序,依次模拟所述事件流中每个事件的触发;并在所述事件的触发过程中提取相应的汇编代码段;
[0031]从所提取到的每个所述事件的汇编代码段中,提取所嵌入的水印代码,并将所述水印代码转换成相应的水印值;
[0032]对所转换得到的每个水印值的准确性和有效性进行判断,并删除其中无效或错误的水印值,得到嵌入到软件中的水印信息。
[0033]综上所述,本发明提出的一种软件水印的嵌入和提取方法,通过在水印和程序本身之间建立一种逻辑依赖关系,可以提高水印信息的隐藏性,从而可以对Android平台应用软件进行有效保护。
【专利附图】
【附图说明】
[0034]图1为本发明实施例一的软件水印嵌入流程示意图;
[0035]图2为本发明实施例二的软件水印提取流程示意图。
【具体实施方式】
[0036]为使本发明的目的、技术方案和优点更加清楚,下面将结合附图及具体实施例对本发明作进一步地详细描述。
[0037]本发明的核心思想是:根据用户触发的应用软件的应用事件流(密钥)和待嵌入的水印信息,生成相应的水印代码,并嵌入到各事件对应的汇编代码段中(即Dalvik字节码段中)。如此,通过在水印和程序本身之间建立一种逻辑依赖关系,可以提高水印信息的隐藏性。另外,水印的嵌入是基于汇编代码进行的,因此,避免了对源代码的依赖,从而使本发明易于实施。
[0038]图1为本发明实施例一的流程示意图,如图1所示,该实施例主要包括:
[0039]步骤101、对待嵌入的水印进行拆分,得到一组水印值。
[0040]本步骤用于把待嵌入应用软件中的水印进行拆分,以便嵌入到应用软件中。
[0041]较佳地,可以利用中国剩余定理,对待嵌入的水印进行拆分。利用这些手段实现拆分的具体方法为本领域技术人员所掌握,在此不再赘述。
[0042]步骤102、启动待嵌入水印的软件,捕获用户触发的事件,并根据所捕获到的每个事件的原始信息,按照事件触发的时间顺序,生成事件密钥脚本文件。
[0043]本步骤用于生成事件密钥脚本文件,这个文件用于保存用户触发的事件流(包括用户事件及系统事件),该事件流将用于限定步骤101中所生成的各水印值嵌入的代码段位置,因此,该事件密钥脚本文件相当于一个“密钥”,用于指示水印的嵌入与提取位置。也就是说,本发明中用于嵌入水印的密钥是以用户触发的事件流形式实现的。
[0044]较佳地,可以采用下述方法生成事件密钥脚本文件:
[0045]对于所捕获到的每个事件,对事件的原始信息进行解析,生成相应的事件详细信息,所述事件详细信息包括事件触发时间、事件类型及事件属性,按照事件触发的时间顺序,将每个事件对应的所述事件详细信息写入到所述软件密钥脚本文件中。
[0046]步骤103、判断所述水印值的数量是否小于等于所述捕获的事件数量;如果是,则执行步骤104 ;否则,执行步骤102。
[0047]这里,如果事件数量小于水印值的数量,则需要返回步骤102重新生成事件流,以满足将所有水印值嵌入到应用软件中的需要。反之,如果水印值的数量是否小于等于所述捕获的事件数量,则每个水印值都可以对应一个的事件,且可确保不同水印值可以对应一个事件。
[0048]步骤104、将每个所述水印值分别与所述事件密钥脚本文件中的事件建立--对应关系,其中,不同水印值对应不同事件。
[0049]较佳地,简单起见,可以按照水印值在组中的先后顺序和事件密钥脚本文件中事件的先后触发顺序,依次将水印值和事件建立一一对应关系,直至所有水印值都有对应的事件。为了提高复杂度,也可以按照预设的对应关系函数建立两者的一一对应关系。本步骤中,只需要将水印值和事件建立一一对应关系即可,具体采用何种方法不限于上述。
[0050]步骤105、将每个所述水印值转化为水印代码,并嵌入到该水印值所对应事件的汇编代码段中。
[0051]较佳的,可以采用下述方法实现本步骤:
[0052]对于每个水印值,将该水印值转换成二进制数,按照I代表跳转语句目的地址大于原地址,O代表跳转语句目的地址小于原地址的转换原则,根据nQ = m0-k0和Ii1 = Hirk1,生成相应的Smali跳转语句,将所生成的Smali跳转语句嵌入到该水印值所对应事件的代码段中,进行所述嵌入后的代码段满足:按照Smali跳转语句的先后顺序和所述转换原则,依次将所述代码段中的Smali跳转语句转换为O或I后,得到的数值与该水印值对应的二进制数相同,并且所述汇编代码段中已有的跳转语句的执行顺序在所述嵌入后保持不变。
[0053]其中,Iltl表示需要生成的代表O的跳转语句数叫表示需要生成代表I的跳转语句数:1?表示所述二进制数中O的个数吨表示所述二进制数中I的个数;k(!表示水印值所对应事件的汇编代码段中已有的跳转语句目的地址小于原地址的跳转语句数丸表示水印值所对应事件的汇编代码段中已有的跳转语句目的地址大于原地址的跳转语句数。
[0054]在上述方法中,为每个水印值所生成的Smali跳转语句,将与该水印值所对应事件的汇编代码段中已有的Smali跳转语句,共同作为该水印值的水印代码,将所生的成的Smali跳转语句嵌入到汇编代码段中时,需要使得汇编代码段中的所有Smali跳转语句进行0/1转换后,即为该水印值对应的水印代码,从而实现水印值的嵌入。另外,汇编代码段中原有语句的执行顺序需要在嵌入水印后保持不变,以使水印的嵌入不影响汇编代码段中代码的正常执行,确保汇编代码段的原有功能保持不变。
[0055]这里需要说明的是,上述方法中的Smali跳转语句属于Dalvik的寄存器语言。Dalvik是Android平台的java虚拟机。
[0056]上述方法中,充分利用Android Dalvik语句特征,将水印信息转换成跳转语句进行嵌入。如此,将水印信息换成汇编代码进行嵌入,可以使水印信息具有高隐藏性,不易被破坏,同时还可以避免对源代码的依赖所产生的部署难度,使水印的嵌入与提取易于实现。
[0057]与上述水印嵌入方法相对应,本发明实施例二给出了一软件水印的提取方法,该方法用于对利用上述方法嵌入的水印进行提取,如图2所示,该方法包括:
[0058]步骤201、根据所述事件密钥脚本文件,生成按照事件触发的时间顺序排列的事件流。
[0059]本步骤,用于生成水印嵌入作者所触发的事件流,并根据时间戳按序进行排列。
[0060]步骤202、按照所述事件触发的时间顺序,依次模拟所述事件流中每个事件的触发;并在所述事件的触发过程中提取相应的汇编代码段。
[0061]具体地,本步骤,可以利用Android自动化测试工具(如Robotium、Monkey Runner等),按照所述事件触发的时间顺序自动运行事件流中的各事件,同时,可以利用IDA等动态调试工具提取触发事件对应的汇编代码段。具体实现为本领域技术人员所掌握,在此不再赘述。
[0062]步骤203、从所提取到的每个所述事件的汇编代码段中,提取所嵌入的水印代码,并将所述水印代码转换成相应的水印值。
[0063]具体地,可以采用下述方法获取所嵌入的水印代码,并将所述水印代码转换成相应的水印值包括:
[0064]从所提取到的每个所述事件的汇编代码段中,按照代码执行顺序依次提取其中的Smali跳转语句,对于每个跳转语句,进行跳转原地址与目的地址比较,如果目的地址大于原地址,则提取出二进制数1,如果目的地址小于原地址,则提取出二进制数O ;将从每个所述事件的汇编代码段中提取出的二进制数转换为十进制数,得到每个所述事件对应的水印值。
[0065]步骤204、对所转换得到的每个水印值的准确性和有效性进行判断,并删除其中无效或错误的水印值,得到嵌入到软件中的水印信息。
[0066]较佳地,可以利用中国剩余定理,对所转换得到的每个水印值的准确性和有效性进行判断。
[0067]上述提取方法,是与上述水印嵌入方法相逆的过程,基于水印嵌入时所生成的事件密钥脚本文件,即可实现该逆过程,因此可以快速提取出所嵌入的水印,并进行有效性判断。
[0068]通过上述水印的嵌入与提出方法可以看出,本发明利用Android移动应用软件独有的事件流特征,将水印值转换成汇编代码进行嵌入,为水印和程序本身之间建立一种逻辑依赖关系,使水印信息具有高隐藏性,同时水印的嵌入与提取均为自动化过程,对于开发者来说使用难度低,开发者使用过程不需要提供应用源码,从而可以保证了开发者的权益。
[0069]另外,通过利用SandMark中各类攻击方式,包括去除攻击、变形攻击、添加攻击及共谋攻击等,采用本发明所嵌入的Android软件水印仍能够成功被提取,可以证明本发明具有足够弹性能够抵御攻击。
[0070]进一步地,本发明所实现的水印嵌入与提取,可以批量执行应用软件的重打包检测,并在检测后分别自动生成txt文本格式和xls数据表格格式的检测报告,易于分类记录管理,并可在需要的时候生成检测结果的综合报告,方便综合查阅、分析。
[0071]综上所述,以上仅为本发明的较佳实施例而已,并非用于限定本发明的保护范围。凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。
【权利要求】
1.一种软件水印的嵌入方法,其特征在于,包括: a、对待嵌入的水印进行拆分,得到一组水印值; b、启动待嵌入水印的软件,捕获用户触发的事件,并根据所捕获到的每个事件的原始信息,按照事件触发的时间顺序,生成事件密钥脚本文件; C、判断所述水印值的数量是否小于等于所述捕获的事件数量;如果是,则将每个所述水印值分别与所述事件密钥脚本文件中的事件建立--对应关系,其中,不同水印值对应不同事件;否则,执行步骤b; d、将每个所述水印值转化为水印代码,并嵌入到该水印值所对应事件的汇编代码段中。
2.根据权利要求1所述的方法,其特征在于,所述生成事件密钥脚本文件包括: 对于所捕获到的每个事件,对事件的原始信息进行解析,生成相应的事件详细信息,所述事件详细信息包括事件触发时间、事件类型及事件属性,按照事件触发的时间顺序,将每个事件对应的所述事件详细信息写入到所述软件密钥脚本文件中。
3.根据权利要求1所述的方法,其特征在于,利用中国剩余定理,对待嵌入的水印进行所述拆分。
4.根据权利要求1所述的方法,其特征在于,所述步骤d包括: 对于每个水印值,将该水印值转换成二进制数,按照I代表跳转语句目的地址大于原地址,O代表跳转语句目的地址小于原地址的转换原则,根据nQ = m0-k0和Ii1 = Hirk1,生成相应的Smali跳转语句,将所生成的Smali跳转语句嵌入到该水印值所对应事件的汇编代码段中,进行所述嵌入后的汇编代码段满足:按照Smali跳转语句的先后顺序和所述转换原则,依次将所述汇编代码段中的Smali跳转语句转换为O或I后,得到的数值与该水印值对应的二进制数相同,并且所述汇编代码段中原有语句的执行顺序在所述嵌入后保持不变; 其中,Iitl表示需要生成的代表O的跳转语句数;ηι表示需要生成代表I的跳转语句数;m0表示所述二进制数中O的个数:1?表示所述二进制数中I的个数木表示水印值所对应事件的汇编代码段中已有的目的地址小于原地址的跳转语句数丸表示水印值所对应事件的汇编代码段中已有的目的地址大于原地址的跳转语句数。
5.一种软件水印的提取方法,用于对利用权利要求1至5所述的任一方法嵌入的水印进行提取,其特征在于,包括: 根据所述事件密钥脚本文件,生成按照事件触发的时间顺序排列的事件流; 按照所述事件触发的时间顺序,依次模拟所述事件流中每个事件的触发;并在所述事件的触发过程中提取相应的汇编代码段; 从所提取到的每个所述事件的汇编代码段中,提取所嵌入的水印代码,并将所述水印代码转换成相应的水印值; 对所转换得到的每个水印值的准确性和有效性进行判断,并删除其中无效或错误的水印值,得到嵌入到软件中的水印信息。
6.根据权利要求5所述的方法,其特征在于,所述获取所嵌入的水印代码,并将所述水印代码转换成相应的水印值包括: 从所提取到的每个所述事件的汇编代码段中,按照代码执行顺序依次提取其中的Smali跳转语句,对于每个跳转语句,进行跳转原地址与目的地址比较,如果目的地址大于原地址,则提取出二进制数1,如果目的地址小于原地址,则提取出二进制数O ;将从每个所述事件的汇编代码段中提取出的二进制数转换为十进制数,得到每个所述事件对应的水印值。
7.根据权利要求5所述的方法,其特征在于,利用中国剩余定理,对所转换得到的每个水印值的准确性和有效性进行判断。
【文档编号】G06F21/14GK104462884SQ201410806446
【公开日】2015年3月25日 申请日期:2014年12月22日 优先权日:2014年12月22日
【发明者】胡阳雨, 徐国爱, 李承泽, 张程鹏, 董枫 申请人:北京邮电大学