1. 程式人生 > >Android程式碼混淆需要知道以及注意的事情

Android程式碼混淆需要知道以及注意的事情

自古英雄不問出處,奈何我卻不是英雄!

以前專案中沒有做過程式碼混淆,近期公司專案被安全測試機構檢測出安全問題,結果第一個就是混淆問題,木有辦法,只有混淆了。沒有做過混淆真是一頭霧水,前前後後搞了三天,想想也是喝多了。

說道混淆,就要提一下為什麼混淆。如果不加混淆分分鐘把你程式碼反編譯出來。至於有什麼影響我這裡就不說了,既然你們看到這篇文章那麼你們就是出現各自的問題了。

要注意的是不同的版本,不同IDE之間是有一些不同的。Eclipse中老版本的ADT裡面是proguard.cfg,然後在defult.properties加入proguard.config=proguard.cfg。defult.properties檔案是這樣的

# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-19
proguard.config=proguard.cfg

新版ADT沒有了proguard.cfg而是換成了project.properties和proguard-project.txt。其實沒啥區別在project.properties加入proguard.config=proguard-project.txt。就可以了。proguard-project.txt檔案是這樣的。
這裡要知道一個地方proguard.cfg是可以直接拿過來當proguard-project.txt用的。

# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
# proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

# Project target.
target=android-19
proguard.config=proguard-project.txt
新版ADT沒下面說一下android studio的使用,到了android studio中又有了不同這回沒有了proguard-project.txt變成了proguard-rules.txt其實就是名字變了而已。用法一樣。不同的是studio中沒有了eclipse裡面的project.properties或者defult.properties。而是換成了build.gradle。build.gradle中有這麼一段。只要把minifyEnabled 後面的false改為true就會執行混淆程式碼了。
buildTypes {
    release {
        // minifyEnabled為true會執行proguard-rules.txt混淆程式碼
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
    }
}

說完了兩個IDE已經不同版本之間的不同再來說一下混淆程式碼時候一些注意的地方

1、android studio下 jar問題

我想你應該見過下面的程式碼。需要知道的是這個在android studio中是不能用的如果你加了這個在編譯的時候會出現
> java.io.IOException: The same input jar [D:\xx\app\libs\xx.jar] is specified twice.(我就不翻譯了)在eclipse是不會有問題了

-libraryjars libs/alipaysdk.jar
-libraryjars libs/alipaysecsdk.jar
-libraryjars libs/alipayutdid.jar
-libraryjars libs/android-support-v4-21.jar

2、javabean解析為null

如果你的專案中用到了Gson。並且你的程式在混淆之後執行後發現獲取了資料,但是在看解析成Gson的時候都是null,那麼你就要加上下面的程式碼。這裡要注意最後一行。這個是你javabean物件的路徑

-keepattributes Signature
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.** { *; }
-keep class com.xx.xx.**{ *; }

3、微信分享問題

微信的分享或者支付相當很多程式都有接入。很多第三方sdk為了在專案混淆的時候避免自己的sdk出現問題,在開發後臺會提醒開發者在混淆的時候加上自己提供的一些-keep程式碼。來確保混淆的時候sdk不被混淆。如果你加上下面這段程式碼那麼蛋疼的時候就來了,我看很多開發者因為這是在網上直接說微信分享就是垃圾。微信提供的是這句。

-keep class com.tencent.mm.sdk.openapi.WXMediaMessage {*;}
-keep class com.tencent.mm.sdk.openapi.** implements com.tencent.mm.sdk.openapi.WXMediaMessage$IMediaObject {*;}
誰會想到微信官方提供的竟然不能用。因為這段程式碼是可以用的,不過要放到以前。微信後來更新了支付還有其他的功能之後,那麼這個jar包結構就變了。我因此也是弄了半天,本來一個複製貼上的時候搞的這麼悲催換了誰都會怒一把。加上下面這兩句程式碼就可以(不要問我為什麼)
-dontwarn com.tencent.mm.**
-keep class com.tencent.mm.**{*;}

4、自定View問題

(這個問題我網上沒看到和我相似情況的帖子)如果你專案中有自定義的View,那麼要保持自定義View不被混淆。一般情況下網上的混淆帖子都會給出下面三個程式碼段中的後兩個。但是我加上後兩個之後仍然會出錯,後來我又加上了第一個才解決了問題

-keepclasseswithmembers class * {
    public <init>(android.content.Context);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
5、webview與js互動,方法無法呼叫

如果你的專案中有webView頁面比且需要和android互動的話,要注意加上下面的程式碼。如果不加在webView頁面呼叫android程式碼會不起作用。下面程式碼用萬用字元的目的是解決如果一個專案中有多個webView頁面的情況

-keepattributes *JavascriptInterface*
-keepclassmembers class com.xx.activity.**$**{ //萬用字元標識的分別是activity的名字和類名 注意下面的事例
  public *;
}
專案例項
    /**
     * AndroidHtml 5J函式說明 ()
     */
    final class MaiLeGouApp { // MaiLeGouApp 就是第二個萬用字元
        @JavascriptInterface
        public void XX(String xx, String xx) {
           
        }        
    }

這是我在專案中遇到的一些問題,感覺這些問題聽普遍的,所以寫了出來,希望能幫到也在做混淆的你們。以後這篇文章還會更新。