1. 程式人生 > >安卓程式碼混淆

安卓程式碼混淆

Proguard是安卓提供的方便開發者對程式碼和apk進行保護和精簡的工具,可在SDK/tools資料夾下找到。

 

proguard的作用 :

1,程式碼混淆

2,精簡程式碼,刪掉沒有用到的程式碼,減小apk的體積。

 

使用場景:

1,對sighed APK進行程式碼混淆和精簡,從而使得釋出的程式碼可以防止被別人反編譯解析。(注意,直接build生成的APK是不進行混淆的,必須是signed的apk才會混淆)

2,對jar包進行混淆,方便將自己的程式碼(jar包)給別人使用並保證關鍵程式碼的不可見性。

 

下面分別針對以上兩種情況進行說明:

混淆APK:

所謂混淆APK,就是讓反編譯APK後得到的程式碼是混淆的。在Android Studio中,可以自動在打包APK的時候程式碼進行混淆。方法很簡單,只需要三步:

  • 在app下的build.gradle中配置:

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }

}

上面紅色的單詞由false改成true

  • 在proguard-rules.pro中進行配置,即按照proguard的語法規則對自己工程中的程式碼進行選擇性的混淆。這裡給出一個典型的配置如下:

 

-optimizationpasses 5                                             #指定程式碼壓縮級別

-dontusemixedcaseclassnames                                 #混淆時不會產生形形色色的類名

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

-dontpreverify                                              #不預校驗,如果需要預校驗,是-dontoptimize

-ignorewarnings                                             #遮蔽警告

-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.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

-keep class android.support.v7.** { *; }    #過濾android.support.v7  注意這裡v4還是v7要看gradle裡面compile了那個擴充套件包

-keep interface android.support.constraint.** { *; }

-keep class com.alibaba.fastjson.** {*;}    #保持第三方包fastjson不被混淆,否則會報錯

 

以上程式碼中,藍色基本可以固定不變,綠色部分是為了讓引入的第三方包不混淆,如果不新增會報錯。比如不新增v7支援包則會導致Studio對整個V7包進行混淆 ,然後就發現它會混淆好久。。。至於對自己建立的包裡面那些類需要混淆哪些不混淆,讀者可以自己百度這方面的語法規則,數不勝數。

  • 利用Studio中的build-signedAPK釋出簽名APK,完了以後在app下就會生成app-release.apk,這個就是我們得到的混淆程式碼後的apk。下圖就是反編譯APK以後得到的 jar包中的程式碼,已經被混淆。

 

 

混淆JAR包:

 

jar包的混淆方法我之前試過在Studio中進行,結果愣是沒搞定,然後我就採用的proguard自帶的GUI介面實現了jar包混淆,方法為:

 

在安卓SDK下找到\tools\proguard\bin資料夾,開啟proguardgui.bat(linux下為.sh),出現一個介面,這裡其實挺簡單,首先按照上面說的proguard-rules.pro裡面的規則寫一個配置檔案,字尾是.txt,然後載入,直接跳到最後一步process即可,這裡需要注意的是,配置檔案裡面跟之前不太一樣,主要有兩點區別:

 

1,因為是對jar包混淆,所以需要寫上injar和outjar的名字,比如我寫的:

 

-injars android.jar

-outjars 'confuseDemo.jar'

 

其中android.jar是需要混淆的jar包(放到proguardgui.bat同個目錄下),後者為混淆後的 jar包,會自動在該目錄下生成。

 

2,被混淆的jar包不包含裡面引用到的第三方庫,需要在配置檔案裡面宣告它用到的第三方jar包,比如我寫的:

 

-libraryjars C:\Users\Machenike-Pc\Desktop\fastjson.jar

-libraryjars C:\Users\Machenike-Pc\Desktop\org.apache.http.legacy.jar

-libraryjars  E:\softneed\Andriod\AndroidSDK\platforms\android-21\android.jar

 

需要注意最後一行,因為安卓工程肯定要用安卓SDK,因此要加上對應版本的sdk中的jar包

其他的寫法跟之前的proguard-rules.pro相同。

 

 

最後總結一下:在混淆過程中,如果工程比較大,一次混淆很可能會出現各種問題,這裡就需要有耐心逐個排除。在較大的工程中引用的jar包可能會有數十個,各個jar包在官網或使用說明裡可能會有說明如何在混淆中使用。如果沒有,最好是將整個jar包都不要混淆,即加上規則: -keep class xx.xxx.xxxx.** {*;} ,該方法可以將jar包裡面的所有類和子包裡面的類都排除不混淆,就不會出現問題。 此外即使所有的包都不混淆,也有報錯的可能,主要有兩個原因:

1.沒有按照規則把系統元件,資源類,列舉等排除,比如我在專案中就忘記了將實現Parcelable介面的類排除,結果導致伺服器傳來的資料無法獲取,app執行時沒有正常顯示資料。

2.有的jar包中使用了反射技術,此時在呼叫時就會出現及時jar包沒有混淆,但是如果呼叫的類混淆了,也會產生錯誤。這種情況下需要通過看log日誌,定位到出錯的類,將該類混淆去掉。