4

我想反编译一个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:好的,我猜在字节码级别这样的命名是可能的,所以使用更智能的反编译器(自动重命名类并修复它们的引用)这个问题可以解决。

4

3 回答 3

2

您真的需要解压整个 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 反编译器也不完美。通过从重新编译中消除大部分反编译代码,您可以避免反编译器遇到的大多数问题,例如异常处理程序重叠、混淆符号中的特殊字符、变量范围问题等。

于 2010-12-28T22:16:29.417 回答
1

Java 的导入机制为命名事物提供了一种简写,但在发生冲突时显然不能使用它。您始终可以在代码中使用完全限定名称,例如

package org.foo;  

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

编辑:

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

于 2010-12-28T17:36:16.573 回答
0

您不能在 Java 中导入包,那么为什么会出现名称冲突呢?你从编译器得到哪个错误信息?

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

于 2010-12-28T17:16:23.563 回答