Android代码混淆一直以来是一件让人特别头疼的事,我也在网上或者别人的博客里参考了很多,大体上的思路是一样的。下面我就写一下我自己在写代码混淆时的步骤和遇到的一些问题。仅供参考!
1.
首先确保你创建的安卓程序中存在这两个文件,如果没有也不要着急,从别人的程序中拷贝一下这两个文件放到你的程序中就行啦~~~
2.文件project.properties中把#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt这句话中的#符号去掉。
3.接下来是编写proguard-project.tex中的代码,这一步是最重要的。首先,你的程序中有第三方的类库,有些类库是不能混淆的。当你在调用这些类库时,官网上应该都有介绍
语法
<span style="font-size:14px;">-basedirectory {directoryname} 指定基础目录为以后相对的档案名称
-injars {class_path} 指定要处理的应用程序jar,war,ear和目录
-outjars {class_path} 指定处理完后要输出的jar,war,ear和目录的名称
-libraryjars {classpath} 指定要处理的应用程序jar,war,ear和目录所需要的程序库文件
-dontskipnonpubliclibraryclasses 指定不去忽略非公共的库类。
-dontskipnonpubliclibraryclassmembers 指定不去忽略包可见的库类的成员。
保留选项
-keep {Modifier} {class_specification} 保护指定的类文件和类的成员
-keepclassmembers {modifier} {class_specification} 保护指定类的成员,如果此类受到保护他们会保护的更好
-keepclasseswithmembers {class_specification} 保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。
-keepnames {class_specification} 保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)
-keepclassmembernames {class_specification} 保护指定的类的成员的名称(如果他们不会压缩步骤中删除)
-keepclasseswithmembernames {class_specification} 保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)
-printseeds {filename} 列出类和类的成员-keep选项的清单,标准输出到给定的文件
压缩
-dontshrink 不压缩输入的类文件
-printusage {filename}
-whyareyoukeeping {class_specification}
优化
-dontoptimize 不优化输入的类文件
-assumenosideeffects {class_specification} 优化时假设指定的方法,没有任何副作用
-allowaccessmodification 优化时允许访问并修改有修饰符的类和类的成员
混淆
-dontobfuscate 不混淆输入的类文件
-printmapping {filename}
-applymapping {filename} 重用映射增加混淆
-obfuscationdictionary {filename} 使用给定文件中的关键字作为要混淆方法的名称
-overloadaggressively 混淆时应用侵入式重载
-useuniqueclassmembernames 确定统一的混淆类的成员名称来增加混淆
-flattenpackagehierarchy {package_name} 重新包装所有重命名的包并放在给定的单一包中
-repackageclass {package_name} 重新包装所有重命名的类文件中放在给定的单一包中
-dontusemixedcaseclassnames 混淆时不会产生形形色色的类名
-keepattributes {attribute_name,...} 保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and
InnerClasses.
-renamesourcefileattribute {string} 设置源文件中给定的字符串常量 </span></span>
Demo
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-libraryjars libs/alipaySDK-20150610.jar
-dontwarn com.alipay.**
-dontwarn com.ta.utdid2.**
-dontwarn com.ut.device.**
-keep class com.alipay.** { *; }
-keep class com.ta.utdid2.** { *; }
-keep class com.ut.device.** { *; }
-libraryjars libs/android-async-http-1.4.8.jar
-dontwarn com.loopj.android.http.**
-keep class com.loopj.android.http.** { *; }
-libraryjars libs/android-support-v4.jar
-dontwarn android.support.v4.**
-keep class android.support.v4.** { *; }
-keep interface android.support.v4.** { *; }
-keep public class * extends android.support.v4.**
-keep public class * extends android.app.Fragment
-libraryjars libs/jg_filter_sdk_1.1.jar
-libraryjars libs/libammsdk.jar
-dontwarn com.tencent.**
-keep class com.tencent.** { *; }
-keep class com.tencent.wxop.** { *; }
-libraryjars libs/mid-sdk-2.20.jar
-libraryjars libs/mta-android-stat-sdk-2.1.0_20160111.jar
-keep class com.tencent.stat.** {* ;}
-keep class com.tencent.mid.** {* ;}
-libraryjars libs/wup-1.0.0-SNAPSHOT.jar
-libraryjars libs/Xg_sdk_v2.38_20150616_1057.jar
-keep class com.tencent.android.tpush.** {* ;}
-keep class com.tencent.mid.** {* ;}
-libraryjars libs/armeabi/libtpnsSecurity.so
-libraryjars libs/armeabi/libtpnsWatchdog.so
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
-keepclassmembers class com.shinewonder.shinecloudapp.** {*;}
-keepclassmembers class com.shinewonder.shinecloudapp.wxapi.**{*;}
-keep class android.** {*; }
-keep public class * extends android.view
-keep public class * extends android.app.Fragment
-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
-keep class com.tencent.mm.sdk.openapi.WXMediaMessage {*;}
-keep class com.tencent.mm.sdk.openapi.** implements com.tencent.mm.sdk.openapi.WXMediaMessage$IMediaObject {*; }
-keep public class * extends LinearLayout
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set*(...);
}
-keepclasseswithmembernames class * {# 所有native的方法不能去混淆
native <methods>;
}
-keepclasseswithmembers class * {#某些构造方法不能去混淆
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {#某些构造方法不能去混淆
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity { # 保持自定义控件类不被混淆
public void *(android.view.View);
}
-keepclassmembers enum * {#枚举类不能去混淆
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable { #aidl文件不能去混淆
public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class **.R$* {*;}#不混淆R文件里的资源
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
-keep class com.test.model.response.** {*;}#反射类不能进行混淆编译</span></span>
demo只是我自己的程序的混淆,不全面,你自己的程序还有哪些不需要混淆,自己再写进去就可以了。
4.最后一步:签名打包。
完成这四步,你的代码混淆就算完成了,接下来检验一下你的混淆是否成功了
我测试用到的这个工具ApkIDE.exe。ApkIDE是反编译你的apk的,
操作特别简单,首先把你的打开ApkIDE.exe,把你混淆好的apk拖拽到里面就能进行反编译了
证明反编译成功了
编译好的程序中的smali就是class,你的一些class被一些a,b,c......字母代替了,证明你的反编译成功了。恭喜你!
我的代码混淆就介绍这么多了
温馨提示:
代码混淆是一个特别麻烦的工作,中间会出现好多的错误,导致你混淆后的apk根本就无法运行,这时候你需要用到ddms.bat这个工具进行调试。