Java 编译、反编译、反反编译

  有「编译」(compile),就有「反编译」(decompile);有「反编译」,就有「反反编译」。对于Java和.NET这种虚拟机器的中间码来说,尤其明显。
  
  Java程序编译后的结果是Java Bytecode,而.NET编译后的结果是CIL(Common Intermediate Language),两者都具有下列的特性:
  
  -同为堆栈式(stack-based)指令集。
  
  -同为高阶面向对象机器语言
  
  -和平台无关
  
  -Code Validation
  
  -Symbolic Link
  
  上述任何一点特色,都可以让程序变得更轻易反编译,全部五点结合起来更是不得了。所以要反编译Java和.NET可以说是相当轻易的。网络上就到处流传着Java的反编译器(decompiler),可以把编译后的档案反推出原始码,
  相信不久之后.NET也会碰到一样的问题。(至少,喜欢搞破坏的我就正尝试着写一个.NET decompiler。)
  
  试想,假如你将辛辛劳苦开发出来的Java和.NET程序交给别人(蔡学镛?),他只要透过反编译器,就可以推出源码,你的智能财产很可能会受到侵犯。
  
  想要保护自己,你必须在Java或.NET软件出货前,进行反反编译,这个动作通常称为混淆(obfuscate)。被混淆过的程序代码,依然遵照原来的档案格式和指令集,所以依然可以执行,执行结果也和混淆前一样。只是被混淆过的程序代码变得更乱,更不轻易被反编译成功。
  
  有的Java开发工具(例如JBuilder)有内附混淆器(obfuscator),或者你也可以购买功能更强大的混淆器。这些商业的混淆器通常只做三件事:
  
  -将每一个method内部用更乱的方式组织。
  
  -将Java Constant Pool,或.NET metadata内可以消除的Symbolic Data消除例如private method的名字)。
  
  -将debug信息(例如Java的LocalVariableTable与LineNumberTable)全部删除。
  
  Obfuscator的作用假如只是如同上述一般,只有method局部的作用,效果不大。
  
  欲大幅度地增加反编译的难度,必须搭配下列的方式:
  
  -Class内的混淆:将class内的method互相混淆。
  -Class之间的混淆:将class之间的关系混淆,例如将父类别和子类别合并或拆解等。
  
  有一些学术论文有对上述两点做出研究,但成效仍然不大,而且必须手动调整,无法由软件自动处理。这方面值得大家投入更深入的研究。
  
  混淆过的程序会碰到下面的问题:
  
  -通常效率会变差
  
  -可能无法执行。我欲过这样的情况,有可能是混淆器的错,也有可能是JVM的错。
  
  假如进行「Class之间的混淆」,稍有不慎,就很可能会无法执行。例如:Java程序中假如有用到instanceof,或者C#程序中有用到is,就要很小心的进行「Class之间的混淆」,否则后果不堪设想。
  
  混淆的目的有两个层次:
  
  1.  让程序无法被自动反编译:例如做出一些非凡的跳跃(goto),让程序区块
  (block)的关系无法被找出特定的pattern。
  
  2.  让程序就算被反编译成功,也不轻易被程序员阅读理解:想办法加入一些不易被识破的程序代码来欺骗程序员。
  
  Obfuscator不是万灵丹,假如遇上了一个精通obfuscating技术的人,佐以profiling工具,原始码还是会落入他的手中。所以,使用obfuscator时,你必须有这样的心理预备:「防君子,不妨小人;防笨蛋,不防聪明人」。尽可能将软件放在server改为提供service,而不将软件卖到客户手上,这才是上策 

时间: 2024-09-17 22:49:36

Java 编译、反编译、反反编译的相关文章

java特殊符号的输入后编译出错

