2

私は2つの一般的な解決策があるように思われることを発見しました:

  1. リフレクションAPI[ RetroguardJobfuscate ]を介して参照されるものを難読化しないでください
  2. リフレクションAPI呼び出しの文字列を難読化された名前に置き換えます。

これらのソリューションは、同じプロジェクト内の呼び出しに対してのみ機能します。クライアントコード(別のプロジェクト内)は、リフレクションAPIを使用して非公開APIメソッドにアクセスすることはできません。

2の場合、Reflection APIがコンパイル時に既知の文字列で使用されている場合にのみ機能します(プライベートメソッドのテスト?)。そのような場合、 dp4jは、難読化後にリフレクションコードを挿入するソリューションも提供します。

Proguard FAQを読んで私はそれが言うとき2がそうでなければ常に働いたかどうか疑問に思いました:

ProGuardは、Class.forName( "SomeClass")やSomeClass.classなどの構成を自動的に処理します。参照されるクラスは縮小フェーズで保持され、文字列引数は難読化フェーズで適切に置き換えられます。

可変文字列引数を使用すると、通常、可能な値を判別することはできません。

Q:太字のステートメントはどういう意味ですか?例はありますか?

4

3 に答える 3

2

Zelix KlassMaster Java 難読化ツールは、すべての Reflection API 呼び出しを自動的に処理できます。「暗号化された古い名前」から「難読化された名前」のルックアップ テーブルを使用する AutoReflection という機能があります。

ただし、同じ難読化されたプロジェクト内の呼び出しに対してのみ機能します。

http://www.zelix.com/klassmaster/docs/tutorials/autoReflectionTutorial.htmlを参照してください。

于 2012-03-05T20:53:15.123 に答える
2

可変文字列引数では、通常、可能な値を決定することはできません。

public Class loadIt(String clsName) throws ClassNotFoundException {
    return Class.forName(clsName);
}

基本的に、非定数文字列を Class.forName に渡すと、proguard や難読化ツールがどのクラスについて話しているかを判断する方法が通常ないため、コードを自動的に調整することはできません。

于 2011-04-17T07:29:43.737 に答える
1

これは、次のことを意味します。

String className;
if (Math.random() <= 0.5) className = "ca.simpatico.Foo";
else className = "ca.simpatico.Bar";
Class cl = Class.forName(className);

難読化後は機能しません。ProGuard は、ロードされるクラス名がこれら 2 つの文字列リテラルに由来することを確認するのに十分なほど深いデータフロー分析を行いません。

実際、唯一のもっともらしいオプションは、リフレクションを介してアクセスできるクラス、インターフェイス、およびメソッドを決定し、それらを難読化しないことです。クライアントに対して奇妙な種類の API を効果的に定義しています。

于 2011-04-17T08:12:28.903 に答える