⼀些防⽌Java代码被反编译的⽅法
由于Java字节码的抽象级别较⾼,因此它们较容易被反编译。下⾯给⼤家介绍⼏种常⽤的⽅法,⽤于保护Java字节码不被反编译。通常,这些⽅法不能够绝对防⽌程序被反编译,⽽是加⼤反编译的难度⽽已,因为这些⽅法都有⾃⼰的使⽤环境和弱点。
隔离Java程序
最简单的⽅法就是让⽤户不能够访问到Java Class程序,这种⽅法是最根本的⽅法,具体实现有多种⽅式。例如,开发⼈员可以将关键的Java Class放在服务器端,客户端通过访问服务器的相关接⼝来获得服务,⽽不是直接访问Class⽂件。
这样⿊客就没有办法[反编译Class⽂件。⽬前,通过接⼝提供服务的标准和协议也越来越多,例如 HTTP、Web Service、RPC等。但是有很多应⽤都不适合这种保护⽅式,例如对于单机运⾏的程序就⽆法隔离Java程序。这种保护⽅式见图1所⽰。
对Class⽂件进⾏加密
为了防⽌Class⽂件被直接反编译,许多开发⼈员将⼀些关键的Class⽂件进⾏加密,例如对注册码、序列号管理相关的类等。在使⽤这些被加密的类之前,程序⾸先需要对这些类进⾏解密,⽽后再将这些类装载到JVM当中。这些类的解密可以由硬件完成,也可以使⽤软件完成。
在实现时,开发⼈员往往通过⾃定义ClassLoader类来完成加密类的装载(注意由于安全性的原因,Applet不能够⽀持⾃定义的ClassLoader)。⾃定义的ClassLoader⾸先到加密的类,⽽后进⾏解密,最后将解密后的类装载到JVM当中。
在这种保护⽅式中,⾃定义的ClassLoader是⾮常关键的类。由于它本⾝不是被加密的,因此它可能成为⿊客最先攻击的⽬标。如果相关的解密密钥和算法被攻克,那么被加密的类也很容易被解密。这种保护⽅式⽰意图见图2。
转换成本地代码
将程序转换成本地代码也是⼀种防⽌反编译的有效⽅法。因为本地代码往往难以被反编译。开发⼈员可以选择将整个应⽤程序转换成本地代码,也可以选择关键模块转换。如果仅仅转换关键部分模块,Java程序在使⽤这些模块时,需要使⽤JNI技术进⾏调⽤。
当然,在使⽤这种技术保护Java程序的同时,也牺牲了Java的跨平台特性。对于不同的平台,我们需要维护不同版本的本地代码,这将加重软件⽀持和维护的⼯作。不过对于⼀些关键的模块,有时这种⽅案往往是必要的。
为了保证这些本地代码不被修改和替代,通常需要对这些代码进⾏数字签名。在使⽤这些本地代码之前,往往需要对这些本地代码进⾏认证,确保这些代码没有被⿊客更改。如果签名检查通过,则调⽤相关JNI⽅法。这种保护⽅式⽰意图见图3。
代码混淆
代码混淆是对Class⽂件进⾏重新组织和处理,使得处理后的代码与处理前代码完成相同的功能(语义)。但是混淆后的代码很难被[反编译,即[反编译后得出的代码是⾮常难懂、晦涩的,因此[反编译⼈员很难得出程序的真正语义。
从理论上来说,⿊客如果有⾜够的时间,被混淆的代码仍然可能被破解,甚⾄⽬前有些⼈正在研制反混淆的⼯具。但是从实际情况来看,由于混淆技术的多元化发展,混淆理论的成熟,经过混淆的Java代码还是能够很好地防⽌[反编译。下⾯我们会详细介绍混淆技术,因为混淆是⼀种保护Java程序的重要技术。图4是代码混淆的⽰图。
图4 代码混淆⽰意图
⼏种技术的总结 以上⼏种技术都有不同的应⽤环境,各⾃都有⾃⼰的弱点,表1是相关特点的⽐较。
混淆技术介绍
java源代码加密
表1 不同保护技术⽐较表
到⽬前为⽌,对于Java程序的保护,混淆技术还是最基本的保护⽅法。Java混淆⼯具也⾮常多,包括商业的、免费的、开放源代码的。Sun公司也提供了⾃⼰的混淆⼯具。它们⼤多都是对Class⽂件进⾏混淆处理,也有少量⼯具⾸先对源代码进⾏处理,然后再对Class进⾏处理,这样加⼤了混淆处理的⼒度。
⽬前,商业上⽐较成功的混淆⼯具包括JProof公司的1stBarrier系列、Eastridge公司的JShrink和 4thpa
ss的SourceGuard等。主要的混淆技术按照混淆⽬标可以进⾏如下分类,它们分别为符号混淆(Lexical Obfuscation)、数据混淆(Data Obfuscation)、控制混淆(Control Obfuscation)、预防性混淆(Prevent Transformation)。
在Class中存在许多与程序执⾏本⾝⽆关的信息,例如⽅法名称、变量名称,这些符号的名称往往带有⼀定的含义。例如某个⽅法名为getKeyLength(),那么这个⽅法很可能就是⽤来返回Key的长度。
符号混淆就是将这些信息打乱,把这些信息变成⽆任何意义的表⽰,例如将所有的变量从vairant_001开始编号;对于所有的⽅法从method_001开始编号。
这将对反编译带来⼀定的困难。对于私有函数、局部变量,通常可以改变它们的符号,⽽不影响程序的运⾏。但是对于⼀些接⼝名称、公有函数、成员变量,如果有其它外部模块需要引⽤这些符号,我们往往需要保留这些名称,否则外部模块不到这些名称的⽅法和变量。因此,多数的混淆⼯具对于符号混淆,都提供了丰富的选项,让⽤户选择是否、如何进⾏符号混淆。
数据混淆
数据混淆是对程序使⽤的数据进⾏混淆。混淆的⽅法也有多种,主要可以分为改变数据存储及编码(Store and Encode Transform)、改变数据访问(Access Transform)。
改变数据存储和编码可以打乱程序使⽤的数据存储⽅式。例如将⼀个有10个成员的数组,拆开为10个变量,并且打乱这些变量的名字;将⼀个两维数组转化为⼀个⼀维数组等。对于⼀些复杂的数据结构,我们将打乱它的数据结构,例如⽤多个类代替⼀个复杂的类等。
另外⼀种⽅式是改变数据访问。例如访问数组的下标时,我们可以进⾏⼀定的计算,图5就是⼀个例⼦。
在实践混淆处理中,这两种⽅法通常是综合使⽤的,在打乱数据存储的同时,也打乱数据访问的⽅式。经过对数据混淆,程序的语义变得复杂了,这样增⼤了反编译的难度。
控制混淆
控制混淆就是对程序的控制流进⾏混淆,使得程序的控制流更加难以[反编译,通常控制流的改变需要增加⼀些额外的计算和控制流,因此在性能上会给程序带来⼀定的负⾯影响。有时,需要在程序的性能和混淆程度之间进⾏权衡。控制混淆的技术最为复杂,技巧也最多。这些技术可以分为如下⼏类:
增加混淆控制通过增加额外的、复杂的控制流,可以将程序原来的语义隐藏起来。例如,对于按次序
执⾏的两个语句A、B,我们可以增加⼀个控制条件,以决定B的执⾏。通过这种⽅式加⼤反汇编的难度。但是所有的⼲扰控制都不应该影响B的执⾏。图6就给出三种⽅式,为这个例⼦增加混淆控制。
图6 增加混淆控制的三种⽅式
控制流重组重组控制流也是重要的混淆⽅法。例如,程序调⽤⼀个⽅法,在混淆后,可以将该⽅法代码嵌⼊到调⽤程序当中。反过来,程序中的⼀段代码也可以转变为⼀个函数调⽤。另外,对于⼀个循环的控制流,为可以拆分多个循环的控制流,或者将循环转化成⼀个递归过程。这种⽅法最为复杂,研究的⼈员也⾮常多。
预防性混淆
这种混淆通常是针对⼀些专⽤的反编译器⽽设计的,⼀般来说,这些技术利⽤反编译器的弱点或者Bug来设计混淆⽅案。例如,有些反编译器对于 Return后⾯的指令不进⾏反编译,⽽有些混淆⽅案恰恰将代码放在Return语句后⾯。这种混淆的有效性对于不同反编译器的作⽤也不太相同的。⼀个好的
混淆⼯具,通常会综合使⽤这些混淆技术。
在实践当中,保护⼀个⼤型Java程序经常需要综合使⽤这些⽅法,⽽不是单⼀使⽤某⼀种⽅法。这是因为每种⽅法都有其弱点和应⽤环境。综合使⽤这些⽅法使得Java程序的保护更加有效。另外,我们经常还需要使⽤其它的相关安全技术,例如安全认证、数字签名、PKI等。
本⽂给出的例⼦是⼀个Java应⽤程序,它是⼀个SCJP(Sun Certificate Java Programmer)的模拟考试软件。该应⽤程序带有⼤量的模拟题⽬,所有的题⽬都被加密后存储在⽂件中。由于它所带的题库是该软件的核⼼部分,所以关于题库的存取和访问就成为⾮常核⼼的类。⼀旦这些相关的类被反编译,则所有的题库将被破解。现在,我们来考虑如何保护这些题库及相关的类。
在这个例⼦中,我们考虑使⽤综合保护技术,其中包括本地代码和混淆技术。因为该软件主要发布在Windows上,因此转换成本地代码后,仅仅需要维护⼀个版本的本地代码。另外,混淆对Java程序也是⾮常有效的,适⽤于这种独⽴发布的应⽤系统。
在具体的⽅案中,我们将程序分为两个部分,⼀个是由本地代码编写的题库访问的模块,另外⼀个是由Java开发的其它模块。这样可以更⾼程度地保护题⽬管理模块不被[反编译。对于Java开发的模块,我们仍然要使⽤混淆技术。该⽅案的⽰意图参见图7。
图7 SCJP保护技术⽅案图
对于题⽬管理模块,由于程序主要在Windows下使⽤,所以使⽤C++开发题库访问模块,并且提供了⼀定的访问接⼝。为了保护题库访问的接⼝,我们还增加了⼀个初始化接⼝,⽤于每次使⽤题库访问接⼝之前的初始化⼯作。它的接⼝主要分为两类:
初始化接⼝
在使⽤题库模块之前,我们必须先调⽤初始化接⼝。在调⽤该接⼝时,客户端需要提供⼀个随机数作为参数。题库管理模块和客户端通过这个随机数,按⼀定的算法同时⽣成相同的SessionKey,⽤于加密以后输⼊和输出的所有数据。通过这种⽅式,只有授权(有效)的客户端才能够连接正确的连接,⽣成正确的 SessionKey,⽤于访问题库信息。⾮法的客户很难⽣成正确的SessionKey,因此⽆法获得题库的信息。如果需要建⽴更⾼的保密级别,也可以采⽤双向认证技术。
数据访问接⼝
认证完成之后,客户端就可以正常的访问题库数据。但是,输⼊和输出的数据都是由SessionKey所加密的数据。因此,只有正确的题库管理模块才能够使⽤题库管理模块。图8时序图表⽰了题库管理模块和其它部分的交互过程。
如果有需要领取免费资料的⼩伙伴们,

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。