Android防止反编译_Java如何防止反编译
2015-08-30 10:38:16  By: dwtedx

不管是JavaEE程序还是Android程序都难免会被一些不法份子反编译的尴尬、常用的保护技术 由于Java字节码的抽象级别较高、因此它们较容易被反编译、下面介绍了几种常用的方法、用于保护Java字节码不被反编译、通常、这些方法不能够绝对防止程序被反编译、而是加大反编译的难度而已、因为这些方法都有自己的使用环境和弱点


1、隔离Java程序

最简单的方法就是让用户不能够访问到Java Class程序、这种方法是最根本的方法、具体实现有多种方式、例如、开发人员可以将关键的Java Class放在服务器端、客户端通过访问服务器的相关接口来获得服务、而不是直接访问Class文件、这样黑客就没有办法反编译Class文件

目前、通过接口提供服务的标准和协议也越来越多、例如 HTTP、Web Service、RPC等、但是有很多应用都不适合这种保护方式、例如对于单机运行的程序就无法隔离Java程序


2、对Class文件进行加密

为了防止Class文件被直接反编译、许多开发人员将一些关键的Class文件进行加密、例如对注册码、序列号管理相关的类等、在使用这些被加密的类之前、程序首先需要对这些类进行解密、而后再将这些类装载到JVM当中、这些类的解密可以由硬件完成、也可以使用软件完成

java防止反编译


在实现时、开发人员往往通过自定义ClassLoader类来完成加密类的装载(注意由于安全性的原因、Applet不能够支持自定义的ClassLoader)、自定义的ClassLoader首先找到加密的类、而后进行解密、最后将解密后的类装载到JVM当中、在这种保护方式中、自定义的ClassLoader是非常关键的类、由于它本身不是被加密的、因此它可能成为黑客最先攻击的目标、如果相关的解密密钥和算法被攻克、那么被加密的类也很容易被解密


3、转换成本地代码

将程序转换成本地代码也是一种防止反编译的有效方法、因为本地代码往往难以被反编译、开发人员可以选择将整个应用程序转换成本地代码、也可以选择关键模块转换、如果仅仅转换关键部分模块、Java程序在使用这些模块时、需要使用JNI技术进行调用

当然、在使用这种技术保护Java程序的同时、也牺牲了Java的跨平台特性、对于不同的平台、我们需要维护不同版本的本地代码、这将加重软件支持和维护的工作、不过对于一些关键的模块、有时这种方案往往是必要的、为了保证这些本地代码不被修改和替代

通常需要对这些代码进行数字签名、在使用这些本地代码之前、往往需要对这些本地代码进行认证、确保这些代码没有被黑客更改、如果签名检查通过、则调用相关JNI方法


4、代码混淆

代码混淆是对Class文件进行重新组织和处理、使得处理后的代码与处理前代码完成相同的功能(语义)、但是混淆后的代码很难被反编译、即反编译后得出的代码是非常难懂、晦涩的、因此反编译人员很难得出程序的真正语义、从理论上来说、黑客如果有足够的时间、被混淆的代码仍然可能被破解

甚至目前有些人正在研制反混淆的工具、但是从实际情况来看、由于混淆技术的多元化发展、混淆理论的成熟、经过混淆的Java代码还是能够很好地防止反编译、下面我们会详细介绍混淆技术、因为混淆是一种保护Java程序的重要技术


5、几种技术的总结

以上几种技术都有不同的应用环境、各自都有自己的弱点、表1是相关特点的比较、到目前为止、对于Java程序的保护、混淆技术还是最基本的保护方法、Java混淆工具也非常多、包括商业的、免费的、开放源代码的

Sun公司也提供了自己的混淆工具、它们大多都是对Class文件进行混淆处理、也有少量工具首先对源代码进行处理、然后再对Class进行处理、这样加大了混淆处理的力度、目前、商业上比较成功的混淆工具包括JProof公司的1stBarrier系列、Eastridge公司的JShrink和4thpass.com的SourceGuard等、主要的混淆技术按照混淆目标可以进行如下分类、它们分别为符号混淆(Lexical Obfuscation)、数据混淆(Data Obfuscation)、控制混淆(Control Obfuscation)、预防性混淆(Prevent Transformation)


6、符号混淆

在Class中存在许多与程序执行本身无关的信息、例如方法名称、变量名称、这些符号的名称往往带有一定的含义、例如某个方法名为getKeyLength()、那么这个方法很可能就是用来返回Key的长度、符号混淆就是将这些信息打乱、把这些信息变成无任何意义的表示、例如将所有的变量从vairant_001开始编号;对于所有的方法从method_001开始编号

这将对反编译带来一定的困难、对于私有函数、局部变量、通常可以改变它们的符号、而不影响程序的运行、但是对于一些接口名称、公有函数、成员变量、如果有其它外部模块需要引用这些符号、我们往往需要保留这些名称、否则外部模块找不到这些名称的方法和变量、因此、多数的混淆工具对于符号混淆、都提供了丰富的选项、让用户选择是否、如何进行符号混淆


若资源对你有帮助、浏览后有很大收获、不妨小额打赏我一下、你的鼓励是维持我不断写博客最大动力

想获取DD博客最新资讯、你可以扫描下方的二维码、关注DD博客微信公众号(ddblogs)

或者你也可以关注我的新浪微博、了解DD博客的最新动态:DD博客官方微博(dwtedx的微博)

如对资源有任何疑问或觉得仍然有很大的改善空间、可以对该博文进行评论、希望不吝赐教

为保证及时回复、可以使用博客留言板给我留言: DD博客留言板(dwtedx的留言板)

感谢你的访问、祝你生活愉快、工作顺心、欢迎常来逛逛


快速评论


博文评论

  • 该博文还没有评论、赶快抢沙发吧...
DD记账
top
+