2012-02-10 13 views
10

私はJavassistを使用して、クラスがロードされるときに動的に操作しています。メソッドにコードを追加するのは比較的簡単ですが、にはコードを削除する方法がありません。Javaバイトコードからの命令の削除

現時点では、nop命令を使用して、コードの削除をシミュレートして、ターゲットのオペコードとパラメータを置き換えます。しかし、私はほとんどハックになるこのことを考慮してください。

  • 各オペコードは、パラメータのバイト長が異なるため、別々に処理する必要があります。場合によっては、削除されたオペコードがスタックに影響を与えるかどうかによって、noppopのいずれかを選択する必要もあります。この種の操作は退屈になり始めており、コードはそれに応じて複雑になっています。ですから、当然のことながら、私は既存のソリューションを望んでいます。

  • 最終結果はnopの指示で満たされます。 JVMはパフォーマンスに影響を与えずにそれらを最適化する必要がありますが、結果として得られるバイトコードはまだまだ魅力的でなく、それよりも大きくなければなりません。これは美学の問題の多くですが、それはまだ検討するべきことです。

残念ながら、単にギャップを閉じるためにバイトコード配列の一部をシフトすることは十分ではない - 移動コード(例えば、分岐命令インデックス)への参照が同様に更新されるべきです。

Javassistを使用して命令を削除することはできますか?あるいは、私自身がバイトコードを本質的に解析することなく、簡単に行うことができるバイトコード操作ライブラリがありますか?

+2

私は興味があります。なぜあなたはこれをしたいのですか?クラスを逆コンパイルして変更してコンパイルするのは簡単ではないでしょうか? – Luixv

+0

@Luixv:私は操作プロセスを実行時に自動的に実行したい - 実際のソースコードを手動で変更することはオプションではない。 – thkala

+0

クラスを 'jar'に置くと、重複した' nop'がかなりよく圧縮され、圧縮されたサイズはあまり大きくなりません。 –

答えて

3

Apache BCELあなたはdelete instructionsすることができます:命令の

削除も非常に簡単です。指定された範囲内のすべての命令ハンドルおよび包含された命令は、命令リストから除去され、廃棄される。しかし、delete()メソッドは、命令ターゲットが依然として削除された命令の1つを参照しているときに、TargetLostExceptionをスローする可能性があります。ユーザーはtry-catch節でそのような例外を処理し、これらの参照を別の場所にリダイレクトする必要があります。

マニュアルにも例があります。 Javassistのチュートリアルから

+0

+1私はまだBCELを見ていないが、それは有望であると思う。私は既存のコードにどのように組み込むのが簡単かわかります... – thkala

0

Javassistのメソッドやフィールドを削除することはできませんが、名前を変更することができます。したがって、メソッドがもう必要でない場合は、CtMethodで宣言されたsetName()およびsetModifiers()を呼び出すことによって、メソッドを名前を変更してプライベートメソッドに変更する必要があります。

+0

私はメソッドを削除したくありません - メソッド内のメソッドを削除したいです*メソッド内... – thkala

+0

おっと、私の悪い!完全性のために、このチュートリアルでは、 'フィールドまたはメソッドを削除するには、CtClassのremoveField()またはremoveMethod()を呼び出します。 :S – user1205938

関連する問題