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) をスタックの一番上にポップし、その長さのバイト配列を作成し、その配列をスタックにプッシュします。
  4. barスタック (バイト配列) の一番上にある値を、スタック ( ) の上から 2 番目にあるオブジェクトのフィールド #2 (つまり ) の値として設定しますthis。(また、2 つをスタックからポップします。)

これは、元の Java ソースにうまく対応していません。ご覧のとおり、「this.bar = …」を実装する部分の途中に「new byte[3]」に相当する部分が挿入されており、これだけの単純な式でも順番が狂っています。バイトコードからステートメントを再構築することはおそらく簡単ではありません – それらは明示的に区切られていません.スタックからすべてをポップするとステートメントは終了します.

于 2012-07-17T22:50:16.460 に答える