真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Android混淆-創(chuàng)新互聯(lián)

一、為什么要混淆

為了避免apk在發(fā)布后被用戶通過反編譯拿到源代碼和資源文件,然后修改資源和代碼之后就變成一個新的apk。而經(jīng)過混淆后的APK,即使被反編譯,也難以閱讀,注意混淆不是讓apk不能閱讀,而是加大閱讀的難度,為了避免勞動成果被竊取,也避免出現(xiàn)安全漏洞和隱患,所以在apk發(fā)布之前一定要進(jìn)行混淆。

創(chuàng)新互聯(lián)致力于互聯(lián)網(wǎng)網(wǎng)站建設(shè)與網(wǎng)站營銷,提供成都網(wǎng)站設(shè)計、成都網(wǎng)站制作、網(wǎng)站開發(fā)、seo優(yōu)化、網(wǎng)站排名、互聯(lián)網(wǎng)營銷、小程序開發(fā)、公眾號商城、等建站開發(fā),創(chuàng)新互聯(lián)網(wǎng)站建設(shè)策劃專家,為不同類型的客戶提供良好的互聯(lián)網(wǎng)應(yīng)用定制解決方案,幫助客戶在新的全球化互聯(lián)網(wǎng)環(huán)境中保持優(yōu)勢。

二、混淆的原理

Java是一種跨平臺、解釋型語言,Java源代碼編譯成的class文件中有大量包含語義的變量名、方法名的信息,很容易被反編譯為Java源代碼。為了防止這種現(xiàn)象,我們可以對Java字節(jié)碼進(jìn)行混淆?;煜粌H能將代碼中的類名、字段、方法名變?yōu)闊o意義的名稱,保護代碼,也由于移除無用的類、方法,并使用簡短名稱對類、字段、方法進(jìn)行重命名縮小了程序的大小。

ProGuard由shrink、optimize、obfuscate和preverify四個步驟組成,每個步驟都是可選的,需要哪些步驟都可以在腳本中配置。參見ProGuard官方介紹。
壓縮(Shrink):默認(rèn)開啟,偵測并移除代碼中無用的類、字段、方法和特性,減少應(yīng)用體積,并且會在優(yōu)化動作執(zhí)行之后再次執(zhí)行(因為優(yōu)化后可能會再次暴露一些未使用的類和成員)。
-dontshrink 關(guān)閉混淆
優(yōu)化(Optimize):默認(rèn)開啟,分析和優(yōu)化字節(jié)碼,讓應(yīng)用運行的更快。
-dontoptimize 關(guān)閉優(yōu)化,默認(rèn)混淆配置文件開始
-optimizationpasses n 表示proguard對代碼進(jìn)行迭代優(yōu)化的次數(shù),Android一般為5
混淆(Obfuscate):默認(rèn)開啟,使用a、b、c、d這樣簡短而無意義的名稱,對類、字段和方法進(jìn)行重命名,增大反編譯難度。
-dontobfuscate 關(guān)閉混淆
上面三個步驟使代碼大小更小、更高效,也更難被逆向工程。
預(yù)檢(Preverify):在java平臺上對處理后的代碼進(jìn)行預(yù)檢。
混淆流程圖:

Android混淆
Proguard讀入input jars(or wars,zip or directories),經(jīng)過四個步驟生成處理之后的jars(or wars,ears,zips or directories),Optimization步驟可選擇多次進(jìn)行。
為了確定哪些代碼應(yīng)該被保留,哪些代碼應(yīng)該被移除或混淆,需要確定一個或多個Entry Point。Entry Point經(jīng)常是帶有main methods,applets,midlets的classes,它們在混淆過程中會被保留。
Proguard的幾個步驟如何處理Entry Points。
(1).在壓縮階段,Proguard從上述Entry Points開始遍歷搜索哪些類和類成員被使用。其他沒有被使用的類和類成員會移除。
(2).在優(yōu)化階段,Proguard進(jìn)一步設(shè)置非Entry Point的類和方法為private、static和final來進(jìn)行優(yōu)化,不使用的參數(shù)會被移除,某些方法會被標(biāo)記為內(nèi)聯(lián)。
(3).在混淆階段,Proguard重命名非Entry Points的類和類成員。
(4).預(yù)檢階段是唯一沒有觸及Entry Points的階段。

