我正忙于开发一个简单的 Android 反编译器。我想做一个漂亮的反编译 View 。我使用dex2jar。
假设我有一个字段声明:public byte[] test = new byte[2];
使用 FieldVisitor
我得到:
public as modifier
byte[] as type
test as name
and an Object as value <--
如果您有像 byte[2]
这样的对象,是否可以获取 new byte[2]
literal
?
最佳答案
代码:
public class Foo {
public byte[] bar = new byte[3];
}
编译结果与:
class Foo2 {
public byte[] bar;
public Foo2() {
this.bar = new byte[3];
}
}
这里没有“文字”,字段初始化程序和初始化程序 block 只是被添加到每个构造函数的代码中(我认为按源代码顺序) - 您正在查找的信息不会被保留。您必须查看这些构造函数的反编译代码并以某种方式对其进行分析,但这会是不明确的。
此构造函数的操作码是:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_3
6: newarray byte
8: putfield #2; //Field bar:[B
11: return
索引 4 到 8 对应于行 this.bar = new byte[3];
。它们的意思大致是:
- 将
this
引用压入堆栈。 - 将整数
3
压入堆栈。 - 从堆栈顶部弹出一个整数(
3
),创建该长度的字节数组,然后将该数组压入堆栈。 - 将堆栈顶部的值(字节数组)设置为堆栈上倒数第二个对象 (
this
) 的字段 #2(即bar
)的值。 (另外,将两者从堆栈中弹出。)
这并不能很好地映射到原始的 Java 源代码;正如您所看到的,与“new byte[3]”相对应的部分被插入到实现“this.bar = …”的部分的中间,即使对于像这样简单的表达式,事情也会发生困惑。从字节码重建语句可能不会是微不足道的 - 它们没有明确分隔,当您从堆栈中弹出所有内容时,语句就会结束。
关于java - 如何以编程方式将值编译为源文字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11531775/