如何反编译混淆的java程序,避免类/包名冲突

时间:2010-12-28 16:56:26

标签: java decompiler

我想反编译一个java程序并重新编译派生(混淆)的源代码。我解压缩了.jar存档并获得了类似的目录结构:

com/
com/foo/A/
com/foo/A/A.class
com/foo/A/B.Class
com/foo/B/A.class
...
com/foo/A.class
com/foo/B.class
org/foo/Bar.class
...

问题是包和类之间存在名称冲突,这使得无法重新编译反编译的类文件。 反编译的类看起来像这样:

package org.foo;
import com.foo.A; // <-- name collision error

class Bar {
    ...
}

有没有办法解决这些命名问题,而无需重命名类文件?

编辑: 这不是一个反编译器问题,而是如何使用违反命名约定的类来生成.jar文件的问题。

EDIT2: 好吧,我想在字节码级别上这样命名是可能的,因此使用更智能的反编译器(他自动重命名类并修复它们的引用)可以解决这个问题。

3 个答案:

答案 0 :(得分:1)

Java的导入机制提供了命名事项的简写,但是当发生冲突时你显然无法使用它。您始终可以在代码中使用完全限定名称,例如

package org.foo;  

class Bar { 
    private com.foo.Bar aDifferentBar;
    ...
}

编辑:

我认为可能存在符合JVM规范的类文件,但这些类文件不能由符合JLS规范的Java程序生成。如果是这样,那么你肯定需要一个更聪明的反编译器。

答案 1 :(得分:0)

你不能用Java导入包,那么为什么这应该是名字冲突呢?您从编译器获得了哪条错误消息?

如果混淆代码中存在名称冲突,则代码将无法运行。因此反编译的代码应该是无冲突的。

答案 2 :(得分:0)

你真的需要解压整个jar并重新编译一切吗?不要自行重新编译整个反编译源,而是使用原始jar作为类路径,并仅提取和重新编译需要修改的类。然后,当您需要打包重新编译的代码时,只需复制原始jar并使用jar -uf替换已修改的类文件:

jar -uf ./lib/copy_of_original_jar_file.jar -C ./bin com/foo/A.class com/foo/B.class [...]

...和./lib/copy_of_original_jar_file.jar成为您的新图书馆。

有一件事是肯定的,那就是原始jar必须与Java类加载器一起正常运行才能运行程序。它应该同样适用于编译一次性.class文件。

通过使用原始jar,您应该遇到更少的命名冲突问题,因为您保持运行的应用程序将使用的相同类路径扫描顺序。不仅如此,Java反编译器并不完美。通过从重新编译中消除大部分反编译代码,可以避免反编译器遇到的大多数问题,例如异常处理程序重叠,混淆符号中的特殊字符,变量作用域问题等等。