问题描述 java特殊符号的输入后编译出错 java编写代码每次到特殊符号如|都编译不出来 求大神教教我 解决方案 已自行解决 Java 双竖线按住shift加""""就行了 || 解决方案二: 在java中,||为或符号,为一种特殊字符,所以在字符串中需要在前面加上转义字符"".

页面上有个textarea,在里面写java代码,然后如何动态编译执行这段java代码??

问题描述 页面上有个textarea,在里面写java代码,然后如何动态编译执行这段java代码?? 页面上有个textarea,在里面写java代码,然后如何动态编译执行这段java代码?? 解决方案 可以使用一些前端的模板引擎,java是编译的 解决方案二: ajax提交客户端输入的代码动态执行就行,看下面参考 ajax提交http://www.w3school.com.cn/jquery/ java中怎么执行字符串中的代码http://bbs.csdn.net/topics/3903563

Java HotSpot VM中的JIT编译

原文地址译者:郭蕾 校对:丁一 本文是Java HotSpot VM and just-in-time(JIT) compilation系列的第一篇. Java HotSpot虚拟机是Oracle收购Sun时获得的,JVM和开源的OpenJDK都是以此虚拟机为基础发展的.如同其它虚拟机,HotSpot虚拟机为字节码提供了一个运行时环境.实际上,它主要会做这三件事情: 执行方法所请求的指令和运算. 定位.加载和验证新的类型(即类加载). 管理应用内存. 最后两点都是各自领域的大话题,所以这篇文章中

为什么java源文件中有两个类编译后只产生一个类文件

问题描述 classdemoA{publicstaticvoidmain(String[]args){demoad=newdemoa();d.getmoney();}voidgetmoney(){System.out.println("package123123123");}}classdemoa{voidgetmoney(){System.out.println("package1111");}}为什么java源文件中有两个类编译后只产生一个类文件demoA,且运

java中执行gcc编译,得不到编译结果

问题描述 java中执行gcc编译,得不到编译结果 Process process = Runtime.getRuntime().exec(cmd); BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); String s = br.readline(); 可以得到一般命令的输出,但是GCC编译出错时结果得不到 解决方案 后来我尝试用gcc a.cpp -o a.cpp 2

.jar文件已经反编译成.java的文件,如何再编译回.jar?

问题描述 我将一个.jar的文件反编译成了java文件,生成了N多的文件夹与.java的文件,修改了里面的代码后,如何将这些文件再编译成.jar文件呢? 解决方案 解决方案二:myeclipse里面不是可以打包成多种格式的包嘛解决方案三:找到主类运行完后将生成的class文件在dos下打成jar或者直接用eclipse打成jar包解决方案四:基本上是不可能的解决方案五:使用命令jar-u....u就是用来更新jar包中的内容的.

Android应用程序的编译流程及使用Ant编译项目的攻略_Android

Android 工程构建的持续集成,需要搭建一套编译和打包自动化流程,比如建立每日构建系统.自动生成发布文件等等.这些都需要我们对Android工程的编译和打包有一个比较深入的理解,例如知道它的每一步都做了什么,需要什么环境和工具,输入和输出是什么,等等. 首先,假定你的系统(Windows.Linux.Mac OS都行,本文默认使用Linux系统来举例子,但在 Windows中几乎没有什么差别)已经安装了JDK和Android SDK. 我们重点关心的是:     (1)这个过程的输入是什么?

Android反编译代码和防止反编译_Android

一.反编译apk文件 安装ApkTool工具,该工具可以解码得到资源文件,但不能得到Java源文件.          安装环境:需要安装JRE1.6 1> 到http://code.google.com/p/android-apktool/      下载apktool1.3.2.tar.bz2 和apktool-install-windows-2.2_r01-3.tar.bz2 文件.      解压两个文件,然后把解压后的文件放在一起,如:c:\apktool 2> 在系统变量PATH中

《智能路由器开发指南》——第2章 开发环境及编译分析 2.1 安装编译环境

第2章 开发环境及编译分析 如果你想从事智能路由器OpenWrt开发,首先必须掌握如何编译OpenWrt.本章将从搭建环境,到编译代码,再到安装部署运行以及VirtualBox虚拟网络环境的搭建,一步一步地教你如何进入到OpenWrt大门. OpenWrt是一个针对嵌入式设备的Linux发行版.OpenWrt提供了非常方便的开发环境,使用流行的Linux操作系统Ubuntu即可搭建好编译环境.OpenWrt有非常多的平台适应性,可以运行在ARM/MIPS/X86平台上,因此我们的研发网络部署也可

javascript中的取反再取反~~没有意义_javascript技巧

操作符~, 是按位取反的意思,表面上~~(取反再取反)没有意义,实际上在JS中可以将浮点数变成整数. 复制代码 代码如下: <html> <script> var myArray = new Array(); myArray.push("a"); myArray.push("b"); myArray.push("c"); myArray.push("d"); //现在要随机从数组中取出一个元素 var