三、Android Studio默認(rèn)的混淆方案及字段解讀

1.開啟混淆    

在build.gradle文件內(nèi)相應(yīng)的構(gòu)建類型中添加minifyEnabled true即可。
除了minifyEnable屬性外,還有用于定義ProGuard規(guī)則的proguardFiles屬性:

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

官方文檔介紹:
getDefaultProguardFile('proguard-android.txt')方法可從Android SDK tools/proguard/文件夾獲取默認(rèn)的ProGuard設(shè)置。要想做進(jìn)一步的代碼壓縮,請嘗試使用位于同一位置的proguard-android-optimize.txt文件。它包括相同的Proguard規(guī)則,但還包括其他在字節(jié)碼一級(方法內(nèi)和方法間)執(zhí)行分析的優(yōu)化,以進(jìn)一步減少APK大小和幫助提高其運行速度。
proguard-rules.pro文件用于添加自定義Proguard規(guī)則。默認(rèn)情況下,該文件位于模塊根目錄(build.gradle文件旁),內(nèi)容為空。
在gradle 2.2之后,defaultProguardFile沒有使用sdk目錄下的proguard-android.txt,而是使用了gradle自帶的proguard-android.txt,不同的gradle版本帶有不同的默認(rèn)混淆文件,在項目根目錄的build/intermediates/proguard-files/proguard-android.txt-2.3.1。
混淆配置文件不檢查規(guī)則是否重復(fù),如果兩條規(guī)則沖突,則采用白名單的,比如設(shè)置了開啟優(yōu)化和不優(yōu)化兩個選項后,不論順序,最終都會執(zhí)行不優(yōu)化的操作。

2.構(gòu)建輸出

構(gòu)建時Proguard都會輸出下列文件:(build之后)
(1)dump.txt --- 說明APK中所有類文件的內(nèi)部結(jié)構(gòu)
(2)mapping.txt --- 提供原始與混淆過的類、方法和字段名稱之間的轉(zhuǎn)換
(3)seeds --- 列出未進(jìn)行混淆的類和成員
(4)usage.txt --- 列出從APK移除的代碼
這些文件保存在/build/outputs/mapping/release目錄下。

3.解碼混淆過的堆棧追蹤

使用混淆后,保存好mapping文件,程序csh時通過腳本進(jìn)行解碼。
retrace工具位于/tools/proguard/目錄下,解碼命令為:

retrace.bat|retrace.sh [-verbose] mapping.txt []

4.默認(rèn)的混淆方案及字段解讀

(1)不適用大小混寫類名

-dontusemixedcaseclassnames

默認(rèn)情況下混淆的類名可以包含大小寫字符的混合
(2)不忽略公共類庫

-dontskipnonpubliclibraryclasses

指定不去忽略非public的library classes。從Proguard 4.5開始,是默認(rèn)的設(shè)置。
(3)不優(yōu)化指定的文件與不預(yù)檢驗

-dontoptimize
-dontpreverify

默認(rèn)optimize和preverify選項是關(guān)閉的,因為Android的dex并不想Java虛擬機需要optimize(優(yōu)化)和previrify(預(yù)檢)兩個步驟。
(4)指定哪個屬性不要混淆,可一次指定多個屬性

-keeppattributes [attribute_filter]

通常Exceptions,Signature,Deprecated,SourceFile,SourceDir,LineNumberTable,LocalVariableTable,LocalVariableTypeTable,Synthetic,EnclosingMethod,RuntimeVisibleAnnotations,RuntimeInvisibleAnnotations,RuntimeVisibleParameterAnnotations,RuntimeInvisibleParameterAnnotations,AnnotationDefault屬性需要被保留,根據(jù)項目具體使用情況保留。

gradle默認(rèn)的keepattributes屬性不全,只保留了Annotations,Signature,InnerClasses,EnclosingMethod,為了混淆之后定位csh代碼方便,需要在proguard_rules.pro中手動添加拋出異常時保留代碼行號,并且重命名超出異常時的文件名稱,這樣能方便定位問題:
#拋出異常時保留代碼行號

 -keeppattributes SourceFile,LineNumberTable

