バイトコードの難読化の目標は、デコンパイラーが正しいJavaソースコードをビルドできなかったJVMコマンドのセットをビルドすることです。
難読化ツールと逆コンパイラーの対立は常に続いています。
たとえば、 Soot研究プロジェクトの枠組みでは、 JBCO難読化ツールとDAVAデコンパイラーが同時に開発されており、その開発者は互いに競合しています。
侵入者や真正な開発者がJavaプログラムを逆コンパイルする必要があるのはなぜですか?
- 独自のAPIリバースエンジニアリング
- さまざまなライセンスメカニズムを無効にするためのバイトコードの変更
- 機密情報へのアクセスの取得
従来の難読化ツールは、2番目のタイプの攻撃に対する保護で比較的うまく機能します。 JavaプログラムはJava APIを使用するため、リバースエンジニアリングからの支援は不十分です。JavaAPIはパブリックであり、難読化ツールはそれを変更できません。 例外が1つありますが、これは難読化ツールではなく、Java APIのネイティブ実装であるExcelsior JETを備えた本格的な仮想マシンです。
現在、トロイの木馬に「ブーム」があり、JVMの脆弱性を使用してユーザーのコンピューターに侵入して悪意のあるアクションを実行していることは周知の事実です。
Javaコードを保護する最新の手段は、逆コンパイルから保護するのではなく、Javaサンドボックス内にサンドボックスを編成する必要があります:)
Java / Java FXアプリケーションのライセンスシステムC3の開発中にこれらの問題に直面しました。 そして、 ストリンガーが生まれました。
現実に戻りましょう。 商用Javaアプリケーション(さまざまなAndroidアプリケーションを含む)の開発者が保護したいロジックのほとんどは、文字列に関連付けられています...ああ、これらのjava.lang.Stringの。
たとえば。 インターネットリソースから特定の形式のデータを受信し、解析してユーザーに表示するグラフィカルクライアントがあります。 攻撃者はJavaクラスの定数プールにアクセスするだけで十分であり、クローンプログラムを作成することは難しくありません。
通常、開発者は文字列暗号化機能を使用するか、これらの機能をサポートする難読化ツールを使用して、これらの攻撃から保護します。
ストリンガーはこのタスクを非常にうまく行うことができます。
- 暗号化は、保護された各Javaパッケージの動的暗号化キーを使用したAESアルゴリズムに基づいています
- 復号化関数のロジックは、既存のクラスファイルに動的に埋め込まれます。
保護を埋め込む前の逆コンパイルされたクラスファイルの断片:
public class App { public static void main(String args[]) { System.out.println("Hello World!"); } }
保護を組み込んだ後の逆コンパイルされたクラスファイルの断片:
public class App { public static void main(String args[]) { System.out.println(main("\u916E\u2E67\uCB8D\u16B9\u479D\u7669\u3F20\uD7DC\u75C5\u30F1\uEC7E\uA26B\uEEB0\u2F0E\u4828\u19C6")); } .... }
- 復号化呼び出しコンテキスト保護
さらに、上記のサンドボックスの編成の可能性:リフレクションの使用に対する保護、クラスおよびメソッドのプライベートフィールドの保護、最終クラスフィールドの変更からの保護。
ほとんどすべての開発者は文字列暗号化機能を必要とし、製品のユーザーを情報盗難から保護したい企業のために、StringerはJavaアプリケーション内で安全な環境を編成することができますが、このトピックは別の投稿に値します...
現在、Androidアプリケーション用のStringerを開発しています。
お楽しみに:)
PS
ところで、私たちのCrackMeをクラックした人はいませんでした。
Habrのユーザーに加えて、Javalobbyのユーザーも非常に積極的に参加しました。 合計ダウンロード数は約1,000であり、参加者のうち1人だけがライセンスサーバーとのやり取りの段階に達しました。