4

Java プログラムを逆コンパイルし、派生した (難読化された) ソースを再コンパイルしたいと考えています。.jar アーカイブを解凍すると、次のようなディレクトリ構造が得られました。

com/
com/foo/A/
com/foo/A/A.class
com/foo/A/B.Class
com/foo/B/A.class
...
com/foo/A.class
com/foo/B.class
org/foo/Bar.class
...

問題は、パッケージとクラスの間に名前の衝突があり、逆コンパイルされたクラス ファイルを再コンパイルできないことです。逆コンパイルされたクラスは次のようになります。

package org.foo;
import com.foo.A; // <-- name collision error

class Bar {
    ...
}

クラスファイルの名前を変更せずに、これらの命名の問題を解決する方法はありますか?

編集: これは逆コンパイラの問題ではありませんが、命名規則に違反するクラスを含む .jar ファイルを動作させる方法についての質問です。

EDIT2:わかりました、バイトコードレベルでそのような命名が可能だと思いますので、よりスマートな逆コンパイラ(クラスの名前を自動的に変更して参照を修正する)を使用すると、この問題を解決できます。

4

3 に答える 3

2

jar ファイル全体を解凍して、すべてを再コンパイルする必要がありますか? 逆コンパイルされたソース全体を単独で再コンパイルする代わりに、元の jar をクラスパスとして使用し、変更が必要なクラスのみを抽出して再コンパイルします。次に、再コンパイルしたコードをパッケージ化する必要がある場合は、元の jar をコピーし、jar -uf を使用して、変更されたクラス ファイルを置き換えます。

jar -uf ./lib/copy_of_original_jar_file.jar -C ./bin com/foo/A.class com/foo/B.class [...]

...そして ./lib/copy_of_original_jar_file.jar が新しいライブラリになります。

1 つ確かなことは、プログラムを実行するためには、元の jar が Java クラスローダーで適切に動作する必要があるということです。1 回限りの .class ファイルをコンパイルする場合と同様に機能するはずです。

元の jar を使用すると、実行中のアプリケーションが使用するのと同じクラスパス スキャン順序が維持されるため、名前の競合の問題が大幅に減少するはずです。それだけでなく、Java 逆コンパイラーは完璧ではありません。逆コンパイルされたコードの大部分を再コンパイルから除外することで、例外ハンドラーのオーバーラップ、難読化されたシンボルの特殊文字、変数のスコープの問題など、逆コンパイラーが持つ問題の大部分を回避できます。

于 2010-12-28T22:16:29.417 に答える
1

Java のインポート メカニズムは名前付けの省略形を提供しますが、衝突がある場合は明らかにそれを使用できません。コードではいつでも完全修飾名を使用できます。

package org.foo;  

class Bar { 
    private com.foo.Bar aDifferentBar;
    ...
}

編集:

JVM 仕様に準拠していても、JLS 仕様に準拠した Java プログラムでは生成できないクラス ファイルが存在する可能性があると思います。もしそうなら、間違いなくよりスマートな逆コンパイラが必要になります。

于 2010-12-28T17:36:16.573 に答える
0

Java ではパッケージをインポートできないのに、なぜこれが名前衝突になるのでしょうか? コンパイラからどのエラー メッセージが表示されますか?

難読化されたコードで名前の競合が発生すると、コードは実行されません。したがって、逆コンパイルされたコードには衝突がないはずです。

于 2010-12-28T17:16:23.563 に答える