#重命名拋出異常時的文件名稱

  -renamesourcefileattribute SourceFile

keep選項制定了哪些類,哪些方法不被混淆,從而保證了程序的正常運行。
keep用法有6種:
(1)-keep(names)選項 指定類和類成員(變量和方法)不被混淆
-keep [,modifier,...] class_specification
//指定類名不被改變

      -keep public class com.google.vending.licensing.ILicensingService

//指定使用了Keep注解的類和類成員都不被改變

      -keep @android.support.annotation.Keep class * {*;}

(2)-keepclassmembers(names) 指定類成員不被混淆,類名會被混淆

      //keep setters in views 使得animations仍然能夠工作

               -keepclassmembers public class * extends android.view.View {
        void set*(***);
        *** get*();
      }

(3)-keepclasseswithmembers(names) 指定類和類成員都不被混淆
-keepclasseswithmembers [,modifier,...] class_specification
//包含native方法的類名和native方法都不能被混淆,如果native方法未被調(diào)用,則被移除。由于native方法與對應(yīng)so庫中的方法名稱對應(yīng),方法名被混淆會導(dǎo)致調(diào)用出現(xiàn)問題,所以native方法不能被混淆。

-keepclasseswithmembernames class * {
         native ;
}

不帶names的選項為From being removed or renames,既不會被移除或重命名,即使類或類成員未被使用。帶有names的選項為From being renamed,不會被重命名,如果是無用的類或類成員,會被移除,移除是指在壓縮(Shrinking)時是否會被刪除。
通用Options:
(1)-verbose 打印混淆詳細(xì)信息
(2)-dontnote選項:指定不去輸出打印該類產(chǎn)生的錯誤或遺漏
-dontnote com.android.vending.licensing.ILicensingService
-dontnote android.support.**
(3)-dontwarn選項:指定不去warn unresolved references和其他重要的problem
-dontwarn android.support.**
如上面(2)(3)所示,android.support的libraries需要保留。

四、自定義混淆文件

1.Filters

?    匹配一個字符
*    匹配一個名字,除了目錄外分隔符外的任意部分
**    匹配任意名,可能包含任意路徑分隔符
!   排除
    匹配類中的所有字段
 匹配類中所有的方法
     匹配類中所有的構(gòu)造函數(shù)

-keep class com.lily.test.**      本包和所包含子包下的類名都保持
-keep class com.lily.test.*      保持該包下的類名
-keep class com.lily.test.** {*;}   保持包和子包的類名和里面的內(nèi)容均不被混淆

如果要保留一個類中的內(nèi)部類不被混淆則需要用$符號。

2.-assumenosideeffects指令:

assumeosideeffects是Optimization過程中的選項,所以為保證指令的有效,需要開啟optimization。這個指令的含義是Proguard會在optimization過程中刪除對這些方法的調(diào)用,需要注意:當(dāng)你知道你在做什么的時候才能使用它。

3.一個自定義文件

Android混淆

#代碼混淆壓縮比,在0~7之間
-optimizationpasses 5# 
#混淆時不適用大小寫混合,混合后的類名為小寫
-dontusemixedcaseclassnames

#指定不去忽略非公共庫的類
-dontskipnonpubliclibraryclasses

#不做預(yù)校驗,preverify是proguard的四個步驟之一,Android不需要precerify,去掉這一步能夠加快混淆速度。
-dontpreverify

-verbose

