Procyon:反编译 jar 的特定 类

Procyon: decompiling specific classes of jar

我正在尝试使用 com.strobel.decompiler.Decompiler decompiler from the Procyon 库从 jar 文件中反编译特定的 classes。

这是我目前的做法:

// jar file containing foo.class and bar.class
JarFile myJar = new JarFile("my.jar");
// creating decompiler settings
DecompilerSettings settings = new DecompilerSettings();
// set type loader to jar file
settings.setTypeLoader(new JarTypeLoader(myJar));

StringWriter foo = new StringWriter();
Decompiler.decompile("com.myjar.foo", new PlainTextOutput(foo), settings);
System.out.print(foo.toString());

但这只会打印:!!! ERROR: Failed to load class com.myjar.foo.

我很确定我在 class 从 my.jar 加载 classes 时错过了一些东西。 (认为​​这可以通过设置类型加载器来完成)。

实际问题:如何使用 procyon 反编译器从 jar 文件反编译特定 class? (我的方法做错了什么?)

你好,NopMind。

答案很简单:class 名称空间不以 . 为前缀,而是以 / 为前缀。

所以只需替换 Decompiler.decompile("com/myjar/foo", ...) 就可以了。抱歉

你可以用 class 个名字哄 Procyon 变得更宽容。您所要做的就是将 'primary' 类型的加载程序包装在 InputTypeLoader.

settings.setTypeLoader(new InputTypeLoader(new JarTypeLoader(myJar)));

InputTypeLoader 将首先尝试使用您的主要类型加载器定位 classes,如果找不到匹配项,它将尝试 'massage' class 名字。它由命令行反编译器使用,用户可能会尝试使用替代形式,例如 . 而不是 /$。比如存在classcom/jar/Foo,用户尝试反编译com.jar.Foo,应该可以解决。它也应该适用于内部 classes,例如,com.jar.Foo.Bar 可用于定位 com/jar/Foo$Bar。想不想用就看你了

我确实有一个建议给你,不过:你可能不想使用 JarTypeLoader 作为你的 主要 类型装载机。如果您这样做,Procyon 将 在您的特定罐子中搜索 classes。这可能听起来像你想要的,但它可能不是。

看,Procyon 有一些优化只能在它可以解析和分析 class 的依赖项时才能执行。例如,当它反编译一个方法调用时,Procyon 最初会在每个不 完全 匹配目标方法参数类型的参数前插入强制转换。为了正确性,它必须这样做,因为该方法可能有重载,并且删除这些转换可能会导致调用绑定到错误的方法。 但是,如果 Procyon 可以找到声明方法 的 class 它可以找到它的所有祖先 classes ,然后它可以确定哪些转换可以安全地删除,同时仍然绑定到正确的方法。然后它会删除那些多余的转换,从而产生更清晰的输出。这只是一个例子——还有其他例子。

这是我推荐使用的:

settings.setTypeLoader(
    new InputTypeLoader(                // allow more relaxed type names
        new CompositeTypeLoader(
            new JarTypeLoader(myJar),   // search your specific jar first
            new ClasspathTypeLoader()   // fall back to your classpath
        )
    )
);

这将使 Procyon 有机会在 JRE 和恰好在您的 class 路径中的任何其他地方搜索依赖项。