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 路径中的任何其他地方搜索依赖项。
我正在尝试使用 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 路径中的任何其他地方搜索依赖项。