#google推薦算法
-optimizations !code/simplification/arithmetic,!code/simplication/cast,!field/*,!class/mergin/*

#避免混淆Annotation、內(nèi)部類、泛型、匿名類
-keepattributes *Annotation*,InnerClasses,Signature,EnclosingMethod

#重命名拋出異常時的文件名稱
-renamesourcefileattribute SourceFile

#拋出異常時保留代碼行號
-keepattributes SourceFile,LineNumberTable

#處理support包
-dontnote android.support.**
-dontwarn android.support.**

#保留四大組件,自定義的Application等這些類不被混淆
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * entends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

#保留本地native方法不被混淆
-keepclasseswithmembernames class * {
native }

#保留枚舉類不被混淆
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

#第三方j(luò)ar包不被混淆
-keep class com.github.test.** {*;}

#保留自定義的Test類和類成員不被混淆
-keep class class.lily.Test {*;}

#保留自定義的xlog文件夾下面的類、類成員和方法不被混淆
-keep class com.text.xlog.** {;;
}

#assume no side effects;刪除android.util.Log輸出的日志
-assumenosideeffects class android.util.Log {
public static *** v(...);
public static *** d(...);
public static *** i(...);
public static *** w(...);
public static *** e(...);
}

#保留keep注解的類名和方法
-keep,allowobfuscation @interface android.support.annotation.Keep
-keep @android.support.annotation.Keep class *
-keepclassmember class * {
@android.support.annotation.Keep *;
}

Android混淆

五、常用到的不混淆

1.jni方法不混淆

jni方法不混淆,因為方法需要和native方法保持一致。

-keepclasseswithmembernames class * { 
    # 保持native方法不被混淆
    native ;
}

2.反射不混淆

反射用到的類不混淆(否則混淆可能出現(xiàn)問題)。

-keepatrributes EnclosingMethod

3.AndroidMainfest中的類不混淆

AndroidMainfest中的類不混淆,所以四大組件和Application的子類和Framework層下所有的類默認(rèn)不會進(jìn)行混淆。自定義的View默認(rèn)也不會被混下,所以排除自定義View,或者四大組件被混淆的規(guī)則在ndroid Studio中無需加入的,下面是兼容性比較高的規(guī)則:

Android混淆

-keep public class * extends android.app.Fragment
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Service
-keep public class * extends android.content。BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * entends android.app.backup.BackupAgentHelper
-keep public class * entends android.preference.Preference

Android混淆

4.JSON對象類不混淆

與服務(wù)器交互時,使用GSON、fastjson等框架解析服務(wù)端數(shù)據(jù)時,所寫的JSON對象類不混淆,否則無法將JSON解析成對應(yīng)的對象。

5.第三方開源或SDK包

使用第三方開源庫或者引用其他第三方的SDK包時,如果有特別要求,也需要在混淆文件中加入對應(yīng)的混淆規(guī)則。

6.WebView的JS調(diào)用的接口方法不混淆

有用到WebView的JS調(diào)用也需要保證寫的接口方法不混淆,原則和第一條一樣。

-keepclassmembers classs fqcn.of.javascript.interface.for.webview {
    public *;
}

7.Parcelable的子類和Creator靜態(tài)成員變量不混淆

Parcelable的子類和Creator靜態(tài)成員變量不混淆,否則會產(chǎn)生Android.os.BadParcelableException異常;

-keep class * implements Android.os.Parcelable { 
    # 保持Parcelable不被混淆
    public static final Android.os.Parcelable$Creator *;
}

8.enum類型

使用enum類型時需要注意避免以下兩個方法混淆,因為enum類的特殊性,以下兩個方法會被反射調(diào)用。

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

9.注解不混淆

-keepatrributes *Annotation*
-keep class * extends java.lang.annotation.Annotation {*;}

10.泛型不混淆

-keepattributes Signature

11.內(nèi)部類不混淆

-keepattributes InnerClasses

六、第三方混淆參考規(guī)則

1.Gson

-dontwarn com.google.**
-keep class com.google.gson.** {*;}

2.otto

-keepattributes *Annotation*
-keepclassmembers class ** {
    @com.squareup.Subscribe public *;
    @com.squareup.otto.Produce public *;
}

3.universal-p_w_picpath-loader

-dontwarn com.nostra13.universalp_w_picpathloader.**
-keep class com.nostra13.universalp_w_picpathloader.** {*;}

4.友盟統(tǒng)計

Android混淆

-keepclassmembers class * {
    public  (org.json.JSONObject);
}
#友盟統(tǒng)計5.0.0以上SDK需要
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
#友盟統(tǒng)計R.java刪除問題
-keep public class com.gdhbgh.activity.R$*{
    public static final int *;
}

Android混淆

5.OkHttp

-dontwarn com.squareup.okhttp.**
-keep class com.squareup.okhttp.** {*;}
-keep interface com.squareup.okhttp.** {*;}
-dontwarn okio.**

6.nineoldandroids

-dontwarn com.nineoldandroids.*;
-keep class com.nineoldandroids.** {*;}

7.支付寶

Android混淆

-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keep class com.alipay.sdk.app.PayTask{
    public *;
}
-keep class com.alipay.sdk.app.AuthTask{
    public *;
}

Android混淆

8.Socket.io

-keep class socket.io-client.
-keepclasswithmembers,allowshrinking class socket.io-client.* {*;}
-keep class io.socket.
-keepclasseswithmembers,allowshrinking class io.socket.* {*;}

9.JPUSH

-dontwarn cn.jpush.**
-keep class cn.jpush.** {*;}

# protobuf(jpush依賴)
-dontwarn com.google.**
-keep class com.google.protobuf.** {*;}

10.友盟分享

Android混淆

-dontwarn com.umeng.**
-dontwarn com.tencent.weibo.sdk.**

-keep public interface com.tencent.**
-keep public interface com.umeng.socialize.**
-keep public interface com.umeng.socialize.sensor.**
-keep public interface com.umeng.scrshot.**

-keep public class com.umeng.socialize.* {*;}

-keep class com.umeng.scrshot.**
-keep public class com.tencent.** {*;}
-keep class com.umeng.socialize.sensor.**
-keep class com.umeng.socialize.handler.**
-keep class com.umeng.socialize.handler.*
-keep class com.tencent.mm.sdk.modelmsg.WXMediaMessage {*;}
-keep class com.tencent.mm.sdk.modelmsg.** implements com.tencent.mm.sdk.modelmsg.WXMediaMessage$IMediaObject {*;}

-keep class im.yixin.sdk.api.YXMessage {*;}
-keep class im.yixin.sdk.api.** implements im.yixin.sdk.api.YXMessage$YXMessageData{*;}

-keep class com.tencent.** {*;}
-dontwarn com.tencent.**
-keep public class com.umeng.soexample.R$*{
public static final int *;
}
-keep class com.tencent.open.TDialog$*
-keep class com.tencent.open.TDialog$* {*;}
-keep class com.tencent.open.PKDialog
-keep class com.tencent.open.PKDialog {*;}
-keep class com.tencent.open.PKDialog$*
-keep class com.tencent.open.PKDialog$* {*;}

-keep class com.sina.** {*;}
-dontwarn com.sina.**
-keep class com.alipay.share.sdk.** {*;}

Android混淆

七、常見的一些問題

1.網(wǎng)絡(luò)層混淆

一般網(wǎng)絡(luò)層都不進(jìn)行混淆,可以經(jīng)過劃分包后直接不混淆網(wǎng)絡(luò)層的包:

-keep class com.xxx.xxx.http.** {*;}

2.數(shù)據(jù)模型混淆

-keep class * implements java.io.Serializable {*;}
-keepclassmembers class * implements java.io.Serializable {*;}

有時候上面的這種方式可能會導(dǎo)致應(yīng)用卡住,沒有任何錯誤提示,所以建議采用分包模式,吧所有bean放在同一個包中,直接對該包加白名單。

-keep class com.xxx.xxx.domain.xx {*;}

3.XML映射混淆

如果遇到一些空間無法Inflate,報NullPointException,比如ListView,NavigationView等等

-keep class *.** {*;}

4.混淆規(guī)則編寫方法

如果混淆后報錯,通過retrace后找到錯誤的問題后可以直接編寫規(guī)則來去掉混淆,但是如果報的錯誤莫名其妙,而且報錯的類沒有混淆,那么可以采用極端的方法,加入下面的規(guī)則:

-keep class *.** {*;}

這條規(guī)則表示不混淆所有類及其中所有代碼,加了這條規(guī)則之后,還不能運行表示是其他問題,例如注解,內(nèi)部類等等,可以運行后,可以通過反編譯,尋找所有包名,記錄下來,吧上述規(guī)則改為:

-keep class android.** {*;}
-keep class com.** {*;}
-keep class org.** {*;}

一個個去掉檢查是否有報錯,例如查到

-keep class com.** {*;}

加了就沒有錯誤,則可以繼續(xù)一級級往下檢查。
但要注意,有時候可能是幾個包混合問題。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。


文章名稱:Android混淆-創(chuàng)新互聯(lián)
當(dāng)前URL:http://weahome.cn/article/isieh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部