有反汇编器吗+ java 调试器(ala OllyDbg / SoftICE 用于汇编器)?
有没有类似于 OllyDbg / SoftICE for java 的实用程序?即执行类(从 jar / 带有类路径),并且在没有源代码的情况下,显示中间代码的反汇编,并能够单步执行/单步执行/搜索引用/编辑内存中的特定中间代码/将编辑应用于文件。 如果没有,
是否可以写这样的东西(假设我们愿意在调试期间没有热点)?
编辑:我不是在谈论 JAD、JD 或 Cavaj。这些都是很好的反编译器,但我不想要反编译器有几个原因,最值得注意的是它们的输出不正确(充其量,有时只是完全错误)。我不是在寻找神奇的“将字节编译为java代码” - 我想查看即将执行的实际字节。另外,我希望能够更改这些字节(就像在程序集调试器中一样),并希望将更改的部分写回到类文件中。
Edit2:我知道 javap 存在 - 但它只有一种方式(并且没有任何类型的分析)。 示例(代码取自 vmspec 文档): 在 java 代码中,我们使用“javac”将其编译
void setIt(int value) {
i = value;
}
int getIt() {
return i;
}
为 java .class 文件。使用 javap -c 我可以获得以下输出:
Method void setIt(int)
0 aload_0
1 iload_1
2 putfield #4
5 return
Method int getIt()
0 aload_0
1 getfield #4
4 ireturn
这对于反汇编部分来说是可以的(如果没有分析就不太好 - “field #4 is Example.i”),但我找不到其他两个“工具”:
- 调试器它会检查指令本身(包括堆栈、内存转储等),使我能够检查实际的代码和环境。
- 逆转该过程的方法 - 编辑反汇编代码并重新创建 .class 文件(使用编辑后的代码)。
Is there a utility similar to OllyDbg / SoftICE for java? I.e. execute class (from jar / with class path) and, without source code, show the disassembly of the intermediate code with ability to step through / step over / search for references / edit specific intermediate code in memory / apply edit to file...
If not, is it even possible to write something like this (assuming we're willing to live without hotspot for the debug duration)?
Edit: I'm not talking about JAD or JD or Cavaj. These are fine decompilers, but I don't want a decompiler for several reasons, most notable is that their output is incorrect (at best, sometimes just plain wrong). I'm not looking for a magical "compiled bytes to java code" - I want to see the actual bytes that are about to be executed. Also, I'd like the ability to change those bytes (just like in an assembly debugger) and, hopefully, write the changed part back to the class file.
Edit2: I know javap exists - but it does only one way (and without any sort of analysis).
Example (code taken from the vmspec documentation):
From java code, we use "javac" to compile this:
void setIt(int value) {
i = value;
}
int getIt() {
return i;
}
to a java .class file. Using javap -c I can get this output:
Method void setIt(int)
0 aload_0
1 iload_1
2 putfield #4
5 return
Method int getIt()
0 aload_0
1 getfield #4
4 ireturn
This is OK for the disassembly part (not really good without analysis - "field #4 is Example.i"), but I can't find the two other "tools":
- A debugger that goes over the instructions themselves (with stack, memory dumps, etc), allowing me to examine the actual code and environment.
- A way to reverse the process - edit the disassembled code and recreate the .class file (with the edited code).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为这并不是一个完整的答案,但一些指针可能提供一些可行的东西:
(1)在查看和直接使用字节码方面,旧的 BCEL 类构建工具包 可能很有用(它是我所知道的唯一字节码 GUI 编辑器)。
(2)在调试和单步执行字节码方面,这个Eclipse插件,它与Eclipse的调试器集成可能会满足您的需求。
我不知道有任何实用程序可以结合这些功能并允许您在执行代码时操作字节码(至少以与 OllyDbg 等中相同的方式)。但是,Java 调试器 API 应该是能够支持在运行时操作代码(不过,考虑到 HotSpot 和 JIT 的一般性质,我不知道是否可以在调用指令之前重写指令——当前执行的字节码操作码实际上是解释器如何选择实现操作的抽象,与本机代码不同,在本机代码中,反汇编的操作码实际上是发送到 CPU 的指令)。或者,您可以查看 Java Instrumentation API提供了一种在运行时重新定义字节代码的方法。当然,任何各种开源字节码操作库都可以是能够提供帮助或提供灵感。
当然,总是可以选择绕过整个 JVM 基础设施并简单地将调试器附加到 JVM 进程。 在此问题和从该问题链接到此页面。
然而,底线是,您似乎试图完成的事情虽然在本机代码世界中很常见,但在 Java 世界中并不常见(使用 Java 的部分原因是抽象)从所有血淋淋的细节中)。这一点,以及字节码反编译(与 C++ 相比)的相对琐碎性质,导致了这种类型的需求稀缺的情况,这种类型的工具也是稀缺的。
I don't think this is really a full answer, but some pointers that may provide something workable:
(1) In terms of viewing and directly working with bytecode the old BCEL Class Construction Kit can be useful (it's the only GUI editor for bytecode I'm aware of).
(2) In terms of debugging and stepping through the bytecode, this Eclipse plugin, which integrates with Eclipse's debugger may meet your needs.
I'm not aware of any utilities that would combine these features and allow you to manipulate bytecode while the code is being executed (at least in the same way you can in OllyDbg, etc.). However, the Java debugger API should be able to support manipulating the code at runtime (though, given the nature of HotSpot and JIT in general, I don't know if it would be possible to rewrite an instruction just before it is invoked --- the currently executing bytecode opcode is really an abstraction for how the interpreter chooses to implement the op, unlike native code where the disassembled opcode is, in fact, the instruction sent to the CPU). Alternatively, you could look into the Java Instrumentation API which provides a way to redefine byte code at runtime. And, of course, any of the various open source bytecode manipulation libraries may be able to help or provide inspiration.
And, of course, there is always the option of of circumventing the whole JVM infrastructure and simply attaching a debugger to the JVM process. There's some discussion of this in this question and on this page linked from that question.
The bottom line, however, is, that what you seem to be trying to accomplish, while common-place in the world of native code, is not all that common a practice in the Java world (part of the reason for using Java is abstraction from all the gory details). This, and the relatively trivial nature of byte code decompilation (compared with, say C++) has lead to a situation where this type of requirement is scarce and so is this type of tooling.
查看 JAD Decomplier 用于反编译 Java 代码。然后,您可以使用生成的源代码运行 IDE 的内置调试器。 IDE 可以是 IntelliJ、Eclipse 或 NetBeans。这种方法不是完全自动的,但它应该可以完成工作。
Take a look at JAD Decomplier for decompiling Java code. You can then run an IDE's built-in debugger using produced sources. IDE can be IntelliJ, Eclipse or NetBeans. This approach is not completely automatic, but it should do the job.