Android应用开发之代码混淆
混淆器(ProGuard)
混淆器通过删除从未用过的代码和使用晦涩名字重命名类、字段和方法,对代码进行压缩,优化和混淆。结果是一个比較小的.apk文件,该文件比較难进行逆向project。因此,当你的应用程序对安全敏感(要求高),比如当你授权应用程序的时候,混淆器是一种重要的保护手段。
混淆器被集成在android构建系统中,所以你不必手动调用它。同一时候混淆器仅在公布模式下进行构建应用程序的时候才会执行起来,所以在调试模式下构建程序时,你不必处理混淆代码。让混淆器执行起来是可选择的,可是推荐选上。
1.改动project.properties
#ThisfileisautomaticallygeneratedbyAndroidTools. #Donotmodifythisfile--YOURCHANGESWILLBEERASED! # #ThisfilemustbecheckedinVersionControlSystems. # #TocustomizepropertiesusedbytheAntbuildsystemedit #"ant.properties",andoverridevaluestoadaptthescripttoyour #projectstructure. # #ToenableProGuardtoshrinkandobfuscateyourcode,uncommentthis(availableproperties:sdk.dir,user.home): #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt #Projecttarget. target=android-19
将proguard.config前面的凝视去掉
2.改动proguard-project.txt
#ToenableProGuardinyourproject,editproject.properties #todefinetheproguard.configpropertyasdescribedinthatfile. # #AddprojectspecificProGuardruleshere. #Bydefault,theflagsinthisfileareappendedtoflagsspecified #in${sdk.dir}/tools/proguard/proguard-android.txt #YoucanedittheincludepathandorderbychangingtheProGuard #includepropertyinproject.properties. # #Formoredetails,see #http://developer.android.com/guide/developing/tools/proguard.html #Addanyprojectspecifickeepoptionshere: #IfyourprojectusesWebViewwithJS,uncommentthefollowing #andspecifythefullyqualifiedclassnametotheJavaScriptinterface #class: #-keepclassmembersclassfqcn.of.javascript.interface.for.webview{ #public*; #}
假设在程序中使用了第三方的`jar`包,在混淆后导致出错,这时我们须要在proguard-project.txt中去进行对应的配置,来让其在混淆时不要混淆对应的jar包。对改配置文件里的相关配置解释例如以下:
```java -keeppublicclass*extendsandroid.app.Activity【不进行混淆类名的类,保持其原类名和包名】 -keeppublicabstractinterfacecom.asqw.android.Listener{ publicprotected<methods>;【全部publicprotected的方法名不进行混淆】 } -keeppublicclasscom.asqw.android{ publicvoidStart(java.lang.String);【对该方法不进行混淆】 } -keepclasseswithmembernamesclass*{【对全部类的native方法名不进行混淆】 native<methods>; } -keepclasseswithmembersclass*{【对全部类的指定方法的方法名不进行混淆】 public<init>(android.content.Context,android.util.AttributeSet); } -keepclassmembersclass*extendsandroid.app.Activity{【对全部类的指定方法的方法名不进行混淆】 publicvoid*(android.view.View); } -keepclassmembersenum*{【对枚举类型enum的全部类的下面指定方法的方法名不进行混淆】 publicstatic**[]values(); publicstatic**valueOf(java.lang.String); } -keepclass*implementsandroid.os.Parcelable{【对实现了Parcelable接口的全部类的类名不进行混淆,对其成员变量为Parcelable$Creator类型的成员变量的变量名不进行混淆】 publicstaticfinalandroid.os.Parcelable$Creator*; } -keepclasseswithmembersclassorg.jboss.netty.util.internal.LinkedTransferQueue{【对指定类的指定变量的变量名不进行混淆】 volatiletransientorg.jboss.netty.util.internal.LinkedTransferQueue$Nodehead; volatiletransientorg.jboss.netty.util.internal.LinkedTransferQueue$Nodetail; volatiletransientintsweepVotes; } -keeppublicclasscom.unionpay.**{*;}【对com.unionpay包下全部的类都不进行混淆,即不混淆类名,也不混淆方法名和变量名】 ```
经过上面这两部之后反编译后就能混淆了,可是四大组件还在,为什么四大组件还在呢,由于四大组件是在清单文件里进行配置的,假设混淆后就不能依据清单文件的配置去寻找了。
假设对于一些自己的代码中要想提供出来让别人通过反射调用的方法时,我们不想让部分代码被混淆,或者是我们使用别人提供的第三方jar包,由于第三方的jar包一般都是已经混淆过的,我们要是再混淆就会报错了,所以我们要保证这些内容不用混淆,这里我们仅仅需改动这个文件,然后加上后面的一句话,他就不会混淆我们给出的内容
-keepattributes*Annotation* -keeppublicclass*extendsandroid.app.Activity -keeppublicclass*extendsandroid.app.Application -keeppublicclass*extendsandroid.app.Service -keeppublicclass*extendsandroid.content.BroadcastReceiver -keeppublicclass*extendsandroid.content.ContentProvider -keeppublicclass*extendsandroid.app.backup.BackupAgent -keeppublicclass*extendsandroid.preference.Preference -keeppublicclass*extendsandroid.support.v4.app.Fragment -keeppublicclass*extendsandroid.app.Fragment -keeppublicclasscom.android.vending.licensing.ILicensingService -keepclasscom.itheima.mobilesafe.engine.AppInfoProvider -keepclassnet.youmi.android.**{ *; }