java 反汇编 重新组装
假设我想获取一个 java 类文件,反汇编它,调整 java 字节码输出,然后再次重新组装它。
我需要重命名常量池表中的符号。我也无法访问源代码,并且使用反编译器对此似乎有些过分了。我并不是想优化任何东西——java 在这方面做得很好。
有...一个简单的方法可以做到这一点吗? 我找到了几种用于拆卸或重新组装的工具,但没有一个可以同时用于两者;或者没有成对的工具似乎使用相同的格式来表示文本中的字节码。
Say I want to take a java class file, disassemble it, tweak the java bytecode output, and then reassemble it again.
I need to rename a symbol in the constant pool table. I also don't have access to the source code, and using a decompiler seems like overkill for this. I'm not trying to optimize anything - java does a fine job at that.
Is there... a simple way to do this?
I've found several tools for either disassembly or reassembly, but none for both; or no pairs of tools which seem to use the same format for representing the bytecode in text.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您检查过 ASM API 吗?
下面是一个代码示例(改编自官方文档),解释了如何修改类字节码:
然后 b2 可以存储在 .class 文件中以供将来使用。如果您定义了自己的类加载器,您还可以使用方法
ClassLoader.defineClass(String,byte[],int,int)
来加载它。Did you check the ASM API?
Here is a code sample (adapted from the official documentation) explaining how to modify a class bytecode:
Then b2 can be stored in a .class file for future use. You can also use the method
ClassLoader.defineClass(String,byte[],int,int)
to load it if you define your own classloader.Krakatau 提供了一个开源反汇编程序和汇编程序,使这一切变得非常简单。 Krakatau 被设计为 Jasmin 的替代品。它使用类似 Jasmin 的语法来实现向后兼容性,但扩展了格式以支持类文件格式中的所有晦涩功能并修复 Jasmin 中的错误。它还可以让您轻松地反汇编、修改和重新组装类。
Krakatau 唯一真正的缺点是它目前没有很好的记录。但如果您有任何疑问,请随时提问。 (披露:我写了喀拉喀托)。
Krakatau provides an open source disassembler and assembler that make this very easy. Krakatau is designed to be a replacement for Jasmin. It uses a Jasmin like syntax for backwards compatibility but extends the format to support all the obscure features in the classfile format and fix bugs in Jasmin. It also lets you easily disassemble, modify, and reassemble classes.
The only real downside to Krakatau is that it currently doesn't documented very well. But if you have any questions, feel free to ask. (Disclosure: I wrote Krakatau).
这个问题现在有点老了,但由于我在 stackoverflow 上的任何地方都找不到这个答案,所以让我把它记录下来:
有一个我过去成功使用过的标准 jasper/jasmin 组合:
jasper 唯一的烦恼是它忘记为 switch default 子句创建一个标签,然后jasmin 会给你类似的错误这意味着您必须进入 .j 文件并手动修复它。 “javap -c”可能会帮助你。对于该错误,我建议您在进行任何修改之前立即使用 jasper 和 jasmin,以确保其有效。您实际上可以通过将此补丁应用于 jasper 来修复该标签错误:
我已将其提交给作者,但是我感觉这个项目已经很多年没有开发了,所以我不知道它是否会被合并。
编辑:应用了上述补丁的 Jasper 现在可以在https://github.com/EugenDueck/Jasper
然后是 Eclipse 字节码大纲 ,如这个答案中所述:
java字节码编辑器?
This question is a bit older now, but as I don't find this answered anywhere on stackoverflow, let me put it on record:
There's the standard jasper/jasmin combo that I have successfully used in the past:
The only annoyance with jasper is that it forgets to create a label for the switch default clause, and then jasmin will give you errors likeWhich then means you have to go into the .j file, and manually fix it. "javap -c" might assist you there. For that bug I'd suggest you jasper and immediately jasmin, before any modifications, just to make sure that works.You can actually fix that label bug by applying this patch to jasper:
I submitted it to the author, but I got a feeling the project has not been worked on for many years, so I don't know if it'll get merged in.
Edit: Jasper with the above patch applied is now available at https://github.com/EugenDueck/Jasper
And then there's Eclipse Bytecode Outline, as described in this answer:
java bytecode editor?
找到原始源代码,修改它,然后重新编译不是更容易吗?或者这是来自您没有源代码的某些二进制代码?
专业提示:内置 Java 类库的源代码作为 OpenJDK 项目的一部分提供,特别是在OpenJDK 6 源代码中。
Wouldn't it just be easier to find the original source code, modify it, then recompile it? Or is this from some binary code you don't have the source to?
Pro tip: The source code to the built-in Java Class Library is available as part of the OpenJDK project, specifically in the OpenJDK 6 Source.
您正在描述现代编译器已经做什么。除此之外,大多数 JVM 可以(并尝试)在应用程序运行时不断优化字节码。
首先研究现有的编译器/JVM 如何处理字节码。最好的情况是您可以改进 JVM 的优化器,这是可能的,但可能性很小,而且无论哪种方式您都可能重新发明轮子。最糟糕的情况是您的更改实际上会干扰运行时优化器并导致整体性能下降。
[编辑] 找到相关帖子:字节码操作模式
You are describing what modern compilers do already. In addition to that, most JVMs can (and try to) keep optimizing the byte code while the app is running.
Start with studying what existing compilers/JVM's are doing with the byte code. The best case is that you can improve on the the JVM's optimizer which is possible but a low probability and either way you may be reinventing the wheel. The worst case is your changes actually interfere with the the runtime optimizer and cause overall performance to go down.
[EDIT] Found a related post: Bytecode manipulation patterns