1

我正忙于一个简单的 Android 反编译器。我想做一个漂亮的反编译视图。我使用 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支持?

4

1 回答 1

1

编码:

public class Foo {
    public byte[] bar = new byte[3];
}

编译为相同:

class Foo2 {
    public byte[] bar;

    public Foo2() {
        this.bar = new byte[3];
    }
}

这里没有“文字”,字段初始化程序和初始化程序块只是被添加到每个构造函数的代码之前(我认为是源代码顺序)——您要查找的信息不会被保留。您必须查看那些构造函数的反编译代码并以某种方式对其进行分析,但这将是模棱两可的。

此构造函数的操作码是:

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];。它们的大致意思是:

  1. this引用压入堆栈。
  2. 将整数压3入堆栈。
  3. 弹出3堆栈顶部的整数(the),创建该长度的字节数组,将数组压入堆栈。
  4. 将堆栈顶部的值(字节数组)设置为堆栈顶部倒数bar第二个对象的字段#2(即 )的值(this)。(另外,将这两个从堆栈中弹出。)

这并不能很好地映射到原始 Java 源代码;如您所见,对应于“new byte[3]”的部分被插入到实现“this.bar = ...”的部分中间,即使对于像这样简单的表达式,事情也会发生混乱。从字节码重构语句可能不会是微不足道的——它们没有明确分隔,当你从堆栈中弹出所有内容时,语句就结束了。

于 2012-07-17T22:50:16.460 回答