需要:Java 字节码反汇编器,以十六进制显示地址、操作码、操作数

逆向工程 爪哇 十六进制 反汇编者
2021-06-12 04:03:33

我在寻找一个 java 字节码反汇编器,它的输出包括字节码本身、它们的操作数和它们在 .class 文件中的地址,并以十六进制而不是十进制显示数字。

为了说明我的意思,这里有几行摘自 javap 的输出:

private java.text.SimpleDateFormat createTimeFormat();
  Code:
   Stack=3, Locals=2, Args_size=1
   0:    new    #84; //class java/text/SimpleDateFormat
   3:    dup
   4:    ldc    #17; //String yyyy-MM-dd'T'HH:mm:ss
   6:    invokespecial    #87; //Method java/text/SimpleDateFormat."<init>":(Ljava/lang/String;)V
   9:    astore_1

我发现的每个 Java 字节码反汇编器(我在谷歌上花了很多时间,并下载了几个不同的尝试)产生的输出基本上与此相同。一些格式或稍微不同的装饰;有些用漂亮的 GUI 替换命令行界面;但其中没有一个显示 .class 文件中指令的地址,也没有显示字节码本身 - 有几个声称显示字节码,但实际上没有一个显示,它们只显示表示字节码的文本助记符,而不是字节码本身。此外,它们都以十进制而不是十六进制显示数字信息。

这是上述输出的编辑版本,我手动对其进行了转换,以生成我正在寻找的类型的示例:

private java.text.SimpleDateFormat createTimeFormat();
  Code:
   Stack=3, Locals=2, Args_size=1
000010cf    0:    bb 00 54    new    #54; //class java/text/SimpleDateFormat
000010d2    3:    59          dup
000010d3    4:    12 11       ldc    #11; //String yyyy-MM-dd'T'HH:mm:ss
000010d5    6:    b7 00 57    invokespecial    #57; //Method java/text/SimpleDateFormat."<init>":(Ljava/lang/String;)V
000010d8    9:    4c          astore_1

行开头的地址对应于 .class 文件中指令的位置,就像在普通的十六进制转储中可以找到的那样。显示了字节码及其操作数的十六进制表示,反汇编显示了十六进制的常量。

有什么可用的东西会产生类似的输出吗?字段的顺序是否不同并不重要,只要它们都在那里即可。它必须在 Linux 上运行,无论是本机还是在 Java 下。

3个回答

也许radare2就是你要找的。看这个截图:

radare2 反编译 java 字节码

如果您只需要在原始文件中查找需要更改的字节,IDA 会在状态栏中显示原始文件的偏移量。您还可以在十六进制视图中检查操作码。

IDA 中的 Java 文件

我不知道有什么反汇编器可以做到这一点,但我已经编写了一个具有字节码输出模式的 Java 反编译器。它是开源的,很容易修改以满足您的需求。随意在这里检查一下