关于如何使用反编译器,获取源码清单

关于反编译器      从概念上讲,反编译器使用起来非常简单。他就是把编译器逆过来用:你给它 .class 文件,它还给你一个源代码文件。
      一些比较新的反编译器有精致的图形界面。但在一开始所举的例子中,我们将使用的是 Mocha,它是第一个公开的可利用的反编译器。在本文的最后,我会讨论一下在 GPL 下一个较新的反编译器。(请参阅参考资料,下载 Mocha 并获取 Java 反编译器的清单。)
       让我们假设在目录中有一个名为 Foo.class 的类文件。用 Mocha 对它进行反编译非常简单,只要键入以下命令:
$ java mocha.Decompiler Foo.class
      这会生成一个新的名为 Foo.mocha 的文件(Mocha 使用 Foo.mocha 这个名字以避免覆盖原文件的源代码)。这个新文件就是 Java 的源文件,并且假设一切顺利的话,您现在就能正常地编译它。只需把它重命名为 Foo.java 就可以开始了。
关于如何使用反编译器,获取源码清单
      但是这儿有个问题:如果在一些您已经有所改动的代码上运行 Mocha,您会注意到它生成的代码和源代码不是完全一样的。我举个例子,这样您能明白我的意思。清单 3 所示的原始源代码是来自一个名为 Foo.java 的测试程序。
清单 3. Foo.java 的一小部分原始源代码     private int member = 10;     public Foo() {       int local = returnInteger();       System.out.println( "foo constructor" );       priv( local );     }
以下是 Mocha 生成的代码
清单 4. Mocha 生成的 Foo.java 的源代码       private int member;       public Foo()       {           member = 10;           int local = returnInteger();           System.out.println("foo constructor");           priv(local);       }
      这两个代码片段的成员变量 member 被初始化为 10 的位置不同。在原始源代码中,它在与声明的同一行中被表示为一个初始值,而在被反编译后的源代码中,它在一个构造符中被表示为一条赋值语句。反编译后的代码告诉我们一些有关源代码被编译的方法;即它的初始值是作为在构造符中的赋值来被编译的。通过观察其反编译后的输出结果,您能了解到不少 Java 编译器的工作方法。
反编译是困难的:不断重复       虽然 Mocha 的确可以反汇编您的目标代码,但它不会总是成功的。由于困难重重,没有一个反编译器能够准确无误地翻译出源代码,而且每个反编译器处理它们在翻译过程中的漏洞的方式也不同。举例来说,Mocha 有时在输出准确的循环构造的结构方面有一些问题。如果真的这样,它会在最终输出中使用伪 goto 语句,如清单 5 所示。
清单 5. Mocha 不能准确地反编译           if (i1 == i3) goto 214 else 138;           j3 = getSegment(i3).getZOrder();           if (j1 != 1) goto 177 else 154;           if (j3 > k2 && (!k1 || j3 < j2)) goto 203 else 173;           expression 0           if (j3 < k2 && (!k1 || j3 > j2)) goto 203 else 196;           expression 0           if == goto 201           continue;           i2 = i3;
      撇开 Mocha 的问题不谈,反编译器在通常情况下还是能比较准确地翻译出源代码。一旦知道了某一反编译器的弱点,您可以手工分析和转换反编译后的代码,以使它们能较准确地符合原始源代码。随着反编译器正变得越来越出色,
      我们又碰到了另外一个问题:如果您不想让任何人能反编译您的代码,那该怎么办呢?小编在此友情推荐:爱加密安卓破解技术有哪些?如何防反编译,讲解的还不错:http://www.ijiami.cn/newsInfo?id=289&v=3

你可能感兴趣的:(关于如何使用反编译器,获取源码清单)