防止反编译
Ⅰ 怎样防止.class文件被反编译
使用混淆器,如RetroGuard。很多开发工具里都有集成。
Ⅱ 如何防止程序员反编译
java从诞生以来,其基因就是开放精神,也正因此,其可以得到广泛爱好者的支持和奉献,最终很快发展壮大,以至于有今天之风光!但随着java的应用领域越来越广,特别是一些功能要发布到终端用户手中(如Android开发的app),有时候,公司为了商业技术的保密考虑,不希望这里面的一些核心代码能够被人破解(破解之后,甚至可以被简单改改就发布出去,说严重点,就可能会扰乱公司的正常软件的市场行为),这时候就要求这些java代码不能够被反编译。
这里要先说一下反编译的现象。因为java一直秉持着开放共享的理念,所以大家也都知道,我们一般共享一个自己写的jar包时,同时会共享一个对应的source包。但这些依然与反编译没有什么关系,但java的共享理念,不只是建议我们这样做,而且它自己也在底层上“强迫”我们这么做!在java写的.java文件后,使用javac编译成class文件,在编译的过程,不像C/C++或C#那样编译时进行加密或混淆,它是直接对其进行符号化、标记化的编译处理,于是,也产生了一个逆向工程的问题:可以根据class文件反向解析成原来的java文件!这就是反编译的由来。
但很多时候,有些公司出于如上述的原因考虑时,真的不希望自己写的代码被别人反编译,尤其是那些收费的app或桌面软件(甚至还有一些j2ee的wen项目)!这时候,防止反编译就成了必然!但前面也说过了,因为开放理念的原因,class是可以被反编译的,那现在有这样的需求之后,有哪些方式可以做到防止反编译呢?经过研究java源代码并进行了一些技术实现(结果发现,以前都有人想到过,所以在对应章节的时候,我会贴出一些写得比较细的文章,而我就简单阐述一下,也算偷个懒吧),我总共整理出以下这几种方式:
代码混淆
这种方式的做法正如其名,是把代码打乱,并掺入一些随机或特殊的字符,让代码的可读性大大降低,“曲线救国”似的达到所谓的加密。其实,其本质就是打乱代码的顺序、将各类符号(如类名、方法名、属性名)进行随机或乱命名,使其无意义,让人读代码时很累,进而让人乍一看,以为这些代码是加过密的!
由其实现方式上可知,其实现原理只是扰乱正常的代码可读性,并不是真正的加密,如果一个人的耐心很好,依然可以理出整个程序在做什么,更何况,一个应用中,其核心代码才是人们想去了解的,所以大大缩小了代码阅读的范围!
当然,这种方式的存在,而且还比较流行,其原因在于,基本能防范一些技术人员进行反编译(比如说我,让我破解一个混淆的代码,我宁愿自己重写一个了)!而且其实现较为简单,对项目的代码又无开发上的侵入性。目前业界也有较多这类工具,有商用的,也有免费的,目前比较流行的免费的是:proguard(我现象临时用的就是这个)。
上面说了,这种方式其实并不是真正加密代码,其实代码还是能够被人反编译(有人可能说,使用proguard中的optimize选项,可以从字节流层面更改代码,甚至可以让JD这些反编译软件可以无法得到内容。说得有点道理,但有两个问题:1、使用optimize对JDK及环境要求较高,容易造成混淆后的代码无法正常运行;2、这种方式其实还是混淆,JD反编译有点问题,可以有更强悍的工具,矛盾哲学在哪儿都是存在的^_^)。那如何能做到我的class代码无法被人反编译呢?那就需要我们下面的“加密class”!
加密class
在说加密class之前,我们要先了解一些java的基本概念,如:ClassLoader。做java的人已经或者以后会知道,java程序的运行,是类中的逻辑在JVM中运行,而类又是怎么加载到JVM中的呢(JVM内幕之类的,不在本文中阐述,所以点到为止)?答案是:ClassLoader。JVM在启动时是如何初始化整个环境的,有哪些ClassLoader及作用是什么,大家可以自己问度娘,也不在本文中讨论。
让我们从最常见的代码开始,揭开一下ClassLoader的一点点面纱!看下面的代码:
Java代码
publicclassDemo{
publicstaticvoidmain(String[]args){
System.out.println(“helloworld!”);
}
}
在编译代码时(如使用ant或maven),使用插件将代码进行加密(加密方式自己选),将class文件里面的内容读取成byte[],然后进行加密后再写回到class文件(这时候class文件里面的内容不是标准的class,无法被反编译了)
在启动项目代码时,指定使用我们自定义的ClassLoader就行了,而自定义的部分,主要就是在这里做解密工作!
上面这段代码,大家都认识。但我要问的是:如果我们使用javac对其进行编译,然后使用java使其运行(为什么不在Eclipse中使用Runas功能呢?因为Eclipse帮我们封闭,从而简化了太多东西,使我们忽略了太多的底层细节,只有从原始的操作上,我们才能看到本质),那么,它是怎么加载到JVM中的?答案是:通过AppClassLoader加载的(相关知识点可以参考:http://hxraid.iteye.com/blog/747625)!如果不相信的话,可以输出一下System.out.println(Thread.currentThrea().getContextLoader());看看。
那又有一个新的问题产生了:ClassLoader又是怎样加载class的呢?其实,AppClassLoader继承自java.lang.ClassLoader类,所以,基本操作都在这个类里面,让我们直接看下面这段核心代码吧:
看到这里,已经没有必要再往下面看了(再往下就是native方法了,这是一个重大伏笔哦),我们要做的手脚就在这里!
手脚怎么做呢?很简单,上面的代码逻辑告诉我们,ClassLoader只是拿到class文件中的内容byte[],然后交给JVM初始化!于是我们的逻辑就简单了:只要在交给JVM时是正确的class文件就行了,在这之前是什么样子无所谓!所以,我们的加密的整个逻辑就是:
如此,搞定!以上的做法比较完整的阐述,可以仔细阅读一下这篇文章:https://www.ddtsoft.com/#developerworks/cn/java/l-secureclass/文章中的介绍。
通过这个方法貌似可以解决代码反编译的问题了!错!这里有一个巨大的坑!因为我们自定义的ClassLoader是不能加密的,要不然JVM不认识,就全歇菜了!如果我来反编译,呵呵,我只要反编译一下这个自定义的ClassLoader,然后把里面解密后的内容写到指定的文件中保存下来,再把这个加了逻辑的自定义ClassLoader放回去运行,你猜结果会怎样?没错,你会想死!因为你好不容易想出来的加密算法,结果人家根本不需要破解,直接就绕过去了!
现在,让我们总结一下这个方法的优缺点:实现方式简单有效,同时对代码几乎没有侵入性,不影响正常开发与发布。缺点也很明显,就是很容易被人破解!
当然啦,关于缺点问题,你也可以这么干:先对所有代码进行混淆、再进行加密,保证:1、不容易找到我们自定义的那个ClassLoader;2、就算找到了,破解了,代码可读性还是很差,让你看得吐血!(有一篇文章,我觉得写得不错,大家可以看一看:http://www.scjgcj.com/#blog/851544)
嗯,我觉得这个方法很好,我自己也差点被这个想法感动了,但是,作为一个严谨的程序员,我真的不愿意留下一个隐患在这里!所以,我继续思索!
高级加密class
前面我们说过有个伏笔来着,还记得吧?没错,就是那个native!native定义的方法是什么方法?就是我们传说中的JNI调用!前面介绍过的有一篇文章中提到过,其实jvm的真实身份并不是java,而是c++写的jvm.dll(windows版本下),java与dll文件的调用就是通过JNI实现的!于是,我们就可以这样想:JNI可以调用第三方语言的类库,那么,我们可不可以把解密与装载使用第三方语言写(如C++,因为它们生成的库是不好反编译的),这样它可以把解密出来的class内容直接调jvm.dll的加载接口进行初始化成class,再返回给我们的ClassLoader?这样,我们自定义的ClassLoader只要使用JNI调用这个第三方语言写的组件,整个解密过程,都在黑盒中进行,别人就无从破解了!
嗯,这个方法真的很不错的!但也有两个小问题:1.使用第三方语言写,得会第三方语言,我说的会,是指很溜!2.对于不同的操作系统,甚至同一操作系统不同的版本,都可能要有差异化的代码生成对应环境下的组件(如window下是exe,linux是so等)!如果你不在乎这两个问题,我觉得,这个方式真的挺不错的。但对于我来说,我的信条是,越复杂的方式越容易出错!我个人比较崇尚简洁的美,所以,这个方法我不会轻易使用!
对了,如果大家觉得这个方法还算可行的话,可以推荐一个我无意中看到的东西给大家看看(我都没有用过的):jinstall,
更改JVM
看到这个标题,我想你可能会震惊。是的,你没看错,做为一个程序员,是应该要具有怀疑一切、敢想敢做的信念。如果你有意留心的话,你会发现JVM版本在业界其实也有好几个版本的,如:Sun公司的、IBM的、Apache的、Google的……
所以,不要阻碍自己的想象力,现在没有这个能力,并不代表不可能。所以,我想到,如果我把jvm改了,在里面对加载的类进行解密,那不就可以了吗?我在设计构思过程中,突然发现:人老了就是容易糊涂!前面使用第三方语言实现解密的两个问题,正好也是更改JVM要面对的两个问题,而且还有一个更大的问题:这个JVM就得跟着这个项目到处走啊!
Ⅲ 如何防止代码被反编译
针对代码反编译,推荐使用CBS赛博锁,通过把安全容器内嵌到操作系统中,对容器内的应用和数据进行加锁,程序和数据在容器内运行,实现最后一米数据安全,防止核心数据被泄露,防止服务器终端中病毒,防止反编译,反破解。
Ⅳ 如何对编译的dll文件进行加密来防止反编译
使用过.NET的程序员都知道,.NET是一个巨大的跨时代进步,它开发效率高、功能强、界面美观、耐用、新的语言C#已经提交为行业规范、CLR共公运行库资源丰富,这所有的特点标志着它成为主流编程语言是必然的。
可是他也有一个缺点,那就是编译好的程序集可以完全被反编译成源代码,这给一些不法份子提供了很好的机会,试想想,您辛苦的劳动成果就这样轻易的给别人利用,是多么不公平的事阿?所以如何保护我们的知识产权成了一个大问题。
MAXTOCODE 已经完全超越了传统的混淆手段来保护源代码的方式,他将完全加密您的代码,使您的代码完全没有办法反编译。保护强度已经不是混淆器可以与之抗衡,是目前保护强度最大,最完美的.NET产品保护方案。
MAXTOCODE 是 Aiasted.SOFT 完全自主开发的一款 .NET 代码保护工具。它是目前世界上高强度保护工具之一。
第一种代码保护方案是混淆,这是一个不错的方案,可惜强度还是无法保证,如果要做一个大的逆向工程有一定困难,但针对某个算法或功能进行解读还是很容易的。反观混淆原理则发现,混淆其实只是一个与障眼法差不多的技术。第二种就是MAXTOCODE的保护技术了,MAXOTCODE 采用了难以理解的机器语言来加密您的.NET程序集,(特别注意:MAXTOCODE的强度建立在加密算法之上,而不上简单的混淆。)在程序集运行时运态解放源代码,所以在原理上已经比混淆强度提高了许多。我们保护您所有的代码,不让不法份子看到您任何一个有效的代码,使不法份子完全无法被反编译。
Ⅳ 怎么防止开发出来的程序被别人反编译
1.本地数据加密
iOS应用防反编译加密技术之一:对NSUserDefaults,sqlite存储文件数据加密,保护帐号和关键信息
2.URL编码加密
iOS应用防反编译加密技术之二:对程序中出现的URL进行编码加密,防止URL被静态分析
3.网络传输数据加密
iOS应用防反编译加密技术之三:对客户端传输数据提供加密方案,有效防止通过网络接口的拦截获取数据
4.方法体,方法名高级混淆
iOS应用防反编译加密技术之四:对应用程序的方法名和方法体进行混淆,保证源码被逆向后无法解析代码
5.程序结构混排加密
iOS应用防反编译加密技术之五:对应用程序逻辑结构进行打乱混排,保证源码可读性降到最低
Ⅵ 易语言模块有什么办法防止被反编译吗
易语言论坛中的方法:防止模块被反编译的有效方法:
请在模块中建立一个或多个窗口,将其"可视"属性设置为假,窗口上放一些随机类型的组件(尽量不要用常用组件),重要数据分散放在这些组件的属性里面,模块中的代码动态载入这些窗口,从这些组件属性中读入相关数据使用.
原理: 由于易语言有相当多类型的组件,而每个组件的属性数据保存格式都不一样,模块反编译想把每种组件中的属性数据反编译出来具有相当的难度,所以数据放在组件属性里面是安全的.
个人方法:你可以把模块转化成动态链接库DLL,这样就不容易反编译了
Ⅶ C#怎样防止反编译
我使用的方法是利用加壳工具:virboxProtectorStandalone。直接进行加壳。高级混淆、虚拟化代码、智能压缩等加密策略。如果要授权控制,可使用许可版本的virboxProtector。
未经加壳保护的 ILspy 反编译效果如下:
public int add(int a, int b){
return a + b;}public int div(int a, int b){
return a / b;}public int mul(int a, int b){
return a * b;}public int sub(int a, int b){
return a - b;}
解决方案:
深思自主研发了为 C# .net 语言做保护的外壳(Virbox Protector)。将C# .net 编译成的执行程序(.exe),动态库(.dll)直接拖入加壳工具即可完成保护操作,十分方便。并且在效果上已经完全看不到源码中的逻辑。
加密后的效果
public int add(int a, int b){
return (int)dm.dynamic_method((object)this, System.Reflection.MethodBase.GetCurrentMethod(), 16416u, 21, 16384u, 32u, 31516u, 5).Invoke(this, new object[]
{
this,
a,
b
});}
public int div(int a, int b){
return (int)dm.dynamic_method((object)this, System.Reflection.MethodBase.GetCurrentMethod(), 16956u, 21, 16924u, 32u, 31516u, 2).Invoke(this, new object[]
{
this,
a,
b
});}
public int mul(int a, int b){
return (int)dm.dynamic_method((object)this, System.Reflection.MethodBase.GetCurrentMethod(), 16776u, 21, 16744u, 32u, 31516u, 3).Invoke(this, new object[]
{
this,
a,
b
});}
public int sub(int a, int b){
return (int)dm.dynamic_method((object)this, System.Reflection.MethodBase.GetCurrentMethod(), 16596u, 21, 16564u, 32u, 31516u, 4).Invoke(this, new object[]
{
this,
a,
b
});}
架构支持
IIS 服务架构的后台逻辑 DLL 文件
windows PC 应用程序 EXE 文件
windows PC 应用程序动态库 DLL 文件
UG等第三方绘图工具使用的 DLL 文件
Unity3d 编译使用的 DLL 文件
Ⅷ C#如何防止被别人反编译
C# 编写的代码通过VS编译器生成 dll 或 exe ,很容易被一些反编译工具查看到源码或对源码进行修改。
为防止代码被反编译或被篡改,我们可以进行一定的防范措施。但不能杜绝,因为DotNet编写代码运行必须编译成IL 中间语言,IL是很规则,同时也很好反编译。
反编译防范措施:
设置项目代码反汇编属性
混淆
方法一:防止 Ildasm.exe(MSIL 反汇编程序) 反汇编程序集
方法很简单在项目文件AssemblyInfo.cs中增加SuppressIldasm属性。
效果很明显,很难看出反编译代码所写的真正逻辑。
缺点:
C#代码通过混淆工具生成后,增加了很多转换过程。这使得反编译工具无法很直观看到源码真正逻辑。但源码代码过多转换会使软件本身运行效率降低,甚至会出现报错情况。
Ⅸ 如何防止代码被反编译
由于apk是Android虚拟机加载的,它有一定的规范,加密apk后Dalvik无法识别apk了。完全避免是不可能的,总有人能够破解你的代码。但是有几种方式来提高被反编译取代码的难度。
1 关键代码使用jni调用本地代码,用c或者c++编写,因此相对比较难于反编译
2 混淆java代码。混淆是不改变代码逻辑的情况下,增加无用代码,或者重命名,使反编译后的源代码难于看懂。 网上开源的java代码混淆工具较多,一般是用ant的方式来编译的。
1 . 在工程文件project.properties中加入下proguard.config=proguard.cfg , 如下所示:
target=android-8
proguard.config=proguard.cfg
Eclipse会通过此配置在工程目录生成proguard.cfg文件
2 . 生成keystore (如已有可直接利用)
按照下面的命令行 在D:\Program Files\Java\jdk1.6.0_07\bin>目录下,输入keytool -genkey -alias android.keystore -keyalg RSA -validity 100000 -keystore android.keystore
参数意义:-validity主要是证书的有效期,写100000天;空格,退格键 都算密码。
命令执行后会在D:\Program Files\Java\jdk1.6.0_07\bin>目录下生成 android.keystore文件。
3. 在Eclipce的操作
File -> Export -> Export Android Application -> Select project -> Using the existing keystore , and input password -> select the destination APK file
经过混淆后的源代码,原先的类名和方法名会被类似a,b,c。。。的字符所替换,混淆的原理其实也就是类名和方法名的映射。
但4大组件并没有混淆(所有在清单文件定义的组件不能被混淆),因为系统需要通过清单文件来查找和运行应用程序。
proguard.cfg 文件代码解读
-optimizationpasses 5 ->设置混淆的压缩比率 0 ~ 7
-dontusemixedcaseclassnames -> Aa aA
- ->如果应用程序引入的有jar包,并且想混淆jar包里面的class
-dontpreverify
-verbose ->混淆后生产映射文件 map 类名->转化后类名的映射
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* ->混淆采用的算法.
-keep public class * extends android.app.Activity ->所有activity的子类不要去混淆
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>; -> 所有native的方法不能去混淆.
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
-->某些构造方法不能去混淆
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * { -> 枚举类不能去混淆.
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable { -> aidl文件不能去混淆.
public static final android.os.Parcelable$Creator *;
}
Ⅹ VB写的东西怎样防止反编译具体点、
编译成p代码的步骤如下:文件--生成工程,在生成工程对话框里点最下面的“选项”按钮,然后选择“编译”选项卡,选第一项“编译为P-代码”就行了!如下图: