androidアプリでコード混淆の実例を詳しく説明します。
新しい任務を受けて、既存のプロジェクトにコードを混同する。以前は混淆に対していくつか理解したことがあって、しかしあまり詳しくて完全ではありませんて、一部のものが混淆し始めることを知っています。でも、今のプロジェクトはあまり複雑ではないので、早めに完成します。
第一部分
操作の流れを紹介します。
1、混淆器を開けます。プロジェクトのルートディレクトリにあるproject.propertiesファイルを見つけて、「嗲progurd.co fig={sdk.dir}/tools/progurd/progurard-and.txt:progurd-project.txt」という行の前の「ζ」を削除すればいいです。
2、混淆プロファイルを修正します。プロジェクトのルートディレクトリの下にあるprogurd-project.txtファイルを見つけて、その中のコードを修正します。この部分が一番重要です。
3、関連ファイルを保存して後でエラーが発生した時に使用します。主にエクスポートされたappkファイルとプロジェクトのルートディレクトリの下のプログレッシブディレクトリのファイル(主にmapping.txt)とプロジェクトのソースコードがあります。
4、プロジェクトの運行過程でエラー処理:エラー情報と第3ステップで保存したmappingによってエラー位置を特定します。
これらを知ってから、私たちはそれを展開します。eclipseを開けてプロジェクトを新規作成します。デフォルトではprogurd-project.txtとproject.propertiesを作成します。私たちのコードを作成して、プログレッシブ-project.txtの「((au)progurd.co.fig=$sdk.dir)/tools/proggaard/progurd-android.txt:progurd-project.txt」を削除して、最後に導き出すとコードの混同ができます。以下は私のテストコードです。
上記のコードを分析すると、ユーザー定義の方法名は特別な意味のない短い文字に置き換えられていますが、activityのonCreateの方法は変わりません。最後のtestErrer()メソッドは私たちが起動していないので削除されました。これらはデフォルトの混淆処理戦略です。ここを見たら、混同しているような気がします。それとも小caseのですか?
続けて、私達はログアウトしたtestErr()を開けて、包装運転の時にエラーが発生します。エラー情報は下記の通りです。
retrace.bat mappings.txt logs.txt
上の図からよく分かるように、エラーログのb()方法は私達の実際のコードの中のsetName()方法です。
ここで注意したいのは、appingをエクスポートするたびにプロジェクト内のディレクトリのプログレッシブフォルダの下で一つの対応するmappingファイルを生成するので、各アプリに対しては対応するmappingファイルを保存する必要があります。これで全部紛らわしい流れを紹介しました。
参考:
公式文書:http://developer.android.com/tools/help/proguard.html
公式文書の翻訳:http://www.cnblogs.com/over140/archive/2011/04/22/2024528.html (自分でひっくり返したいですが、昔農民のおじさんが翻訳していました。ここで直接引用して感謝しています。)
第二部分
第一部分はどのように操作するかを説明しました。公式文書を参照して、基本的に把握します。残りも一番難しいのがprogurd-project.txtファイルの作成です。この部分については、二つの処理戦略があります。自分で作成して、他の人が書いたものを使ってください。まず、他の人が書いたものをどう使うかというと、私達が引用した第三者の倉庫は開源にしても閉鎖源にしても、特別な状況があれば、彼のUser Guideに混同コードの配置を見つけられます。例えば、私達は有名なguilllep PulTorefshを引用したら、彼の文の中から次のコードを見つけられます。
以前と比較して,その中のget String法は混同されていないことを見出した。そうです。上のプログレッシブ-project.txtはMainActivityのget Stringを維持するという意味です。上記の混淆コードに注釈されている2行の効果を試してみてもいいです。
ここでProGardの核心部分に触れ始めました。残りはProGardの文書を読み、彼の文法を把握して使います。完全なプログラードの翻訳文書を探していますが、Nを探してみましたが、一つも見つけられませんでした。しかも、点々とした翻訳もとても少なくて、最近は時間がきついです。それに、能力も限られています。ここではまず簡単にkeepコマンドを紹介します。
-keep[,modifier,…]class_specification
あなたのコードには、切り込みポイントとして保持されるクラスまたはクラスのメンバー(属性と方法)を指定します。例えば、アプリケーションを維持するために、メインクラスと彼のメインメソッドを指定することができます。ライブラリを処理するためには、彼のpublic訪問の要素を詳しく説明する必要があります。
また、keepの簡単な概要と文法中の規範もあります。Class Specificationでは、構造方法、属性、方法、*と*の違いなどを教えてくれます。例えば、*は任意のクラス名にマッチするが、パケットのセパレータは含まれない。*は任意のクラス名にマッチし、任意の数のパケットセパレータを含んでいる。したがって、上記のコメントのコードの意味は以下の通りである。2行目はcomp.ttdevs.progurdのすべてのクラスとサブパッケージのクラスを維持するすべての方法とメンバー変数が混同されません。
//TODOの詳細はまだたくさんあります。例えば、-library jars、-dontwarn、-keepatoributesなど、これを続けましょう。
この文章を通して、読者のコードの混淆を助けることができることを望んで、みんなの当サイトに対する支持に感謝します。
第一部分
操作の流れを紹介します。
1、混淆器を開けます。プロジェクトのルートディレクトリにあるproject.propertiesファイルを見つけて、「嗲progurd.co fig={sdk.dir}/tools/progurd/progurard-and.txt:progurd-project.txt」という行の前の「ζ」を削除すればいいです。
2、混淆プロファイルを修正します。プロジェクトのルートディレクトリの下にあるprogurd-project.txtファイルを見つけて、その中のコードを修正します。この部分が一番重要です。
3、関連ファイルを保存して後でエラーが発生した時に使用します。主にエクスポートされたappkファイルとプロジェクトのルートディレクトリの下のプログレッシブディレクトリのファイル(主にmapping.txt)とプロジェクトのソースコードがあります。
4、プロジェクトの運行過程でエラー処理:エラー情報と第3ステップで保存したmappingによってエラー位置を特定します。
これらを知ってから、私たちはそれを展開します。eclipseを開けてプロジェクトを新規作成します。デフォルトではprogurd-project.txtとproject.propertiesを作成します。私たちのコードを作成して、プログレッシブ-project.txtの「((au)progurd.co.fig=$sdk.dir)/tools/proggaard/progurd-android.txt:progurd-project.txt」を削除して、最後に導き出すとコードの混同ができます。以下は私のテストコードです。
public class MainActivity extends Activity {
private String mName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mName = ttdevs;
getString(mName);
setName(mName);
showDialog();
// testError();
}
public String getString(String name) {
return hello + name;
}
public void setName(String name) {
System.out.println(I'm + name);
}
private void showDialog() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
ScoreAlertDialog.showDialog(MainActivity.this);
}
}, 2000);
}
public static class ScoreAlertDialog {
public static void showDialog(final Activity activity) {
if (activity.isFinishing()) {
return;
}
try {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle(alert_title);
builder.setNegativeButton(cancel, null);
builder.setPositiveButton(submit, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
Toast.makeText(activity, Welcome, Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
});
builder.show();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void testError() {
try {
int error = 1 / 0;
} catch (Exception e) {
e.printStackTrace();
}
}
}
包装、逆コンパイル、最後に次のコードを得ました。上記のコードを分析すると、ユーザー定義の方法名は特別な意味のない短い文字に置き換えられていますが、activityのonCreateの方法は変わりません。最後のtestErrer()メソッドは私たちが起動していないので削除されました。これらはデフォルトの混淆処理戦略です。ここを見たら、混同しているような気がします。それとも小caseのですか?
続けて、私達はログアウトしたtestErr()を開けて、包装運転の時にエラーが発生します。エラー情報は下記の通りです。
java.lang.ArithmeticException: divide by zero
at com.ttdevs.proguard.MainActivity.b(Unknown Source)
at com.ttdevs.proguard.MainActivity.onCreate(Unknown Source)
at android.app.Activity.performCreate(Activity.java:4531)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1071)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2150)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2229)
at android.app.ActivityThread.access$600(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1261)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4945)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
この例は簡単なので、どこで問題が起きたか分かりやすいですが、やはり私たちが表現したい問題を説明します。混淆されたコードのエラー情報をどうやって還元しますか?この目的を達成するためには、3つのファイルが必要です。android-sdk-windows oolsprogardin etrace.bat、mappingn.txtと上記のエラー情報(logs.txt)。次のコマンド(windowシステム)を実行します。retrace.bat mappings.txt logs.txt
上の図からよく分かるように、エラーログのb()方法は私達の実際のコードの中のsetName()方法です。
ここで注意したいのは、appingをエクスポートするたびにプロジェクト内のディレクトリのプログレッシブフォルダの下で一つの対応するmappingファイルを生成するので、各アプリに対しては対応するmappingファイルを保存する必要があります。これで全部紛らわしい流れを紹介しました。
参考:
公式文書:http://developer.android.com/tools/help/proguard.html
公式文書の翻訳:http://www.cnblogs.com/over140/archive/2011/04/22/2024528.html (自分でひっくり返したいですが、昔農民のおじさんが翻訳していました。ここで直接引用して感謝しています。)
第二部分
第一部分はどのように操作するかを説明しました。公式文書を参照して、基本的に把握します。残りも一番難しいのがprogurd-project.txtファイルの作成です。この部分については、二つの処理戦略があります。自分で作成して、他の人が書いたものを使ってください。まず、他の人が書いたものをどう使うかというと、私達が引用した第三者の倉庫は開源にしても閉鎖源にしても、特別な状況があれば、彼のUser Guideに混同コードの配置を見つけられます。例えば、私達は有名なguilllep PulTorefshを引用したら、彼の文の中から次のコードを見つけられます。
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}</init></init></methods>
この部分のコードがあれば、直接に私達のプロジェクトにcopyを挿入することができます。この方式はまだcopy式です。では、以下の例を挙げてみます。コードを自分で書いてコントロールするのはどうすればいいですか?それとも第一部の例を使って、私達はこのプロジェクトのprogurd-project.txtファイルの中で(前は空いています)次のいくつかの行に参加します。
# -keep public class com.ttdevs.proguard.** { *; }
# -keepclasseswithmembers public class com.ttdevs.proguard.** { *; }
-keep public class com.ttdevs.proguard.MainActivity {
java.lang.String getString(java.lang.String);
}
そして、アプリをエクスポートして逆コンパイルして、次のコードを得ました。以前と比較して,その中のget String法は混同されていないことを見出した。そうです。上のプログレッシブ-project.txtはMainActivityのget Stringを維持するという意味です。上記の混淆コードに注釈されている2行の効果を試してみてもいいです。
ここでProGardの核心部分に触れ始めました。残りはProGardの文書を読み、彼の文法を把握して使います。完全なプログラードの翻訳文書を探していますが、Nを探してみましたが、一つも見つけられませんでした。しかも、点々とした翻訳もとても少なくて、最近は時間がきついです。それに、能力も限られています。ここではまず簡単にkeepコマンドを紹介します。
-keep[,modifier,…]class_specification
あなたのコードには、切り込みポイントとして保持されるクラスまたはクラスのメンバー(属性と方法)を指定します。例えば、アプリケーションを維持するために、メインクラスと彼のメインメソッドを指定することができます。ライブラリを処理するためには、彼のpublic訪問の要素を詳しく説明する必要があります。
また、keepの簡単な概要と文法中の規範もあります。Class Specificationでは、構造方法、属性、方法、*と*の違いなどを教えてくれます。例えば、*は任意のクラス名にマッチするが、パケットのセパレータは含まれない。*は任意のクラス名にマッチし、任意の数のパケットセパレータを含んでいる。したがって、上記のコメントのコードの意味は以下の通りである。2行目はcomp.ttdevs.progurdのすべてのクラスとサブパッケージのクラスを維持するすべての方法とメンバー変数が混同されません。
//TODOの詳細はまだたくさんあります。例えば、-library jars、-dontwarn、-keepatoributesなど、これを続けましょう。
この文章を通して、読者のコードの混淆を助けることができることを望んで、みんなの当サイトに対する支持に感謝します。