【发布时间】:2010-11-12 05:48:59
【问题描述】:
有时在反编译 Java 代码时,反编译器无法正确反编译它,您最终会在输出中得到少量字节码。
反编译器的弱点是什么?有没有 Java 源代码编译成难以反编译的字节码的例子?
更新:
请注意,我知道利用这些信息隐藏代码中的秘密并不是一种安全的方法,而且反编译器可以在未来得到改进。
尽管如此,我仍然有兴趣找出今天的反编译器是什么类型的代码。
【问题讨论】:
标签: java obfuscation decompiling
有时在反编译 Java 代码时,反编译器无法正确反编译它,您最终会在输出中得到少量字节码。
反编译器的弱点是什么?有没有 Java 源代码编译成难以反编译的字节码的例子?
更新:
请注意,我知道利用这些信息隐藏代码中的秘密并不是一种安全的方法,而且反编译器可以在未来得到改进。
尽管如此,我仍然有兴趣找出今天的反编译器是什么类型的代码。
【问题讨论】:
标签: java obfuscation decompiling
任何经过混淆器处理的 Java 字节码都会从反编译器得到“荒谬”的输出。此外,当您有其他语言(如 Scala)编译为 JVM 字节码时,没有规定字节码可以很容易地用 Java 表示,而且很可能不是。
随着时间的推移,反编译器必须跟上新的语言特性和它们产生的字节码,因此新语言特性不容易被您使用的工具逆转,这似乎是合理的。
编辑:作为 .NET 中的示例,以下代码:
lock (this)
{
DoSomething();
}
编译成这样:
Monitor.Enter(this);
try
{
DoSomething();
}
catch
{
Monitor.Exit(this);
}
反编译器必须知道 C#(相对于任何其他 .NET 语言)具有专门用于这两个调用的特殊语法。否则你会得到意想不到的(冗长的)结果。
【讨论】:
用于 DB2 Connect 的 JDBC type-4 驱动程序是经典的。一切都称为一个或两个字母的名称,不相关的代码最终没有效果,等等。曾经尝试看一下调试一个特别烦人的问题,基本放弃了。我希望(但绝不有信心)这是通过混淆器传递的,而不是实际上看起来像那样的代码。
另一个最喜欢的技巧(虽然我不记得产品)是重命名要从集合 {'0','O','l','1'} 构造的所有对象,这使得阅读变得非常困难。
【讨论】:
假设您可以将源代码反编译回合理的样式(您不能总是这样做),那么难以“逆向工程”的是在不熟悉的问题域中运行的算法。如果您不了解快速傅里叶变换,那么您是否可以取回实现 FFT 蝴蝶的代码并不重要。 (如果这句话你不熟悉,我编码一个我已经赢了。如果你熟悉它,你是一个很好的工程师,可能对逆向工程没有任何兴趣代码)。 [你与朝鲜人的里程可能会有所不同。]
【讨论】:
Java 在字节码中保留了大量信息(例如许多名称)。所以反编译比较容易。难以反编译的字节码主要是由难以阅读的源代码生成的(所以这不是一个真正的选择)。如果您真的想混淆您的代码,请使用混淆器,它将所有方法和变量重命名为无法识别的内容。
【讨论】:
异常通常很难反编译。 但是,任何被混淆或用其他语言编写的代码都很难反编译。
顺便说一句:你为什么想知道这个?
【讨论】:
Java Bytecode 并不直接对应Java 构造,所以反编译意味着你知道某个Java 字节码序列对应Java 代码构造。
用于反编译 java 字节码的 Soot 框架有很多这方面的信息,但是他们的网页现在对我来说是关闭的。
【讨论】: