如何以编程方式将值编译为源文字?

时间:2012-07-17 22:31:29

标签: java decompiler dex2jar

我正忙着为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 回来?

1 个答案:

答案 0 :(得分: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)堆栈顶部,创建一个该长度的字节数组,将数组推入堆栈。
  4. 将堆栈顶部的值(字节数组)设置为堆栈中第二个顶层对象的字段#2(即bar)的值({{ 1}})。 (另外,将两个弹出窗口。)
  5. 这并没有真正映射到原始的Java源代码;如你所见,对应于“new byte [3]”的部分被插入到实现“this.bar = ...”的部分的中间,即使表达式如此简单,事情也会发生故障。从字节码重构语句可能不会是微不足道的 - 它们不是显式分隔的,当你从堆栈中弹出所有内容时语句结束。