著录项信息
专利名称 | 一种通过虚拟机保护JAVA可执行程序的方法及设备 |
申请号 | CN201310287243.3 | 申请日期 | 2013-07-10 |
法律状态 | 暂无 | 申报国家 | 中国 |
公开/公告日 | 2013-11-27 | 公开/公告号 | CN103413075A |
优先权 | 暂无 | 优先权号 | 暂无 |
主分类号 | G06F21/14 | IPC分类号 | G;0;6;F;2;1;/;1;4查看分类表>
|
申请人 | 北京深思数盾科技有限公司 | 申请人地址 | 北京市海淀区西北旺东路10号院东区5号楼5层510
变更
专利地址、主体等相关变化,请及时变更,防止失效 |
权利人 | 北京深思数盾科技股份有限公司 | 当前权利人 | 北京深思数盾科技股份有限公司 |
发明人 | 不公告 |
代理机构 | 暂无 | 代理人 | 暂无 |
摘要
本发明公开了一种保护JAVA可执行程序的方法和设备。该方法创建一个本地动态链接库文件,枚举受保护JAVA软件中的.class文件,分析该.class文件中的JVM代码,随机抽取代码片段,原位置替换为对native方法的调用,在本地动态链接库中生成导出函数,使用自定义的虚拟机实现抽取出代码片段的功能。通过本发明提供的方法,可以有效防止JAVA软件的代码和逻辑被逆向和破解,提高了软件的安全强度。
1.一种保护JAVA可执行程序的方法,其特征在于,包括如下步骤:
步骤1:创建本地动态链接库文件;
步骤2:枚举受保护的JAVA可执行程序中的.class文件;
步骤3:分析所述.class文件中的JVM代码,然后根据单入单出和堆栈平衡的原则选取JVM代码中的代码片段;
步骤4:将选中的所述代码片段从.class文件中抽去,在所述代码片段的原位置处替换成对本地方法的调用;
步骤5:在所述本地动态链接库中,生成本地代码导出函数,所述本地代码导出函数的名称与所述本地方法对应,并且在所述导出函数的函数体中插入自定义虚拟机指令,其中所述插入的虚拟机的代码所实现的功能与被抽取的代码等效,用于实现步骤4中所抽取出的代码片段的功能;
步骤6:返回步骤2,继续枚举,直至结束。
2.根据权利要求1所述的方法,其特征在于,所述步骤1中的本地动态链接库文件名称是随机的,或者步骤4中本地方法名称是随机的。
3.根据权利要求1所述的方法,其特征在于,步骤5中逐条模拟代码片段中的指令包括对访问类、对象的指令使用JNI模拟。
4.根据权利要求1所述的方法,其特征在于,步骤5中逐条模拟代码片段中的JVM指令包括访问类、对象的指令以及算术和控制指令。
5.一种保护JAVA可执行程序的设备,其特征在于,包括:
枚举模块,用于枚举受保护的JAVA软件中的.class文件;
分析模块,用于分析.class文件中的JVM代码,根据单入单出和堆栈平衡的原则选取JVM代码中的代码片段;
替换代码模块,将选中的所述代码片段从所述.class文件中抽去,在所述代码片段的原位置处替换成对本地方法的调用;
生成自定义虚拟机指令模块,用于生成本地代码导出函数,并在本地代码导出函数中插入自定义虚拟机指令,实现所述被抽取出的代码片段的功能;
自定义虚拟机解释模块,由一系列的本地代码,搭配必要的JNI功能,解释本地代码导出函数中的自定义虚拟机指令。
6.根据权利要求5所述的保护JAVA可执行程序的设备,其特征在于,还包括:加密/解密模块,用于对本地代码生成模块进行加密/解密。
一种通过虚拟机保护JAVA可执行程序的方法及设备\n技术领域\n[0001] 本发明涉及软件保护领域,特别涉及一种保护JAVA可执行程序的方法及设备。\n背景技术\n[0002] JAVA软件一般由一些资源文件和JAVA可执行文件(单独的.class文件或者包装在.jar或.war包中的.class文件)组成。JAVA可执行文件是能被JAVA虚拟机执行的二进制文件,其代码是与平台无关的,格式遵循JAVA虚拟机规范,很容易被一些反编译分析工具还原为JAVA源代码,导致软件的逻辑和流程被泄露和窃取。\n[0003] 在JAVA语言中,类对象的方法函数有两种类型:普通方法和本地方法。普通方法是由JAVA语言编写编译成JAVA指令代码,运行时由JAVA虚拟机(JAVA Virtual Machine,JVM)执行;另一类本地方法(Native Method),它是通过JNI(JAVA Native Interface,JAVA本地调用)的接口访问外部的运行在本地操作系统的库。JNI实现了JAVA程序和外部库之间的相互调用,通常用来为JAVA程序提供非JAVA语言实现的功能。\n[0004] 软件由一个或多个JAVA可执行文件(如.jar、.war或者.class)和一个或者多个本地动态链接库文件(如.dll或者.so等格式)组成。JAVA中的可执行文件中的代码会调用动态链接库中导出接口(interface),实现特定的功能。类(class)是JAVA的基本概念,.jar文件中包括多个.class文件(jar包和war包等都是由若干.class文件和资源文件组成),对其不再进行详细描述。\n[0005] 目前常见的JAVA软件保护手段是对.class文件中的JVM(JAVA Virtual Machine JAVA,虚拟机)代码进行混淆处理,或借助于自定义的Class Loader,将.class文件加密存储,加载到JVM时才解密。前者是在JVM指令的层面进行处理,受到JVM规范的限制,且自动化算法的效果还不够理想(常见的自动化算法包括名称和符号混淆,但是不易自动实现复杂的流程和类关系);而后者在JVM加载.class文件后,内存中就有原始的.class代码,容易受到内存DUMP(内存DUMP是将JVM运行时进程内存中的内容做"快照"并保存到文件)的攻击。\n发明内容\n[0006] 为了防止JAVA软件的代码和逻辑被逆向和破解,本发明提供了一种保护JAVA可执行程序的方法及设备。首先创建一个本地动态链接库文件,枚举受保护JAVA软件中的.class文件,分析该.class文件中的JVM代码,随机抽取JVM代码中的部分代码片段,在所抽取的部分代码片段的原位置处替换为对native方法(即本地方法)的调用,在本地动态链接库中插入自定义虚拟机的代码,其中所述插入的虚拟机的代码所实现的功能与被抽取的代码等效,然后生成导出函数,运行时通过调用自定义虚拟机执行等效代码实现所述被抽取出的部分代码片段的功能。通过本发明提供的方法,可以提高软件的安全强度。\n[0007] 本发明不仅适用于windows平台,也适用于其他使用动态库机制的操作系统。\n[0008] 一种保护JAVA可执行程序的方法,具体步骤包括:\n[0009] 1. 创建一个本地动态连接库文件;\n[0010] 2. 枚举受保护的JAVA软件中的.class文件;\n[0011] 3. 分析该.class文件中的JVM代码,随机选取代码片段;\n[0012] 4. 将选中的代码片段从.class文件中抽去,原位置替换为对native方法的调用;\n[0013] 5. 在步骤1中的本地动态链接库中,生成一个导出函数,函数名称与步骤4中的native方法对应,在所述导出函数的函数体中插入自定义虚拟机的代码(该代码逐条模拟JAVA代码片段中的指令),实现步骤4中抽取出的代码片段的功能。\n[0014] 6. 回到步骤2,继续枚举,直至结束。\n[0015] 根据本发明的一个方面,所述步骤1中的本地动态链接库文件名称是随机的。\n[0016] 根据本发明的一个方面,所述步骤3中为便于自动化实现,抽取代码片段遵循单入单出和堆栈平衡原则。所述单入单出和堆栈平衡原则,是指执行流程只能从所述代码片段开头处进入这段代码,无法从所述代码片段外跳转到所述代码片段中间,并且只能从所述代码片段结尾处离开这段代码,无法从所述代码片段中跳转到代码片段外;所述代码片段中的基本运算是完整的,进出所述代码片段时不涉及JVM堆栈中的临时变量。这两个原则都可以通过静态分析JVM指令实现。\n[0017] 根据本发明的一个方面,步骤4中native方法名称是随机的。\n[0018] 根据本发明的一个方面,步骤5中,使用自定义指令集的虚拟机指令逐条模拟代码片段中的指令。JVM中常见的访问类、对象等指令、算数和控制转移等指令,在自定义虚拟机中都有对应的等效功能指令(不一定是一一对应的关系,一条JVM指令可能转换为多条自定义虚拟机指令,多条JVM指令也可能转换为一条自定义虚拟机指令,指令的格式也与JVM不同)。在程序运行时,自定义虚拟机指令最终还是由自定义虚拟机解释代码(本地代码)模拟(必要的访问JVM的功能可通过JNI实现)。\n[0019] 一种保护JAVA可执行程序的装置,具体包括:\n[0020] 枚举模块,用于枚举受保护的JAVA软件中的.class文件,并能从.jar、.war包中提取.class文件;\n[0021] 分析模块,用于分析.class文件中的JVM代码,根据单入单出和堆栈平衡原则来选取代码片段;\n[0022] 替换代码模块,用于将选中的代码片段从.class文件中抽取出去,在被抽取的代码片段的原位置处替换为对一个随机命名的native方法的调用;\n[0023] 生成自定义虚拟机指令模块,用于生成一个本地代码导出函数,并在函数中插入自定义虚拟机指令,实现所述被抽取出的代码片段的功能。\n[0024] 虚拟机解释模块:由一系列的本地代码,搭配必要的JNI功能,解释导出函数中的自定义虚拟机指令。\n[0025] 使用本发明保护后的JAVA软件中,代码的逻辑被分散到本地动态库文件中,可以较好的防范JVM层面的反编译静态分析,而且由于部分逻辑被替换为自定义虚拟机指令,流程分散在JVM的内外,增加了分析和破解的难度。另外,本地动态库中的代码是由自定义虚拟机解释运行的,JVM中不可能有替换前的代码,这样免受DUMP的攻击。因此本发明较好的保护了软件的逻辑和流程,以及运行时的代码和数据安全,并能够提供自动化的算法实现,提高了软件的安全性。\n附图说明\n[0026] 图1为按照本发明的一种保护JAVA可执行程序的方法和设备的实施例1的流程图。\n[0027] 图2为按照本发明的一种保护JAVA可执行程序的方法和设备的一优选实施例的整体流程示意图。\n[0028] 图3为按照本发明的一种保护JAVA可执行程序的方法和设备的结构框图。\n具体实施方式\n[0029] 为使本发明的目的、技术方案及优点更加清楚明白,以下参照附图并举实施例,对本发明进一步详细说明。\n[0030] 根据本发明的一个实施例,如图2所示,提供一种保护JAVA可执行程序的方法,具体步骤包括:\n[0031] 1.创建一个本地动态连接库文件;\n[0032] 2.枚举受保护的JAVA软件中的.class文件;\n[0033] 3.分析该.class文件中的JVM代码,随机选取代码片段;\n[0034] 4.将选中的代码片段从.class文件中抽去,原位置替换为对native方法的调用;\n[0035] 5.在步骤1中的本地动态链接库中,生成一个导出函数,函数名称与步骤4中的native方法对应,在所述导出函数的函数体中插入自定义虚拟机指令,其中所述插入的虚拟机的代码所实现的功能与被抽取的代码等效,用于实现步骤4中抽取出的代码片段的功能。\n[0036] 6.回到步骤2,继续枚举,直至结束。\n[0037] 根据本发明的一个方面,所述步骤1中的本地动态链接库文件名称可以是随机的。\n[0038] 根据本发明的一个方面,所述步骤3中为便于自动化实现,抽取代码片段遵循单入单出和堆栈平衡原则。\n[0039] 根据本发明的一个方面,步骤4中native方法名称可以是随机的。\n[0040] 根据本发明的一个方面,步骤5中逐条模拟代码片段中的JVM指令包括对访问类、对象等指令、算术和控制等指令。自定义虚拟机指令与JVM指令不一定一一对应,且格式不同,最终由虚拟机解释代码(本地代码)解释执行自定义虚拟机指令(必要的访问JVM的功能借助JNI实现)。\n[0041] 所述单入单出和堆栈平衡原则,即执行流程是只能从片段开头进入这段代码,不可以从片段外跳转到片段中间,只能从片段结尾离开这段代码,不可以在片段中跳转到外面。并且片段中基本运算是完整的,进出片段时不涉及JVM堆栈中的临时变量。这两个原则都可以通过静态分析JVM指令实现。\n[0042] 根据本发明的一个实施例,如图3所示,提供一种保护JAVA可执行程序的设备,具体包括:\n[0043] 枚举模块,用于枚举受保护的JAVA软件中的.class文件,并能从.jar、.war包中提取.class文件。\n[0044] 分析模块,用于分析.class文件中的JVM代码,根据单入单出和堆栈平衡的原则选取代码片段。\n[0045] 替换代码模块,用于将选中的代码片段从.class文件中抽取出去,原位置替换为对一个随机命名的native方法的调用。\n[0046] 生成自定义虚拟机指令模块,用于生成一个本地代码导出函数,并在本地代码导出函数中插入自定义虚拟机指令,实现所述被抽取出的代码片段的功能。\n[0047] 自定义虚拟机解释模块,由一系列的本地代码,搭配必要的JNI功能,解释本地代码导出函数中的自定义虚拟机指令。\n[0048] 作为优选,本实施例的保护可执行程序的设备还包括加密模块,用于对导出函数中的自定义虚拟机代码加密。其中,由虚拟机解释代码在运行时解密。\n[0049] 本发明创建一个本地动态链接库文件,枚举受保护JAVA软件中的.class文件,分析该.class文件中的JVM代码,随机抽取代码片段,原抽取位置替换为对native(本地方法)方法的调用,在本地动态链接库中生成导出函数,插入自定义虚拟机代码,实现抽取出代码片段的功能。使用本发明保护后的JAVA软件中,代码的逻辑被分散到本地动态库文件中,可以较好的防范JVM层面的反编译静态分析,而且由于部分逻辑被替换为自定义虚拟机代码,流程分散在JVM的内外,增加了分析和破解的难度。另外,本地动态库中的代码是由自定义虚拟机解释执行的,JVM中不可能有替换前的代码,这样一来,免受DUMP的攻击。因此本发明较好的保护了软件的逻辑和流程,以及运行时的代码和数据安全,并能够提供自动化的算法实现,提高了软件的安全性。\n[0050] 实施例1\n[0051] 根据本发明的一个实施例,参见图1,图1包括本实施例中各部分的代码示意片段。\n具体实例如下:某JAVA编写的软件,源代码中有一个类MyClass,其中定义了三个字段a、b、c和一个实例方法Mul,该方法的逻辑是将字段b与c的值相乘,结果赋给字段a。\n[0052] Java源代码在编译时,会为每一个类生成一个.class文件,该.class文件的结构是在JVM文档中定义的,是一系列属性和值的集合。通过解析.class文件中的类名称相关属性,可以得知它来自于源代码中的哪个类;再解析方法表属性,可以得到类中所有方法的列表;解析每一个方法的Code属性,可以得到方法的JVM字节码。\n[0053] 例如图1中所示源代码编译后对应MyClass.class文件,在解析出的方法表中有Mul方法,字节码(JVM指令)如下,即,该段源代码编译后,生成的.class文件中会有如下JVM指令与Mul方法的逻辑对应:(仅为示意,实际的JVM指令会更复杂)\n[0054] load MyClass.a //将当前对象的a字段加载到JVM运行堆栈\n[0055] load MyClass.c //将当前对象的c字段加载到JVM运行堆栈\n[0056] mul //将堆栈中的两个数弹出并相乘,将运算结果压栈[0057] setField MyClass.b //将堆栈中的数弹出并保存到当前对象的b字段[0058] 根据JVM文档,字节码中的跳转指令都只限于方法内部,即不会跳转到其他方法的代码中(call指令也只能转移到其他方法的代码起始),因此方法是“单入”的;又因为所有跳转指令的目标位置是静态的(即在编译时就能确定,没有寄存器和间接转移,包括异常处理等也是静态的),所以可以将方法中每一条JVM指令列成一张表,分析并标记出每一条指令是否是跳转或call指令,以及是否为可能的跳转目的地。考虑由连续的若干条JVM指令组成的代码片段,如果它们都不是跳转或call指令(或有跳转但目的地也在片段内),也不是跳转目的地(或是目的地但都来自区间内),则这个片段是单入单出的。\n[0059] JVM是基于堆栈的,每一条指令的执行对堆栈的影响在文档中都有规定。如load int指令会向堆栈中压入一个字,而mul int会弹出2个,再压入1个,总计相当于减少一个字,这些也都是编译时可静态确定的。对方法中JVM指令列表,并用一个堆栈指针来记录每条指令执行对堆栈的影响。如果某单入单出区间中的连续若干条JVM指令,执行后堆栈指针不变,则这个子区间是堆栈平衡的。上面示意的JVM指令区间,即是单入单出和堆栈平衡的。\n[0060] 用本发明的方法进行保护后,.class文件中的以上JVM指令被抽去,替换为对本地方法native_fun123的调用。而新增的本地动态链接库中导出了native_fun123函数,函数体中的自定义虚拟机指令与以上JVM指令等效。\n[0061] 可以看到,保护后的软件中已经没有Mul方法的JVM指令。而本地动态库中的导出函数中,也只有自定义虚拟机的指令。\n[0062] 本方法不仅适用于windows平台,也适用于其他使用动态库机制的操作系统。其他操作系统使用时,方法步骤与windows平台步骤基本相同,此处不再赘述。\n[0063] 以上所述仅为本发明的较佳实施例而已,并非用于限定本发明的保护范围。凡在本发明的精神和原则之内,所作的任何修改、等同替换以及改进等,均应包含在本发明的保护范围之内。
法律信息
- 2023-01-20
专利权人的姓名或者名称、地址的变更
专利权人由北京深思数盾科技股份有限公司变更为北京深盾科技股份有限公司
地址由100193 北京市海淀区西北旺东路10号院东区5号楼5层510变更为100193 北京市海淀区西北旺东路10号院东区5号楼5层510
- 2016-11-16
专利权人的姓名或者名称、地址的变更
专利权人由北京深思数盾科技股份有限公司变更为北京深思数盾科技股份有限公司
地址由100872 北京市海淀区中关村大街甲59号文化大厦1706室变更为100193 北京市海淀区西北旺东路10号院东区5号楼5层510
- 2016-05-04
- 2016-04-13
著录事项变更
申请人由北京深思数盾科技有限公司变更为北京深思数盾科技股份有限公司
地址由100872 北京市海淀区中关村大街甲59号文化大厦1706室变更为100872 北京市海淀区中关村大街甲59号文化大厦1706室
- 2013-12-25
实质审查的生效
IPC(主分类): G06F 21/14
专利申请号: 201310287243.3
申请日: 2013.07.10
- 2013-11-27
引用专利(该专利引用了哪些专利)
序号 | 公开(公告)号 | 公开(公告)日 | 申请日 | 专利名称 | 申请人 |
1
| |
2011-06-01
|
2010-11-15
| | |
2
| |
2012-12-19
|
2012-07-28
| | |
3
| |
2012-10-03
|
2012-05-12
| | |
被引用专利(该专利被哪些专利引用)
序号 | 公开(公告)号 | 公开(公告)日 | 申请日 | 专利名称 | 申请人 | 该专利没有被任何外部专利所引用! |